I am currently suffering from a problem which relates to the behaviour
of the CXF WS-Addressing (WSA) implementation (CXF 2.1.4), specifically
how it processes Message Addressing Properties (MAPs). My problem raises
issues about how the WSA MAP API is expected to be used under JAX-WS.
Unfortunately, there is no correct answer to any such questions, not
since the JAX-WS expert group decided to drop the originally proposed
MAP API and reference implementation from the JAX-WS standard. Anyway,
first I'll explain what I am doing in my app and why, then why the
current CXF implementation is giving me grief. I'll also contrast this
with the behaviour of the MAP processing code in JBossWS. I am not
claiming that CXF is doing the wrong thing, rather that what it does
restricts the utility of MAPs and might be worth reconsidering. This
decision ought to be hammered out by the JAX-WS expert group but I don't
think that will happen very soon.
So, to set the scene, I have implemented the WS-AT and WS-BA web service
transaction standards over JBossWS/Native using JAX-WS to provide the
messaging layer for communications between:
the transaction client and the transaction coordinator
the transaction participants and the transaction coordinator
I am now trying to modify that implementation to run over JBossWS/CXF.
The WS-AT and WS-BA specs include WSDL defining a variety of one-way
messages used to negotiate creation, enlistment, coordination and
termination of a web services transaction. One way messages are employed
because there are a variety of overlapping, multi-message sequences
between the two pairs of parties identified above which may arise during
the transaction. The specs require the use of one way messages and WSA
and are very specific about the values certain of the WSA SOAP headers
must take.
In order to correlate messages in a specific sequence my implementation
generates ids and sets the MAP MessageId field before dispatching a
one-way request. When a server fields an incoming message and decides to
dispatch the next message in the sequence it retrieves the MessageId
field from the incoming MAP and uses it to populate the RelatesTo field
of the message it is about to dispatch. This allows the recipient of the
second message to correlate it with the first one. Ditto for 2nd and 3rd
etc.
The problem I am facing is that CXF assumes that it knows what the value
in the RelatesTo field means. The CXF PhaseInterceptor employs a
MAPCodec object to process MAP properties on a specific communication
link. MAPCodec caches MessageId values when it processes an outgoing
message and then correlates them with RelatesTo messages when in
processes an incoming message. If an incoming message has a RelatesTo
entry which does not match a cached MessageId then MAPCodec logs an
error and aborts the interceptor chain.
This is all well and good if a the RelatesTo field is only ever
populated in the reply for an RPC style exchange. However, it does not
allow WSA to be used for correlation of independent one way messages. As
a specific example of how the problem arises in my app consider when a
client sends a Commit message to the coordinator. After various
exchanges with the enlisted participants, the coordinator eventually
responds to the client with either a Commited or an Aborted message. The
Commit and Committed/Aborted messages are independent one way exchanges
(I know they *could* be two way but the WS-AT standard defines them as
one-way). So the outgoing MAP for the Committed/Aborted message is
populated with a RelatesTo field populated with the MessageId from the
original Commit request. However on the receiving end this MessageId is
not found in the incoming MAPCodec's cache and the Committed/Aborted
message does nto get delivered.
I don't consider this an illegitimate use case for the WSA
MessageId/RelatesTo headers. There is nothing in WSA which suggests that
these headers should only be used to correlate requests and replies in
an RPC style exchange. Since the JAX-WS spec fails to provide an API for
MAP management it consequently fails to specify what the JAX-WS
implementation should do when MAP fields are supplied and/or retrieved.
Personally, I think it is probably correct for CXF to perform the
exchange validation for RPC style exchanges but it is clearly
inappropriate to do so
i) for incoming requests and
ii) for responses to one way exchanges
In case i) clearly there will never be a correlated id in the cache so
it is pointless trying to look for one. Deciding that this must be an
error is one option but it rules out a legitimate use case for WSA
headers. Case ii) should never arise since one way messages don't have
any associated replies to process.
As a comparison point the JBossWS Native stack doesn't attempt to
correlate MessageIds with values in the RelatesTo field (I think it does
when using WS-RM but not to the exclusion of application-specified
RelatesTo data). Actually, JBossWS also differs from CXF in that it's
MAP implementation type provides for a sequence of RelatesTo entries
rather than a single value. I believe this is as per the original JAX-WS
reference implementation that was eventually dropped. Is there a good
reason for CXF doing it differently?. The provision for multiple
RelatesTo entries perhaps makes it explicit that the RelatesTo field was
not solely intended for the use to which it has been put by CXF.
I would actually suggest a further refinement of the current CXF
exchange validation beyond restricting it to validating replies in RPC
style exchanges. If CXF is specifically interested in establishing this
exchange correlation for its own purposes then perhaps it should install
a RelatesTo entry with a specific RelationshipType and only fail when it
cannot correlate RelatesTo values of this type. That way a vanilla
(untyped) RelatesTo entry installed by application code would be passed
through for handling by application code.
I would be happy to supply a patch for the current behaviour if you want
one. My current concern is to ensure that I would be providing something
which is appropriate.
regards,
Andrew Dinn
-----------