Context-Aware configuration in AEM by Ashwini Sathe
Overview
Configurations in AEM
When looking at an AEM implementation, it is very common to see an OSGI config for every service in the system. This is a very handy way to store configurations and it’s very easy to extract the configuration from there for consumption. So, developers tend to store all kinds of configurable data inside OSGI. But it is not recommended to use OSGI for all kinds of configurations such as runmode specific configs, API configs, configs for specific content path, scheduler configs and so on.
What is Context aware configuration (CA-config) :
The configurations which are specific to content resource or resource tree is known as context aware configuration. These configurations are related to the content e.g. web site or tenant site. So with CA-config we can have different configurations for different subtrees in the resource hierarchy.
Here is an example of what the content tree looks like.
In this example, the application needs configurations specific to sites, regions and tenants. Some configuration parameters are shared, so inheritance for nested contexts is supported. Also, since global fallback is supported, if for some contexts we have not specified the configuration so fallback configuration will be picked up. We can have full control on which content subtrees are relevant context in our application.
OSGI vs Context aware :
OSGI Configuration
- Run mode/environment specific configuration
- Stored under /apps folder
- GUI supported
- With the help of Felix console we can modify the OSGI config
- Hierarchy based inheritance is not supported
Context aware Configuration
- Context specific configuration
- Stored under /conf folder
- No support in GUI to edit or replicate ca-config
- External io.wcm CA-editor tool is used to modify the CA-configs or else we can edit the ca-config only with crxde
- Supports hierarchy based inheritance
Context aware configuration use cases:
CA-config is introduced with AEM 6.2 which stores configuration inside the repository. It offer lots of other features which are very handy in different use cases
- It implements an approach based on the repository hierarchy. If configuration value is not found at a specific location, the hierarchy is walked towards the root and further configurations are consulted, until a configuration is found or the root node is hit.
- Lookup process is very configurable.
- Developers don’t have to take care of the nodes or resources here, they only need to deal with POJOs. Such implementation hides the details like where the configuration is stored but location of the config is specified in the node property.
Let us see two use cases here:
Use case 1: Consider a multi-tenant system having multi-country and multi-language sites. Each country site has different user groups which acts as an approver in the content activation process of each language site. In the past this was often done by storing it as a part of the page, but from a permission point of view it was possible for authors to change it which resulted in a lot of issues. We can achieve this using OSGI factory configuration as well but that needs more custom code to identify the country and language. With CA-config this can be stored outside the /content tree in /conf, but closely aligned with content. So with the help of CA-config we can have configuration at language level hierarchy in the country site.
Use case 2: Consider sites based on MSM livecopies. There is a component which is used in these live copies, it contains some configurable values which should be different for each livecopy, also it should be different within some pages inside the livecopy site. Now to solve this we can have OSGI factory configuration with an identifier which can differentiate between these configurations and pick proper config for each page. But with this approach we need to implement a lot of custom code to pick the exact config and to identify that config uniquely. With CA-config we can have different config values for different contexts here and it is easy to maintain and retrieve this config.
Configuration resource resolving:
The context is defined by setting sling:configRef property to the content. Each resource that has a sling:configRef property set defines the root resource of the context, the whole subtree is the context. Within the subtree further nested contexts can be defined.
For example
If we want to get ca-config for the resource “/content/tenant1/north-america/us/en” it will try to find out the path specified in the sling:confRef property i.e “/conf/brand1/tenant1/north-america/us/en”. If the configuration is not present for this path then it will look for the parent one which is ““/conf/brand1/tenant1/north-america/us” and further in the hierarchy till the config is found or the root node is hit. So if the config is not found at “/conf/brand1/” then it will try to look at “/conf/global” if not there then it will look for “/apps/conf” and “/libs/conf” in respective order.
Conclusion :
CA-config addresses the need we often see in projects having configurations which are neither OSGI config nor real content, but something in between. Currently we need to install the third party dependency to get the editor, we would expect AEM to have this functionality out of the box in future. In meantime we encourage you to refer to the Sling documentation for the implementation of CA-config.
Q&A
Please use this thread to ask questions relating to this article