I hope you saw my other email which forwarded the announcement that the Java EE platform spec lead has proposed "that we
defer to Java EE 8 the areas of PaaS enablement and multitenancy support".
You may remember that last November I made some proposals for JMS_SPEC-57 (Add Java EE 7 multi-tenancy support). These
proposals didn't go anywhere and now that they are no longer required I am withdrawing them. I'll leave the issue open
for consideration in a later revision of JMS.
Nigel
On 23/11/2011 16:51, Nigel Deakin wrote:
> (I'm using HTML email to allow me to paste some tables below...)
>
> On 11/11/2011 18:25, Nigel Deakin wrote:
>> I've created this JIRA issue:
>> http://java.net/jira/browse/JMS_SPEC-57
>>
>> This is a placeholder for work to extend the JMS 2.0 specification to support multi-tenancy as defined in Java EE 7.
>>
>> I've written some proposals (and some options) in a document (13 pages) which I have uploaded to the project download
>> page: http://java.net/projects/jms-spec/downloads/download/JMS20MTv3.pdf
>>
>> Here's a synopsis of the document:
>>
>> * It reviews the Java EE 7 proposals for resource configuration metadata in respect of JMS resources.
>>
>> * It reviews the Java EE 7 proposals for multi-tenancy and discusses the three ways in which the destinations used by
>> different instances of a multi-tenant application might be isolated from one another.
>>
>> * It proposes extensions to the @JMSDestinationDefinition and @JMSConnectionFactoryDefinition annotations (and their
>> XML equivalents) to allow the application to specify the tenant isolation level of a given destination to be either
>> "shared" or "isolated".
>>
>> * It proposes extensions to the javax.jms.Destination and javax.jms.ConnectionFactory interfaces to allow a deployer
>> to specify the isolation level to be used with these administered objects.
>>
>> * If suggests four alternative means by which an application server could pass the tenantId of a running application
>> to the JMS client. Two of these options would require changes to the JCA spec. I'm not sure which one to recommend,
>> so that's the section I'd particularly appreciate comments and help on.
>>
>> This is all closely tied to the requirements for multi-tenancy support being defined by the Java EE platform expert
>> group, so I'd particularly welcome any comments and contributions from JSR 343 EG members who are also on the Java EE
>> platform expert group.
>>
>> Nigel
>
> No-one has commented on this document. I can't say I'm surprised. Multi-tenancy is an area where JMS seems to be
> ahead of other specs, notably the Java EE platform spec and the various database specs.
>
> I had a long meeting with the Java EE spec leads to review this document, which I've summarised below and in a new
> chapter in the document, which is now available at:
> http://java.net/projects/jms-spec/downloads/download/JMS20MTv4.pdf
>
> In summary:
>
> * My proposals to extend the JMS resource metadata (JMSConnectionFactoryDefintiion and JMSDestinationDefinition) to
> allow the required tenant isolation to be specified as "isolated" or "shared" received support.
> * My proposal of four alternative ways for passing tenantId from the app server to the JMS client are all rejected
> because they could not be extended to support per-thread tenantId in Java EE 8. Instead the Java EE platform EG
> will devise a generic way of passing per-thread tenantId, probably via Java SE security APIs, which can be used by
> JMS, JPA and other resource managers.
>
> Detailed notes below:
>
>
> Notes from a review of version 3
>
> The following notes were made following a review of version 3 of this document with the Java EE platform specification
> leads.
>
>
> Specifying the required isolation level in resource metadata
>
> The use of resource metadata to specify the required isolation level was endorsed.
>
> @JMSDestinationDefinition {
>
> description=“MDB input queue”
>
> name="ims/inboundQueue",
>
> className="javax.jms.Queue",
>
> resourceName="orderQueue",
>
> tenantIsolation="ISOLATED"
>
> }
>
> @JMSConnectionFactoryDefinition {
>
> className="javax.jms.ConnectionFactory",
>
> tenantIsolation="ISOLATED"
>
> }
>
> To avoid any possible confusion with database technology, the term "isolation level" should be avoided and the term
> "tenant isolation" used.
>
>
> Passing tenantId to the connection used by a MDB to consume messages
>
> In the discussion "How to pass tenantId to the JMS client", option 3 discussed how the JCA spec allows the application
> server to pass a javax.security.auth.Subject objectto the resource adapter when creating a new connection or fetching
> one from the pool. This Subject object could be extended to hold a new Principal object that containedthe tenantId..
>
> However this doesn't coverthe connection used by a MDB to receive messages.
>
> JCA defines a security inflow contract, which, is a mechanism for allowing the RA to pass a caller
> java.security.Principal to the MDB application. The application can obtain this by calling
> EJBContext.getCallerPrincipal(). (Can it also call Subject.getPrincipals() to obtain this Principal?).
>
> However this doesn't help with Java EE 7 multi-tenancy, where we need a way for the /application server/ to pass the
> tenant information to the RA when the endpoint is activated.
>
> JCA 1.6 doesn't specify a way to do this currently. One possibility is to add a third argument to
> ResourceAdapter.endpointActivation(MessageEndpointFactory endpointFactory, ActivationSpec spec) as follows:
>
> ResourceAdapter.endpointActivation(
>
> MessageEndpointFactory endpointFactory, ActivationSpec spec,
>
> javax.security.auth.Subject subject)
>
> The application server would need to set an appropriate javax.security.auth.Subject. This would require a change to
> the JCA specification.
>
> An alternative to passing this in via the JCA API would be for the app server to associate the tenantId with the
> current thread (how would it do this?), so that the endpointActivation() implementation could call
> Subject.getPrincipals() and obtain, say, a TenantPrincipal.
>
> Note that I don't see tenantId as flowing in with each message: it's the other way round: the call to
> endpointActivation() would pass the tenantId to the JMS server when creating the consumer.
>
>
> Passing tenantId in a Java EE 8 SaaS application
>
> The document makes four proposals for passing tenantId to the JMS client when a connection was created.These proposals
> were reviewed to assess which of them could be easily extended to support the needs of Java EE 8. This will provide
> full support for SaaS, which will mean the ability of a single deployed application to work on behalf of multiple
> tenants.
>
> Although the details of how this would work do not need to be decided for Java EE 7, the basic idea would be that
> tenantId would be associated not with the deployed application but with the current thread.
>
> We reviewed which of the four options for passing tenantId to the JMS client discussed above, could be extended to
> handle SaaS multi-tenancy:
>
> Mechanism for passing tenantId to the JMS client
>
>
>
> Would it work in a SaaS application?
>
> 1.The deployer would set the tenantId on the connection factory or destination administered objects used by a tenant
> application instance.
>
>
>
> No, since all tenants using a given deployed application would see the same administered objects.
>
> 2.The JMS client could use JNDI to lookup the tenantId from a well-known JNDI context, such as java:comp/tenantId.
>
>
>
> Yes, JNDI could be made to return a different tenantId depending on the thread that called it. However since the
> tenantId would need to be checked every time a JMS client method was used, and JNDI may be relatively slow, this is
> potentially a slow solution.
>
> 3.The JCA API could be extended to allow the application server to pass the tenantId to the resource adapter by means
> of a javax.security.auth.Subject object when a connection was created or fetched from the pool (and when an endpoint
> was activated).
>
>
>
> No, this would allow per-connection tenantId but not per-thread tenantId.
>
> 4.Extend JCA API to allow tenantId to be passed as an argument when a connection was created or fetched from the pool
> (and when an endpoint was activated).
>
>
>
> No, this would allow per-connection tenantId but not per-thread tenantId.
>
> However it was considered that the use of a javax.security.auth.Subject object to pass tenantId might be a good way to
> pass a per-thread tenantId, since Java SE already has the concept of per-thread security credentials. This would
> by-pass any need to pass this information using the JCA API.
>
> The Java EE 7 expert group would take on the issue of how best to pass tenantId to a resource manager in a way which
> would work on a per-thread basis for Java EE 8. There is therefore no need for a JMS-specific solution.
>
>