cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Dan Diephouse" <...@envoisolutions.com>
Subject Re: Proposal for Decoupling and Issues with CXFServlet
Date Sun, 07 Jan 2007 22:05:25 GMT
Hi Eoghan,

Comments inline...

On 1/5/07, Glynn, Eoghan <eoghan.glynn@iona.com> 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

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message