OSGi component in AEM that is active only in specific run mode (say, publish).

Scenario
Implementing an OSGi component in AEM which is active (that runs) only in specific run modes (say, publish).

Implementation
Generally, in OSGi container (Apache felix in AEM), to get a component ‘satisfied’, all the referenced services have to be available. Here, to make such a component ‘satisfied’ we ask for an additional dependency on configuration object. We would ask the container to make the component active only when the configuration object is available.

This can easily be done using an SCR (Service Component Runtime) annotation.

@Component(policy = ConfigurationPolicy.REQUIRE)

Here’s the working code.

package com.computepatterns.apppatterns.osgi;

import java.util.Map;

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(label = "Compute Patterns - OSGi component that is active only in specific run modes.",
    description = "OSGi component which works only in specific run mode (say, publish run mode).",
    policy = ConfigurationPolicy.REQUIRE, immediate = true)
/*** Sample OSGi component which works only in specific run mode. When we make component 'policy' to 'REQUIRE', OSGi container expects corresponding configuration object (osgi:Config node) to become satisfied. If we define the sling:OsgiConfig node under 'config.publish' folder, we could get this component active in 'publish' only run mode and 'unsatisfied' in all other run modes.
 */
public class RunmodeSpecificComponent{
  private static final Logger log = LoggerFactory.getLogger(RunmodeSpecificComponent.class);

  @Activate
  protected void activate(Map<String, String> config) {
    log.info("RunmodeAwareComponent ACTIVATED");
  }
}

 

Deploy the code and we will notice the component in ‘unsatisfied’ state in the apache felix component console (http://localhost:4502/system/console/components). We are yet to supply the configuration object to it.

In AEM, configuration objects are supplied through sling:OsgiConfig nodes. So, creating a node of type sling:OsgiConfig with the ‘service pid’ under /apps/<your project>/configs/config/<service.pid> will make the component active. This will make the component active for all run modes. Nevertheless, this is not what we intended.

To make it active for a specific run mode, say – publish, we will keep the sling:OsgiConfig only under /apps/<your project>/configs/config.publish/<service.pid>. Now, if we check the felix component console in ‘publish’ instance, you would see the component being active. You could also confirm it through the log message (error.log) in publish instance.

This component could also be made as a service with the @Service annotation.

Summary
To make the OSGi component active in specific run mode

  • Annotate the component with ‘ConfigurationPolicy.REQUIRE’
  • Add a sling:OSGiConfig node under /apps/<your project>/configs/cong.<your runmode>/<service.pid>

Grab the complete code from github ComputePatterns-AEM project.

 

OSGi component in AEM that is active only in specific run mode (say, publish).