OSGi Toolkit Launches Twice with Various Configurations

I use embedded Felix in my application. An application can deal with many plugins, which provides a similar IFoo interface. The default implementation is FooImpl I hope that for most plugins, by default, FooImpl can be used with specific configuration files.

I want to dynamically install and run the same kit (with FooImpl ) when a new configuration file appears. I already looked at FileInstall, but I have no idea how to use it.

UPDATE : deployment sequence. The box containing FooImpl and IFoo is stable, but I need a hot deployment of new instances that result from loading a new .cfg file into the FileInstall area. It is desirable very simply - the user loads .cfg, a new service appears (an instance of FooImpl ).

+4
source share
2 answers

Using Factory Configurations will allow you to create different instances of FooImpl based on different configurations.

For example, in Declarative Services you can create a component, for example

 import org.apache.felix.scr.annotations.*; import org.apache.sling.commons.osgi.PropertiesUtil; @Component(metatype = true, name = FooImpl.SERVICE_PID, configurationFactory = true, specVersion = "1.1", policy = ConfigurationPolicy.REQUIRE) public class FooImpl implements IFoo { //The PID can also be defined in interface public static final String SERVICE_PID = "com.foo.factory"; private static final String DEFAULT_BAR = "yahoo"; @Property private static final String PROP_BAR = "bar"; @Property(intValue = 0) static final String PROP_RANKING = "ranking"; private ServiceRegistration reg; @Activate public void activate(BundleContext context, Map<String, ?> conf) throws InvalidSyntaxException { Dictionary<String, Object> props = new Hashtable<String, Object>(); props.put("type", PropertiesUtil.toString(config.get(PROP_BAR), DEFAULT_BAR)); props.put(Constants.SERVICE_RANKING, PropertiesUtil.toInteger(config.get(PROP_RANKING), 0)); reg = context.registerService(IFoo.class.getName(), this, props); } @Deactivate private void deactivate() { if (reg != null) { reg.unregister(); } } } 

Key points here

  • You are using a component of type configurationFactory
  • In the activation method, you read the configuration, and then based on this register the service
  • When deactivating, you explicitly unregister the service
  • Then end users will create a configuration file named <pid>-<some name>.cfg . Then DS activates the component.

Then you can create multiple instances by creating a configuration (using File Install like) named <pid>-<some name>.cfg , for example com.foo.factory-type1.cfg

Refer to the JdbcLoginModuleFactory and the corresponding config for one such example.

If you want to achieve the same through simple OSGi, you need to register a ManagedServiceFactory . See JaasConfigFactory for one such example.

Key points here

  • You register an instance of ManagedServiceFactory with the configuration PID as a service property
  • In the properties of the ManagedServiceFactory (String pid, Dictionary), FooImpl callback instances based on configuration properties
+7
source

It looks like you want to have only one package with FooImpl installed, but it registers several IFoo services, one for each configuration. Browse declarative services and use factory configurations using Config Admin to set up multiple configurations for the DS component.

+1
source

All Articles