Best Practice: Treat OSGi Configurations as Code

Best-Practice-Treat-OSGi-Configurations-as-Code
The Question
A few months ago, one of our customers who self-manages their Adobe Experience Manager stack was doing some digging in the filesystem underneath the crx-quickstart folder. They noticed a correlation between the filenames found there (specifically, under crx-quickstart/launchpad/config and the changes they would make in the Felix Console at system/console/configMgr to configure OSGi bundles.) Putting two and two together, this enterprising SysAdmin asked me:
“If I pull those out and drop them into a fresh instance and restart, will that ‘configure’ [the bundle] for me? Is this the best way to accomplish this and similar tasks? Are there API calls I can make to the site to configure these types of things? I’m trying to gauge what it’s going to take to stand up a fully functional instance without having to touch it every time. It seems awfully cumbersome to track down these files after every configuration piece. Do you have any pro-tips?”

Our Answer
While it was awesome that this guy found the correlation, we were quick to reply that we do NOT consider managing these text files to be an ideal way of configuring OSGi services. The better solution, we feel, is to put these configurations into your source control such that they are created as sling:osgiConfig nodes inside your JCR. There are two solutions for that.

Setting up the Package Structure
The short answer is to create the nodes directly with your IDE under jcr_root/apps/myproject/config in one of the existing modules.

Here’s an asciinema recording of me looking at such a setup on my own filesystem. However, Systems Admins are frequently not Adobe Experience Manager Developers, so it’s a lot to expect them to know/remember the directory structure and XML syntax for these configuration files. An easier way to create these things is by making the appropriate node in a CRXDE Lite running locally, and then using VLT (or CRXDE Lite’s Package Manager) to export the node structure and send it to the developers for incorporation into the code repository.

How Many Settings Could a Sysadmin Set If a Sysadmin Could Set Settings?
When doing it via this method, I sometimes begin by going to /system/console/configMgr and finding the service I want to configure. Clicking on the service in this screen opens a dialog.

Here, by way of example, is the dialog for the Apache Jackrabbit Oak Default Sync Handler:
dialogfortheApacheJackrabbitOakDefaultSyncHandler

In the CRXDE Lite, make a new node under /apps//config, of type sling:osgiConfig.

The node’s name will be based on the PID found at the bottom of the configMgr dialog. If the service being configured is a factory (as Apache Jackrabbit Oak Default Sync Handler is), then we will append .config. to the”Factory PID” instead.
FactoryPID

When Felix creates these nodes for you, it will put a UUID in the space, but this can really be any distinct value you choose—I usually like to choose a more meaningful name so I don’t have to remember UUIDs. This .config. is used because, as a Service Factory, there can be many distinct configurations of the same service living side by side; for example, we may want a different one per site.

Here’s what the dialog looks like CRXDE Lite:
identifierconfig

For each configuration value in the dialog, we will create an appropriate property on this new sling:osgiConfig node. The name of the property will be the name in parens at the end of the documentation string:
slingosgiConfignode

The type of the property will depend on the value; you should always refer to the API documentation for a given service the first few times you configure it, but after a while you start to notice a few patterns between the datatypes of service properties and their representation in the OSGi Configuration Manager. For example:

  • checkboxes are represented as a Boolean
  • simple integer values (e.g., user.membershipNestingDepth in the above) are of type Long in the service
  • pretty much everything else is a String

Also, pay attention to the little +/- buttons along the right edge of some inputs; where these appear, you should select the “Multi” toggle:
plusminusbuttons

multitoggle

When you have “Multi” selected, hitting “Add” will open a multi-value dialog. Input the appropriate values (in this specific case, there are none to enter, so we leave the initial box blank) and hit OK.
multi-valuedialog

Here’s what the completed sling:osgiConfig will look like:
completedsling-osgiConfig

Save your work and use the “vlt” command-line tool to export this. Here’s an example invocation using the default password of “admin” and connecting to an instance running on localhost:4502:
vlt –credentials admin:admin export -v -t platform http://localhost:4502/crx /apps/myproject somedir

That will create the same directory structure you saw in the asciinema above (it is, in fact, exactly how I created that structure.)

Now, your OSGi configurations can be moved into your change management process, giving better repeatable results, and moving us further down the pipeline to Infrastructure as Code. Let me know if you have any questions about any of the above!