You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by "Bertrand Delacretaz (JIRA)" <ji...@apache.org> on 2015/02/05 16:58:35 UTC

[jira] [Comment Edited] (SLING-4386) Multi-tenant content model prototype

    [ https://issues.apache.org/jira/browse/SLING-4386?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14307368#comment-14307368 ] 

Bertrand Delacretaz edited comment on SLING-4386 at 2/5/15 3:57 PM:
--------------------------------------------------------------------

h2. Working proof of concept, February 5th, 2015

Revision 1657588 provides a reasonable proof of concept of the content model at [1], with a few changes improvised during implementation. To test it, start the sling launchpad and install the 3 bundles provided at [2].

The changes to Sling are minimal (see the resolver module at [2], compare with rev 1656760 where it was forked), I'm just using a custom {{MultiTenantScriptResolver}} instead of the default {{SlingScriptResolver}} (but sharing a lot of code with it) for Resources that adapt to {{ContentDrivenTenant}}. This means that existing Sling applications that use content resources found outside of tenant subtrees should continue to work unchanged.

This is definitely a prototype, there's lots of room for optimizations - it's just meant to demonstrate the ideas and evaluate how much impact this has on Sling.

h3. Tenants
The tenants are identified simply by having a {{sling:tenantRoot}} property under {{/content/T}}. The {{/content/T/example.com}} node for example has such a property, so it's the root of the example.com content-driven tenant. Such tenants can be nested, see the {{subsite}} child node.

Resources found in such subtrees can be adapted to {{ContentDrivenTenant}} which provides tenant-specific search and execution paths for scripts and servlets.

Those paths are defined based on the modules listed in the tenant definition resource, in this example:

{code}
curl -s http://localhost:8080/tenants.tidy.3.json | grep -v jcr
{
  "example.com": {
    "sling:tenant": {
      "modules": [
        "sling-default-servlets/1.0",
        "blog/v42"
      ],
      },
    "subsite": {
      "sling:tenant": {
        "modules": ["blog/v43"],
        }}}}
{code}

The {{example.com}} tenant lists two modules, one that gives access to the Sling default servlets and v42 of a blog module.

The {{example.com/subsite}} tenant does not include the Sling default servlets, the default {{.json}} rendering will not be available to render resources found under there for example. It also uses a different version of the blog module.

The servlet search/executions paths are computed based on these module references and the module definitions shown below, by the {{ContentDrivenTenantImpl}} class. The new {{MultiTenantScriptResolver}} uses these per-Resource search paths instead of the globally defined ones, allowing tenant-specific scripts and (up to a point) servlets.

h3. Modules
The modules are defined under {{/modules}}:

{code}
curl -s http://localhost:8080/modules.tidy.6.json | grep -v jcr
{
  "blog": {
    "v42": {
      "scripts": {
        "blog": {
          "homepage": {
            "sling:resourceSuperType": "blog/page"
            },
          "page": {
            "page.esp": {
              }
            }
          }
        }
      },
    "v43": {
      "scripts": {
        "blog": {
          "homepage": {
            "homepage.esp": {
              }
            },
          "page": {
            "page.esp": {
              }
            }
          }
        }
      }
    },
  "sling-default-servlets": {
    "1.0": {
      "searchPath": "/libs",
      "executionPath": "/libs/sling/servlet/default",
      }
    }
  }
{code}

Module scripts have to be placed in a {{scripts}} subfolder, and we should later enforce their resource types to start with the module name for consistency. The blog module shows an example of that.

The sling-default-servlets module does not define any scripts, it only provides an additional search path element with a limitation (only accept resources under {{/libs/sling/servlet/default}}) to avoid exposing other script/servlet resources found under {{/libs}}.

The tenant's custom scripts location is added in front of the search path, so for example adding a homepage.esp script in the {{/tenants/example.com/sling:tenant/scripts/blog/homepage}} folder would replace the default {{blog/homepage}} GET rendering.

As the tenants point to specific versions of modules, those can easily be upgraded or removed, as long as they consist of scripts only and maybe servlets with specific mounting paths (which are big limitations).

h3. Interesting URLs in this prototype
http://localhost:8080/content/T/example.com.html rendered with the blog/v42 page.esp script which is the supertype of blog/homepage

http://localhost:8080/content/T/example.com/about.html rendered with the same script, directly

http://localhost:8080/content/T/example.com/subsite.html also blog/homepage resource type but renders with the blog/v43 script as the resource belongs to the subsite tenant which points to the blog/v43 module.

http://localhost:8080/content/T/example.com/subsite/somepage.html rendered by blog/v43 page script.

http://localhost:8080/content/T/example.com.json works as the example.com tenant includes the sling-default-servlets module.

http://localhost:8080/content/T/example.com/subsite.json doesn't work as the example.com/subsite tenant does not include the sling-default-servlets module.




[1] https://cwiki.apache.org/confluence/display/SLING/Ideas+for+a+multi-tenant+and+multi-module+content+model

[2] https://svn.apache.org/repos/asf/sling/whiteboard/bdelacretaz/multisling2015


was (Author: bdelacretaz):
h2. Working proof of concept, February 5th, 2015

Revision 1657588 provides a reasonable proof of concept of the content model at [1], with a few changes improvised during implementation. To test it, start the sling launchpad and install the 3 bundles provided at [2].

The changes to Sling are minimal (see the resolver module at [2]), I'm just using a custom {{MultiTenantScriptResolver}} instead of the default {{SlingScriptResolver}} (but sharing a lot of code with it) for Resources that adapt to {{ContentDrivenTenant}}. This means that existing Sling applications that use content resources found outside of tenant subtrees should continue to work unchanged.

This is definitely a prototype, there's lots of room for optimizations - it's just meant to demonstrate the ideas and evaluate how much impact this has on Sling.

h3. Tenants
The tenants are identified simply by having a {{sling:tenantRoot}} property under {{/content/T}}. The {{/content/T/example.com}} node for example has such a property, so it's the root of the example.com content-driven tenant. Such tenants can be nested, see the {{subsite}} child node.

Resources found in such subtrees can be adapted to {{ContentDrivenTenant}} which provides tenant-specific search and execution paths for scripts and servlets.

Those paths are defined based on the modules listed in the tenant definition resource, in this example:

{code}
curl -s http://localhost:8080/tenants.tidy.3.json | grep -v jcr
{
  "example.com": {
    "sling:tenant": {
      "modules": [
        "sling-default-servlets/1.0",
        "blog/v42"
      ],
      },
    "subsite": {
      "sling:tenant": {
        "modules": ["blog/v43"],
        }}}}
{code}

The {{example.com}} tenant lists two modules, one that gives access to the Sling default servlets and v42 of a blog module.

The {{example.com/subsite}} tenant does not include the Sling default servlets, the default {{.json}} rendering will not be available to render resources found under there for example. It also uses a different version of the blog module.

The servlet search/executions paths are computed based on these module references and the module definitions shown below, by the {{ContentDrivenTenantImpl}} class. The new {{MultiTenantScriptResolver}} uses these per-Resource search paths instead of the globally defined ones, allowing tenant-specific scripts and (up to a point) servlets.

h3. Modules
The modules are defined under {{/modules}}:

{code}
curl -s http://localhost:8080/modules.tidy.6.json | grep -v jcr
{
  "blog": {
    "v42": {
      "scripts": {
        "blog": {
          "homepage": {
            "sling:resourceSuperType": "blog/page"
            },
          "page": {
            "page.esp": {
              }
            }
          }
        }
      },
    "v43": {
      "scripts": {
        "blog": {
          "homepage": {
            "homepage.esp": {
              }
            },
          "page": {
            "page.esp": {
              }
            }
          }
        }
      }
    },
  "sling-default-servlets": {
    "1.0": {
      "searchPath": "/libs",
      "executionPath": "/libs/sling/servlet/default",
      }
    }
  }
{code}

Module scripts have to be placed in a {{scripts}} subfolder, and we should later enforce their resource types to start with the module name for consistency. The blog module shows an example of that.

The sling-default-servlets module does not define any scripts, it only provides an additional search path element with a limitation (only accept resources under {{/libs/sling/servlet/default}}) to avoid exposing other script/servlet resources found under {{/libs}}.

The tenant's custom scripts location is added in front of the search path, so for example adding a homepage.esp script in the {{/tenants/example.com/sling:tenant/scripts/blog/homepage}} folder would replace the default {{blog/homepage}} GET rendering.

As the tenants point to specific versions of modules, those can easily be upgraded or removed, as long as they consist of scripts only and maybe servlets with specific mounting paths (which are big limitations).

h3. Interesting URLs in this prototype
http://localhost:8080/content/T/example.com.html rendered with the blog/v42 page.esp script which is the supertype of blog/homepage

http://localhost:8080/content/T/example.com/about.html rendered with the same script, directly

http://localhost:8080/content/T/example.com/subsite.html also blog/homepage resource type but renders with the blog/v43 script as the resource belongs to the subsite tenant which points to the blog/v43 module.

http://localhost:8080/content/T/example.com/subsite/somepage.html rendered by blog/v43 page script.

http://localhost:8080/content/T/example.com.json works as the example.com tenant includes the sling-default-servlets module.

http://localhost:8080/content/T/example.com/subsite.json doesn't work as the example.com/subsite tenant does not include the sling-default-servlets module.




[1] https://cwiki.apache.org/confluence/display/SLING/Ideas+for+a+multi-tenant+and+multi-module+content+model

[2] https://svn.apache.org/repos/asf/sling/whiteboard/bdelacretaz/multisling2015

> Multi-tenant content model prototype
> ------------------------------------
>
>                 Key: SLING-4386
>                 URL: https://issues.apache.org/jira/browse/SLING-4386
>             Project: Sling
>          Issue Type: Task
>          Components: General
>            Reporter: Bertrand Delacretaz
>            Assignee: Bertrand Delacretaz
>
> I'm working on a prototype for [1], will use this issue to keep track of progress.
> [1] https://cwiki.apache.org/confluence/display/SLING/Ideas+for+a+multi-tenant+and+multi-module+content+model



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)