IronJacamar

Conversational Inflow

One feature that the Java EE Connector Architecture specification is lacking at the moment is a way for the Enterprise Information System to have a "conversation" with the application server spanning multiple requests and responses.

Status: Proof of concept stage

State of the Union

Today the Java EE Connector Architecture specification allows a resource adapter to send a request to a MessageEndpoint through a MessageEndpointFactory that is configured with an ActivationSpec instance, and get a response back. If the MessageEndpoint supports transactions then the boundary of those are handled by the MessageEndpointFactory .

This supports a single request-response scenario between the Enterprise Information System and the application server, with an optional transaction context.

Example scenario: Messaging system triggering an Enterprise JavaBean Message Driven Bean (EJB/MDB)
Brief overview: Inbound resource adapter

Description of feature

Conversational inflow will allow the Enterprise Information System to have an interaction with the application server that spans multiple requests / responses while optionally grouping the entire flow under a single transactional context.

This would allow mapping a work flow inside the Enterprise Information System to a work flow executed in an application server context.

In order to enable this interaction we need to extend the current Java EE Connector Architecture specification with new interfaces that defines the contract of these interactions.

First, we need a ConversationalResourceAdapter interface that allows activation and deactivation of a ConversationalMessageEndpointFactory with an associated ActivationSpec instance.

ConversationalResourceAdapter

public void conversationActivation(ConversationalMessageEndpointFactory cmef, ActivationSpec as) throws ResourceException;
public void conversationDeactivation(ConversationalMessageEndpointFactory cmef, ActivationSpec as);

The ConversationalMessageEndpointFactory manage the Conversation instances.

ConversationalMessageEndpointFactory

public Conversation beginConversation(Serializable identifier) throws ResourceException;
public Conversation getConversation(Serializable identifier) throws ResourceException;
public Set<Serializable> activeConversations();

The Conversation controls an entire interaction between the Enterprise Information System and the ConversationalMessageEndpoint instance(s) deployed in the application server. The Conversation also defines the transactional boundary for the interaction.

The Conversation needs to support multiple endpoints of the same type, so a concrete instance is determined by a set of properties that the endpoint is configured with.

Conversation

public ConversationalMessageEndpoint createEndpoint(Class<?> endpoint, Map<Serializable, Serializable> properties, XAResource xares) throws ResourceException;
public Set<Map<Serializable, Serializable>> getProperties(Class<?> endpoint) throws ResourceException;
public boolean isDeliveryTransacted(Class<?> endpoint, Map<Serializable, Serializable> properties, Method method) throws ResourceException;
public Set<Class<?>> getEndpointClasses();
public void endConversation() throws ResourceException;
public void cancelConversation() throws ResourceException;

The ConversationalMessageEndpoint extends the current MessageEndpoint interface, with no new methods.

Example

The ZIP file contains an example of a simple conversation pattern between an Enterprise Information System and the application server.

There are 5 different message types from the Enterprise Information System:

  1. "A": Start a conversation with the supplied conversation identifier
  2. "B": Send a message to endpoint "B" identified by the supplied conversation identifier
  3. "C": Send a message to endpoint "C" identified by the supplied conversation identifier
  4. "D": End a conversation with the supplied conversation identifier
  5. "E": Cancel a conversation with the supplied conversation identifier

So, a simple interaction could be "A", "B", "C" and "D", which starts a conversation, sends messages to two different endpoints, and ends the conversation successfully. The key here is that the two endpoints operates under the same transactional context, as the Conversation instance will enlist the associated XAResource instances.

Even though the example use a specialized message listener interface ( ConversationalMessageListener ) to simplify the JUnit test case, and the entire proof of concept setup it would be possible to convert it to a Java Messaging Service (JMS) based example calling Enterprise JavaBeans Message Driven Beans (EJB/MDB).

In that case, you will end up with a transactional context spanning two MDBs, and thereby tying them "together".

Example overview:

ConversationalTestCase.java - JUnit test case
cra/ConversationalResourceAdapterImpl.java - Conversational resource adapter implementation
cra/inflow/ConversationalActivation.java - Interaction with the Enterprise Information System
cra/inflow/ConversationalActivationSpec.java - The activation specification
cra/inflow/ConversationalMessageListener.java - The message listener interface
spi/ConversationalResourceAdapter.java - New ConversationalResourceAdapter interface
spi/conversation/Conversation.java - New Conversation interface
spi/conversation/ConversationalMessageEndpoint.java - New ConversationalMessageEndpoint interface
spi/conversation/ConversationalMessageEndpointFactory.java - New ConversationalMessageEndpointFactory interface
support/ConversationImpl.java - Example conversation implementation
support/ConversationalMessageEndpointFactoryImpl.java - Example conversational message endpoint factory implementation
support/ConversationalMessageEndpointImpl.java - Example conversational message endpoint implementation

Note, that the example is not meant to be 100% complete, so there may be bugs, and missing cases :)

Future steps

There are a lot of things that needs to be discussed such as recommendations on transaction semantics for conversation implementations, and their associated endpoints. The new interfaces likely need additional methods to cover all use-cases, but the basic interaction pattern is in place.

Hopefully the next version of the Java EE Connector Architecture specification will see a much more powerful inflow model.