Provides information about using the Configuration Admin
Configuration Management
Configuration is the process of assigning and providing configuration data to bundles, running in the OSGi framework. An application that wants to become configurable through the Configuration Admin, should register a Managed Service (org.osgi.service.cm.ManagedService) or Managed Service Factory (org.osgi.service.cm.ManagedServiceFactory) according to its needs.
The Configuration Admin provides management applications with access to exported configurations in the form of org.osgi.service.cm.Configuration objects.
The singleton configurations and factory configurations are stored persistently in the DB Bundle in a custom database called "CONFIG".
Exporting Configuration Properties
A service implementing ManagedService will receive a single set of properties when registered, or when a configuration object is created for it in the Configuration Admin, whichever happens later. It is also informed when its configuration object is changed in the Configuration Admin by a management application.
A service implementing ManagedServiceFactory will receive from 0 to n configuration sets when it registers in the OSGi framework. The factory is informed of updates and deletion of generated configuration objects in the Configuration Admin storage.
The following source is an example of a ManagedService implementation, which publishes the configuration properties as its service properties:
public class ConfigTest implements ManagedService, BundleActivator {
ServiceRegistration reg;
public void start(BundleContext bc) {
reg = bc.registerService(ManagedService.class.getName(),
this, getDefaults());
}
private Hashtable getDefaults() {
Hashtable defaults = new Hashtable();
defaults.put("port", "12345");
defaults.put("product", "device");
defaults.put("baud", "9600");
defaults.put(Constants.SERVICE_PID, "com.acme.serialport.device");
return defaults;
}
public synchronized void updated(Dictionary configuration) {
if (configuration == null){
reg.setProperties(getDefaults());
} else {
reg.setProperties(configuration);
}
}
public void stop(BundleContext bc) {
}
. . .
}
Metadata Management
Overview
The Config Bundle is responsible for loading a bundle's initial configuration data on the basis of metadata exported by the bundle. Management of configuration metadata uses the Extended Metatype API, which extends the OSGi Metatype one by allowing definition of object class instances for initial generation, of attribute and object class modifiers and properties, etc.
Configuration metatypes are handled by the Metatype Bundle, which implements the OSGi Metatype Specification and supports the Extended Metatype API. The bundle's Metadata Manager processes available configuration metatypes and delivers the information to the Config Bundle.
Exporting a Configuration Metatype
Configuration metadata should be put in a Metatype Provider with ID equal to Managed Service's or Managed Service Factory's PID and with a "template" ObjectClassDefinition again with ID equal to the PID.
For a configuration factory, the Metatype Provider can also provide one or more configuration objects in its metatype definition, which will be automatically generated and loaded in the Configuration Admin storage at bundle installation in the case of XML metadata and at bundle start in the case of Metatype Provider service.
A bundle developer has two options for providing configuration metadata - implement a service or write an XML.
Implement a Metatype Provider Service. In this case, a configuration metatype should be registered as an com.prosyst.mbs.services.metatype.MetaTypeProviderExtern service.
To indicate that the Metatype Provider contains configuration metadata, it should be registered with the following String properties:
The ObjectClassDefinition, representing a configuration, should be an instance of the ObjectClassDefinitionEx interface and its attributes - AttributeDefinitionEx instances. To indicate if a configuration and its attributes should be loaded in the Configuration Admin storage, the ObjectClassDefinition should have a modifier (returned by the getModifier method) with key load and value true. Otherwise, the configuration should be explicitly created with the config.create console command or with the Create option for the corresponding metatype in the Configurations tab of the Web Admin Console. Optional attributes can be loaded by default if their load modifier is true.
If the configuration is factory, the Metatype Provider can implement the getConfigurationObjects method so as to return ObjectClassDefinitionEx instances representing configuration objects to be automatically produced by the Config Bundle.
Write a metadata XML resource. XML metadata should be created in accordance with the proprietary DTD or according to the metatype XML Schema from the OSGi Service Platform, Service Compendium.
A bundle, which provides its metadata in the proprietary XML format of the OSGi SDK, must use the Config (for ManagedService) or FactoryConfig (for ManagerServiceFactory) manifest header, or both. Their syntax is:
For example:
FactoryConfig: xml=myconfigs/myhttpconfig.xml; pid=my.http.fpid; name=My HTTP Configuration Factory
You can also store a configuration metadata XML file in an external directory and specify only its PID or FPID in the bundle manifest header. Refer here for more details.
Following is an example of metadata XML for an HTTP server in the format introduced by the SDK. The snippet defines a metatype for a configuration factory and a set of two preloaded configuration instances (in the form of configobject elements) to be generated from the factory. Both inherit the default values of most of the properties defined for the factory. In particular, the first preloaded configuration definition replaces only the default value of the port and connectionType properties, while the second one - of port and requestTimeout:
A configuration metatype written in the Extended XML Format is presented below:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE metatype-provider SYSTEM "conf.dtd">
<metatype-provider>
<objectclass load="true">
<name>HTTP Server Configuration</name>
<id>my.http.fpid</id>
<description>HTTP Server Socket Configuration</description>
<attribute modifier="req">
<name>Port</name>
<id>port</id>
<description>Primary port on which client requests are accepted</description>
<type>∫</type>
<cardinality>0</cardinality>
<key name="minValue" value="1"/>
<key name="maxValue" value="65535"/>
<value>
<scalar>80</scalar>
</value>
</attribute>
<attribute modifier="opt">
<name>Secondary Port</name>
<id>secondaryPort</id>
<description>Secondary port is opened if primary port is busy</description>
<type>∫</type>
<cardinality>0</cardinality>
<key name="minValue" value="1"/>
<key name="maxValue" value="65535"/>
<value>
<scalar>8080</scalar>
</value>
</attribute>
<attribute modifier="req">
<name>Max Users</name>
<id>maxUsers</id>
<description>Maximum number of users simultaneously
connected with http server</description>
<type>∫</type>
<cardinality>0</cardinality>
<key name="minValue" value="0"/>
<key name="maxValue" value="50"/>
<value>
<scalar>50</scalar>
</value>
</attribute>
<attribute modifier="req">
<name>Request Timeout</name>
<id>requestTimeout</id>
<description>Timeout in seconds.
An inactive connection is closed after this timeout expiration.</description>
<type>∫</type>
<cardinality>0</cardinality>
<key name="minValue" value="0"/>
<key name="maxValue" value="300"/>
<value>
<scalar>30</scalar>
</value>
</attribute>
<attribute modifier="req">
<name>Connection Type</name>
<id>connectionType</id>
<description>Type of connection:
1 for plain connection and 2 for secure connection.</description>
<type>∫</type>
<cardinality>0</cardinality>
<key name="minValue" value="1"/>
<key name="maxValue" value="2"/>
<value>
<scalar>1</scalar>
</value>
</attribute>
<attribute modifier="req">
<name>PersistentConnection</name>
<id>persistentConnection</id>
<description>Specifies if persistent connections should be managed</description>
<type>&boolean;</type>
<cardinality>0</cardinality>
<value>
<scalar>true</scalar>
</value>
</attribute>
</objectclass>
<!-- Definition of preloaded configurations inheriting most of the property values from the factory
template, overriding only a few of them.-->
<configobject>
<id>mby.http.fpid</id>
<attribute modifier="req">
<id>port</id>
<value>
<scalar>443</scalar>
</value>
</attribute>
<attribute modifier="req">
<id>connectionType</id>
<value>
<scalar>2</scalar>
</value>
</attribute>
</configobject>
<configobject>
<id>my.http.fpid</id>
<attribute modifier="req">
<id>port</id>
<value>
<scalar>4543</scalar>
</value>
</attribute>
<attribute modifier="req">
<id>requestTimeout</id>
<value>
<scalar>40</scalar>
</value>
</attribute>
</configobject>
</metatype-provider>
If the configuration metatype will be developed in compliant with the OSGi metatype XML schema, it should be available in the bundle JAR file in the OSGI-INF/metatype directory.
The listing above contains the same configuration metatype as the first one but defined according to the OSGi metatype XML schema.
A configuration metatype following the OSGi metatype XML schema is presented below.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<metatype:MetaData xmlns:metatype="http://www.osgi.org/xmlns/metatype/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OCD name="HTTP Server Configuration" id="httpConfig"
description="HTTP Server Socket Configuration">
<AD name="Port" id="port" type="Integer" default="80"
description="Primary port on which client requests are accepted"
min="1" max="65535"/>
<AD name="Secondary Port" id="secondaryPort" type="Integer" default="8080"
description="Secondary port is opened if primary port is busy"
min="1" max="65535" required="false"/>
<AD name="Max Users" id="maxUsers" type="Integer" default="50"
description="Maximum number of users simultaneously connected with http server"
min="0" max="50"/>
<AD name="Request Timeout" id="requestTimeout" type="Integer" default="30"
description="Timeout in seconds. An inactive
connection is closed after this timeout expiration"
min="0" max="300"/>
<AD name="Connection Type" id="connectionType" type="Integer" default="1"
description="Type of connection: 1 for plain connection and 2 for secure connection."
min="1" max="2"/>
<AD name="PersistentConnection" id="PersistentConnection" type="Boolean"
default="true" description="Specifies if persistent connections
should be managed"/>
</OCD>
<Designate factoryPid="my.http.fpid"
bundle="D:/mybundles/myconfig.jar">
<Object ocdref="httpConfig">
<Attribute adref="port" content="446"/>
<Attribute adref="connectionType" content="2"/>
</Object>
</Designate>
<Designate factoryPid="my.http.fpid"
bundle="D:/mybundles/myconfig.jar">
<Object ocdref="httpConfig">
<Attribute adref="port" content="4543"/>
<Attribute adref="requestTimeout" content="40"/>
</Object>
</Designate>
</metatype:MetaData>
Loading Data in the Configuration Admin
When a bundle is installed in the OSGi framework, the Metatype Bundle inspects the bundle for availability of configuration metadata. This is determined by looking for:
If there is a match, the Metatype Bundle sends extracted metadata to the Config Bundle, which converts it into a new configuration instance in the following way:
Finally, the Configuration Admin passes the configuration data to the target bundle.
If the Configuration Admin already holds configurations with the same PID or factory PID, then the default configurations will not be loaded. This allows management entities to predefine configuration data that differs from the default one.
The Config Bundle does not load configurations with duplicate PIDs and factory PIDs.
When a bundle is updated, its configuration data is preserved in the configuration database in binary format. If the update includes changes in a configuration metatype, the Config Bundle will update the information in its database as well.