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.
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).
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:
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
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.
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.
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.