2

We are using Adobe Day CQ for our deployment. We are currently creating OSGi bundles with gets deployed in CQ with all the services using maven-bundle-plugin.

Now we have a scenario where we do not want some services to get enabled in Publish instance but should be enabled in Author.

Is there a way where we can manage two bundles one for author with the services required for author and one for publish which are required on publish, using the same pom.xml ?
Or else is there any other way by which this thing can me managed.
Please help me in this regard. We are right now using this for creating bundles:

<plugin>
            <groupId>org.apache.felix</groupId>
            <artifactId>maven-bundle-plugin</artifactId>
            <version>2.0.1</version>
            <extensions>true</extensions>
            <configuration>
                <instructions>
                    <Import-Package>
                        org.osgi.framework,
                        *;resolution:=optional
                    </Import-Package>
                    <Export-Package>
                          com.abc.platform.enow.aem.core.testing.*,
                        com.abc.platform.enow.aem.core.utils.*,
                    com.abc.platform.enow.aem.core.viewhelper.*,
                        com.abc.platform.enow.aem.core.search.*

                    </Export-Package>
                </instructions>
            </configuration>
</plugin>
Balazs Zsoldos
  • 6,036
  • 2
  • 23
  • 31
Vaibhav
  • 353
  • 1
  • 2
  • 7

2 Answers2

2

There are two ways to do this. The first approach would be preferable

Selective activation via Configuration

You can achieve that by using Sling Run Mode based Configuration support and using Declarative Services for managing service registration.

Bind your service to Configuration

Use SCR annotation to bind your service to configuration

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.ConfigurationPolicy;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;


@Component(
    name = FooImpl.SERVICE_PID,
    policy = ConfigurationPolicy.REQUIRE)
@Service
public class FooImpl implements IFoo{
  public static final String SERVICE_PID = "com.foo.example";

In above code snippet we

  • Register a service which implements IFoo interface
  • ConfigurationPolicy for the component is set to REQUIRE i.e. without any explicit configuration the component and thus the service would not be activated and registered
  • The PID of the config is set to com.foo.example. If you omit it then it default to fully qualified name of the class

Create config under the required Run Mode folder

In CQ the Sling installer would deploy configuration and bundle from the repository based on the Run Mode. So if you are deploying your code via Content Packages then

  • Create a config node under path /apps/<yourProject>/config.author/com.foo.example
  • Under above path just create a blank ode (unless you want to provide other config properties) of type sling:OsgiConfig

With above changes done deploy your content package on various CQ instances

  • When package is deploy on any CQ instance then Configuration for PID com.foo.example would only be created when the run mode is set to Author
  • And only when configuration is active then only FooImpl component and service would be created and registered

Using SlingSettingsService

Another approach can make use of the SlingSettingsService.getRunModes to determine the run mode programatically and then only register the service.

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;

@Component
public class FooImpl implements IFoo{

    @Reference
    private SlingSettingsService settingsService;

    private ServiceRegistration reg;

    @Activate
    public void activate(BundleContext context, Map<String, ?> conf){
        if(settingsService.getRunModes().contains("author")){
           reg = context.registerService(IFoo.class.getName(), this, null);
        }
    }

    @Deactivate
    private void deactivate(){
        if (reg != null){
            reg.unregister();
        }
    }
}

Couple of points to note for above snippet

  • FooImpl is not annotated with @Service tag. So SCR would only activate the component but would not register any service
  • In activate method we use SlingSettingsService to check for required run mode. In case it is author we programatically register the service
  • Service instance is removed later in the deactivate method
Chetan
  • 705
  • 5
  • 10
  • Hi Chetan, This is a very good help. will give a try to this. Can you please let me know if there is a way by which this can happen using the project's pom.xml as it will be easier instead of making changes to the code. – Vaibhav Oct 21 '13 at 03:36
0

We have achieved this by using the runmode property for CQ. We did the below:

  • Created the full build.
  • In the distribution phase we pushed the jar (that we required to install only on author) to the folder /apps/"project_name"/install.author.
  • Here "author" is the run mode for the instance.
  • This jar deploys to both author and publish in the folder install.author but in installed / reflected only on the author mode.

Thanks for the reply, but we found this solution more flexible and feasible.

Regards, Vaibhav

Vaibhav
  • 353
  • 1
  • 2
  • 7