Skip to content

Instantly share code, notes, and snippets.

@ieb
Created July 29, 2016 12:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ieb/460504e79c861cb980f4f0154210a869 to your computer and use it in GitHub Desktop.
Save ieb/460504e79c861cb980f4f0154210a869 to your computer and use it in GitHub Desktop.
Sling Configuration spec

Sling Configuration Bundle.

This bundle provides a service API that may be used by components to interact with configuration. The bundle merges the work started in http://wcm.io/config and AEM Config Manager. For information on the API see sub projects contained within this source code tree. This file documents the semantic structure of configuration giving examples of how that configuration is persisted in the repository and in files.

Purpose

This document has been created to clarifiy and define precisely what is meant by various configuration related concepts. It is a live document, intended to be changed to support a shared understanding and eliminate confusion. It does not attept to define the Java APIs. For more detail on Java APIs or implementation look at the source code.

Configuration concepts.

Conceptually configuration consists of maps of key value pairs organised in a content hierachy referenced by a path. Configuration is context aware such that configuration in one context may differ from configuration in a different context. The context is defined by a resource path. Configuration may inherit and override according to well defined rules.

Configuration definition.

Configuration is defined conceptually as a map of maps, that can be expressed as content in a repository, json files on disk in a file system, yaml files or any other format that can store a map of maps. Each map of configuraiton values is referenced by the path to that map. In these examples configuration is stored under /conf. Rules on overiding configuration are detailed in a later section.

Hierachical Content System representation

/conf/
      global/
             settings/
                      socialmedia/
                                  youtube
                                         @enabled = false  <-  "enabled" is a property of the youtube resource, denoted by the @ prefix
                                         @url = https://youtube.com <-  "url" is a property of the youtube resource, denoted by the @ prefix
      tenants/   
              piedpiper/
                        settings/
                                 socialmedia/
                                             facebook 
                                                  @enabled = true  <-  "enabled" is a property of the facebook resource, denoted by the @ prefix
                                                  @url = https://facebook.com <-  "url" is a property of the facebook resource, denoted by the @ prefix

JSON representation

conf.json
{
    "conf" : {
        "settings" : {
            "socialmedia" : {
                "youtube" : {
                    "enabled" : false,
                    "url" : "https://youtube.com"
                }
            }
        },
        "tenants" : {
            "piedpiper" : {
                "settings" : {
                    "socialmedia" : {
                        "facebook" : {
                            "enabled" : true,
                            "url" : "https://facebook.com"
                        }
                    }
                }
            }
        }
    }
}

Mixed representation

/conf/
      global/
             settings.json
                {
                    "socialmedia" : {
                        "youtube" : {
                            "enabled" : false,
                            "url" : "https://youtube.com"
                        }
                    }
                }
      tenants/   
              piedpiper/
                        settings.json <- file containing...
                            {
                                "socialmedia" : {
                                    "facebook" : {
                                        "enabled" : true,
                                        "url" : "https://facebook.com"
                                    }
                                }
                            }

Configuration Context rules.

Context is defiend by the Resource of interest. If a http request is made to a URL, Sling resolves the URL to a Resource which may then be used by the application to define the context for configuration. Where no configuration configuration has been specified on that resource or its parents, the global configuration (stored at /conf/global) is used. Optionally the Resource may reference an alternative configuration subtree.

The Resource /content/hooli defines a confuration context of /conf/tentants/piedpiper by setting the property sling:conf to reference that configuration. Confiuration defined in that location will overlay the configuration tree in /conf/global

/content/hooli/@sling:conf = "/conf/tentants/piedpiper"

The fully resolved configuration, expressed as json for /content/hooli merges /conf/tentants/piedpiper with /conf/global

    {
        "socialmedia" : {
            "youtube" : {
                "enabled" : false,
                "url" : "https://youtube.com"
            },
            "facebook" : {
                "enabled" : true,
                "url" : "https://facebook.com"
            }
        }
    }

Configuration Context Inheritance

Just as Resource specific context configuration inherits from the global configuration, configuration specific to a Resource will inherit from any configuration context specified in parent resources.

/content/hooli/@sling:conf = "/conf/tentants/piedpiper"
/content/hooli/hooly_france/@sling:conf = "fr"

The configuration for /content/hooli/hoolyxyz consists of confiruation loaded in the following order, relative locations are relative to nearest parent.

/conf/global
/conf/tentants/piedpiper
/conf/tentants/piedpiper/fr

Assuming /conf/tentants/piedpiper/fr is defined as below.

/conf/
      global/
             settings.json
                {
                    "socialmedia" : {
                        "youtube" : {
                            "enabled" : false,
                            "url" : "https://youtube.com"
                        }
                    }
                }
      tenants/   
              piedpiper/
                        settings.json
                            {
                                "socialmedia" : {
                                    "facebook" : {
                                        "enabled" : true,
                                        "url" : "https://facebook.com"
                                    }
                                }
                            }
                        fr/
                                    settings.json
                                        {
                                            "socialmedia" : {
                                                "facebook" : {
                                                    "enabled" : true,
                                                    "url" : "https://facebook.fr"
                                                }
                                            }
                                        }

The configuration for /content/hooli/hooly_france is

{
     "socialmedia" : {
         "youtube" : {
             "enabled" : false,
             "url" : "https://youtube.com"
         },
         "facebook" : {
             "enabled" : true,
             "url" : "https://facebook.fr"   <-- from /conf/tentants/piedpiper/fr
         }
     }
}

Overriding Configuiration

Since an application may need to be modified by a deployer, and that deployer may not want to modify the original application configuration overwriding is available. A confurable overriding sequence, which defaults to /conf, /libs/conf, /apps/conf results every confuguration for each location being loaded. In the above example, configuraiton will be loaded in the following order

/conf/global
/conf/tentants/piedpiper
/conf/tentants/piedpiper/fr
/lib/conf/global
/lib/conf/tentants/piedpiper
/lib/conf/tentants/piedpiper/fr
/apps/conf/global
/apps/conf/tentants/piedpiper
/apps/conf/tentants/piedpiper/fr

DECISION Needed: An alternative pattern might be

/conf/global
/lib/conf/global
/apps/conf/global
/conf/tentants/piedpiper
/lib/conf/tentants/piedpiper
/apps/conf/tentants/piedpiper
/conf/tentants/piedpiper/fr
/lib/conf/tentants/piedpiper/fr
/apps/conf/tentants/piedpiper/fr

Implementation

The implementation should support the behaviour above, however precisely how the configuration is stored as a Resource is an implementation detail. It may be that a ResourceProvider chooses to map /conf to a single json file stored on disk via the FileResourceProvider, or it may be that some other pattern is chosen. I have not included intermediate node paths that may be necessary, such as jcr:content to avoid expressing implementation details in the documentation of concepts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment