Single versus multiple configuration instances

You can also configure multiple configuration instances by using the OSGi metatype services.

As described in the Describing configuration by using the OSGi Metatype service, you can use OSGi metatype service to support a single set of configuration properties for a given service (as identified by a configuration PID). It is also common to support multiple instances of the same configuration type, for example in the way that Liberty supports multiple entries for applications and data sources. This can be done by providing a metatype definition that tells the Liberty configuration parser, and the Configuration Admin service, that it is dealing with a factory configuration. Also, the class that receives the configuration needs to implement the org.osgi.service.cm.ManagedServiceFactory interface.

To support multiple instances of top-level configuration elements in the server.xml file as follows:
<server>
    <teenager name="joy" age="15" />
    <teenager name="angela" age="18" />
</server>
You must define the configuration in metadata by adding a factoryPid attribute to the Designate element.
Note: A pid attribute is still needed if you use a ManagedServiceFactory interface to receive the configuration; if you use a declarative service (DS) component, this is not required.
<?xml version="1.0" encoding="UTF-8"?>
<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.1.0"  
                   xmlns:ibm="http://www.ibm.com/xmlns/appservers/osgi/metatype/v1.0.0">

    <OCD id="teenager-ocd" name="teenager" >
       <AD id="name" name="name" type="String" />
       <AD id="age" name="age" type="Integer" />
    </OCD>

    <Designate factoryPid="teenager" pid="teenager">
        <Object ocdref="teenager-ocd" />
    </Designate>
  
</metatype:MetaData>
The ManagedServiceFactory implementation is registered as a ManagedServiceFactory service type, with the factory pid as follows:
bundleContext.registerService(ManagedServiceFactory.class, new MgdSvcFactoryImpl(), new Hashtable();
defaults.put(org.osgi.framework.Constants.SERVICE_PID, "teenager"));
The ManagedServiceFactory implementation receives a set of properties for each instance of the teenager configuration, each one uniquely identified by its own (internally generated) PID which is provided to the updated() method as follows:
public void updated(String pid, Dictionary<String, ?> properties)
			throws ConfigurationException {
	  String name = (String) properties.get("name");
    Integer age = (Integer) properties.get("age");
	}

If a particular configuration instance is deleted, for example because one of the teenager elements is deleted from the server.xml file, the ManagedServiceFactory implementation is notified through the deleted() method, and the pid of the deleted instance is provided. This allows the ManagedServiceFactory implementation to keep track of the instances that are valid at any given time.