Child pages
  • Multitenancy Support
Skip to end of metadata
Go to start of metadata

Multitenancy Support

Status: DRAFT - see more recent discussions at Multitenancy scenarios and use cases
Created: 2. April 2009
Author: fmeschbe
References: -
Updated: -

Problem Scope

Consider a hosting service provider, who wants to use Sling as the server to run the sites for different customers in the same Sling instance. Here you might want to separate the resolution of resources for each client.

For example some client C1 will have its components below /apps/c1, client C2 will have its components below /apps/c2 and the service provider has shared components below /apps/shared. To shield the client components from each other, being able to have per-client search paths – as returned from ResourceResolver.getSearchPath() – would be a nice feature. This way, requests to client C1's site would have a search path of [ "/apps/c1", "/apps/shared" ] and requests to client C2's site would have search path [ "/apps/c2", "/apps/shared" ].

Proposed Solution

The Sling API defines a new Tenant interface to represant tenants and a TenantProvider service interface which provides access to tenants. The tenant applicable to a given request is available through the new SlingHttpServletRequest.getTenant() method.

Basically a tenant has just three defined properties which are mainly intended to identify the tenant and list it for human consumption:

  • A globally unique identifier
  • A (short) name, which is not required to be unique
  • A (longer) description

In addition a tenant may provide a number of application specific properties. The properties are name value pairs, where the names are strings and the values may be of any type.

One application of the tenant and its property will be the JcrResourceResolverFactory. A new getResourceResolver(Session, Tenant) method is defined, where the tenant is used to inject configuration for the ResourceResolver returned. In a first step the resource.resolver.searchpath tenant property is used to enhance the globally configured search path. If the property is set and can be converted to a String[] the entries are merged with the global search path as follows:

Example: For a globalPath of [ "/apps", "/libs" ] and a tenantPath of [ "/tenant", "c1", "shared" ] the merged search path will be [ "/tenant", "/apps/c1", "/apps/shared", "/apps", "/libs/cq", "/libs/shared", "/libs"].

If the resource.resolver.searchpath property of the tenant does not exist or if no tenant is available to the JcrResourceResolverFactory the global search path configuration is used unmodified.

In the future more properties might be used to augment the configuration of a resource resolver returned for a given tenant.

Proposed API


The Tenant interface is defined in the package of the Sling API bundle


The TenantProvider interface is defined in the package of the Sling API bundle


The Tenant provider bundle should also register an AdapterFactory to adapt ResourceResolver and other objects to Tenant instances.


The SlingHttpServletRequest interface is extended to return the Tenant applicable for the request.


The SlingHttpServletRequestWrapper interface is extended to return the Tenant applicable for the request.
  • No labels