Tenant Implementation in Sling

classic Classic list List threaded Threaded
23 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Tenant Implementation in Sling

Andreas Schaefer
Hi

I am working for a client which needs support for tenants and because the current implementation of the Tenants in Sling is just that but no integration I started to code a workaround. For now I have a patch that does the trick but it is not clean because I use a Servlet Filter to place the tenant id on a thread local instance. Afterwards I started to look into how to implemented this cleanly into the current version of Sling.

There are a few areas that need to be changed in order to implement tenant support. For now I am only looking into how to implement a “per-call overlays of servlets / JSPs” in order to give tenants the chance to change aspects of their presentation.

1) Tenant Identification: Sling must be able to identify a tenant. This can be a sub domain, path, cookies or even parameters. This means the client needs to provide a service which is then used by Sling in order to retrieve the tenant and provide it to whomever wants to use it.

2) Servlet Resolver needs to be changed twofolds
        a) Being able to extend the search path for Servlets / JSPs based on the tenant’s data
        b) Caching the Servlets / JPSs separated for different tenants

3) Change the Felix OSGi Web Plugin to allow the clients to add properties (single and multi values)


For 1) I would suggest just to define an interface the client can implement as an OSGi service which is used to identify a tenant. Then somewhere in the SlingMainServlet or the Request Data the Tenant is retrieved set on the Sling Http Servlet Request and if applicable the Search Path of the Resource Resolver is “enhanced/extended”.

For 2) I would suggest to add a new property to the Resource Resolver which contains the Search Path Extension. Because the Servlet Resolver uses the Administrative Resource Resolver we need a way to “Enhance the Search Path” for that particular call. This could be done with a one-off wrapper. Based on the Extended Search Path we can determine which Servlet is an overlay and cache the overlays separately.

3) should be straight forward.

Carsten was suggesting something like a TenantProvider like the ServletProvider but in the current code the ServletProvider is called with either the Sling Servlet Request, the Resource or a Resource Resolver and path. This means the tenant id must be available to any of these calls which would require to put the tenant id inside the Resource Resolver.

Let me know what you think.

- Andy Schaefer

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Henry Saginor
Hi Andy,

Thank you for bringing this up. I have a similar requirement.
I don’t see any way of integrating Tenants other than patching Servlet Resolver. This is what I had done for my customer but for a really specific case (they are not truly multi-tenant).  
I also had to use ThreadLocal. I didn’t really see a better approach because a request is not always available in servlet resolver. So, if you have to map your tenant id to any information in the request you have to. Please let me know if you can think of something better.

Also, for 1) I think beyond an interface you can provide some generic implementation and configuration factory. With configuration factory you can create and configure multiple instances with different configurations (sub-domain/path/cookies/parameters). With this I would say 3) is not a requirement unless I miss-undertood what you meant.

Maybe you could open a JIRA ticket and post a patch there.

Henry

On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]> wrote:

> Hi
>
> I am working for a client which needs support for tenants and because the current implementation of the Tenants in Sling is just that but no integration I started to code a workaround. For now I have a patch that does the trick but it is not clean because I use a Servlet Filter to place the tenant id on a thread local instance. Afterwards I started to look into how to implemented this cleanly into the current version of Sling.
>
> There are a few areas that need to be changed in order to implement tenant support. For now I am only looking into how to implement a “per-call overlays of servlets / JSPs” in order to give tenants the chance to change aspects of their presentation.
>
> 1) Tenant Identification: Sling must be able to identify a tenant. This can be a sub domain, path, cookies or even parameters. This means the client needs to provide a service which is then used by Sling in order to retrieve the tenant and provide it to whomever wants to use it.
>
> 2) Servlet Resolver needs to be changed twofolds
> a) Being able to extend the search path for Servlets / JSPs based on the tenant’s data
> b) Caching the Servlets / JPSs separated for different tenants
>
> 3) Change the Felix OSGi Web Plugin to allow the clients to add properties (single and multi values)
>
>
> For 1) I would suggest just to define an interface the client can implement as an OSGi service which is used to identify a tenant. Then somewhere in the SlingMainServlet or the Request Data the Tenant is retrieved set on the Sling Http Servlet Request and if applicable the Search Path of the Resource Resolver is “enhanced/extended”.
>
> For 2) I would suggest to add a new property to the Resource Resolver which contains the Search Path Extension. Because the Servlet Resolver uses the Administrative Resource Resolver we need a way to “Enhance the Search Path” for that particular call. This could be done with a one-off wrapper. Based on the Extended Search Path we can determine which Servlet is an overlay and cache the overlays separately.
>
> 3) should be straight forward.
>
> Carsten was suggesting something like a TenantProvider like the ServletProvider but in the current code the ServletProvider is called with either the Sling Servlet Request, the Resource or a Resource Resolver and path. This means the tenant id must be available to any of these calls which would require to put the tenant id inside the Resource Resolver.
>
> Let me know what you think.
>
> - Andy Schaefer
>

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
In reply to this post by Andreas Schaefer
Hi

I started to look into how to add tenant support to Sling.

This is my test scenario:

I have an /apps/foo/bar/html.esp and a /apps/tenant1/foo/bar/html.esp and a /content/mynode entry. The title of the second html.esp is different so that I know which one is loaded.

Changes to the code:

1) Added get/setSearchPathExtension() to the Resource Resolver and its implementation.

2) In the SlingRequestProcessorImpl I extract the tenant from the first sub domain (no OSGi Service yet) and prepend it with /apps/ to the Search Path Extension

3) In the Servlet Resolver added the code to set the Search Path Extension from the Resource’s Resource Resolver onto the Script Resource Resolver.

Ran it and it showed the Tenant Specific ESP when the host name has a tenant it as sub domain and the original ESP when used with localhost.

This shows that is it basically possible to thread through the tenant Search Path on a per-call basis to the Servlet Resolver. There is still much to do like the Cache handling in the Servlet Resolver and a OSGi service that provides the tenant from a request.

I can create an Issue and add a patch of my changes to it if anyone is interested.

Cheers - Andy

On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]> wrote:

> Hi
>
> I am working for a client which needs support for tenants and because the current implementation of the Tenants in Sling is just that but no integration I started to code a workaround. For now I have a patch that does the trick but it is not clean because I use a Servlet Filter to place the tenant id on a thread local instance. Afterwards I started to look into how to implemented this cleanly into the current version of Sling.
>
> There are a few areas that need to be changed in order to implement tenant support. For now I am only looking into how to implement a “per-call overlays of servlets / JSPs” in order to give tenants the chance to change aspects of their presentation.
>
> 1) Tenant Identification: Sling must be able to identify a tenant. This can be a sub domain, path, cookies or even parameters. This means the client needs to provide a service which is then used by Sling in order to retrieve the tenant and provide it to whomever wants to use it.
>
> 2) Servlet Resolver needs to be changed twofolds
> a) Being able to extend the search path for Servlets / JSPs based on the tenant’s data
> b) Caching the Servlets / JPSs separated for different tenants
>
> 3) Change the Felix OSGi Web Plugin to allow the clients to add properties (single and multi values)
>
>
> For 1) I would suggest just to define an interface the client can implement as an OSGi service which is used to identify a tenant. Then somewhere in the SlingMainServlet or the Request Data the Tenant is retrieved set on the Sling Http Servlet Request and if applicable the Search Path of the Resource Resolver is “enhanced/extended”.
>
> For 2) I would suggest to add a new property to the Resource Resolver which contains the Search Path Extension. Because the Servlet Resolver uses the Administrative Resource Resolver we need a way to “Enhance the Search Path” for that particular call. This could be done with a one-off wrapper. Based on the Extended Search Path we can determine which Servlet is an overlay and cache the overlays separately.
>
> 3) should be straight forward.
>
> Carsten was suggesting something like a TenantProvider like the ServletProvider but in the current code the ServletProvider is called with either the Sling Servlet Request, the Resource or a Resource Resolver and path. This means the tenant id must be available to any of these calls which would require to put the tenant id inside the Resource Resolver.
>
> Let me know what you think.
>
> - Andy Schaefer
>

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
Sorry, I forgot to mention that the Search Path Extension is prepended to the Search Path when it is requested (in the Resource Resolver).

- Andy

On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <[hidden email]> wrote:

> Hi
>
> I started to look into how to add tenant support to Sling.
>
> This is my test scenario:
>
> I have an /apps/foo/bar/html.esp and a /apps/tenant1/foo/bar/html.esp and a /content/mynode entry. The title of the second html.esp is different so that I know which one is loaded.
>
> Changes to the code:
>
> 1) Added get/setSearchPathExtension() to the Resource Resolver and its implementation.
>
> 2) In the SlingRequestProcessorImpl I extract the tenant from the first sub domain (no OSGi Service yet) and prepend it with /apps/ to the Search Path Extension
>
> 3) In the Servlet Resolver added the code to set the Search Path Extension from the Resource’s Resource Resolver onto the Script Resource Resolver.
>
> Ran it and it showed the Tenant Specific ESP when the host name has a tenant it as sub domain and the original ESP when used with localhost.
>
> This shows that is it basically possible to thread through the tenant Search Path on a per-call basis to the Servlet Resolver. There is still much to do like the Cache handling in the Servlet Resolver and a OSGi service that provides the tenant from a request.
>
> I can create an Issue and add a patch of my changes to it if anyone is interested.
>
> Cheers - Andy
>
> On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]> wrote:
>
>> Hi
>>
>> I am working for a client which needs support for tenants and because the current implementation of the Tenants in Sling is just that but no integration I started to code a workaround. For now I have a patch that does the trick but it is not clean because I use a Servlet Filter to place the tenant id on a thread local instance. Afterwards I started to look into how to implemented this cleanly into the current version of Sling.
>>
>> There are a few areas that need to be changed in order to implement tenant support. For now I am only looking into how to implement a “per-call overlays of servlets / JSPs” in order to give tenants the chance to change aspects of their presentation.
>>
>> 1) Tenant Identification: Sling must be able to identify a tenant. This can be a sub domain, path, cookies or even parameters. This means the client needs to provide a service which is then used by Sling in order to retrieve the tenant and provide it to whomever wants to use it.
>>
>> 2) Servlet Resolver needs to be changed twofolds
>> a) Being able to extend the search path for Servlets / JSPs based on the tenant’s data
>> b) Caching the Servlets / JPSs separated for different tenants
>>
>> 3) Change the Felix OSGi Web Plugin to allow the clients to add properties (single and multi values)
>>
>>
>> For 1) I would suggest just to define an interface the client can implement as an OSGi service which is used to identify a tenant. Then somewhere in the SlingMainServlet or the Request Data the Tenant is retrieved set on the Sling Http Servlet Request and if applicable the Search Path of the Resource Resolver is “enhanced/extended”.
>>
>> For 2) I would suggest to add a new property to the Resource Resolver which contains the Search Path Extension. Because the Servlet Resolver uses the Administrative Resource Resolver we need a way to “Enhance the Search Path” for that particular call. This could be done with a one-off wrapper. Based on the Extended Search Path we can determine which Servlet is an overlay and cache the overlays separately.
>>
>> 3) should be straight forward.
>>
>> Carsten was suggesting something like a TenantProvider like the ServletProvider but in the current code the ServletProvider is called with either the Sling Servlet Request, the Resource or a Resource Resolver and path. This means the tenant id must be available to any of these calls which would require to put the tenant id inside the Resource Resolver.
>>
>> Let me know what you think.
>>
>> - Andy Schaefer
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Carsten Ziegeler
Hi Andy,

this sounds interesting - and I guess a patch would be great. Now I just
would like to present my idea again - just for the sake of discussion :)

I think over time there will be more components than just the servlet
resolver which make use of the tenant and the extended search path, so I
think it would be great to have some generic mechanism to get the "current"
tenant.
My first idea was to have a TenantAware interface which passes in a
TenantResolver (bad name) instance. And whenever the tenant aware component
needs the current tenant it asks the resolver, maybe a method like
Tenant getTenant(ResourceResolver resolver)
We could then extend the Tenant interface to provide the extended search
path.

This would keep all the tenant extension stuff out of the resource resolver
- and would just be an extension.

Instead of using a TenantResolver we could go with
ResourceResolver.adaptTo(Tenant.class)

WDYT?

Carsten


2014-02-21 7:53 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:

> Sorry, I forgot to mention that the Search Path Extension is prepended to
> the Search Path when it is requested (in the Resource Resolver).
>
> - Andy
>
> On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <[hidden email]>
> wrote:
>
> > Hi
> >
> > I started to look into how to add tenant support to Sling.
> >
> > This is my test scenario:
> >
> > I have an /apps/foo/bar/html.esp and a /apps/tenant1/foo/bar/html.esp
> and a /content/mynode entry. The title of the second html.esp is different
> so that I know which one is loaded.
> >
> > Changes to the code:
> >
> > 1) Added get/setSearchPathExtension() to the Resource Resolver and its
> implementation.
> >
> > 2) In the SlingRequestProcessorImpl I extract the tenant from the first
> sub domain (no OSGi Service yet) and prepend it with /apps/ to the Search
> Path Extension
> >
> > 3) In the Servlet Resolver added the code to set the Search Path
> Extension from the Resource's Resource Resolver onto the Script Resource
> Resolver.
> >
> > Ran it and it showed the Tenant Specific ESP when the host name has a
> tenant it as sub domain and the original ESP when used with localhost.
> >
> > This shows that is it basically possible to thread through the tenant
> Search Path on a per-call basis to the Servlet Resolver. There is still
> much to do like the Cache handling in the Servlet Resolver and a OSGi
> service that provides the tenant from a request.
> >
> > I can create an Issue and add a patch of my changes to it if anyone is
> interested.
> >
> > Cheers - Andy
> >
> > On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]>
> wrote:
> >
> >> Hi
> >>
> >> I am working for a client which needs support for tenants and because
> the current implementation of the Tenants in Sling is just that but no
> integration I started to code a workaround. For now I have a patch that
> does the trick but it is not clean because I use a Servlet Filter to place
> the tenant id on a thread local instance. Afterwards I started to look into
> how to implemented this cleanly into the current version of Sling.
> >>
> >> There are a few areas that need to be changed in order to implement
> tenant support. For now I am only looking into how to implement a "per-call
> overlays of servlets / JSPs" in order to give tenants the chance to change
> aspects of their presentation.
> >>
> >> 1) Tenant Identification: Sling must be able to identify a tenant. This
> can be a sub domain, path, cookies or even parameters. This means the
> client needs to provide a service which is then used by Sling in order to
> retrieve the tenant and provide it to whomever wants to use it.
> >>
> >> 2) Servlet Resolver needs to be changed twofolds
> >>      a) Being able to extend the search path for Servlets / JSPs based
> on the tenant's data
> >>      b) Caching the Servlets / JPSs separated for different tenants
> >>
> >> 3) Change the Felix OSGi Web Plugin to allow the clients to add
> properties (single and multi values)
> >>
> >>
> >> For 1) I would suggest just to define an interface the client can
> implement as an OSGi service which is used to identify a tenant. Then
> somewhere in the SlingMainServlet or the Request Data the Tenant is
> retrieved set on the Sling Http Servlet Request and if applicable the
> Search Path of the Resource Resolver is "enhanced/extended".
> >>
> >> For 2) I would suggest to add a new property to the Resource Resolver
> which contains the Search Path Extension. Because the Servlet Resolver uses
> the Administrative Resource Resolver we need a way to "Enhance the Search
> Path" for that particular call. This could be done with a one-off wrapper.
> Based on the Extended Search Path we can determine which Servlet is an
> overlay and cache the overlays separately.
> >>
> >> 3) should be straight forward.
> >>
> >> Carsten was suggesting something like a TenantProvider like the
> ServletProvider but in the current code the ServletProvider is called with
> either the Sling Servlet Request, the Resource or a Resource Resolver and
> path. This means the tenant id must be available to any of these calls
> which would require to put the tenant id inside the Resource Resolver.
> >>
> >> Let me know what you think.
> >>
> >> - Andy Schaefer
> >>
> >
>
>


--
Carsten Ziegeler
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Bertrand Delacretaz
In reply to this post by Andreas Schaefer
Hi,

On Fri, Feb 21, 2014 at 7:20 AM, Andreas Schaefer Sr. <[hidden email]> wrote:
> ...I started to look into how to add tenant support to Sling....

I haven't looked at the details but my feeling is that "tenant" means
different things to different people, so it would be good to have a
list of use cases to back this design.

Something like https://cwiki.apache.org/confluence/display/SLING/Sling+Feature+Flags+support
maybe. Let us know your confluence username if you need access.

-Bertrand
Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
In reply to this post by Carsten Ziegeler
Hi Carsten

First I want to clarify that the Search Path Extension has nothing to do with Tenants per se but is a “per-call” extension of the search path which could be used without tenants.In order to make the overlays work the Search Path Extension must be set early on. For this part the client could implement a Service or configure a Service to obtain the Search Path Extension.

Currently I have a working POC for a client using CQ 5.6.1 which uses this concept to having Servlets/JSP overlays but also tenant specific translation (I18n) both working through the Search Path Extension.

The TenantResolver is an good idea but the ResourceResolver.adaptTo(Tenant.class) might be a problem due to the Administrative Resource Resolver (Servlet Resolver) and also ties Tenants into the Resource Resolver module.

- Andy

On Feb 20, 2014, at 11:32 PM, Carsten Ziegeler <[hidden email]> wrote:

> Hi Andy,
>
> this sounds interesting - and I guess a patch would be great. Now I just
> would like to present my idea again - just for the sake of discussion :)
>
> I think over time there will be more components than just the servlet
> resolver which make use of the tenant and the extended search path, so I
> think it would be great to have some generic mechanism to get the "current"
> tenant.
> My first idea was to have a TenantAware interface which passes in a
> TenantResolver (bad name) instance. And whenever the tenant aware component
> needs the current tenant it asks the resolver, maybe a method like
> Tenant getTenant(ResourceResolver resolver)
> We could then extend the Tenant interface to provide the extended search
> path.
>
> This would keep all the tenant extension stuff out of the resource resolver
> - and would just be an extension.
>
> Instead of using a TenantResolver we could go with
> ResourceResolver.adaptTo(Tenant.class)
>
> WDYT?
>
> Carsten
>
>
> 2014-02-21 7:53 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>
>> Sorry, I forgot to mention that the Search Path Extension is prepended to
>> the Search Path when it is requested (in the Resource Resolver).
>>
>> - Andy
>>
>> On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <[hidden email]>
>> wrote:
>>
>>> Hi
>>>
>>> I started to look into how to add tenant support to Sling.
>>>
>>> This is my test scenario:
>>>
>>> I have an /apps/foo/bar/html.esp and a /apps/tenant1/foo/bar/html.esp
>> and a /content/mynode entry. The title of the second html.esp is different
>> so that I know which one is loaded.
>>>
>>> Changes to the code:
>>>
>>> 1) Added get/setSearchPathExtension() to the Resource Resolver and its
>> implementation.
>>>
>>> 2) In the SlingRequestProcessorImpl I extract the tenant from the first
>> sub domain (no OSGi Service yet) and prepend it with /apps/ to the Search
>> Path Extension
>>>
>>> 3) In the Servlet Resolver added the code to set the Search Path
>> Extension from the Resource's Resource Resolver onto the Script Resource
>> Resolver.
>>>
>>> Ran it and it showed the Tenant Specific ESP when the host name has a
>> tenant it as sub domain and the original ESP when used with localhost.
>>>
>>> This shows that is it basically possible to thread through the tenant
>> Search Path on a per-call basis to the Servlet Resolver. There is still
>> much to do like the Cache handling in the Servlet Resolver and a OSGi
>> service that provides the tenant from a request.
>>>
>>> I can create an Issue and add a patch of my changes to it if anyone is
>> interested.
>>>
>>> Cheers - Andy
>>>
>>> On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]>
>> wrote:
>>>
>>>> Hi
>>>>
>>>> I am working for a client which needs support for tenants and because
>> the current implementation of the Tenants in Sling is just that but no
>> integration I started to code a workaround. For now I have a patch that
>> does the trick but it is not clean because I use a Servlet Filter to place
>> the tenant id on a thread local instance. Afterwards I started to look into
>> how to implemented this cleanly into the current version of Sling.
>>>>
>>>> There are a few areas that need to be changed in order to implement
>> tenant support. For now I am only looking into how to implement a "per-call
>> overlays of servlets / JSPs" in order to give tenants the chance to change
>> aspects of their presentation.
>>>>
>>>> 1) Tenant Identification: Sling must be able to identify a tenant. This
>> can be a sub domain, path, cookies or even parameters. This means the
>> client needs to provide a service which is then used by Sling in order to
>> retrieve the tenant and provide it to whomever wants to use it.
>>>>
>>>> 2) Servlet Resolver needs to be changed twofolds
>>>>     a) Being able to extend the search path for Servlets / JSPs based
>> on the tenant's data
>>>>     b) Caching the Servlets / JPSs separated for different tenants
>>>>
>>>> 3) Change the Felix OSGi Web Plugin to allow the clients to add
>> properties (single and multi values)
>>>>
>>>>
>>>> For 1) I would suggest just to define an interface the client can
>> implement as an OSGi service which is used to identify a tenant. Then
>> somewhere in the SlingMainServlet or the Request Data the Tenant is
>> retrieved set on the Sling Http Servlet Request and if applicable the
>> Search Path of the Resource Resolver is "enhanced/extended".
>>>>
>>>> For 2) I would suggest to add a new property to the Resource Resolver
>> which contains the Search Path Extension. Because the Servlet Resolver uses
>> the Administrative Resource Resolver we need a way to "Enhance the Search
>> Path" for that particular call. This could be done with a one-off wrapper.
>> Based on the Extended Search Path we can determine which Servlet is an
>> overlay and cache the overlays separately.
>>>>
>>>> 3) should be straight forward.
>>>>
>>>> Carsten was suggesting something like a TenantProvider like the
>> ServletProvider but in the current code the ServletProvider is called with
>> either the Sling Servlet Request, the Resource or a Resource Resolver and
>> path. This means the tenant id must be available to any of these calls
>> which would require to put the tenant id inside the Resource Resolver.
>>>>
>>>> Let me know what you think.
>>>>
>>>> - Andy Schaefer
>>>>
>>>
>>
>>
>
>
> --
> Carsten Ziegeler
> [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
In reply to this post by Bertrand Delacretaz
Hi

Yeah, I can do that. My confluence name is ‘schaefera’.

BTW I saw that there is a page called "Multitenancy Support” which talks about the Tenant. I would like to create a page called "Multitenancy Integration” where I would talk about how to use Tenants within Sling.

- Andy

On Feb 21, 2014, at 1:34 AM, Bertrand Delacretaz <[hidden email]> wrote:

> Hi,
>
> On Fri, Feb 21, 2014 at 7:20 AM, Andreas Schaefer Sr. <[hidden email]> wrote:
>> ...I started to look into how to add tenant support to Sling....
>
> I haven't looked at the details but my feeling is that "tenant" means
> different things to different people, so it would be good to have a
> list of use cases to back this design.
>
> Something like https://cwiki.apache.org/confluence/display/SLING/Sling+Feature+Flags+support
> maybe. Let us know your confluence username if you need access.
>
> -Bertrand

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Carsten Ziegeler
In reply to this post by Andreas Schaefer
Hi Andy,

I'm not sure if we need search path extensions which are not related to
tenants.
The adaption to a tenant does not tie it to the resource resolver module,
the adapter factory can live in the tenant module and therefore the
resource resolver module is totally unaware of tenant handling. The
adaption can internally use a thread local which holds the tenant from the
request, so even for administrative resource resolvers, an adaptTo would
work within the context of a request.

But these are just rough ideas anyway :)

Regards
Carsten


2014-02-21 17:16 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:

> Hi Carsten
>
> First I want to clarify that the Search Path Extension has nothing to do
> with Tenants per se but is a "per-call" extension of the search path which
> could be used without tenants.In order to make the overlays work the Search
> Path Extension must be set early on. For this part the client could
> implement a Service or configure a Service to obtain the Search Path
> Extension.
>
> Currently I have a working POC for a client using CQ 5.6.1 which uses this
> concept to having Servlets/JSP overlays but also tenant specific
> translation (I18n) both working through the Search Path Extension.
>
> The TenantResolver is an good idea but the
> ResourceResolver.adaptTo(Tenant.class) might be a problem due to the
> Administrative Resource Resolver (Servlet Resolver) and also ties Tenants
> into the Resource Resolver module.
>
> - Andy
>
> On Feb 20, 2014, at 11:32 PM, Carsten Ziegeler <[hidden email]>
> wrote:
>
> > Hi Andy,
> >
> > this sounds interesting - and I guess a patch would be great. Now I just
> > would like to present my idea again - just for the sake of discussion :)
> >
> > I think over time there will be more components than just the servlet
> > resolver which make use of the tenant and the extended search path, so I
> > think it would be great to have some generic mechanism to get the
> "current"
> > tenant.
> > My first idea was to have a TenantAware interface which passes in a
> > TenantResolver (bad name) instance. And whenever the tenant aware
> component
> > needs the current tenant it asks the resolver, maybe a method like
> > Tenant getTenant(ResourceResolver resolver)
> > We could then extend the Tenant interface to provide the extended search
> > path.
> >
> > This would keep all the tenant extension stuff out of the resource
> resolver
> > - and would just be an extension.
> >
> > Instead of using a TenantResolver we could go with
> > ResourceResolver.adaptTo(Tenant.class)
> >
> > WDYT?
> >
> > Carsten
> >
> >
> > 2014-02-21 7:53 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
> >
> >> Sorry, I forgot to mention that the Search Path Extension is prepended
> to
> >> the Search Path when it is requested (in the Resource Resolver).
> >>
> >> - Andy
> >>
> >> On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <[hidden email]>
> >> wrote:
> >>
> >>> Hi
> >>>
> >>> I started to look into how to add tenant support to Sling.
> >>>
> >>> This is my test scenario:
> >>>
> >>> I have an /apps/foo/bar/html.esp and a /apps/tenant1/foo/bar/html.esp
> >> and a /content/mynode entry. The title of the second html.esp is
> different
> >> so that I know which one is loaded.
> >>>
> >>> Changes to the code:
> >>>
> >>> 1) Added get/setSearchPathExtension() to the Resource Resolver and its
> >> implementation.
> >>>
> >>> 2) In the SlingRequestProcessorImpl I extract the tenant from the first
> >> sub domain (no OSGi Service yet) and prepend it with /apps/ to the
> Search
> >> Path Extension
> >>>
> >>> 3) In the Servlet Resolver added the code to set the Search Path
> >> Extension from the Resource's Resource Resolver onto the Script Resource
> >> Resolver.
> >>>
> >>> Ran it and it showed the Tenant Specific ESP when the host name has a
> >> tenant it as sub domain and the original ESP when used with localhost.
> >>>
> >>> This shows that is it basically possible to thread through the tenant
> >> Search Path on a per-call basis to the Servlet Resolver. There is still
> >> much to do like the Cache handling in the Servlet Resolver and a OSGi
> >> service that provides the tenant from a request.
> >>>
> >>> I can create an Issue and add a patch of my changes to it if anyone is
> >> interested.
> >>>
> >>> Cheers - Andy
> >>>
> >>> On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]>
> >> wrote:
> >>>
> >>>> Hi
> >>>>
> >>>> I am working for a client which needs support for tenants and because
> >> the current implementation of the Tenants in Sling is just that but no
> >> integration I started to code a workaround. For now I have a patch that
> >> does the trick but it is not clean because I use a Servlet Filter to
> place
> >> the tenant id on a thread local instance. Afterwards I started to look
> into
> >> how to implemented this cleanly into the current version of Sling.
> >>>>
> >>>> There are a few areas that need to be changed in order to implement
> >> tenant support. For now I am only looking into how to implement a
> "per-call
> >> overlays of servlets / JSPs" in order to give tenants the chance to
> change
> >> aspects of their presentation.
> >>>>
> >>>> 1) Tenant Identification: Sling must be able to identify a tenant.
> This
> >> can be a sub domain, path, cookies or even parameters. This means the
> >> client needs to provide a service which is then used by Sling in order
> to
> >> retrieve the tenant and provide it to whomever wants to use it.
> >>>>
> >>>> 2) Servlet Resolver needs to be changed twofolds
> >>>>     a) Being able to extend the search path for Servlets / JSPs based
> >> on the tenant's data
> >>>>     b) Caching the Servlets / JPSs separated for different tenants
> >>>>
> >>>> 3) Change the Felix OSGi Web Plugin to allow the clients to add
> >> properties (single and multi values)
> >>>>
> >>>>
> >>>> For 1) I would suggest just to define an interface the client can
> >> implement as an OSGi service which is used to identify a tenant. Then
> >> somewhere in the SlingMainServlet or the Request Data the Tenant is
> >> retrieved set on the Sling Http Servlet Request and if applicable the
> >> Search Path of the Resource Resolver is "enhanced/extended".
> >>>>
> >>>> For 2) I would suggest to add a new property to the Resource Resolver
> >> which contains the Search Path Extension. Because the Servlet Resolver
> uses
> >> the Administrative Resource Resolver we need a way to "Enhance the
> Search
> >> Path" for that particular call. This could be done with a one-off
> wrapper.
> >> Based on the Extended Search Path we can determine which Servlet is an
> >> overlay and cache the overlays separately.
> >>>>
> >>>> 3) should be straight forward.
> >>>>
> >>>> Carsten was suggesting something like a TenantProvider like the
> >> ServletProvider but in the current code the ServletProvider is called
> with
> >> either the Sling Servlet Request, the Resource or a Resource Resolver
> and
> >> path. This means the tenant id must be available to any of these calls
> >> which would require to put the tenant id inside the Resource Resolver.
> >>>>
> >>>> Let me know what you think.
> >>>>
> >>>> - Andy Schaefer
> >>>>
> >>>
> >>
> >>
> >
> >
> > --
> > Carsten Ziegeler
> > [hidden email]
>
>


--
Carsten Ziegeler
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Bertrand Delacretaz
In reply to this post by Andreas Schaefer
On Fri, Feb 21, 2014 at 5:19 PM, Andreas Schaefer Sr. <[hidden email]> wrote:
> ...My confluence name is ‘schaefera’....

Ok, I have added you to the sling-contributors group, you should now
have write access to https://cwiki.apache.org/confluence/display

>
> BTW I saw that there is a page called "Multitenancy Support” which talks about the Tenant. I would like to create a
> page called "Multitenancy Integration” where I would talk about how to use Tenants within Sling....

Ok, as long as you add links between those related pages that's fine.

-Bertrand
Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
Hi

Thanks. I’ll created the page here:

https://cwiki.apache.org/confluence/display/SLING/Multitenancy+Support+Integration

and also created a ticket for it here:

https://issues.apache.org/jira/browse/SLING-3414

- Andy

On Feb 24, 2014, at 5:08 AM, Bertrand Delacretaz <[hidden email]> wrote:

> On Fri, Feb 21, 2014 at 5:19 PM, Andreas Schaefer Sr. <[hidden email]> wrote:
>> ...My confluence name is ‘schaefera’....
>
> Ok, I have added you to the sling-contributors group, you should now
> have write access to https://cwiki.apache.org/confluence/display
>
>>
>> BTW I saw that there is a page called "Multitenancy Support” which talks about the Tenant. I would like to create a
>> page called "Multitenancy Integration” where I would talk about how to use Tenants within Sling....
>
> Ok, as long as you add links between those related pages that's fine.
>
> -Bertrand

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
In reply to this post by Carsten Ziegeler
Hi Carsten

Even if a Search Path Extension is not used outside of the Tenants I still think it would be great to keep things separate. Based on my tests if the Search Path Extension is set when the Resource Resolver of a request is created and the Servlet resolver’s own Resource Resolver is temporary extended with the same Search Path Extension we can provide a tenant specific view with multiple tenants.

Even though I like the idea of a Tenant Adapter Factory I don’t think this works out. Tenants are not only used for logged in users but also for the public view and the resource path is limited as well because what if the tenant viewer is requesting a common page (landing page etc) but the tenant provided some customization on the imported sub pages (ESPs, JSPs and Servlets) through overlays.

If a Thread Local is ok and we could make the Search Path Extension on the Resource Resolver settable then we could use a Request Servlet Filter to extract the Tenant from the Request using a Service which the host can override to resolve the Tenant and then set the Search Path Extension. From there on the Servlet Resolver does not need to know if this is a Tenant because the Search Path Extension of the Request or Resource is enough to provide tenant specific view.

Cheers - Andy

On Feb 21, 2014, at 10:06 AM, Carsten Ziegeler <[hidden email]> wrote:

> Hi Andy,
>
> I'm not sure if we need search path extensions which are not related to
> tenants.
> The adaption to a tenant does not tie it to the resource resolver module,
> the adapter factory can live in the tenant module and therefore the
> resource resolver module is totally unaware of tenant handling. The
> adaption can internally use a thread local which holds the tenant from the
> request, so even for administrative resource resolvers, an adaptTo would
> work within the context of a request.
>
> But these are just rough ideas anyway :)
>
> Regards
> Carsten
>
>
> 2014-02-21 17:16 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>
>> Hi Carsten
>>
>> First I want to clarify that the Search Path Extension has nothing to do
>> with Tenants per se but is a "per-call" extension of the search path which
>> could be used without tenants.In order to make the overlays work the Search
>> Path Extension must be set early on. For this part the client could
>> implement a Service or configure a Service to obtain the Search Path
>> Extension.
>>
>> Currently I have a working POC for a client using CQ 5.6.1 which uses this
>> concept to having Servlets/JSP overlays but also tenant specific
>> translation (I18n) both working through the Search Path Extension.
>>
>> The TenantResolver is an good idea but the
>> ResourceResolver.adaptTo(Tenant.class) might be a problem due to the
>> Administrative Resource Resolver (Servlet Resolver) and also ties Tenants
>> into the Resource Resolver module.
>>
>> - Andy
>>
>> On Feb 20, 2014, at 11:32 PM, Carsten Ziegeler <[hidden email]>
>> wrote:
>>
>>> Hi Andy,
>>>
>>> this sounds interesting - and I guess a patch would be great. Now I just
>>> would like to present my idea again - just for the sake of discussion :)
>>>
>>> I think over time there will be more components than just the servlet
>>> resolver which make use of the tenant and the extended search path, so I
>>> think it would be great to have some generic mechanism to get the
>> "current"
>>> tenant.
>>> My first idea was to have a TenantAware interface which passes in a
>>> TenantResolver (bad name) instance. And whenever the tenant aware
>> component
>>> needs the current tenant it asks the resolver, maybe a method like
>>> Tenant getTenant(ResourceResolver resolver)
>>> We could then extend the Tenant interface to provide the extended search
>>> path.
>>>
>>> This would keep all the tenant extension stuff out of the resource
>> resolver
>>> - and would just be an extension.
>>>
>>> Instead of using a TenantResolver we could go with
>>> ResourceResolver.adaptTo(Tenant.class)
>>>
>>> WDYT?
>>>
>>> Carsten
>>>
>>>
>>> 2014-02-21 7:53 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>>>
>>>> Sorry, I forgot to mention that the Search Path Extension is prepended
>> to
>>>> the Search Path when it is requested (in the Resource Resolver).
>>>>
>>>> - Andy
>>>>
>>>> On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <[hidden email]>
>>>> wrote:
>>>>
>>>>> Hi
>>>>>
>>>>> I started to look into how to add tenant support to Sling.
>>>>>
>>>>> This is my test scenario:
>>>>>
>>>>> I have an /apps/foo/bar/html.esp and a /apps/tenant1/foo/bar/html.esp
>>>> and a /content/mynode entry. The title of the second html.esp is
>> different
>>>> so that I know which one is loaded.
>>>>>
>>>>> Changes to the code:
>>>>>
>>>>> 1) Added get/setSearchPathExtension() to the Resource Resolver and its
>>>> implementation.
>>>>>
>>>>> 2) In the SlingRequestProcessorImpl I extract the tenant from the first
>>>> sub domain (no OSGi Service yet) and prepend it with /apps/ to the
>> Search
>>>> Path Extension
>>>>>
>>>>> 3) In the Servlet Resolver added the code to set the Search Path
>>>> Extension from the Resource's Resource Resolver onto the Script Resource
>>>> Resolver.
>>>>>
>>>>> Ran it and it showed the Tenant Specific ESP when the host name has a
>>>> tenant it as sub domain and the original ESP when used with localhost.
>>>>>
>>>>> This shows that is it basically possible to thread through the tenant
>>>> Search Path on a per-call basis to the Servlet Resolver. There is still
>>>> much to do like the Cache handling in the Servlet Resolver and a OSGi
>>>> service that provides the tenant from a request.
>>>>>
>>>>> I can create an Issue and add a patch of my changes to it if anyone is
>>>> interested.
>>>>>
>>>>> Cheers - Andy
>>>>>
>>>>> On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]>
>>>> wrote:
>>>>>
>>>>>> Hi
>>>>>>
>>>>>> I am working for a client which needs support for tenants and because
>>>> the current implementation of the Tenants in Sling is just that but no
>>>> integration I started to code a workaround. For now I have a patch that
>>>> does the trick but it is not clean because I use a Servlet Filter to
>> place
>>>> the tenant id on a thread local instance. Afterwards I started to look
>> into
>>>> how to implemented this cleanly into the current version of Sling.
>>>>>>
>>>>>> There are a few areas that need to be changed in order to implement
>>>> tenant support. For now I am only looking into how to implement a
>> "per-call
>>>> overlays of servlets / JSPs" in order to give tenants the chance to
>> change
>>>> aspects of their presentation.
>>>>>>
>>>>>> 1) Tenant Identification: Sling must be able to identify a tenant.
>> This
>>>> can be a sub domain, path, cookies or even parameters. This means the
>>>> client needs to provide a service which is then used by Sling in order
>> to
>>>> retrieve the tenant and provide it to whomever wants to use it.
>>>>>>
>>>>>> 2) Servlet Resolver needs to be changed twofolds
>>>>>>    a) Being able to extend the search path for Servlets / JSPs based
>>>> on the tenant's data
>>>>>>    b) Caching the Servlets / JPSs separated for different tenants
>>>>>>
>>>>>> 3) Change the Felix OSGi Web Plugin to allow the clients to add
>>>> properties (single and multi values)
>>>>>>
>>>>>>
>>>>>> For 1) I would suggest just to define an interface the client can
>>>> implement as an OSGi service which is used to identify a tenant. Then
>>>> somewhere in the SlingMainServlet or the Request Data the Tenant is
>>>> retrieved set on the Sling Http Servlet Request and if applicable the
>>>> Search Path of the Resource Resolver is "enhanced/extended".
>>>>>>
>>>>>> For 2) I would suggest to add a new property to the Resource Resolver
>>>> which contains the Search Path Extension. Because the Servlet Resolver
>> uses
>>>> the Administrative Resource Resolver we need a way to "Enhance the
>> Search
>>>> Path" for that particular call. This could be done with a one-off
>> wrapper.
>>>> Based on the Extended Search Path we can determine which Servlet is an
>>>> overlay and cache the overlays separately.
>>>>>>
>>>>>> 3) should be straight forward.
>>>>>>
>>>>>> Carsten was suggesting something like a TenantProvider like the
>>>> ServletProvider but in the current code the ServletProvider is called
>> with
>>>> either the Sling Servlet Request, the Resource or a Resource Resolver
>> and
>>>> path. This means the tenant id must be available to any of these calls
>>>> which would require to put the tenant id inside the Resource Resolver.
>>>>>>
>>>>>> Let me know what you think.
>>>>>>
>>>>>> - Andy Schaefer
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>> --
>>> Carsten Ziegeler
>>> [hidden email]
>>
>>
>
>
> --
> Carsten Ziegeler
> [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Carsten Ziegeler
If you want the method to get the search paths extensions to be on the
resource resolver and make it independent of a tenant, then why do we need
this method at all?
In the case of a tenant getSearchPath would return the normal search path
with the tenant specific one prepended.

Carsten


2014-02-24 18:43 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:

> Hi Carsten
>
> Even if a Search Path Extension is not used outside of the Tenants I still
> think it would be great to keep things separate. Based on my tests if the
> Search Path Extension is set when the Resource Resolver of a request is
> created and the Servlet resolver's own Resource Resolver is temporary
> extended with the same Search Path Extension we can provide a tenant
> specific view with multiple tenants.
>
> Even though I like the idea of a Tenant Adapter Factory I don't think this
> works out. Tenants are not only used for logged in users but also for the
> public view and the resource path is limited as well because what if the
> tenant viewer is requesting a common page (landing page etc) but the tenant
> provided some customization on the imported sub pages (ESPs, JSPs and
> Servlets) through overlays.
>
> If a Thread Local is ok and we could make the Search Path Extension on the
> Resource Resolver settable then we could use a Request Servlet Filter to
> extract the Tenant from the Request using a Service which the host can
> override to resolve the Tenant and then set the Search Path Extension. From
> there on the Servlet Resolver does not need to know if this is a Tenant
> because the Search Path Extension of the Request or Resource is enough to
> provide tenant specific view.
>
> Cheers - Andy
>
> On Feb 21, 2014, at 10:06 AM, Carsten Ziegeler <[hidden email]>
> wrote:
>
> > Hi Andy,
> >
> > I'm not sure if we need search path extensions which are not related to
> > tenants.
> > The adaption to a tenant does not tie it to the resource resolver module,
> > the adapter factory can live in the tenant module and therefore the
> > resource resolver module is totally unaware of tenant handling. The
> > adaption can internally use a thread local which holds the tenant from
> the
> > request, so even for administrative resource resolvers, an adaptTo would
> > work within the context of a request.
> >
> > But these are just rough ideas anyway :)
> >
> > Regards
> > Carsten
> >
> >
> > 2014-02-21 17:16 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
> >
> >> Hi Carsten
> >>
> >> First I want to clarify that the Search Path Extension has nothing to do
> >> with Tenants per se but is a "per-call" extension of the search path
> which
> >> could be used without tenants.In order to make the overlays work the
> Search
> >> Path Extension must be set early on. For this part the client could
> >> implement a Service or configure a Service to obtain the Search Path
> >> Extension.
> >>
> >> Currently I have a working POC for a client using CQ 5.6.1 which uses
> this
> >> concept to having Servlets/JSP overlays but also tenant specific
> >> translation (I18n) both working through the Search Path Extension.
> >>
> >> The TenantResolver is an good idea but the
> >> ResourceResolver.adaptTo(Tenant.class) might be a problem due to the
> >> Administrative Resource Resolver (Servlet Resolver) and also ties
> Tenants
> >> into the Resource Resolver module.
> >>
> >> - Andy
> >>
> >> On Feb 20, 2014, at 11:32 PM, Carsten Ziegeler <[hidden email]>
> >> wrote:
> >>
> >>> Hi Andy,
> >>>
> >>> this sounds interesting - and I guess a patch would be great. Now I
> just
> >>> would like to present my idea again - just for the sake of discussion
> :)
> >>>
> >>> I think over time there will be more components than just the servlet
> >>> resolver which make use of the tenant and the extended search path, so
> I
> >>> think it would be great to have some generic mechanism to get the
> >> "current"
> >>> tenant.
> >>> My first idea was to have a TenantAware interface which passes in a
> >>> TenantResolver (bad name) instance. And whenever the tenant aware
> >> component
> >>> needs the current tenant it asks the resolver, maybe a method like
> >>> Tenant getTenant(ResourceResolver resolver)
> >>> We could then extend the Tenant interface to provide the extended
> search
> >>> path.
> >>>
> >>> This would keep all the tenant extension stuff out of the resource
> >> resolver
> >>> - and would just be an extension.
> >>>
> >>> Instead of using a TenantResolver we could go with
> >>> ResourceResolver.adaptTo(Tenant.class)
> >>>
> >>> WDYT?
> >>>
> >>> Carsten
> >>>
> >>>
> >>> 2014-02-21 7:53 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
> >>>
> >>>> Sorry, I forgot to mention that the Search Path Extension is prepended
> >> to
> >>>> the Search Path when it is requested (in the Resource Resolver).
> >>>>
> >>>> - Andy
> >>>>
> >>>> On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <[hidden email]>
> >>>> wrote:
> >>>>
> >>>>> Hi
> >>>>>
> >>>>> I started to look into how to add tenant support to Sling.
> >>>>>
> >>>>> This is my test scenario:
> >>>>>
> >>>>> I have an /apps/foo/bar/html.esp and a /apps/tenant1/foo/bar/html.esp
> >>>> and a /content/mynode entry. The title of the second html.esp is
> >> different
> >>>> so that I know which one is loaded.
> >>>>>
> >>>>> Changes to the code:
> >>>>>
> >>>>> 1) Added get/setSearchPathExtension() to the Resource Resolver and
> its
> >>>> implementation.
> >>>>>
> >>>>> 2) In the SlingRequestProcessorImpl I extract the tenant from the
> first
> >>>> sub domain (no OSGi Service yet) and prepend it with /apps/ to the
> >> Search
> >>>> Path Extension
> >>>>>
> >>>>> 3) In the Servlet Resolver added the code to set the Search Path
> >>>> Extension from the Resource's Resource Resolver onto the Script
> Resource
> >>>> Resolver.
> >>>>>
> >>>>> Ran it and it showed the Tenant Specific ESP when the host name has a
> >>>> tenant it as sub domain and the original ESP when used with localhost.
> >>>>>
> >>>>> This shows that is it basically possible to thread through the tenant
> >>>> Search Path on a per-call basis to the Servlet Resolver. There is
> still
> >>>> much to do like the Cache handling in the Servlet Resolver and a OSGi
> >>>> service that provides the tenant from a request.
> >>>>>
> >>>>> I can create an Issue and add a patch of my changes to it if anyone
> is
> >>>> interested.
> >>>>>
> >>>>> Cheers - Andy
> >>>>>
> >>>>> On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]>
> >>>> wrote:
> >>>>>
> >>>>>> Hi
> >>>>>>
> >>>>>> I am working for a client which needs support for tenants and
> because
> >>>> the current implementation of the Tenants in Sling is just that but no
> >>>> integration I started to code a workaround. For now I have a patch
> that
> >>>> does the trick but it is not clean because I use a Servlet Filter to
> >> place
> >>>> the tenant id on a thread local instance. Afterwards I started to look
> >> into
> >>>> how to implemented this cleanly into the current version of Sling.
> >>>>>>
> >>>>>> There are a few areas that need to be changed in order to implement
> >>>> tenant support. For now I am only looking into how to implement a
> >> "per-call
> >>>> overlays of servlets / JSPs" in order to give tenants the chance to
> >> change
> >>>> aspects of their presentation.
> >>>>>>
> >>>>>> 1) Tenant Identification: Sling must be able to identify a tenant.
> >> This
> >>>> can be a sub domain, path, cookies or even parameters. This means the
> >>>> client needs to provide a service which is then used by Sling in order
> >> to
> >>>> retrieve the tenant and provide it to whomever wants to use it.
> >>>>>>
> >>>>>> 2) Servlet Resolver needs to be changed twofolds
> >>>>>>    a) Being able to extend the search path for Servlets / JSPs based
> >>>> on the tenant's data
> >>>>>>    b) Caching the Servlets / JPSs separated for different tenants
> >>>>>>
> >>>>>> 3) Change the Felix OSGi Web Plugin to allow the clients to add
> >>>> properties (single and multi values)
> >>>>>>
> >>>>>>
> >>>>>> For 1) I would suggest just to define an interface the client can
> >>>> implement as an OSGi service which is used to identify a tenant. Then
> >>>> somewhere in the SlingMainServlet or the Request Data the Tenant is
> >>>> retrieved set on the Sling Http Servlet Request and if applicable the
> >>>> Search Path of the Resource Resolver is "enhanced/extended".
> >>>>>>
> >>>>>> For 2) I would suggest to add a new property to the Resource
> Resolver
> >>>> which contains the Search Path Extension. Because the Servlet Resolver
> >> uses
> >>>> the Administrative Resource Resolver we need a way to "Enhance the
> >> Search
> >>>> Path" for that particular call. This could be done with a one-off
> >> wrapper.
> >>>> Based on the Extended Search Path we can determine which Servlet is an
> >>>> overlay and cache the overlays separately.
> >>>>>>
> >>>>>> 3) should be straight forward.
> >>>>>>
> >>>>>> Carsten was suggesting something like a TenantProvider like the
> >>>> ServletProvider but in the current code the ServletProvider is called
> >> with
> >>>> either the Sling Servlet Request, the Resource or a Resource Resolver
> >> and
> >>>> path. This means the tenant id must be available to any of these calls
> >>>> which would require to put the tenant id inside the Resource Resolver.
> >>>>>>
> >>>>>> Let me know what you think.
> >>>>>>
> >>>>>> - Andy Schaefer
> >>>>>>
> >>>>>
> >>>>
> >>>>
> >>>
> >>>
> >>> --
> >>> Carsten Ziegeler
> >>> [hidden email]
> >>
> >>
> >
> >
> > --
> > Carsten Ziegeler
> > [hidden email]
>
>


--
Carsten Ziegeler
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
If we have the search path extension separate and it is settable we do the following with it:

1) We can set it with a Servlet Filter instead of having it to hook into the Engine

2) In the Servlet Resolver the Search Path that did deliver the Servlet can be used in order to manage the cache. For example if a Servlet it found in the tenant’s own folder then it will be added to the cache of this folder, if it is found in a shared path then it is placed in the shared cache and the rest will be still cache system wide. When looking for a cached entry we just to through the Search Path Extension entries, look for a cache and if the servlet is found ok otherwise we need to load it. This way the cache is only cache a Servlet once and not multiple times if the cache would be per tenant.

3) The adjustment of the Search Path for the Administrative Resource Resolver can be done without having to blindly replacing the Search Path.

That said it might a good idea to add the getSearchPathExtension() to the Tenant because it has such a central role but I would keep the Tenant out of the Engine or the Servlet Resolver if possible.

- Andy

On Feb 24, 2014, at 1:09 PM, Carsten Ziegeler <[hidden email]> wrote:

> If you want the method to get the search paths extensions to be on the
> resource resolver and make it independent of a tenant, then why do we need
> this method at all?
> In the case of a tenant getSearchPath would return the normal search path
> with the tenant specific one prepended.
>
> Carsten
>
>
> 2014-02-24 18:43 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>
>> Hi Carsten
>>
>> Even if a Search Path Extension is not used outside of the Tenants I still
>> think it would be great to keep things separate. Based on my tests if the
>> Search Path Extension is set when the Resource Resolver of a request is
>> created and the Servlet resolver's own Resource Resolver is temporary
>> extended with the same Search Path Extension we can provide a tenant
>> specific view with multiple tenants.
>>
>> Even though I like the idea of a Tenant Adapter Factory I don't think this
>> works out. Tenants are not only used for logged in users but also for the
>> public view and the resource path is limited as well because what if the
>> tenant viewer is requesting a common page (landing page etc) but the tenant
>> provided some customization on the imported sub pages (ESPs, JSPs and
>> Servlets) through overlays.
>>
>> If a Thread Local is ok and we could make the Search Path Extension on the
>> Resource Resolver settable then we could use a Request Servlet Filter to
>> extract the Tenant from the Request using a Service which the host can
>> override to resolve the Tenant and then set the Search Path Extension. From
>> there on the Servlet Resolver does not need to know if this is a Tenant
>> because the Search Path Extension of the Request or Resource is enough to
>> provide tenant specific view.
>>
>> Cheers - Andy
>>
>> On Feb 21, 2014, at 10:06 AM, Carsten Ziegeler <[hidden email]>
>> wrote:
>>
>>> Hi Andy,
>>>
>>> I'm not sure if we need search path extensions which are not related to
>>> tenants.
>>> The adaption to a tenant does not tie it to the resource resolver module,
>>> the adapter factory can live in the tenant module and therefore the
>>> resource resolver module is totally unaware of tenant handling. The
>>> adaption can internally use a thread local which holds the tenant from
>> the
>>> request, so even for administrative resource resolvers, an adaptTo would
>>> work within the context of a request.
>>>
>>> But these are just rough ideas anyway :)
>>>
>>> Regards
>>> Carsten
>>>
>>>
>>> 2014-02-21 17:16 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>>>
>>>> Hi Carsten
>>>>
>>>> First I want to clarify that the Search Path Extension has nothing to do
>>>> with Tenants per se but is a "per-call" extension of the search path
>> which
>>>> could be used without tenants.In order to make the overlays work the
>> Search
>>>> Path Extension must be set early on. For this part the client could
>>>> implement a Service or configure a Service to obtain the Search Path
>>>> Extension.
>>>>
>>>> Currently I have a working POC for a client using CQ 5.6.1 which uses
>> this
>>>> concept to having Servlets/JSP overlays but also tenant specific
>>>> translation (I18n) both working through the Search Path Extension.
>>>>
>>>> The TenantResolver is an good idea but the
>>>> ResourceResolver.adaptTo(Tenant.class) might be a problem due to the
>>>> Administrative Resource Resolver (Servlet Resolver) and also ties
>> Tenants
>>>> into the Resource Resolver module.
>>>>
>>>> - Andy
>>>>
>>>> On Feb 20, 2014, at 11:32 PM, Carsten Ziegeler <[hidden email]>
>>>> wrote:
>>>>
>>>>> Hi Andy,
>>>>>
>>>>> this sounds interesting - and I guess a patch would be great. Now I
>> just
>>>>> would like to present my idea again - just for the sake of discussion
>> :)
>>>>>
>>>>> I think over time there will be more components than just the servlet
>>>>> resolver which make use of the tenant and the extended search path, so
>> I
>>>>> think it would be great to have some generic mechanism to get the
>>>> "current"
>>>>> tenant.
>>>>> My first idea was to have a TenantAware interface which passes in a
>>>>> TenantResolver (bad name) instance. And whenever the tenant aware
>>>> component
>>>>> needs the current tenant it asks the resolver, maybe a method like
>>>>> Tenant getTenant(ResourceResolver resolver)
>>>>> We could then extend the Tenant interface to provide the extended
>> search
>>>>> path.
>>>>>
>>>>> This would keep all the tenant extension stuff out of the resource
>>>> resolver
>>>>> - and would just be an extension.
>>>>>
>>>>> Instead of using a TenantResolver we could go with
>>>>> ResourceResolver.adaptTo(Tenant.class)
>>>>>
>>>>> WDYT?
>>>>>
>>>>> Carsten
>>>>>
>>>>>
>>>>> 2014-02-21 7:53 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>>>>>
>>>>>> Sorry, I forgot to mention that the Search Path Extension is prepended
>>>> to
>>>>>> the Search Path when it is requested (in the Resource Resolver).
>>>>>>
>>>>>> - Andy
>>>>>>
>>>>>> On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <[hidden email]>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi
>>>>>>>
>>>>>>> I started to look into how to add tenant support to Sling.
>>>>>>>
>>>>>>> This is my test scenario:
>>>>>>>
>>>>>>> I have an /apps/foo/bar/html.esp and a /apps/tenant1/foo/bar/html.esp
>>>>>> and a /content/mynode entry. The title of the second html.esp is
>>>> different
>>>>>> so that I know which one is loaded.
>>>>>>>
>>>>>>> Changes to the code:
>>>>>>>
>>>>>>> 1) Added get/setSearchPathExtension() to the Resource Resolver and
>> its
>>>>>> implementation.
>>>>>>>
>>>>>>> 2) In the SlingRequestProcessorImpl I extract the tenant from the
>> first
>>>>>> sub domain (no OSGi Service yet) and prepend it with /apps/ to the
>>>> Search
>>>>>> Path Extension
>>>>>>>
>>>>>>> 3) In the Servlet Resolver added the code to set the Search Path
>>>>>> Extension from the Resource's Resource Resolver onto the Script
>> Resource
>>>>>> Resolver.
>>>>>>>
>>>>>>> Ran it and it showed the Tenant Specific ESP when the host name has a
>>>>>> tenant it as sub domain and the original ESP when used with localhost.
>>>>>>>
>>>>>>> This shows that is it basically possible to thread through the tenant
>>>>>> Search Path on a per-call basis to the Servlet Resolver. There is
>> still
>>>>>> much to do like the Cache handling in the Servlet Resolver and a OSGi
>>>>>> service that provides the tenant from a request.
>>>>>>>
>>>>>>> I can create an Issue and add a patch of my changes to it if anyone
>> is
>>>>>> interested.
>>>>>>>
>>>>>>> Cheers - Andy
>>>>>>>
>>>>>>> On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <[hidden email]>
>>>>>> wrote:
>>>>>>>
>>>>>>>> Hi
>>>>>>>>
>>>>>>>> I am working for a client which needs support for tenants and
>> because
>>>>>> the current implementation of the Tenants in Sling is just that but no
>>>>>> integration I started to code a workaround. For now I have a patch
>> that
>>>>>> does the trick but it is not clean because I use a Servlet Filter to
>>>> place
>>>>>> the tenant id on a thread local instance. Afterwards I started to look
>>>> into
>>>>>> how to implemented this cleanly into the current version of Sling.
>>>>>>>>
>>>>>>>> There are a few areas that need to be changed in order to implement
>>>>>> tenant support. For now I am only looking into how to implement a
>>>> "per-call
>>>>>> overlays of servlets / JSPs" in order to give tenants the chance to
>>>> change
>>>>>> aspects of their presentation.
>>>>>>>>
>>>>>>>> 1) Tenant Identification: Sling must be able to identify a tenant.
>>>> This
>>>>>> can be a sub domain, path, cookies or even parameters. This means the
>>>>>> client needs to provide a service which is then used by Sling in order
>>>> to
>>>>>> retrieve the tenant and provide it to whomever wants to use it.
>>>>>>>>
>>>>>>>> 2) Servlet Resolver needs to be changed twofolds
>>>>>>>>   a) Being able to extend the search path for Servlets / JSPs based
>>>>>> on the tenant's data
>>>>>>>>   b) Caching the Servlets / JPSs separated for different tenants
>>>>>>>>
>>>>>>>> 3) Change the Felix OSGi Web Plugin to allow the clients to add
>>>>>> properties (single and multi values)
>>>>>>>>
>>>>>>>>
>>>>>>>> For 1) I would suggest just to define an interface the client can
>>>>>> implement as an OSGi service which is used to identify a tenant. Then
>>>>>> somewhere in the SlingMainServlet or the Request Data the Tenant is
>>>>>> retrieved set on the Sling Http Servlet Request and if applicable the
>>>>>> Search Path of the Resource Resolver is "enhanced/extended".
>>>>>>>>
>>>>>>>> For 2) I would suggest to add a new property to the Resource
>> Resolver
>>>>>> which contains the Search Path Extension. Because the Servlet Resolver
>>>> uses
>>>>>> the Administrative Resource Resolver we need a way to "Enhance the
>>>> Search
>>>>>> Path" for that particular call. This could be done with a one-off
>>>> wrapper.
>>>>>> Based on the Extended Search Path we can determine which Servlet is an
>>>>>> overlay and cache the overlays separately.
>>>>>>>>
>>>>>>>> 3) should be straight forward.
>>>>>>>>
>>>>>>>> Carsten was suggesting something like a TenantProvider like the
>>>>>> ServletProvider but in the current code the ServletProvider is called
>>>> with
>>>>>> either the Sling Servlet Request, the Resource or a Resource Resolver
>>>> and
>>>>>> path. This means the tenant id must be available to any of these calls
>>>>>> which would require to put the tenant id inside the Resource Resolver.
>>>>>>>>
>>>>>>>> Let me know what you think.
>>>>>>>>
>>>>>>>> - Andy Schaefer
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Carsten Ziegeler
>>>>> [hidden email]
>>>>
>>>>
>>>
>>>
>>> --
>>> Carsten Ziegeler
>>> [hidden email]
>>
>>
>
>
> --
> Carsten Ziegeler
> [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Carsten Ziegeler
Right, 2) and also 3) are good reasons to keep it separate. I think it
makes sense to link the search path extension somehow to the tenant.
In the old proposal (
https://cwiki.apache.org/confluence/display/SLING/Multitenancy+Support) we
suggested to have a special method on the resource resolver factory to get
a tenant aware resource resolver - while this sounds nice, it bloads the
resource resolver api and directly couples it.
I still like my TenantAware approach :) as by this you explicitely mark
your component to handle things Tenant specific.

Regards
Carsten


2014-02-25 2:41 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:

> If we have the search path extension separate and it is settable we do the
> following with it:
>
> 1) We can set it with a Servlet Filter instead of having it to hook into
> the Engine
>
> 2) In the Servlet Resolver the Search Path that did deliver the Servlet
> can be used in order to manage the cache. For example if a Servlet it found
> in the tenant's own folder then it will be added to the cache of this
> folder, if it is found in a shared path then it is placed in the shared
> cache and the rest will be still cache system wide. When looking for a
> cached entry we just to through the Search Path Extension entries, look for
> a cache and if the servlet is found ok otherwise we need to load it. This
> way the cache is only cache a Servlet once and not multiple times if the
> cache would be per tenant.
>
> 3) The adjustment of the Search Path for the Administrative Resource
> Resolver can be done without having to blindly replacing the Search Path.
>
> That said it might a good idea to add the getSearchPathExtension() to the
> Tenant because it has such a central role but I would keep the Tenant out
> of the Engine or the Servlet Resolver if possible.
>
> - Andy
>
> On Feb 24, 2014, at 1:09 PM, Carsten Ziegeler <[hidden email]>
> wrote:
>
> > If you want the method to get the search paths extensions to be on the
> > resource resolver and make it independent of a tenant, then why do we
> need
> > this method at all?
> > In the case of a tenant getSearchPath would return the normal search path
> > with the tenant specific one prepended.
> >
> > Carsten
> >
> >
> > 2014-02-24 18:43 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
> >
> >> Hi Carsten
> >>
> >> Even if a Search Path Extension is not used outside of the Tenants I
> still
> >> think it would be great to keep things separate. Based on my tests if
> the
> >> Search Path Extension is set when the Resource Resolver of a request is
> >> created and the Servlet resolver's own Resource Resolver is temporary
> >> extended with the same Search Path Extension we can provide a tenant
> >> specific view with multiple tenants.
> >>
> >> Even though I like the idea of a Tenant Adapter Factory I don't think
> this
> >> works out. Tenants are not only used for logged in users but also for
> the
> >> public view and the resource path is limited as well because what if the
> >> tenant viewer is requesting a common page (landing page etc) but the
> tenant
> >> provided some customization on the imported sub pages (ESPs, JSPs and
> >> Servlets) through overlays.
> >>
> >> If a Thread Local is ok and we could make the Search Path Extension on
> the
> >> Resource Resolver settable then we could use a Request Servlet Filter to
> >> extract the Tenant from the Request using a Service which the host can
> >> override to resolve the Tenant and then set the Search Path Extension.
> From
> >> there on the Servlet Resolver does not need to know if this is a Tenant
> >> because the Search Path Extension of the Request or Resource is enough
> to
> >> provide tenant specific view.
> >>
> >> Cheers - Andy
> >>
> >> On Feb 21, 2014, at 10:06 AM, Carsten Ziegeler <[hidden email]>
> >> wrote:
> >>
> >>> Hi Andy,
> >>>
> >>> I'm not sure if we need search path extensions which are not related to
> >>> tenants.
> >>> The adaption to a tenant does not tie it to the resource resolver
> module,
> >>> the adapter factory can live in the tenant module and therefore the
> >>> resource resolver module is totally unaware of tenant handling. The
> >>> adaption can internally use a thread local which holds the tenant from
> >> the
> >>> request, so even for administrative resource resolvers, an adaptTo
> would
> >>> work within the context of a request.
> >>>
> >>> But these are just rough ideas anyway :)
> >>>
> >>> Regards
> >>> Carsten
> >>>
> >>>
> >>> 2014-02-21 17:16 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
> >>>
> >>>> Hi Carsten
> >>>>
> >>>> First I want to clarify that the Search Path Extension has nothing to
> do
> >>>> with Tenants per se but is a "per-call" extension of the search path
> >> which
> >>>> could be used without tenants.In order to make the overlays work the
> >> Search
> >>>> Path Extension must be set early on. For this part the client could
> >>>> implement a Service or configure a Service to obtain the Search Path
> >>>> Extension.
> >>>>
> >>>> Currently I have a working POC for a client using CQ 5.6.1 which uses
> >> this
> >>>> concept to having Servlets/JSP overlays but also tenant specific
> >>>> translation (I18n) both working through the Search Path Extension.
> >>>>
> >>>> The TenantResolver is an good idea but the
> >>>> ResourceResolver.adaptTo(Tenant.class) might be a problem due to the
> >>>> Administrative Resource Resolver (Servlet Resolver) and also ties
> >> Tenants
> >>>> into the Resource Resolver module.
> >>>>
> >>>> - Andy
> >>>>
> >>>> On Feb 20, 2014, at 11:32 PM, Carsten Ziegeler <[hidden email]>
> >>>> wrote:
> >>>>
> >>>>> Hi Andy,
> >>>>>
> >>>>> this sounds interesting - and I guess a patch would be great. Now I
> >> just
> >>>>> would like to present my idea again - just for the sake of discussion
> >> :)
> >>>>>
> >>>>> I think over time there will be more components than just the servlet
> >>>>> resolver which make use of the tenant and the extended search path,
> so
> >> I
> >>>>> think it would be great to have some generic mechanism to get the
> >>>> "current"
> >>>>> tenant.
> >>>>> My first idea was to have a TenantAware interface which passes in a
> >>>>> TenantResolver (bad name) instance. And whenever the tenant aware
> >>>> component
> >>>>> needs the current tenant it asks the resolver, maybe a method like
> >>>>> Tenant getTenant(ResourceResolver resolver)
> >>>>> We could then extend the Tenant interface to provide the extended
> >> search
> >>>>> path.
> >>>>>
> >>>>> This would keep all the tenant extension stuff out of the resource
> >>>> resolver
> >>>>> - and would just be an extension.
> >>>>>
> >>>>> Instead of using a TenantResolver we could go with
> >>>>> ResourceResolver.adaptTo(Tenant.class)
> >>>>>
> >>>>> WDYT?
> >>>>>
> >>>>> Carsten
> >>>>>
> >>>>>
> >>>>> 2014-02-21 7:53 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
> >>>>>
> >>>>>> Sorry, I forgot to mention that the Search Path Extension is
> prepended
> >>>> to
> >>>>>> the Search Path when it is requested (in the Resource Resolver).
> >>>>>>
> >>>>>> - Andy
> >>>>>>
> >>>>>> On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <
> [hidden email]>
> >>>>>> wrote:
> >>>>>>
> >>>>>>> Hi
> >>>>>>>
> >>>>>>> I started to look into how to add tenant support to Sling.
> >>>>>>>
> >>>>>>> This is my test scenario:
> >>>>>>>
> >>>>>>> I have an /apps/foo/bar/html.esp and a
> /apps/tenant1/foo/bar/html.esp
> >>>>>> and a /content/mynode entry. The title of the second html.esp is
> >>>> different
> >>>>>> so that I know which one is loaded.
> >>>>>>>
> >>>>>>> Changes to the code:
> >>>>>>>
> >>>>>>> 1) Added get/setSearchPathExtension() to the Resource Resolver and
> >> its
> >>>>>> implementation.
> >>>>>>>
> >>>>>>> 2) In the SlingRequestProcessorImpl I extract the tenant from the
> >> first
> >>>>>> sub domain (no OSGi Service yet) and prepend it with /apps/ to the
> >>>> Search
> >>>>>> Path Extension
> >>>>>>>
> >>>>>>> 3) In the Servlet Resolver added the code to set the Search Path
> >>>>>> Extension from the Resource's Resource Resolver onto the Script
> >> Resource
> >>>>>> Resolver.
> >>>>>>>
> >>>>>>> Ran it and it showed the Tenant Specific ESP when the host name
> has a
> >>>>>> tenant it as sub domain and the original ESP when used with
> localhost.
> >>>>>>>
> >>>>>>> This shows that is it basically possible to thread through the
> tenant
> >>>>>> Search Path on a per-call basis to the Servlet Resolver. There is
> >> still
> >>>>>> much to do like the Cache handling in the Servlet Resolver and a
> OSGi
> >>>>>> service that provides the tenant from a request.
> >>>>>>>
> >>>>>>> I can create an Issue and add a patch of my changes to it if anyone
> >> is
> >>>>>> interested.
> >>>>>>>
> >>>>>>> Cheers - Andy
> >>>>>>>
> >>>>>>> On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <
> [hidden email]>
> >>>>>> wrote:
> >>>>>>>
> >>>>>>>> Hi
> >>>>>>>>
> >>>>>>>> I am working for a client which needs support for tenants and
> >> because
> >>>>>> the current implementation of the Tenants in Sling is just that but
> no
> >>>>>> integration I started to code a workaround. For now I have a patch
> >> that
> >>>>>> does the trick but it is not clean because I use a Servlet Filter to
> >>>> place
> >>>>>> the tenant id on a thread local instance. Afterwards I started to
> look
> >>>> into
> >>>>>> how to implemented this cleanly into the current version of Sling.
> >>>>>>>>
> >>>>>>>> There are a few areas that need to be changed in order to
> implement
> >>>>>> tenant support. For now I am only looking into how to implement a
> >>>> "per-call
> >>>>>> overlays of servlets / JSPs" in order to give tenants the chance to
> >>>> change
> >>>>>> aspects of their presentation.
> >>>>>>>>
> >>>>>>>> 1) Tenant Identification: Sling must be able to identify a tenant.
> >>>> This
> >>>>>> can be a sub domain, path, cookies or even parameters. This means
> the
> >>>>>> client needs to provide a service which is then used by Sling in
> order
> >>>> to
> >>>>>> retrieve the tenant and provide it to whomever wants to use it.
> >>>>>>>>
> >>>>>>>> 2) Servlet Resolver needs to be changed twofolds
> >>>>>>>>   a) Being able to extend the search path for Servlets / JSPs
> based
> >>>>>> on the tenant's data
> >>>>>>>>   b) Caching the Servlets / JPSs separated for different tenants
> >>>>>>>>
> >>>>>>>> 3) Change the Felix OSGi Web Plugin to allow the clients to add
> >>>>>> properties (single and multi values)
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> For 1) I would suggest just to define an interface the client can
> >>>>>> implement as an OSGi service which is used to identify a tenant.
> Then
> >>>>>> somewhere in the SlingMainServlet or the Request Data the Tenant is
> >>>>>> retrieved set on the Sling Http Servlet Request and if applicable
> the
> >>>>>> Search Path of the Resource Resolver is "enhanced/extended".
> >>>>>>>>
> >>>>>>>> For 2) I would suggest to add a new property to the Resource
> >> Resolver
> >>>>>> which contains the Search Path Extension. Because the Servlet
> Resolver
> >>>> uses
> >>>>>> the Administrative Resource Resolver we need a way to "Enhance the
> >>>> Search
> >>>>>> Path" for that particular call. This could be done with a one-off
> >>>> wrapper.
> >>>>>> Based on the Extended Search Path we can determine which Servlet is
> an
> >>>>>> overlay and cache the overlays separately.
> >>>>>>>>
> >>>>>>>> 3) should be straight forward.
> >>>>>>>>
> >>>>>>>> Carsten was suggesting something like a TenantProvider like the
> >>>>>> ServletProvider but in the current code the ServletProvider is
> called
> >>>> with
> >>>>>> either the Sling Servlet Request, the Resource or a Resource
> Resolver
> >>>> and
> >>>>>> path. This means the tenant id must be available to any of these
> calls
> >>>>>> which would require to put the tenant id inside the Resource
> Resolver.
> >>>>>>>>
> >>>>>>>> Let me know what you think.
> >>>>>>>>
> >>>>>>>> - Andy Schaefer
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>>
> >>>>>
> >>>>>
> >>>>> --
> >>>>> Carsten Ziegeler
> >>>>> [hidden email]
> >>>>
> >>>>
> >>>
> >>>
> >>> --
> >>> Carsten Ziegeler
> >>> [hidden email]
> >>
> >>
> >
> >
> > --
> > Carsten Ziegeler
> > [hidden email]
>
>


