May 13, 2020
Estimated Post Reading Time ~

OSGI Factory Configuration Services in CQ

One of the most powerful parts of AEM is OSGI and the ability that gives you configure servies and modify those confiugration on the fly if needed. By creating custom services and providing appopriate configuration properties, your services become more flexible. If we extend that a bit furthur, and use runmode scoped configurations in the repository we can now dynamically modify how our services behave based on the environment they are running in. But for me personally, the one piece that was always missing was how to create a factory configuration service. That is, how can I create single service, but apply multiple configuration to it and then consume those configurations from another class, similar to how the loggers are configured. What follows are the steps needed to create such a configuration; it actually turns out to be pretty simple.

First, we create a service class to hold our configuration values. More or less, this is exactly the same as any other service, except that the @Component annotations declare itself as a configurationFactory with a configuration policy if required.
MyFactoryConfigServiceClass.java
@Component(configurationFactory = true,
policy = ConfigurationPolicy.REQUIRE, metatype = true, immediate = true)
@Service()
public class MyFactoryConfigServiceClass {

//define config properties here as usual
@Property(name = "some.prop.name", label = "My Property", value = "")
private String myProperty

/**
* Activate the configuration.
*
* @param ctx
* the component context object
*/
@Activate
protected void activate(final ComponentContext ctx) {
log.info("activating instance of {}", this.getClass().getName());
Dictionary<?, ?> props = ctx.getProperties();
//init property values using PropertiesUtil
myProperty = PropertiesUtil.toString(props.get("some.prop.name"),"");
}
}


Next, we need a way to read our configuration values. For that, we will take advantage of osgi dynamic binding. From another service where you need to read your configurations, add the following.

MyFactoryConsumer.java
@Component()
@Service()
public class MyFactoryConsumer {

@Reference(referenceInterface = MyFactoryConfigServiceClass.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE,
policy = ReferencePolicy.DYNAMIC)
private List<MyFactoryConfigServiceClass> configs;

protected synchronized void bindMyFactoryConfigServiceClass(final MyFactoryConfigServiceClass config) {
if (configs == null) {
configs = new ArrayList<MyFactoryConfigServiceClass>();
}

configs.add(config);
}

protected synchronized void unbindMyFactoryConfigServiceClass(final MyFactoryConfigServiceClass config) {
configs.remove(config);
}

}

More or less, that’s all there is to it. You now have a list of all the available configuration, which you can loop through and/or use as needed.


By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.