Hi Eoghan,
Comments inline...
On 1/5/07, Glynn, Eoghan <[EMAIL PROTECTED]> wrote:
Put HTTP (or any other specific transport) out of your mind for a moment,
and lets consider the fundamental question as to we originally came to the
conclusion that partial responses are needed by RM.
*snip*
OK, thanks for the good summary of the issues here.
Now for an asynch transport that uses the same *long-lived* destination to
receive *all* responses (and ACKs), and where that transport is continually
listening for incoming traffic on that destination regardless of whether
there's an outstanding reply expected, then the requirement for partial
responses shouldn't even arise (i.e. the acksTo should always be
non-anonymous in this case).
But, says you, shouldn't the above statement be true of all async
transports?
Nope, unfortunately that's not the case.
Take for example the CXF JMS transport. For good or ill, the way this
currently works is that a *different* temporary queue is specified as the
replyTo for each request, and the client-side transport only expects to
receive a *single* incoming message on that destination (i.e. in JMS
parlance, instead of installing a MessageListener on the response Queue to
allow for a series of onMessage() notifications, it makes just one call to
MessageConsumer.receive() to accept a single response message).
For this style of JMS transport, we could envisage sending first a partial
response, recognizable in some way as such by the receiving JMSConduit so as
to cause it to make a second call to MessageConsumer.receive() in
expectation of the full response in the twoway case. For oneways, it would
make just one (instead of zero) calls to MessageConsumer.receive().
You get the idea I hope ... Even though this transport is async, it still
uses an anonymous style of response back-channel (in the wider sense as
defined above).
So why not just "fix" the JMS transport so that it works in a more
naturally async way? Well, that a whole other discussion, but my main point
is that even an async-style transport may require partial response
semantics. So we should not tie our usage of partial response to HTTP (by
setting the 202 response code from within the RM layer), as we can't be sure
that the underlying transport is actually HTTP.
Ok, some more thoughts.
First, if there is a transport which requires an anonymous partial response,
we could still support that. In my mind this is analagous to the SOAP case.
SOAP has an HTTP binding and HTTP specific semantics.We have some HTTP
specific code in the SOAP module to support things like response codes. I
wouldn't be any more keen on adding SOAP specifics into the HTTP transport
than I am to add WS-A/RM semantics.
Second, what is the use case for RM over JMS? JMS is inherently reliable. RM
over JMS doesn't buy you anything that I know of. The only case I can think
of is that if we were bridging transports - but in that the messages
wouldn't be destined to the JMS endpoints. Am I missing something here?
Now please bear with me for just a little while longer here. I want to go
back to the pseudocode of the current logic which gets the back channel:
public Conduit getBackChannel(inMessage, partialResponse, partialResponse) {
if (replyToEPR == null) {
return backChannel;
else {
if (partialResponse != null) {
partialResponse.put(RESPONSE_CODE, HTTP_ACCEPTED);
return backChannel;
}
else return conduitInitiator.getConduit(destinationEPR, replyToEPR);
}
}
The main things I would want to change about this are:
1. Take the partial response logic out of the HTTP transport
2. Remove the decoupling encapsulation. By this I mean on the server side,
it should not be providing a decoupled conduit transparently (i.e.
conduitInitiator.getConduit(...)). And on the client side we shouldn't have
a reference to the ServerEngine and provide a server side Destination via
getBackChannel()
And let me try to give a fair recap for why I understand you think things
are best this way:
A) Partial responses are best dealt with in the transport layer because they
have transport specific logic. Namely the HTTP response code needs to be
set.
B) You can't achieve (A) without encapsulating the decoupling in the
transport interfaces (via the getBackChannel methods)
C) Doing things in this way makes it easier to enforce security policy
Please let me know if I've misrepresented your position. I have absolutely
no desire to do so.
I completely follow your logic in B, however I think I disagree with A.
- As I mentioned above, RM has HTTP specific semantics and those
should be contained inside the RM module. This is the same policy we have
with things like the SOAP binding. This does not mean it has to be hardcoded
into the partial response logic. The RM module could discover different
transport specific logic. i.e. we could have an RMTransport interface
which has something like a "void setupPartialResponse(Message)" method.
- The JMS transport doesn't seem to even have any transport specific
logic for partial responses, so that could already be handled in the RM
layer just fine. HTTP is the only one we're concerned about here. And unless
I'm completely something, I'm not even sure why we're worried about RM over
JMS.
Furthermore, I'm really not a fan of B, which makes me less inclined to like
A. Why?
- Encapsulating the decoupling logic complicates transports: For
instance, methods we've added for encapsulation of the decoupling include:
Conduit.getBackChannel(), Destination.getBackChannel(),
ConduitInitiator.getConduit(EndpointInfo, EndpointReferenceTarget).
- This makes transports harder to write and maintain. Writers need to
understand RM semantics - and this is quite confusing (I think this
discussion is just one example of how complex it can be ;-))
- In the HTTP case, it creates dependencies on specific HTTP
implementations. For instance, currently our HTTPConduit is dependent on
Jetty at the moment. If we abstract both the server and client HTTP
implementations we end up making things even more complex. I would much
prefer a world were I could write a commons HTTP Conduit and not have to
worry about a decoupled Destination.
(BTW, I do think an abstraction that encapsulated message sending/receiving
over decoupled channels would be really cool. Kind of like WCF's Channel
concept. I just don't think the low level transport layer is the place for
it.)
Regards,
- Dan
--
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog