Hi Marcel,

You're missing the point as I tried to explain in these issues; you assume that 
any method that needs to do something with a tenant eventually has access to 
the tenant.id, via a HTTP request or some other parameter passed in the method. 
This is not true, as for example in the Shindig case. The Shindig API does not 
pass http requests and so you cannot resolve the tenant.id from a http request 
or from any argument passed to the method. Still, some Shindig services need to 
be made tenant aware, like the persistent storage that manages opensocial 
persons (associated with users in UserAdmin, which are/will be tenant aware).
I do understand the downsides of using ThreadLocal variables (and already 
experienced some of them, like thread pooling), but when you look at my context 
patch you will see that using ThreadLocal variables is in fact an 
implementation detail. But again, without using ThreadLocal variables; how 
would you resolve the proper tenant in this Shindig API method?

Public List<Person> PersonService.getPersons()


Regards, Ivo

-----Original Message-----
From: amdatu-developers-bounces at amdatu.org 
[mailto:[email protected]] On Behalf Of Marcel Offermans
Sent: donderdag 6 januari 2011 9:47
To: amdatu-developers at amdatu.org
Subject: Re: [Amdatu-developers] Multi-tenancy (and more) design

Hello Ivo,

On 5 Jan 2011, at 16:30 , Ivo Ladage-van Doorn wrote:

> To clarify my concerns, they are covered by these JIRA issues
> 
> http://jira.amdatu.org/jira/browse/AMDATU-84
> http://jira.amdatu.org/jira/browse/AMDATU-245
> http://jira.amdatu.org/jira/browse/AMDATU-246
> 
> which are referred to by the container issue;
> 
> http://jira.amdatu.org/jira/browse/AMDATU-247
> 
> This explains my concerns assuming that the 'current tenant' is always known 
> by putting Amdatu services that are tenant unaware on a separate 
> single-tenant container. This may be true for tenant unaware services on a 
> single-tenant container, but we still need to resolve tenants on a 
> multi-tenant container with tenant aware services. We might end up putting 
> most/too many services (including the heavy ones like Shindig) on a separate 
> container as they cannot be made tenant aware. Finally, it only solves the 
> issue for tenants but not for any other context-related info, like the name 
> of the logged in user.

First of all, I think we should stick to multi-tenancy design in this thread, 
and not expand it to other context-related information.

Let's start with AMDATU-84 which raises the question of how a REST service 
knows what tenant is invoking it. I would say that is determined by something 
in the HTTP request, so either the hostname, path or some request variable.

Now two things can happen, depending on the type of container:

1) We're in a tenant specific container. In this case, the world is our tenant, 
so we can simply invoke any service we see.

2) We're in a multi-tenancy container that hosts services for more than one 
tenant. In that case the REST service needs to extract the tenant.id from the 
request and use it to lookup any services it needs.

Doing it like this answers the first question of AMDATU-245 as well, as a REST 
service that runs in a multi-tenancy container will need to have a way to 
resolve the tenant from "something" in the HTTP request. The other questions 
are not relevant as they are solved above.

In the same way, AMDATU-246 is not related to multi-tenancy at all. I'm not 
saying the questions are invalid, I just don't think they're related to 
multi-tenancy and need to be solved independently of that.

Maybe I need to elaborate a bit on how the multi-tenancy container would hook 
up services? Basically, since every service has a tentant.id, it can also use 
that to filter out the correct service when it depends on other services. By 
making all services in such a container tenant aware, the tenant.id is known 
everywhere and can be propagated without the need for a context.

That brings us back to the question: so what if you have a service that is not 
really tenant aware? That depends on two questions:

1) Does that service share its data with all tenants?

2) Does that service have dependencies on other services that are tenant aware?

If the first question is true, and the second is false, we can simply deploy 
the component and have it expose a single service.

If the first question is false, we cannot deploy it and need to at least create 
some kind of adapter in front of it to make it tenant aware and decide how to 
store the data for each tenant.

If the first question is true and the second is true, it really is a tenant 
aware service. It does share data, but depending on which tenant invoked it, it 
will invoke its dependent services for that same tenant. Probably the best way 
to deploy such a service is to have the component publish a service for each 
tenant, even though it probably shares the same back-end implementation.

That, in my view, is how we should deal with multi-tenancy.

Reasons not to use a ThreadLocal based context (apart from the fact that we 
don't need it here):
a) it does not support scenarios where operations are handled asynchronously, 
for example if you want to submit a task to a pool of threads;
b) it does not support cross-JVM boundaries so for those we would need a 
separate mechanism anyway;
c) it's hard to debug and test.

Greetings, Marcel


_______________________________________________
Amdatu-developers mailing list
Amdatu-developers at amdatu.org
http://lists.amdatu.org/mailman/listinfo/amdatu-developers

Reply via email to