Glynn, Eoghan wrote:
-----Original Message-----
Must be a Client in order for there to be an invocation
request/response/fault/ack protocol?
Nope, a Client is not currently required for an invocation to occur.
An "invocation" or "sending a Message"?
Either.
I don't get it. A message goes one way. An invocation *MAY* go one way,
but mostly does expect a single response.
I understand that "THE Client" is not the *only* way to do "invocations"
in CXF. You certainly may "invent" other things that just use
interceptors. Fine.
However, the Client is a way that employs certain lower level message
sending machinery to implement the abstraction of an invocation.
I would classify an "invocation" as an abstract element that
is composed of by two other abstract elements, a "request"
and a "response" that are correlated with each other.
We've tried not to immerse the CXF dispatch architecture in such
RPC-oriented concepts.
Obviously we haven't been completely successful in doing so, but the
architecture is more message-oriented and less RPC-oriented than you may
be used to.
Well, obviously there is a reason for that, no? Perhaps, the concept is
endemic to the nature of doing things?
It would appear that the Client is the object in CXF that
performs invocations.(i.e. sends a "request" and collects
the "response"
realized as CXF Messages.
It is an EXAMPLE of one such object, it is not THE object that performs
invocations.
I pointed this out in my last mail.
I got it.
The "request" messages seems to get sent out over a Conduit,
which is an abstract element that seems to suggest a
"connection" to a particular server (for lack of a better word).
In this model, the "response" can come back by some other
means (protocol, address, connection orientation, etc),
It cannot come by another means. It must be the *same* transport as
delivered the outgoing request. I pointed this restriction out to you
already in a previous mail.
And for similar reasons, I'd venture that it must be the same protocol
(e.g. SOAP) also.
and
as a result of being by any other means, the response quite
possibly completely uncorrelated, except for the thing that
correlates the request and resposne, ie. the Client.
You're incorrect here.
The Client does NOT correlate and indeed cannot do so in the presence of
concurrent invocations.
As I said in my last mail on this thread, either the WS-A layer or the
transport does the correlation.
All the Client does is wait for the Exchange to be notify()d after the
response has been dispatched on the incoming chain by
Client.onMessage(). Response correlation in CXF boils down to
associating the incoming response message with the Exchange object of
the original request message. This association may only be done by the
transport or WS-A.
Okay, what I meant was that the Client is the correlating agent for the
application code.
The application making the "invocation" (that abstraction) is realized
by a single operation on the Client called "invoke". This call waits for
the lower level internals to correlate the messages and return the
response to the correct Client.
So, I surmise if you are going to do "invocations" in CXF,
you get the Client to do the work of the correlation of
request and response.
Once again ... an invocation does not require a Client, neither does the
Client have anything to do with correlation.
So, do transports make invocations?
Therefore The Client should be setting the "response"
endpoints (Destination? BackChannel? DecoupledEndpoint?),
shouldn't it?
I disagree.
Your description of the JAX-WS Dispatch stuff being used
means that CXF is used underneath where the Client would use
it. So if there is a correlation of request and response by
JAX-WS Dispatch its implementation should be taking care of
it. So, why isn't it using a Client?
The Dispatch doesn't do any correlation. No more than the Client does.
Right now, I see the Conduit as a one way tunnel in which a
Message is sent from a client to any server. I assume that
abstract element on which Messages are received is a "Destination".
Your view is incorrect.
Unless the replyTo is non-anonymous, there is no backchannel
Destination, and the Conduit most certainly is not one-way.
This is what I am getting at. It is said that responses are returned via
the transport/Conduit, *unless* the EPR is set for "decoupled
responses". That is a far cry from saying that *all* responses to sent
messages are returned via the same transport.
Therefore, I surmise that response messages are directed to come back to
a particular point regardless. If the responses come back on the same
transport is a matter of a specific implementation of default behavior.
These two things are only very loosely coupled at best, and
the fact that a response may come back on the same underlying
transport (i.e.
URLConnection) is merely coincidence.
Again, you're talking about what you'd surmise/guess/assume the
implementation to be. This is not reflected in the actual code.
Perhaps, I'm suggesting what the implementation should be, or the
architecture should be documented to be otherwise. There is a reason I
"guess".
If the response comes back on the same connection, then it is dealt with
*directly* by the sending Conduit, not by separate Destination. A
separate backchannel Destination is *only* used if the replyTo is
decoupled.
Again, that is *if* the response comes back on the same connection.
Maybe a conduit should have a default Destination (i.e. unless
overridden) to which it directs messages when they come back on the same
connection. That seems cleaner.
From what I can gather, is that a Client composes an
invocation by placing a "request" Message on a Conduit,
through a bunch of special interceptors, and receives a
correlated "response" message by picking it up off a
predetermined Destination (listen point? Queue?).
This is incorrect.
The Client does not *pull* the response off any transport-level queue,
listener, whatever.
Instead it implements the MessageObserver interface, which allows the
transport to *push* incoming messages up to Client.
Same difference. The Client waits for the queue effectively to be filled.
You want these two things to be correlated at the outset so
that addressing information can be injected into the message
headers (in the case of http). Right?
Wrong.
First, as I wrote above, the Client is not responsible for dealing with
the response Destination.
Second, addressing information does not go in the HTTP headers. This is
encoded in the protocol headers, e.g. the SOAP headers.
Okay, if the Client is not responsible for dealing with the response
Destination, shouldn't it be?
If the JAX-WS Dispatch doesn't use a client, then what does
it use?
It uses itself. As the MessageObserver. The Client is not the exclusive
one-and-only implementation of MessageObserver.
I got that. So, if the JAX-WS Dispatch (CXF implementation) has to do
the collect the responses, etc.
If it's suppose to correlate its own responses, then
perhaps it's operating at a lower level and has to do more of
the work the client does.
The Dispatch is NOT supposed to having anything to do with correlation.
Well something has to correlate the response with the request. What does
that?
Whatever the MessageObserver is set on the Conduit gets to
process the response(s).
This is a lower level mechanism that notices the messages and
gets them
to go somewhere to get processed. Should this really be a thing some
application code should be using?
In CXF terms, "messages ... go somewhere to get processed" translates as
"messages get dispatched on an InterceptorChain".
So if the application code is already sufficiently low-level to wire
together its own interceptor chains, then yes it should also act as a
MessageObserver. All onMessage() needs to do grab the in-interceptor
chain, call doIntercept() and possibly wake up the original invoking
thread. So the main thing is the ability to wire together the
interceptor chain. If the app is doing this already, then acting as the
MessageObserver is just a small extra step.
Fine, then I'm just saying that the lower you go, the less CXF does for
you.
I think this might all be better served if a Conduit always has a
Destination and the MessageObserver hangs off of that. If the Conduit's
Destination is overrided by some EPR, then the Protocol Headers (e.g.
SOAP) WS-A MI headers can be assigned to outgoing messages, and messages
coming back on the conduit's connection are effectively ignored (as they
aren't supposed to be coming back to there, right?).
Cheers,
-Polar
Cheers,
Eoghan,.