AEM Best Practice: OSGi Configurations

One of the best practices I’ve come across recently in AEM is to never use the OSGi console directly to edit configurations. People may argue “But that’s what it’s there for!”, and indeed it is an easy interface to use for configuration changes. However there are drawbacks to managing your configuration changes this way in a AEM project.

Let’s demonstrate this by changing the configuration of the Apache Sling GET Servlet.

Apache Sling GET Servlet

When you edit a configuration in the OSGi console and save it, the updated configuration is saved to the JCR, generally under /apps/sling/config or /apps/system/config depending on the component you configure. First thing to note here is that you have no control over where this node is saved to, or if this configuration should be for a specific runmode – the parent folder is called config, not config.author or config.publish (for more information on runmodes, see How to set up run mode and my previous post Confirming the Runmode).

Content Explorer File Binary

Secondly, and more importantly, the configuration node that has been created is of type nt:file. Therefore it contains a child called jcr:content, which has a property called jcr:data which contains the binary contents of the file. So as you can see (or more accurately NOT see), the details of the configuration itself are not readily apparent. When viewing this binary, we see the following:

aliases=”xml:pdf”
index=B”false”
enable.txt=B”false”
index.files=[“index”,”index.html”]
enable.html=B”false”
enable.json=B”true”
enable.xml=B”true”
json.maximumresults=I”600″

Why is this bad? What happens when you want to change a single configuration value here programatically, or even through CRXDE lite, CRX Explorer, or curl for that matter? You would need to write code that extracts the binary contents of the file, manipulate this content to adjust the values to the desired configuration, then write this back to the jcr:data property of the file contents. This is quite messy, if all you want to do is change a single value of a complex configuration and leave the rest the same.

So what’s the alternative? Create the configuration node manually, and use properties for each of the configuration settings. The configuration screen in the OSGi console gives you virtually all the information you need to create this node yourself. In addition, you also have the ability to choose the location of these settings, and therefore you can store them under you project branch, and also control the runmode in which they are used. This can be done in 3 simple steps:

1 – Create the folder structure

Create folders /apps/myproject/config.author and /apps/myproject/config.publish. Make sure the config.author and config.publish folders are of type sling:Folder

Content Explorer Config With Runmodes

2 – Create the configuration node

Create a node of type sling:OsgiConfig under the runtime folder you wish to configure. The name of the node should be the same name as the Persistent Identity (PID) of the configuration in the OSGi Console. HINT: If this is a factory class and can have multiple instances, use the Factory Persistent Identifier (Factory PID) and append the name with ‘-xxxxx’, where xxxxx is a unique identifier.

Sling GET Servlet PID

Content Explorer Author Config

3 – Add the names and values from the OSGi configuration as properties

Using the label in brackets at the end of the configuration description as the property name, and the value of the configuration as the values of the properties.

Sling GET Servlet Properties

Content Explorer Author Config With Properties

That is it! Now, if you change the values of the configuration nodes’ properties, you can refresh the OSGi console and see these changes reflected to prove the configuration is taking effect. So from now on, whenever you need to change a configuration, you can make the change directly in the JCR, as well as easily make any configuration changes via curl or java, without needing to deal with file binaries.

This entry was posted in AEM, CQ5 and tagged , , , . Bookmark the permalink.

8 Responses to AEM Best Practice: OSGi Configurations

  1. anand says:

    Hi
    This bog is helpful indeed. I have 100 properties and would like to group it in a separate node instead adding them in a single node.
    is there a way i could use the above mentioned method to load all of these property in a sincgle service?
    Thanks.
    Regards,
    Anand

    • Kristian says:

      Hi Anand,

      The OSGi configurations are generally for setting configs for bundles/services. If you wrote a service to do what you need that exposed changeable parameters to the OSGi console, then I would recommend using the above approach to manipulate the service configuration as required. If you’re talking about a one off service to do what you are after, then using OSGi configurations is probably not needed.

  2. karen says:

    what is the best practice for # of nodes in a parent / child structure. How many nodes can be under the parent without having performance impact.

  3. Kristian says:

    Hi Karen,

    For Apache Jackrabbit (AEM 5.6.1 and earlier), performance starts to degrade from around 10,000 child nodes (see http://wiki.apache.org/jackrabbit/Performance for more information). I’m unsure if this limit has changed with the introduction of Apache Oak in AEM 6.0, but I’ve not read anything to tell me it’s a different number.

  4. Arc says:

    Hi Kristian,
    It was a very helpful post. However I am facing an issue. When I change a property from felix console, the node automatically gets converted from sling:OsgiConfig to nt:folder and the properties get saved as binary in jcr:data property of jcr:content

    • Kristian says:

      This is the expected behaviour – changing a value in the console will convert the config to a file. Best practice is to not make changes in the console, but rather through the properties of the OSGi config node in the JCR.

      • So what should be the best approach if a use case does involve changing the property from the console

        • Kristian says:

          Hard one to answer. Depends on the project, requirements, use cases, how often it needs to change (and why) etc. I guess the options are to have it change in the console, then read the values from the file, or create your own UI interface for someone to make the changes, then write the values to the OSGi config node properties.

Add a comment...