--
Carsten Ziegeler
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Bertrand Delacretaz
In reply to this post by Andreas Schaefer
On Tue, Feb 25, 2014 at 2:41 AM, Andreas Schaefer Sr. <[hidden email]> wrote:
> ...it might a good idea to add the getSearchPathExtension() to the Tenant...

Shouldn't that rather be called getAdditionalSearchPaths?

In Sling, "extension" means the .html at the end of a URL, IMO we
should avoid reusing that term for other things, as much as possible.

-Bertrand
Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
In reply to this post by Carsten Ziegeler
> I still like my TenantAware approach :) as by this you explicitely mark
> your component to handle things Tenant specific.

Do you mean with that that we place the Tenant on a Thread Local which then can be obtained from the Servlet Resolver?

If so do you intent to place the Tenant into the “bundles” directory (from “contrib”) because you would need then Tenant in the Servlet Resolver?

- Andy

On Feb 24, 2014, at 10:39 PM, Carsten Ziegeler <[hidden email]> wrote:

> Right, 2) and also 3) are good reasons to keep it separate. I think it
> makes sense to link the search path extension somehow to the tenant.
> In the old proposal (
> https://cwiki.apache.org/confluence/display/SLING/Multitenancy+Support) we
> suggested to have a special method on the resource resolver factory to get
> a tenant aware resource resolver - while this sounds nice, it bloads the
> resource resolver api and directly couples it.
> I still like my TenantAware approach :) as by this you explicitely mark
> your component to handle things Tenant specific.
>
> Regards
> Carsten
>
>
> 2014-02-25 2:41 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>
>> If we have the search path extension separate and it is settable we do the
>> following with it:
>>
>> 1) We can set it with a Servlet Filter instead of having it to hook into
>> the Engine
>>
>> 2) In the Servlet Resolver the Search Path that did deliver the Servlet
>> can be used in order to manage the cache. For example if a Servlet it found
>> in the tenant's own folder then it will be added to the cache of this
>> folder, if it is found in a shared path then it is placed in the shared
>> cache and the rest will be still cache system wide. When looking for a
>> cached entry we just to through the Search Path Extension entries, look for
>> a cache and if the servlet is found ok otherwise we need to load it. This
>> way the cache is only cache a Servlet once and not multiple times if the
>> cache would be per tenant.
>>
>> 3) The adjustment of the Search Path for the Administrative Resource
>> Resolver can be done without having to blindly replacing the Search Path.
>>
>> That said it might a good idea to add the getSearchPathExtension() to the
>> Tenant because it has such a central role but I would keep the Tenant out
>> of the Engine or the Servlet Resolver if possible.
>>
>> - Andy
>>
>> On Feb 24, 2014, at 1:09 PM, Carsten Ziegeler <[hidden email]>
>> wrote:
>>
>>> If you want the method to get the search paths extensions to be on the
>>> resource resolver and make it independent of a tenant, then why do we
>> need
>>> this method at all?
>>> In the case of a tenant getSearchPath would return the normal search path
>>> with the tenant specific one prepended.
>>>
>>> Carsten
>>>
>>>
>>> 2014-02-24 18:43 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>>>
>>>> Hi Carsten
>>>>
>>>> Even if a Search Path Extension is not used outside of the Tenants I
>> still
>>>> think it would be great to keep things separate. Based on my tests if
>> the
>>>> Search Path Extension is set when the Resource Resolver of a request is
>>>> created and the Servlet resolver's own Resource Resolver is temporary
>>>> extended with the same Search Path Extension we can provide a tenant
>>>> specific view with multiple tenants.
>>>>
>>>> Even though I like the idea of a Tenant Adapter Factory I don't think
>> this
>>>> works out. Tenants are not only used for logged in users but also for
>> the
>>>> public view and the resource path is limited as well because what if the
>>>> tenant viewer is requesting a common page (landing page etc) but the
>> tenant
>>>> provided some customization on the imported sub pages (ESPs, JSPs and
>>>> Servlets) through overlays.
>>>>
>>>> If a Thread Local is ok and we could make the Search Path Extension on
>> the
>>>> Resource Resolver settable then we could use a Request Servlet Filter to
>>>> extract the Tenant from the Request using a Service which the host can
>>>> override to resolve the Tenant and then set the Search Path Extension.
>> From
>>>> there on the Servlet Resolver does not need to know if this is a Tenant
>>>> because the Search Path Extension of the Request or Resource is enough
>> to
>>>> provide tenant specific view.
>>>>
>>>> Cheers - Andy
>>>>
>>>> On Feb 21, 2014, at 10:06 AM, Carsten Ziegeler <[hidden email]>
>>>> wrote:
>>>>
>>>>> Hi Andy,
>>>>>
>>>>> I'm not sure if we need search path extensions which are not related to
>>>>> tenants.
>>>>> The adaption to a tenant does not tie it to the resource resolver
>> module,
>>>>> the adapter factory can live in the tenant module and therefore the
>>>>> resource resolver module is totally unaware of tenant handling. The
>>>>> adaption can internally use a thread local which holds the tenant from
>>>> the
>>>>> request, so even for administrative resource resolvers, an adaptTo
>> would
>>>>> work within the context of a request.
>>>>>
>>>>> But these are just rough ideas anyway :)
>>>>>
>>>>> Regards
>>>>> Carsten
>>>>>
>>>>>
>>>>> 2014-02-21 17:16 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>>>>>
>>>>>> Hi Carsten
>>>>>>
>>>>>> First I want to clarify that the Search Path Extension has nothing to
>> do
>>>>>> with Tenants per se but is a "per-call" extension of the search path
>>>> which
>>>>>> could be used without tenants.In order to make the overlays work the
>>>> Search
>>>>>> Path Extension must be set early on. For this part the client could
>>>>>> implement a Service or configure a Service to obtain the Search Path
>>>>>> Extension.
>>>>>>
>>>>>> Currently I have a working POC for a client using CQ 5.6.1 which uses
>>>> this
>>>>>> concept to having Servlets/JSP overlays but also tenant specific
>>>>>> translation (I18n) both working through the Search Path Extension.
>>>>>>
>>>>>> The TenantResolver is an good idea but the
>>>>>> ResourceResolver.adaptTo(Tenant.class) might be a problem due to the
>>>>>> Administrative Resource Resolver (Servlet Resolver) and also ties
>>>> Tenants
>>>>>> into the Resource Resolver module.
>>>>>>
>>>>>> - Andy
>>>>>>
>>>>>> On Feb 20, 2014, at 11:32 PM, Carsten Ziegeler <[hidden email]>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi Andy,
>>>>>>>
>>>>>>> this sounds interesting - and I guess a patch would be great. Now I
>>>> just
>>>>>>> would like to present my idea again - just for the sake of discussion
>>>> :)
>>>>>>>
>>>>>>> I think over time there will be more components than just the servlet
>>>>>>> resolver which make use of the tenant and the extended search path,
>> so
>>>> I
>>>>>>> think it would be great to have some generic mechanism to get the
>>>>>> "current"
>>>>>>> tenant.
>>>>>>> My first idea was to have a TenantAware interface which passes in a
>>>>>>> TenantResolver (bad name) instance. And whenever the tenant aware
>>>>>> component
>>>>>>> needs the current tenant it asks the resolver, maybe a method like
>>>>>>> Tenant getTenant(ResourceResolver resolver)
>>>>>>> We could then extend the Tenant interface to provide the extended
>>>> search
>>>>>>> path.
>>>>>>>
>>>>>>> This would keep all the tenant extension stuff out of the resource
>>>>>> resolver
>>>>>>> - and would just be an extension.
>>>>>>>
>>>>>>> Instead of using a TenantResolver we could go with
>>>>>>> ResourceResolver.adaptTo(Tenant.class)
>>>>>>>
>>>>>>> WDYT?
>>>>>>>
>>>>>>> Carsten
>>>>>>>
>>>>>>>
>>>>>>> 2014-02-21 7:53 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>>>>>>>
>>>>>>>> Sorry, I forgot to mention that the Search Path Extension is
>> prepended
>>>>>> to
>>>>>>>> the Search Path when it is requested (in the Resource Resolver).
>>>>>>>>
>>>>>>>> - Andy
>>>>>>>>
>>>>>>>> On Feb 20, 2014, at 10:20 PM, Andreas Schaefer Sr. <
>> [hidden email]>
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Hi
>>>>>>>>>
>>>>>>>>> I started to look into how to add tenant support to Sling.
>>>>>>>>>
>>>>>>>>> This is my test scenario:
>>>>>>>>>
>>>>>>>>> I have an /apps/foo/bar/html.esp and a
>> /apps/tenant1/foo/bar/html.esp
>>>>>>>> and a /content/mynode entry. The title of the second html.esp is
>>>>>> different
>>>>>>>> so that I know which one is loaded.
>>>>>>>>>
>>>>>>>>> Changes to the code:
>>>>>>>>>
>>>>>>>>> 1) Added get/setSearchPathExtension() to the Resource Resolver and
>>>> its
>>>>>>>> implementation.
>>>>>>>>>
>>>>>>>>> 2) In the SlingRequestProcessorImpl I extract the tenant from the
>>>> first
>>>>>>>> sub domain (no OSGi Service yet) and prepend it with /apps/ to the
>>>>>> Search
>>>>>>>> Path Extension
>>>>>>>>>
>>>>>>>>> 3) In the Servlet Resolver added the code to set the Search Path
>>>>>>>> Extension from the Resource's Resource Resolver onto the Script
>>>> Resource
>>>>>>>> Resolver.
>>>>>>>>>
>>>>>>>>> Ran it and it showed the Tenant Specific ESP when the host name
>> has a
>>>>>>>> tenant it as sub domain and the original ESP when used with
>> localhost.
>>>>>>>>>
>>>>>>>>> This shows that is it basically possible to thread through the
>> tenant
>>>>>>>> Search Path on a per-call basis to the Servlet Resolver. There is
>>>> still
>>>>>>>> much to do like the Cache handling in the Servlet Resolver and a
>> OSGi
>>>>>>>> service that provides the tenant from a request.
>>>>>>>>>
>>>>>>>>> I can create an Issue and add a patch of my changes to it if anyone
>>>> is
>>>>>>>> interested.
>>>>>>>>>
>>>>>>>>> Cheers - Andy
>>>>>>>>>
>>>>>>>>> On Feb 17, 2014, at 6:58 PM, Andreas Schaefer Sr. <
>> [hidden email]>
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>> Hi
>>>>>>>>>>
>>>>>>>>>> I am working for a client which needs support for tenants and
>>>> because
>>>>>>>> the current implementation of the Tenants in Sling is just that but
>> no
>>>>>>>> integration I started to code a workaround. For now I have a patch
>>>> that
>>>>>>>> does the trick but it is not clean because I use a Servlet Filter to
>>>>>> place
>>>>>>>> the tenant id on a thread local instance. Afterwards I started to
>> look
>>>>>> into
>>>>>>>> how to implemented this cleanly into the current version of Sling.
>>>>>>>>>>
>>>>>>>>>> There are a few areas that need to be changed in order to
>> implement
>>>>>>>> tenant support. For now I am only looking into how to implement a
>>>>>> "per-call
>>>>>>>> overlays of servlets / JSPs" in order to give tenants the chance to
>>>>>> change
>>>>>>>> aspects of their presentation.
>>>>>>>>>>
>>>>>>>>>> 1) Tenant Identification: Sling must be able to identify a tenant.
>>>>>> This
>>>>>>>> can be a sub domain, path, cookies or even parameters. This means
>> the
>>>>>>>> client needs to provide a service which is then used by Sling in
>> order
>>>>>> to
>>>>>>>> retrieve the tenant and provide it to whomever wants to use it.
>>>>>>>>>>
>>>>>>>>>> 2) Servlet Resolver needs to be changed twofolds
>>>>>>>>>>  a) Being able to extend the search path for Servlets / JSPs
>> based
>>>>>>>> on the tenant's data
>>>>>>>>>>  b) Caching the Servlets / JPSs separated for different tenants
>>>>>>>>>>
>>>>>>>>>> 3) Change the Felix OSGi Web Plugin to allow the clients to add
>>>>>>>> properties (single and multi values)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> For 1) I would suggest just to define an interface the client can
>>>>>>>> implement as an OSGi service which is used to identify a tenant.
>> Then
>>>>>>>> somewhere in the SlingMainServlet or the Request Data the Tenant is
>>>>>>>> retrieved set on the Sling Http Servlet Request and if applicable
>> the
>>>>>>>> Search Path of the Resource Resolver is "enhanced/extended".
>>>>>>>>>>
>>>>>>>>>> For 2) I would suggest to add a new property to the Resource
>>>> Resolver
>>>>>>>> which contains the Search Path Extension. Because the Servlet
>> Resolver
>>>>>> uses
>>>>>>>> the Administrative Resource Resolver we need a way to "Enhance the
>>>>>> Search
>>>>>>>> Path" for that particular call. This could be done with a one-off
>>>>>> wrapper.
>>>>>>>> Based on the Extended Search Path we can determine which Servlet is
>> an
>>>>>>>> overlay and cache the overlays separately.
>>>>>>>>>>
>>>>>>>>>> 3) should be straight forward.
>>>>>>>>>>
>>>>>>>>>> Carsten was suggesting something like a TenantProvider like the
>>>>>>>> ServletProvider but in the current code the ServletProvider is
>> called
>>>>>> with
>>>>>>>> either the Sling Servlet Request, the Resource or a Resource
>> Resolver
>>>>>> and
>>>>>>>> path. This means the tenant id must be available to any of these
>> calls
>>>>>>>> which would require to put the tenant id inside the Resource
>> Resolver.
>>>>>>>>>>
>>>>>>>>>> Let me know what you think.
>>>>>>>>>>
>>>>>>>>>> - Andy Schaefer
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Carsten Ziegeler
>>>>>>> [hidden email]
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Carsten Ziegeler
>>>>> [hidden email]
>>>>
>>>>
>>>
>>>
>>> --
>>> Carsten Ziegeler
>>> [hidden email]
>>
>>
>
>
> --
> Carsten Ziegeler
> [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
In reply to this post by Bertrand Delacretaz
Ok, will adjust the wiki page.

- Andy

On Feb 25, 2014, at 1:11 AM, Bertrand Delacretaz <[hidden email]> wrote:

> On Tue, Feb 25, 2014 at 2:41 AM, Andreas Schaefer Sr. <[hidden email]> wrote:
>> ...it might a good idea to add the getSearchPathExtension() to the Tenant...
>
> Shouldn't that rather be called getAdditionalSearchPaths?
>
> In Sling, "extension" means the .html at the end of a URL, IMO we
> should avoid reusing that term for other things, as much as possible.
>
> -Bertrand

Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Carsten Ziegeler
I think using a thread local is an implementation detail and TenantAware
has a single method like

TenantResolver getTenantResolver()

while TenantResolver has a single method

Tenant getCurrentTenant()

(Don't quote me on the names, its just the first option which came to my
mind)

And then either Tenant gets a method returning the additional search path,
or we use a convention, like /libs/{tenantId} and /apps/{tenantId}

The implementation of the tenant resolver would use a thread local

Carsten


2014-02-25 19:18 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:

> Ok, will adjust the wiki page.
>
> - Andy
>
> On Feb 25, 2014, at 1:11 AM, Bertrand Delacretaz <[hidden email]>
> wrote:
>
> > On Tue, Feb 25, 2014 at 2:41 AM, Andreas Schaefer Sr. <[hidden email]>
> wrote:
> >> ...it might a good idea to add the getSearchPathExtension() to the
> Tenant...
> >
> > Shouldn't that rather be called getAdditionalSearchPaths?
> >
> > In Sling, "extension" means the .html at the end of a URL, IMO we
> > should avoid reusing that term for other things, as much as possible.
> >
> > -Bertrand
>
>


--
Carsten Ziegeler
[hidden email]
Reply | Threaded
Open this post in threaded view
|

Re: Tenant Implementation in Sling

Andreas Schaefer
Just to recap to see if I got this right:

- TenantAware is an OSGi service that a client can implement to identify a tenant (if applicable) based on a request

- A Servlet Filter is taking the request, obtains the TenantAware service and calls a method like "setup(SlingHttpServletRequest)” to initialize the Tenant Resolver

- The Authentication Service as well as the Servlet Resolver is using the TenantResolver to adjust the Search Path when creating / using a Resource Resolver or Resource Resolver must be made aware of the Tenant and adjust their search path when there is a Tenant.

Do you have any other implementation that works like that so that I can better understand where you are coming from.

For me the most important question is if you indent to move the Tenant code into the bundles or if you want it to keep it in the contrib part. For the latter we cannot use the Tenant class anywhere in the modules of the bundles.

- Andy

On Feb 25, 2014, at 12:55 PM, Carsten Ziegeler <[hidden email]> wrote:

> I think using a thread local is an implementation detail and TenantAware
> has a single method like
>
> TenantResolver getTenantResolver()
>
> while TenantResolver has a single method
>
> Tenant getCurrentTenant()
>
> (Don't quote me on the names, its just the first option which came to my
> mind)
>
> And then either Tenant gets a method returning the additional search path,
> or we use a convention, like /libs/{tenantId} and /apps/{tenantId}
>
> The implementation of the tenant resolver would use a thread local
>
> Carsten
>
>
> 2014-02-25 19:18 GMT+01:00 Andreas Schaefer Sr. <[hidden email]>:
>
>> Ok, will adjust the wiki page.
>>
>> - Andy
>>
>> On Feb 25, 2014, at 1:11 AM, Bertrand Delacretaz <[hidden email]>
>> wrote:
>>
>>> On Tue, Feb 25, 2014 at 2:41 AM, Andreas Schaefer Sr. <[hidden email]>
>> wrote:
>>>> ...it might a good idea to add the getSearchPathExtension() to the
>> Tenant...
>>>
>>> Shouldn't that rather be called getAdditionalSearchPaths?
>>>
>>> In Sling, "extension" means the .html at the end of a URL, IMO we
>>> should avoid reusing that term for other things, as much as possible.
>>>
>>> -Bertrand
>>
>>
>
>
> --
> Carsten Ziegeler
> [hidden email]

12