users@jms-spec.java.net

[jms-spec users] [jsr343-experts] Re: (JMS_SPEC-73) Define how messages from a topic are delivered to clustered application server instances

From: Nigel Deakin <nigel.deakin_at_oracle.com>
Date: Mon, 28 Jan 2013 19:43:31 +0000

(Summary: This email is an update on progress getting JCA spec and Java EE spec changes to allow a resource adapter to
implement support thw new JMS 2.0 activation property subscriptionScope. It explains how JMS may not get all the
features we need.)

On 04/12/2012 19:25, Nigel Deakin wrote:
> I refer to this JIRA issue
> http://java.net/jira/browse/JMS_SPEC-73
> Define how messages from a topic are delivered to clustered application server instances
>
[snip]

I hope you are familiar by now with Chapter 12 of the JMS 2.0 public draft, which defines various standard activation
properties. Amongst the properties defined are subscriptionName and subscriptionScope.

The draft specification states that if subscriptionScope is set then the resource adapter will automatically generate
the subscription name (durable or non-durable) that will be used. If subscriptionScope is "Cluster" then for a given
activation the name will be the same for each instance in the cluster. If subscriptionScope is "Instance" the name will
be unique to the activation.

Subsection 12.1.2 "Implementation in a resource adapter" contains some information on how a resource adapter might
implement this, using new methods added to the JCA specification.

----------------------------------------------------------------------------
"The Java EE Connector Architecture (JCA) specification defines a method getInstanceName on
javax.resource.spi.BootstrapContext and a method getActivationUniqueName on MessageEndpointFactory. If a scope of
cluster is specified then a suitable subscription name may be obtained by calling the getActivationUniqueName method. If
a scope of instance is specified then a suitable subscription name may be obtained by calling the getInstanceName and
getActivationUniqueName methods and concatenating the results.

"If a scope of instance is specified then a suitable subscription name may be obtained by calling the getInstanceName
and getActivationUniqueName methods and concatenating the results.

However if the subscriptionName property and the subscription is durable then the value of this property should be used
instead of the value returned by getActivationUniqueName"
----------------------------------------------------------------------------

The proposed required changes to the JCA specification, I discussed our requirements with the JCA spec lead and logged
them as a JCA specification issue:
http://java.net/jira/browse/CONNECTOR_SPEC-1

If you read that issue you will see that I asked that the values returned contained only particular characters and that
when combined together were no longer than 128 characters. This is so we can be sure that any generated subscriptionName
was valid (as defined in the new 6.11.5 "Subscription name characters and length").

I also asked that the names returned should be consistent after the instance is restarted or reconfigured (within
reason). We can't have a subscription name changing after a restart.

I met (on the phone) with the JCA EG last week to explain the JMS requirements. The JCA expert group has now considered
this proposal and is close to making their final decision. Based on what I've heard so far, here's what I am expecting
to happen:

Instance name
-------------

I'm expecting the JCA expert group to reject my proposal to add a method to BootstrapContext to obtain the "instance
name" on the grounds that it is too Java EE-specific.

Fortunately there is a fallback, which is for the resource adapter to lookup the new pre-defined JNDI name
java:comp/InstanceName defined in the Java EE platform spec (see section EE.5.16 "Application Server Instance Name").

However this currently has no limitations on length or on the characters returned.

It is defined as follows:

"EE.5.16 Application Server Instance Name

"In some special cases, it may be necessary to identify the name of the application server instance in which a component
is executing—for example, when a resource adapter needs to perform endpoint activation. A component may access the name
of the application server instance in which it is executing using the pre-defined JNDI name java:comp/InstanceName. This
name is represented by a String object. If the application has been deployed into a clustered application server, this
name identifies the application server instance within the cluster. This name is only guaranteed to be unique within
instances of the same cluster. If the application server is not clustered, it is the empty string."

Activation name
---------------

I'm expecting the JCA expert group to agree to my proposal to add a method to MessageEndpointFactory to obtain the
"activation name".

However it looks as if my proposal for limitations on length and on the characters returned have been rejected as being
"too JMS-specific".

Here's the API proposed by the JCA EG:

"java.lang.String getActivationName()

"Returns a unique name for the message endpoint deployment represented by the MessageEndpointFactory. If the message
endpoint has been deployed into a clustered application server then this method must return the same name for that
message endpoint'ss activation in each application server instance. It is recommended that this name be human-readable
since this name may be used by the resource adapter in ways that may be visible to a user or administrator. It is also
recommended that this name remain unchanged even in cases when the application server is restarted or the message
endpoint redeployed."

Review
------

My main concern here is that the strings obtained by the resource adapter may be of any length and may contain any
characters. The resource adapter will be responsible for converting these strings into a valid subscription name which
conforms to the new JMS section 6.11.5 "Subscription name characters and length" whilst retaining the necessary
semantics and uniqueness. It's not immediately obvious to me that a resource adapter will be able to do this without,
say, using some kind of cluster-wide database to store a mapping between the "long" and "shortened" version of each name.

Let's review which use cases are affected by this problem. There are four use cases we need to consider:

1. subscriptionScope=Cluster, subscriptionName=unset
2. subscriptionScope=Cluster, subscriptionName=specified
3. subscriptionScope=Instance, subscriptionName=unset
4. subscriptionScope=Intance, subscriptionName=specified

1. subscriptionScope=Cluster, subscriptionName=unset
----------------------------------------------------

In this case the subscriptionName used should be based on the activationName returned by the MessageEndpointFactory. The
resource adapter will be responsible for ensuring that the subscriptionName is of less than 128 characters and contains
only valid characters.

2. subscriptionScope=Cluster, subscriptionName=specified
----------------------------------------------------

In this case the subscriptionName used can be the specified subscriptionName. No other information is required from the
container. Since the deployer can be required to provide a name of a valid length and containing valid characters, there
is no problem here.

3. subscriptionScope=Instance, subscriptionName=unset
----------------------------------------------------

In this case the subscriptionName used should be based on the activationName returned by the MessageEndpointFactory,
combined with the instance name obtained by JNDI lookup. The resource adapter will be responsible for ensuring that the
subscriptionName generated is of less than 128 characters and contains only valid characters.

4. subscriptionScope=Instance, subscriptionName=specified
----------------------------------------------------

In this case the subscriptionName used should be based on the specified subscriptionName, combined with the instance
name obtained by JNDI lookup. The resource adapter will be responsible for ensuring that the subscriptionName generated
is of less than 128 characters and contains only valid characters.

My feeling is that in cases 1,3 and 4 we are placing a requirement on the resource adapter that it may be difficult to
implement. (Note that use case 4 would still be a problem even if the JCA has provided what I asked for).

Conclusions
-----------

I haven't come to a firm conclusion yet, but I am beginning to feel that implementing subscriptionScope by requiring the
resource adapter to automatically generate the subscription name may not be practical because it would be difficult to
implement in a portable way which works in multiple application servers.

What do others think? Should we look at other ways of implementing "subscription scope" which does not rely on the
resource adapter generating a subscription name?

Nigel