Composite MaterialsRon Ten-Hove's Weblog |
|
Tuesday Feb 07, 2006
Technical: JBI Component Implementation: Using ExchangeStatus
It seems that there is some confusion in the world of JBI component implementors about how the ExchangeStatus of a MessageExchange instance should be used. This usually arises when looking at the ExchangeStatus.ERROR state. The following code and comments give a basic outline of how a typical JBI component should use the exchange status when accepting a message exchange from its delivery channel, and what the component can assume about the state of the exchange instance. Note that the the component's role (as either consumer or provider) is important in determining what conditions hold, especially in when the instance's status is ERROR.
/**
* Process an accepted message exchange instance. An instance received by this
* component can be sent by a component that is consuming a service that this
* component is offering, or send by a service provider component that this component
* is consuming.
*
* @param me the MessageExchange instance sent to this component by the NMR
*
*/
void processAcceptedMessageExchange(MessageExchange me)
{
if (me.getStatus() == ExchangeStatus.ACTIVE)
{
// next step in the ping-pong game
}
else if (me.getStatus() == ExchangeStatus.DONE)
{
// The game is over; the partner component
// is closing the MEP, and so should I.
// For the following MEPs the following are true:
//
// Pattern me.getRole() me Invariant
// ------- ------ ------------
// In CONSUMER getInMessage() != null && getError() == null
// In-out PROVIDER getInMessage() != null &&
// (getOutMessage() != null xor getFaultMessage() != null) &&
// getError() == null
//
// (the patterns with optional responses are
// more complex.)
}
else if (me.getStatus() == ExchangeStatus.ERROR)
{
// The game is over; the partner component
// is abruptly closing the MEP, and so should I.
// The only ME property I can count on is
// me.getError(). Other ME properties will reflect
// the on-going state of the exchange before it
// was ending by the partner abruptly.
//
// Pattern me.getRole() me Invariant
// ------- ------------ ------------
// In CONSUMER getError() != null && getInMessage() != null
// In-out PROVIDER getInMessage() != null && getError != null &&
// (getOutMessage() != null xor getFaultMessage() != null )
// In-out CONSUMER getInMessage() != null && getError() != null &&
// (getOutMessage() == null || getFaultMessage() == null)
}
}
Notice that the invariants change in the ERROR case for the In-out exchange, depending on the role of the receiving component.
This gets more complex looking when we add in the robust-in-only and in-optional-out message exchange patterns, but the basic processing pattern remains the same. This information isn't new: it's all in the JBI specification, but is scattered in several places, so it is understandable that the role of MessageExchange.getStatus() gets overlooked. This actually works well in the so-called "happy path" for In-only and In-Out MEPs, but becomes problematic in the ERROR case or when dealing with the MEPs that have optional exchanges in their patterns. Posted at 09:21AM Feb 07, 2006 by rtenhove in Java Business Integration | Comments[2] |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Posted by Hossam Karim on February 18, 2006 at 04:26 PM EST #
Posted by Ron Ten-Hove on February 20, 2006 at 10:30 AM EST #