You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Dan Diephouse <da...@envoisolutions.com> on 2007/03/16 23:19:49 UTC

[PROPOSAL] Client and Conduit changes

For those of you who haven't been following the long discussion Eoghan and I
have been having, I'm going to take a moment to summarize my proposal here.
I consider it rather important. If we don't reach any consensus on the
proposal (it sucks/doesn't suck) or if Eoghan & I are the only ones who
participate, I'll probably start a vote. So do your communal duty and
participate so I don't have to do that! :-)

I propose the following:

1. API to set an Asynchronous EndpointReference
I believe we should create a simple method on the Client which allows the
user to specify the asynchronous endpoint that they wish to have used for
decoupled responses:

Client.getAsynchronousEndpoint(EndpointReferenceType epr);

The Client would check to see if this EPR was set. If so, it would call
DestinationFactory.getDestination(epr) for the EPR and use that as the
asynchronous destination. This would result in a standard way to
automatically set up the decoupled destination when using the API.

While it has been said that this isn't generic enough for JMS, I don't
agree. First, I believe that JMS will eventually get a self contained IRI
format which can be stuck in an EPR. We could even create our own
proprietary format. Second, JMS is an edge case. There are other transports
beside just JMS and HTTP, like XMPP or TCP or FTP which work just fine with
URIs. JMS is the odd ball in the sense that historically it has needed stuff
outside the EPR.

2. Access to the Conduits and Destinations
I would like to add the following methods to the Client:

void setConduit(Conduit) - this allows a user to easily specify an alternate
Conduit.
void setAsynchronousDestination(Destination) - this allows a user to easily
specify a decoupled endpoint. It's address would be used for WS-Addressing
interactions. If no Async destination exists, then the Client will only
listen on the Conduit.
Destination getAsynchronousDestination() - utility method to easily get the
asynchronous destination

3. Client.close();
We need a way to shutdown the decouled endpoints (regardless of whether or
not #1 & #2 are adopted). I think there is pretty good conensus we need a
Client.close() method which will do this. It will call getConduit().close()
and getAsynchronousDestination().shutdown().

(Ideally we'd like to be able to shut down RM at this same time. I'm going
to guess that this would require the addition of a client lifecycle
interface which allows RM to listen for Client.close(). This is an issue no
matter which route we go though, so I'll defer this conversation for another
thread)

4. Remove the setup of decoupled destinations from inside the Conduit
Currently, the Conduits are responsible for setting up the decoupled
destinations. We've already got a perfectly good API for creating
destinations, lets use it! Creating another API to create decoupled
destinations introduces inconsistencies into our APIs. Right now if you want
to create different endpoints for receiving ReplyTos and FaultTos you have
configure the ReplyTos using the Conduit API and the FaultTos using the
destination API. Creating those endpoints in different ways is bad IMO.

Putting in decoupled destinations inside the Conduit also makes it more
complex for transport writers or people trying to understand the API. IMO,
people intuitively expect this to be outside the Conduit class.

5. Client Configuration
I would propose that we make the decoupled destination configuration part of
the Client

<jaxws:client id="...SomePort">
  <jaxws:asynchronousEndpoint>
    <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
  </jaxws:asynchronousEndpoint>
</jaxws:client>

<jaxws:client id="...SomePort">

<jaxws:asynchronousDestination><http:destination...></jaxws:asynchronousDestination>
</jaxws:client>

As an added bonus, we can now wire together clients and destinations however
we want. I wouldn't *have* to create a <conduit> config element with the
port name inside it. Instead I could simply do:

<jaxws:client id="...SomePort">
   <jaxws:conduit> <http:conduit... /> </jaxws:conduit>
</jaxws:client>

It also creates a central place to embed Client configuration - such as
enabling MTOM or configuring WS-*:
<jaxws:client id="...SomePort">
   <jaxws:conduit>...</jaxws:conduit>
   <jaxws:binding mtomEnabled="true">
     <jaxws:requestContext>
       <map><entry key="javax.xml.ws.session.maintain" value="true"/></map>
     </jaxws:requestContext>
   </jaxws:binding>
   <jaxws:features>
     <wsrm:reliability timeout="10000" .../>
   </jaxws:features>
</jaxws:client>

Users could still use the <http:conduit id="PORT"/> syntax if they wanted to
though.

(Note: I haven't written the jaxws:client Spring schema yet, but its on my
todo list. The feature stuff will hopefully be part of my commit with
WS-Security)

6. Bring back Destination.getDestination(EndpointReferenceType)
This method would be needed for the API that I propose in #1.

7. Make the JAX-WS dispatch use the client.

----

In summary:
a) This simplifies the API. We've created an API to set up decoupled
endpoints easily. We've reduced the complexity inside Conduits and have
avoided introducing new complexity onto the Conduit interface to specify a
decoupled destination.

b) It creates a consistent API for working with decoupled endpoints. There
is no reason to go writing a new API for setting up decoupled endpoints -
which is only used sometimes.

c) Dependency Injenction: By putting the Conduit & Destination on the Client
we've made it much friendlier to people using Spring or other DI containers.

d) Improved configuration: I think the jaxws:client is a more natural place
to setup the conduit and destination configuration as opposed to nesting the
destination configuration inside the conduit.

e) Setting up decoupled destinations is not the job of the conduit IMO.
We're giving Conduits a dual task unnecessarily. If all Conduits share the
same code for setting up decoupled destinations, that is a sign to me that
we can take it out of the Conduit.

I of course would be volunteering to do all this work.
--

Alternatives: While Eoghan can elaborate, I believe he would rather see
1. The decoupled endpoint remain part of the conduit. He views a decoupled
endpoint as part of the Conduit contract.
2. An API on the Conduit to set up the decoupled endpoint like so:
Client.get(Conduit.class
).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
3. The Client.getConduit/setConduit methods go away and have the Conduit be
an optional part of the Client
4. No Client.setAsynchronousDestination method.
5. Keep the decoupled endpoint configuration as part of the conduit instead
of the client.

Regards,
- Dan

-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
For me the important point is that there will be many people writing or
trying to learn about the Conduit/Destination interfaces. Many more than
those who will be learning about the internals of the Client class. So it
makes sense to try and simplify the Conduit/Destination contracts as much as
possible. Additionally, if we keep things the way they are I think we'll be
forced to complicate them even more ala the introduction of a ConduitPolicy
class.

Eoghan raised the case where someone is not using the Client and doing
invocations, but I think we've established that there is no undue burden
placed on the user to set up decoupled endpoints. The amount of code is
approximately the same and xml configuration still works well with it.

- Dan

On 3/27/07, Daniel Kulp <dk...@apache.org> wrote:
>
>
> Just to jump in here....
>
> I haven't had the time to grok all the details of all the proposals and
> stuff, but I have to say one thing:
>
> IMO, the current transport API's/etc...  are way to complex.   The
> decoupled cases and partial messages and stuff have polluted that layer
> too much.    All of that makes writing new transports much harder than
> it should be.
>
> Thus, if Dan's proposal simplifies that, I'm completely +1 for it.
>
>
> Sometime, I'd like to take some time and re-read all of this, but that
> requires a bit of time I just don't have right now.    :-(
>
>
> Dan
>
>
>
> On Friday 16 March 2007 18:19, Dan Diephouse wrote:
> > For those of you who haven't been following the long discussion Eoghan
> > and I have been having, I'm going to take a moment to summarize my
> > proposal here. I consider it rather important. If we don't reach any
> > consensus on the proposal (it sucks/doesn't suck) or if Eoghan & I are
> > the only ones who participate, I'll probably start a vote. So do your
> > communal duty and participate so I don't have to do that! :-)
> >
> > I propose the following:
> >
> > 1. API to set an Asynchronous EndpointReference
> > I believe we should create a simple method on the Client which allows
> > the user to specify the asynchronous endpoint that they wish to have
> > used for decoupled responses:
> >
> > Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> >
> > The Client would check to see if this EPR was set. If so, it would
> > call DestinationFactory.getDestination(epr) for the EPR and use that
> > as the asynchronous destination. This would result in a standard way
> > to automatically set up the decoupled destination when using the API.
> >
> > While it has been said that this isn't generic enough for JMS, I don't
> > agree. First, I believe that JMS will eventually get a self contained
> > IRI format which can be stuck in an EPR. We could even create our own
> > proprietary format. Second, JMS is an edge case. There are other
> > transports beside just JMS and HTTP, like XMPP or TCP or FTP which
> > work just fine with URIs. JMS is the odd ball in the sense that
> > historically it has needed stuff outside the EPR.
> >
> > 2. Access to the Conduits and Destinations
> > I would like to add the following methods to the Client:
> >
> > void setConduit(Conduit) - this allows a user to easily specify an
> > alternate Conduit.
> > void setAsynchronousDestination(Destination) - this allows a user to
> > easily specify a decoupled endpoint. It's address would be used for
> > WS-Addressing interactions. If no Async destination exists, then the
> > Client will only listen on the Conduit.
> > Destination getAsynchronousDestination() - utility method to easily
> > get the asynchronous destination
> >
> > 3. Client.close();
> > We need a way to shutdown the decouled endpoints (regardless of
> > whether or not #1 & #2 are adopted). I think there is pretty good
> > conensus we need a Client.close() method which will do this. It will
> > call getConduit().close() and getAsynchronousDestination().shutdown().
> >
> > (Ideally we'd like to be able to shut down RM at this same time. I'm
> > going to guess that this would require the addition of a client
> > lifecycle interface which allows RM to listen for Client.close(). This
> > is an issue no matter which route we go though, so I'll defer this
> > conversation for another thread)
> >
> > 4. Remove the setup of decoupled destinations from inside the Conduit
> > Currently, the Conduits are responsible for setting up the decoupled
> > destinations. We've already got a perfectly good API for creating
> > destinations, lets use it! Creating another API to create decoupled
> > destinations introduces inconsistencies into our APIs. Right now if
> > you want to create different endpoints for receiving ReplyTos and
> > FaultTos you have configure the ReplyTos using the Conduit API and the
> > FaultTos using the destination API. Creating those endpoints in
> > different ways is bad IMO.
> >
> > Putting in decoupled destinations inside the Conduit also makes it
> > more complex for transport writers or people trying to understand the
> > API. IMO, people intuitively expect this to be outside the Conduit
> > class.
> >
> > 5. Client Configuration
> > I would propose that we make the decoupled destination configuration
> > part of the Client
> >
> > <jaxws:client id="...SomePort">
> >   <jaxws:asynchronousEndpoint>
> >     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
> >   </jaxws:asynchronousEndpoint>
> > </jaxws:client>
> >
> > <jaxws:client id="...SomePort">
> >
> > <jaxws:asynchronousDestination><http:destination...></jaxws:asynchrono
> >usDestination> </jaxws:client>
> >
> > As an added bonus, we can now wire together clients and destinations
> > however we want. I wouldn't *have* to create a <conduit> config
> > element with the port name inside it. Instead I could simply do:
> >
> > <jaxws:client id="...SomePort">
> >    <jaxws:conduit> <http:conduit... /> </jaxws:conduit>
> > </jaxws:client>
> >
> > It also creates a central place to embed Client configuration - such
> > as enabling MTOM or configuring WS-*:
> > <jaxws:client id="...SomePort">
> >    <jaxws:conduit>...</jaxws:conduit>
> >    <jaxws:binding mtomEnabled="true">
> >      <jaxws:requestContext>
> >        <map><entry key="javax.xml.ws.session.maintain"
> > value="true"/></map> </jaxws:requestContext>
> >    </jaxws:binding>
> >    <jaxws:features>
> >      <wsrm:reliability timeout="10000" .../>
> >    </jaxws:features>
> > </jaxws:client>
> >
> > Users could still use the <http:conduit id="PORT"/> syntax if they
> > wanted to though.
> >
> > (Note: I haven't written the jaxws:client Spring schema yet, but its
> > on my todo list. The feature stuff will hopefully be part of my commit
> > with WS-Security)
> >
> > 6. Bring back Destination.getDestination(EndpointReferenceType)
> > This method would be needed for the API that I propose in #1.
> >
> > 7. Make the JAX-WS dispatch use the client.
> >
> > ----
> >
> > In summary:
> > a) This simplifies the API. We've created an API to set up decoupled
> > endpoints easily. We've reduced the complexity inside Conduits and
> > have avoided introducing new complexity onto the Conduit interface to
> > specify a decoupled destination.
> >
> > b) It creates a consistent API for working with decoupled endpoints.
> > There is no reason to go writing a new API for setting up decoupled
> > endpoints - which is only used sometimes.
> >
> > c) Dependency Injenction: By putting the Conduit & Destination on the
> > Client we've made it much friendlier to people using Spring or other
> > DI containers.
> >
> > d) Improved configuration: I think the jaxws:client is a more natural
> > place to setup the conduit and destination configuration as opposed to
> > nesting the destination configuration inside the conduit.
> >
> > e) Setting up decoupled destinations is not the job of the conduit
> > IMO. We're giving Conduits a dual task unnecessarily. If all Conduits
> > share the same code for setting up decoupled destinations, that is a
> > sign to me that we can take it out of the Conduit.
> >
> > I of course would be volunteering to do all this work.
> > --
> >
> > Alternatives: While Eoghan can elaborate, I believe he would rather
> > see 1. The decoupled endpoint remain part of the conduit. He views a
> > decoupled endpoint as part of the Conduit contract.
> > 2. An API on the Conduit to set up the decoupled endpoint like so:
> > Client.get(Conduit.class
> > ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> > 3. The Client.getConduit/setConduit methods go away and have the
> > Conduit be an optional part of the Client
> > 4. No Client.setAsynchronousDestination method.
> > 5. Keep the decoupled endpoint configuration as part of the conduit
> > instead of the client.
> >
> > Regards,
> > - Dan
>
> --
> J. Daniel Kulp
> Principal Engineer
> IONA
> P: 781-902-8727    C: 508-380-7194
> daniel.kulp@iona.com
> http://www.dankulp.com/blog
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/28/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > Sent: 28 March 2007 15:49
> > To: cxf-dev@incubator.apache.org
> > Subject: Re: [PROPOSAL] Client and Conduit changes
> >
> > We hashed out, but didn't come to any great resolution. I
> > proposed a solution, and as I understand (hopefully I haven't
> > misinterpreted), you agree that my solution is completely
> > feasible, it just isn't your preference.
>
>
> Well my recollection of that discussion was mostly you repeatedly
> questioning the need for partial responses, and me repeatedly explaining
> why we needed them.


Yeah, so I was ignorant of how partial responses worked and their
motiviations. And I thank you for patiently explaining it. I hope we can
move beyond that now.

Please remind me of your proposal if you want to reactivate that
> discussion (on a separate thread).
>
> But if you're referring to your proposal that the RM layer sets the 202
> response code directly, then my objection wasn't on the basis of my
> personal preferences. Instead IIRC I argued on the basis of keeping RM
> transport-neutral.


I think you're mischaracterizing what I was proposing. But I can clean it up
and propose it under a separate thread at some point.

- Dan
-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 28 March 2007 15:49
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> We hashed out, but didn't come to any great resolution. I 
> proposed a solution, and as I understand (hopefully I haven't 
> misinterpreted), you agree that my solution is completely 
> feasible, it just isn't your preference.


Well my recollection of that discussion was mostly you repeatedly
questioning the need for partial responses, and me repeatedly explaining
why we needed them.

Please remind me of your proposal if you want to reactivate that
discussion (on a separate thread).

But if you're referring to your proposal that the RM layer sets the 202
response code directly, then my objection wasn't on the basis of my
personal preferences. Instead IIRC I argued on the basis of keeping RM
transport-neutral.

/Eoghan

 
> But we've heard a few of the concerns over the complexity of 
> the transport APIs in this thread (Willem, Dan, Eric, 
> myself), and I've heard many more offline. People see for 
> simplifying the transport APIs, provided its feasible for the 
> partial response cases. And it is possible.
> 
> - Dan
> 
> On 3/28/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Daniel Kulp [mailto:dkulp@apache.org]
> > > Sent: 27 March 2007 19:00
> > > To: cxf-dev@incubator.apache.org
> > > Subject: Re: [PROPOSAL] Client and Conduit changes
> > >
> > >
> > > Just to jump in here....
> > >
> > > I haven't had the time to grok all the details of all the 
> proposals 
> > > and stuff, but I have to say one thing:
> > >
> > > IMO, the current transport API's/etc...  are way to complex.   The
> > > decoupled cases and partial messages and stuff have polluted that 
> > > layer
> > > too much.    All of that makes writing new transports much
> > > harder than
> > > it should be.
> >
> >
> > DanD's proposal has nothing whatsoever to do with partial responses.
> >
> > That's a completely different issue. That we thrashed out 
> on this list 
> > at extreme length months ago.
> >
> > /Eoghan
> >
> >
> > > Thus, if Dan's proposal simplifies that, I'm completely +1 for it.
> > >
> > >
> > > Sometime, I'd like to take some time and re-read all of this, but 
> > > that
> > > requires a bit of time I just don't have right now.    :-(
> > >
> > >
> > > Dan
> > >
> > >
> > >
> > > On Friday 16 March 2007 18:19, Dan Diephouse wrote:
> > > > For those of you who haven't been following the long
> > > discussion Eoghan
> > > > and I have been having, I'm going to take a moment to 
> summarize my 
> > > > proposal here. I consider it rather important. If we don't
> > > reach any
> > > > consensus on the proposal (it sucks/doesn't suck) or if
> > > Eoghan & I are
> > > > the only ones who participate, I'll probably start a vote.
> > > So do your
> > > > communal duty and participate so I don't have to do that! :-)
> > > >
> > > > I propose the following:
> > > >
> > > > 1. API to set an Asynchronous EndpointReference I believe we 
> > > > should create a simple method on the Client which 
> allows the user
> > > to specify
> > > > the asynchronous endpoint that they wish to have used for 
> > > > decoupled
> > > > responses:
> > > >
> > > > Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> > > >
> > > > The Client would check to see if this EPR was set. If 
> so, it would 
> > > > call DestinationFactory.getDestination(epr) for the EPR and
> > > use that
> > > > as the asynchronous destination. This would result in a
> > > standard way
> > > > to automatically set up the decoupled destination when
> > > using the API.
> > > >
> > > > While it has been said that this isn't generic enough for
> > > JMS, I don't
> > > > agree. First, I believe that JMS will eventually get a self
> > > contained
> > > > IRI format which can be stuck in an EPR. We could even
> > > create our own
> > > > proprietary format. Second, JMS is an edge case. There 
> are other 
> > > > transports beside just JMS and HTTP, like XMPP or TCP 
> or FTP which 
> > > > work just fine with URIs. JMS is the odd ball in the sense that 
> > > > historically it has needed stuff outside the EPR.
> > > >
> > > > 2. Access to the Conduits and Destinations I would like 
> to add the 
> > > > following methods to the Client:
> > > >
> > > > void setConduit(Conduit) - this allows a user to easily 
> specify an 
> > > > alternate Conduit.
> > > > void setAsynchronousDestination(Destination) - this allows
> > > a user to
> > > > easily specify a decoupled endpoint. It's address would be used 
> > > > for WS-Addressing interactions. If no Async destination exists,
> > > then the
> > > > Client will only listen on the Conduit.
> > > > Destination getAsynchronousDestination() - utility method to 
> > > > easily get the asynchronous destination
> > > >
> > > > 3. Client.close();
> > > > We need a way to shutdown the decouled endpoints (regardless of 
> > > > whether or not #1 & #2 are adopted). I think there is 
> pretty good 
> > > > conensus we need a Client.close() method which will do
> > > this. It will
> > > > call getConduit().close() and
> > > getAsynchronousDestination().shutdown().
> > > >
> > > > (Ideally we'd like to be able to shut down RM at this same
> > > time. I'm
> > > > going to guess that this would require the addition of a client 
> > > > lifecycle interface which allows RM to listen for
> > > Client.close(). This
> > > > is an issue no matter which route we go though, so I'll 
> defer this 
> > > > conversation for another thread)
> > > >
> > > > 4. Remove the setup of decoupled destinations from inside
> > > the Conduit
> > > > Currently, the Conduits are responsible for setting up the
> > > decoupled
> > > > destinations. We've already got a perfectly good API 
> for creating 
> > > > destinations, lets use it! Creating another API to create 
> > > > decoupled destinations introduces inconsistencies into 
> our APIs. 
> > > > Right now if you want to create different endpoints for 
> receiving 
> > > > ReplyTos and FaultTos you have configure the ReplyTos using the 
> > > > Conduit
> > > API and the
> > > > FaultTos using the destination API. Creating those endpoints in 
> > > > different ways is bad IMO.
> > > >
> > > > Putting in decoupled destinations inside the Conduit 
> also makes it 
> > > > more complex for transport writers or people trying to
> > > understand the
> > > > API. IMO, people intuitively expect this to be outside 
> the Conduit 
> > > > class.
> > > >
> > > > 5. Client Configuration
> > > > I would propose that we make the decoupled destination
> > > configuration
> > > > part of the Client
> > > >
> > > > <jaxws:client id="...SomePort">
> > > >   <jaxws:asynchronousEndpoint>
> > > >     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
> > > >   </jaxws:asynchronousEndpoint>
> > > > </jaxws:client>
> > > >
> > > > <jaxws:client id="...SomePort">
> > > >
> > > >
> > > 
> <jaxws:asynchronousDestination><http:destination...></jaxws:asynchro
> > > no
> > > >usDestination> </jaxws:client>
> > > >
> > > > As an added bonus, we can now wire together clients and
> > > destinations
> > > > however we want. I wouldn't *have* to create a <conduit> config 
> > > > element with the port name inside it. Instead I could simply do:
> > > >
> > > > <jaxws:client id="...SomePort">
> > > >    <jaxws:conduit> <http:conduit... /> </jaxws:conduit> 
> > > > </jaxws:client>
> > > >
> > > > It also creates a central place to embed Client
> > > configuration - such
> > > > as enabling MTOM or configuring WS-*:
> > > > <jaxws:client id="...SomePort">
> > > >    <jaxws:conduit>...</jaxws:conduit>
> > > >    <jaxws:binding mtomEnabled="true">
> > > >      <jaxws:requestContext>
> > > >        <map><entry key="javax.xml.ws.session.maintain"
> > > > value="true"/></map> </jaxws:requestContext>
> > > >    </jaxws:binding>
> > > >    <jaxws:features>
> > > >      <wsrm:reliability timeout="10000" .../>
> > > >    </jaxws:features>
> > > > </jaxws:client>
> > > >
> > > > Users could still use the <http:conduit id="PORT"/> 
> syntax if they 
> > > > wanted to though.
> > > >
> > > > (Note: I haven't written the jaxws:client Spring schema
> > > yet, but its
> > > > on my todo list. The feature stuff will hopefully be part
> > > of my commit
> > > > with WS-Security)
> > > >
> > > > 6. Bring back Destination.getDestination(EndpointReferenceType)
> > > > This method would be needed for the API that I propose in #1.
> > > >
> > > > 7. Make the JAX-WS dispatch use the client.
> > > >
> > > > ----
> > > >
> > > > In summary:
> > > > a) This simplifies the API. We've created an API to set up
> > > decoupled
> > > > endpoints easily. We've reduced the complexity inside 
> Conduits and 
> > > > have avoided introducing new complexity onto the Conduit
> > > interface to
> > > > specify a decoupled destination.
> > > >
> > > > b) It creates a consistent API for working with 
> decoupled endpoints.
> > > > There is no reason to go writing a new API for setting up 
> > > > decoupled endpoints - which is only used sometimes.
> > > >
> > > > c) Dependency Injenction: By putting the Conduit &
> > > Destination on the
> > > > Client we've made it much friendlier to people using Spring
> > > or other
> > > > DI containers.
> > > >
> > > > d) Improved configuration: I think the jaxws:client is a
> > > more natural
> > > > place to setup the conduit and destination configuration as
> > > opposed to
> > > > nesting the destination configuration inside the conduit.
> > > >
> > > > e) Setting up decoupled destinations is not the job of 
> the conduit 
> > > > IMO. We're giving Conduits a dual task unnecessarily. If
> > > all Conduits
> > > > share the same code for setting up decoupled destinations,
> > > that is a
> > > > sign to me that we can take it out of the Conduit.
> > > >
> > > > I of course would be volunteering to do all this work.
> > > > --
> > > >
> > > > Alternatives: While Eoghan can elaborate, I believe he would 
> > > > rather see 1. The decoupled endpoint remain part of the conduit.
> > > He views a
> > > > decoupled endpoint as part of the Conduit contract.
> > > > 2. An API on the Conduit to set up the decoupled 
> endpoint like so:
> > > > Client.get(Conduit.class
> > > > ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> > > > 3. The Client.getConduit/setConduit methods go away and 
> have the 
> > > > Conduit be an optional part of the Client 4. No 
> > > > Client.setAsynchronousDestination method.
> > > > 5. Keep the decoupled endpoint configuration as part of the 
> > > > conduit instead of the client.
> > > >
> > > > Regards,
> > > > - Dan
> > >
> > > --
> > > J. Daniel Kulp
> > > Principal Engineer
> > > IONA
> > > P: 781-902-8727    C: 508-380-7194
> > > daniel.kulp@iona.com
> > > http://www.dankulp.com/blog
> > >
> >
> 
> 
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
We hashed out, but didn't come to any great resolution. I proposed a
solution, and as I understand (hopefully I haven't misinterpreted), you
agree that my solution is completely feasible, it just isn't your
preference.

But we've heard a few of the concerns over the complexity of the transport
APIs in this thread (Willem, Dan, Eric, myself), and I've heard many more
offline. People see for simplifying the transport APIs, provided its
feasible for the partial response cases. And it is possible.

- Dan

On 3/28/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Daniel Kulp [mailto:dkulp@apache.org]
> > Sent: 27 March 2007 19:00
> > To: cxf-dev@incubator.apache.org
> > Subject: Re: [PROPOSAL] Client and Conduit changes
> >
> >
> > Just to jump in here....
> >
> > I haven't had the time to grok all the details of all the
> > proposals and stuff, but I have to say one thing:
> >
> > IMO, the current transport API's/etc...  are way to complex.   The
> > decoupled cases and partial messages and stuff have polluted
> > that layer
> > too much.    All of that makes writing new transports much
> > harder than
> > it should be.
>
>
> DanD's proposal has nothing whatsoever to do with partial responses.
>
> That's a completely different issue. That we thrashed out on this list
> at extreme length months ago.
>
> /Eoghan
>
>
> > Thus, if Dan's proposal simplifies that, I'm completely +1 for it.
> >
> >
> > Sometime, I'd like to take some time and re-read all of this,
> > but that
> > requires a bit of time I just don't have right now.    :-(
> >
> >
> > Dan
> >
> >
> >
> > On Friday 16 March 2007 18:19, Dan Diephouse wrote:
> > > For those of you who haven't been following the long
> > discussion Eoghan
> > > and I have been having, I'm going to take a moment to summarize my
> > > proposal here. I consider it rather important. If we don't
> > reach any
> > > consensus on the proposal (it sucks/doesn't suck) or if
> > Eoghan & I are
> > > the only ones who participate, I'll probably start a vote.
> > So do your
> > > communal duty and participate so I don't have to do that! :-)
> > >
> > > I propose the following:
> > >
> > > 1. API to set an Asynchronous EndpointReference I believe we should
> > > create a simple method on the Client which allows the user
> > to specify
> > > the asynchronous endpoint that they wish to have used for decoupled
> > > responses:
> > >
> > > Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> > >
> > > The Client would check to see if this EPR was set. If so, it would
> > > call DestinationFactory.getDestination(epr) for the EPR and
> > use that
> > > as the asynchronous destination. This would result in a
> > standard way
> > > to automatically set up the decoupled destination when
> > using the API.
> > >
> > > While it has been said that this isn't generic enough for
> > JMS, I don't
> > > agree. First, I believe that JMS will eventually get a self
> > contained
> > > IRI format which can be stuck in an EPR. We could even
> > create our own
> > > proprietary format. Second, JMS is an edge case. There are other
> > > transports beside just JMS and HTTP, like XMPP or TCP or FTP which
> > > work just fine with URIs. JMS is the odd ball in the sense that
> > > historically it has needed stuff outside the EPR.
> > >
> > > 2. Access to the Conduits and Destinations I would like to add the
> > > following methods to the Client:
> > >
> > > void setConduit(Conduit) - this allows a user to easily specify an
> > > alternate Conduit.
> > > void setAsynchronousDestination(Destination) - this allows
> > a user to
> > > easily specify a decoupled endpoint. It's address would be used for
> > > WS-Addressing interactions. If no Async destination exists,
> > then the
> > > Client will only listen on the Conduit.
> > > Destination getAsynchronousDestination() - utility method to easily
> > > get the asynchronous destination
> > >
> > > 3. Client.close();
> > > We need a way to shutdown the decouled endpoints (regardless of
> > > whether or not #1 & #2 are adopted). I think there is pretty good
> > > conensus we need a Client.close() method which will do
> > this. It will
> > > call getConduit().close() and
> > getAsynchronousDestination().shutdown().
> > >
> > > (Ideally we'd like to be able to shut down RM at this same
> > time. I'm
> > > going to guess that this would require the addition of a client
> > > lifecycle interface which allows RM to listen for
> > Client.close(). This
> > > is an issue no matter which route we go though, so I'll defer this
> > > conversation for another thread)
> > >
> > > 4. Remove the setup of decoupled destinations from inside
> > the Conduit
> > > Currently, the Conduits are responsible for setting up the
> > decoupled
> > > destinations. We've already got a perfectly good API for creating
> > > destinations, lets use it! Creating another API to create decoupled
> > > destinations introduces inconsistencies into our APIs. Right now if
> > > you want to create different endpoints for receiving ReplyTos and
> > > FaultTos you have configure the ReplyTos using the Conduit
> > API and the
> > > FaultTos using the destination API. Creating those endpoints in
> > > different ways is bad IMO.
> > >
> > > Putting in decoupled destinations inside the Conduit also makes it
> > > more complex for transport writers or people trying to
> > understand the
> > > API. IMO, people intuitively expect this to be outside the Conduit
> > > class.
> > >
> > > 5. Client Configuration
> > > I would propose that we make the decoupled destination
> > configuration
> > > part of the Client
> > >
> > > <jaxws:client id="...SomePort">
> > >   <jaxws:asynchronousEndpoint>
> > >     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
> > >   </jaxws:asynchronousEndpoint>
> > > </jaxws:client>
> > >
> > > <jaxws:client id="...SomePort">
> > >
> > >
> > <jaxws:asynchronousDestination><http:destination...></jaxws:asynchrono
> > >usDestination> </jaxws:client>
> > >
> > > As an added bonus, we can now wire together clients and
> > destinations
> > > however we want. I wouldn't *have* to create a <conduit> config
> > > element with the port name inside it. Instead I could simply do:
> > >
> > > <jaxws:client id="...SomePort">
> > >    <jaxws:conduit> <http:conduit... /> </jaxws:conduit>
> > > </jaxws:client>
> > >
> > > It also creates a central place to embed Client
> > configuration - such
> > > as enabling MTOM or configuring WS-*:
> > > <jaxws:client id="...SomePort">
> > >    <jaxws:conduit>...</jaxws:conduit>
> > >    <jaxws:binding mtomEnabled="true">
> > >      <jaxws:requestContext>
> > >        <map><entry key="javax.xml.ws.session.maintain"
> > > value="true"/></map> </jaxws:requestContext>
> > >    </jaxws:binding>
> > >    <jaxws:features>
> > >      <wsrm:reliability timeout="10000" .../>
> > >    </jaxws:features>
> > > </jaxws:client>
> > >
> > > Users could still use the <http:conduit id="PORT"/> syntax if they
> > > wanted to though.
> > >
> > > (Note: I haven't written the jaxws:client Spring schema
> > yet, but its
> > > on my todo list. The feature stuff will hopefully be part
> > of my commit
> > > with WS-Security)
> > >
> > > 6. Bring back Destination.getDestination(EndpointReferenceType)
> > > This method would be needed for the API that I propose in #1.
> > >
> > > 7. Make the JAX-WS dispatch use the client.
> > >
> > > ----
> > >
> > > In summary:
> > > a) This simplifies the API. We've created an API to set up
> > decoupled
> > > endpoints easily. We've reduced the complexity inside Conduits and
> > > have avoided introducing new complexity onto the Conduit
> > interface to
> > > specify a decoupled destination.
> > >
> > > b) It creates a consistent API for working with decoupled endpoints.
> > > There is no reason to go writing a new API for setting up decoupled
> > > endpoints - which is only used sometimes.
> > >
> > > c) Dependency Injenction: By putting the Conduit &
> > Destination on the
> > > Client we've made it much friendlier to people using Spring
> > or other
> > > DI containers.
> > >
> > > d) Improved configuration: I think the jaxws:client is a
> > more natural
> > > place to setup the conduit and destination configuration as
> > opposed to
> > > nesting the destination configuration inside the conduit.
> > >
> > > e) Setting up decoupled destinations is not the job of the conduit
> > > IMO. We're giving Conduits a dual task unnecessarily. If
> > all Conduits
> > > share the same code for setting up decoupled destinations,
> > that is a
> > > sign to me that we can take it out of the Conduit.
> > >
> > > I of course would be volunteering to do all this work.
> > > --
> > >
> > > Alternatives: While Eoghan can elaborate, I believe he would rather
> > > see 1. The decoupled endpoint remain part of the conduit.
> > He views a
> > > decoupled endpoint as part of the Conduit contract.
> > > 2. An API on the Conduit to set up the decoupled endpoint like so:
> > > Client.get(Conduit.class
> > > ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> > > 3. The Client.getConduit/setConduit methods go away and have the
> > > Conduit be an optional part of the Client 4. No
> > > Client.setAsynchronousDestination method.
> > > 5. Keep the decoupled endpoint configuration as part of the conduit
> > > instead of the client.
> > >
> > > Regards,
> > > - Dan
> >
> > --
> > J. Daniel Kulp
> > Principal Engineer
> > IONA
> > P: 781-902-8727    C: 508-380-7194
> > daniel.kulp@iona.com
> > http://www.dankulp.com/blog
> >
>



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Daniel Kulp [mailto:dkulp@apache.org] 
> Sent: 27 March 2007 19:00
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> 
> Just to jump in here....
> 
> I haven't had the time to grok all the details of all the 
> proposals and stuff, but I have to say one thing:
> 
> IMO, the current transport API's/etc...  are way to complex.   The 
> decoupled cases and partial messages and stuff have polluted 
> that layer 
> too much.    All of that makes writing new transports much 
> harder than 
> it should be.


DanD's proposal has nothing whatsoever to do with partial responses.

That's a completely different issue. That we thrashed out on this list
at extreme length months ago.

/Eoghan
 

> Thus, if Dan's proposal simplifies that, I'm completely +1 for it.
> 
> 
> Sometime, I'd like to take some time and re-read all of this, 
> but that 
> requires a bit of time I just don't have right now.    :-(
> 
> 
> Dan
> 
> 
> 
> On Friday 16 March 2007 18:19, Dan Diephouse wrote:
> > For those of you who haven't been following the long 
> discussion Eoghan 
> > and I have been having, I'm going to take a moment to summarize my 
> > proposal here. I consider it rather important. If we don't 
> reach any 
> > consensus on the proposal (it sucks/doesn't suck) or if 
> Eoghan & I are 
> > the only ones who participate, I'll probably start a vote. 
> So do your 
> > communal duty and participate so I don't have to do that! :-)
> >
> > I propose the following:
> >
> > 1. API to set an Asynchronous EndpointReference I believe we should 
> > create a simple method on the Client which allows the user 
> to specify 
> > the asynchronous endpoint that they wish to have used for decoupled 
> > responses:
> >
> > Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> >
> > The Client would check to see if this EPR was set. If so, it would 
> > call DestinationFactory.getDestination(epr) for the EPR and 
> use that 
> > as the asynchronous destination. This would result in a 
> standard way 
> > to automatically set up the decoupled destination when 
> using the API.
> >
> > While it has been said that this isn't generic enough for 
> JMS, I don't 
> > agree. First, I believe that JMS will eventually get a self 
> contained 
> > IRI format which can be stuck in an EPR. We could even 
> create our own 
> > proprietary format. Second, JMS is an edge case. There are other 
> > transports beside just JMS and HTTP, like XMPP or TCP or FTP which 
> > work just fine with URIs. JMS is the odd ball in the sense that 
> > historically it has needed stuff outside the EPR.
> >
> > 2. Access to the Conduits and Destinations I would like to add the 
> > following methods to the Client:
> >
> > void setConduit(Conduit) - this allows a user to easily specify an 
> > alternate Conduit.
> > void setAsynchronousDestination(Destination) - this allows 
> a user to 
> > easily specify a decoupled endpoint. It's address would be used for 
> > WS-Addressing interactions. If no Async destination exists, 
> then the 
> > Client will only listen on the Conduit.
> > Destination getAsynchronousDestination() - utility method to easily 
> > get the asynchronous destination
> >
> > 3. Client.close();
> > We need a way to shutdown the decouled endpoints (regardless of 
> > whether or not #1 & #2 are adopted). I think there is pretty good 
> > conensus we need a Client.close() method which will do 
> this. It will 
> > call getConduit().close() and 
> getAsynchronousDestination().shutdown().
> >
> > (Ideally we'd like to be able to shut down RM at this same 
> time. I'm 
> > going to guess that this would require the addition of a client 
> > lifecycle interface which allows RM to listen for 
> Client.close(). This 
> > is an issue no matter which route we go though, so I'll defer this 
> > conversation for another thread)
> >
> > 4. Remove the setup of decoupled destinations from inside 
> the Conduit 
> > Currently, the Conduits are responsible for setting up the 
> decoupled 
> > destinations. We've already got a perfectly good API for creating 
> > destinations, lets use it! Creating another API to create decoupled 
> > destinations introduces inconsistencies into our APIs. Right now if 
> > you want to create different endpoints for receiving ReplyTos and 
> > FaultTos you have configure the ReplyTos using the Conduit 
> API and the 
> > FaultTos using the destination API. Creating those endpoints in 
> > different ways is bad IMO.
> >
> > Putting in decoupled destinations inside the Conduit also makes it 
> > more complex for transport writers or people trying to 
> understand the 
> > API. IMO, people intuitively expect this to be outside the Conduit 
> > class.
> >
> > 5. Client Configuration
> > I would propose that we make the decoupled destination 
> configuration 
> > part of the Client
> >
> > <jaxws:client id="...SomePort">
> >   <jaxws:asynchronousEndpoint>
> >     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
> >   </jaxws:asynchronousEndpoint>
> > </jaxws:client>
> >
> > <jaxws:client id="...SomePort">
> >
> > 
> <jaxws:asynchronousDestination><http:destination...></jaxws:asynchrono
> >usDestination> </jaxws:client>
> >
> > As an added bonus, we can now wire together clients and 
> destinations 
> > however we want. I wouldn't *have* to create a <conduit> config 
> > element with the port name inside it. Instead I could simply do:
> >
> > <jaxws:client id="...SomePort">
> >    <jaxws:conduit> <http:conduit... /> </jaxws:conduit> 
> > </jaxws:client>
> >
> > It also creates a central place to embed Client 
> configuration - such 
> > as enabling MTOM or configuring WS-*:
> > <jaxws:client id="...SomePort">
> >    <jaxws:conduit>...</jaxws:conduit>
> >    <jaxws:binding mtomEnabled="true">
> >      <jaxws:requestContext>
> >        <map><entry key="javax.xml.ws.session.maintain"
> > value="true"/></map> </jaxws:requestContext>
> >    </jaxws:binding>
> >    <jaxws:features>
> >      <wsrm:reliability timeout="10000" .../>
> >    </jaxws:features>
> > </jaxws:client>
> >
> > Users could still use the <http:conduit id="PORT"/> syntax if they 
> > wanted to though.
> >
> > (Note: I haven't written the jaxws:client Spring schema 
> yet, but its 
> > on my todo list. The feature stuff will hopefully be part 
> of my commit 
> > with WS-Security)
> >
> > 6. Bring back Destination.getDestination(EndpointReferenceType)
> > This method would be needed for the API that I propose in #1.
> >
> > 7. Make the JAX-WS dispatch use the client.
> >
> > ----
> >
> > In summary:
> > a) This simplifies the API. We've created an API to set up 
> decoupled 
> > endpoints easily. We've reduced the complexity inside Conduits and 
> > have avoided introducing new complexity onto the Conduit 
> interface to 
> > specify a decoupled destination.
> >
> > b) It creates a consistent API for working with decoupled endpoints.
> > There is no reason to go writing a new API for setting up decoupled 
> > endpoints - which is only used sometimes.
> >
> > c) Dependency Injenction: By putting the Conduit & 
> Destination on the 
> > Client we've made it much friendlier to people using Spring 
> or other 
> > DI containers.
> >
> > d) Improved configuration: I think the jaxws:client is a 
> more natural 
> > place to setup the conduit and destination configuration as 
> opposed to 
> > nesting the destination configuration inside the conduit.
> >
> > e) Setting up decoupled destinations is not the job of the conduit 
> > IMO. We're giving Conduits a dual task unnecessarily. If 
> all Conduits 
> > share the same code for setting up decoupled destinations, 
> that is a 
> > sign to me that we can take it out of the Conduit.
> >
> > I of course would be volunteering to do all this work.
> > --
> >
> > Alternatives: While Eoghan can elaborate, I believe he would rather 
> > see 1. The decoupled endpoint remain part of the conduit. 
> He views a 
> > decoupled endpoint as part of the Conduit contract.
> > 2. An API on the Conduit to set up the decoupled endpoint like so:
> > Client.get(Conduit.class
> > ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> > 3. The Client.getConduit/setConduit methods go away and have the 
> > Conduit be an optional part of the Client 4. No 
> > Client.setAsynchronousDestination method.
> > 5. Keep the decoupled endpoint configuration as part of the conduit 
> > instead of the client.
> >
> > Regards,
> > - Dan
> 
> --
> J. Daniel Kulp
> Principal Engineer
> IONA
> P: 781-902-8727    C: 508-380-7194
> daniel.kulp@iona.com
> http://www.dankulp.com/blog
> 

Re: [PROPOSAL] Client and Conduit changes

Posted by Daniel Kulp <dk...@apache.org>.
Just to jump in here....

I haven't had the time to grok all the details of all the proposals and 
stuff, but I have to say one thing:

IMO, the current transport API's/etc...  are way to complex.   The 
decoupled cases and partial messages and stuff have polluted that layer 
too much.    All of that makes writing new transports much harder than 
it should be.

Thus, if Dan's proposal simplifies that, I'm completely +1 for it.


Sometime, I'd like to take some time and re-read all of this, but that 
requires a bit of time I just don't have right now.    :-(


Dan



On Friday 16 March 2007 18:19, Dan Diephouse wrote:
> For those of you who haven't been following the long discussion Eoghan
> and I have been having, I'm going to take a moment to summarize my
> proposal here. I consider it rather important. If we don't reach any
> consensus on the proposal (it sucks/doesn't suck) or if Eoghan & I are
> the only ones who participate, I'll probably start a vote. So do your
> communal duty and participate so I don't have to do that! :-)
>
> I propose the following:
>
> 1. API to set an Asynchronous EndpointReference
> I believe we should create a simple method on the Client which allows
> the user to specify the asynchronous endpoint that they wish to have
> used for decoupled responses:
>
> Client.getAsynchronousEndpoint(EndpointReferenceType epr);
>
> The Client would check to see if this EPR was set. If so, it would
> call DestinationFactory.getDestination(epr) for the EPR and use that
> as the asynchronous destination. This would result in a standard way
> to automatically set up the decoupled destination when using the API.
>
> While it has been said that this isn't generic enough for JMS, I don't
> agree. First, I believe that JMS will eventually get a self contained
> IRI format which can be stuck in an EPR. We could even create our own
> proprietary format. Second, JMS is an edge case. There are other
> transports beside just JMS and HTTP, like XMPP or TCP or FTP which
> work just fine with URIs. JMS is the odd ball in the sense that
> historically it has needed stuff outside the EPR.
>
> 2. Access to the Conduits and Destinations
> I would like to add the following methods to the Client:
>
> void setConduit(Conduit) - this allows a user to easily specify an
> alternate Conduit.
> void setAsynchronousDestination(Destination) - this allows a user to
> easily specify a decoupled endpoint. It's address would be used for
> WS-Addressing interactions. If no Async destination exists, then the
> Client will only listen on the Conduit.
> Destination getAsynchronousDestination() - utility method to easily
> get the asynchronous destination
>
> 3. Client.close();
> We need a way to shutdown the decouled endpoints (regardless of
> whether or not #1 & #2 are adopted). I think there is pretty good
> conensus we need a Client.close() method which will do this. It will
> call getConduit().close() and getAsynchronousDestination().shutdown().
>
> (Ideally we'd like to be able to shut down RM at this same time. I'm
> going to guess that this would require the addition of a client
> lifecycle interface which allows RM to listen for Client.close(). This
> is an issue no matter which route we go though, so I'll defer this
> conversation for another thread)
>
> 4. Remove the setup of decoupled destinations from inside the Conduit
> Currently, the Conduits are responsible for setting up the decoupled
> destinations. We've already got a perfectly good API for creating
> destinations, lets use it! Creating another API to create decoupled
> destinations introduces inconsistencies into our APIs. Right now if
> you want to create different endpoints for receiving ReplyTos and
> FaultTos you have configure the ReplyTos using the Conduit API and the
> FaultTos using the destination API. Creating those endpoints in
> different ways is bad IMO.
>
> Putting in decoupled destinations inside the Conduit also makes it
> more complex for transport writers or people trying to understand the
> API. IMO, people intuitively expect this to be outside the Conduit
> class.
>
> 5. Client Configuration
> I would propose that we make the decoupled destination configuration
> part of the Client
>
> <jaxws:client id="...SomePort">
>   <jaxws:asynchronousEndpoint>
>     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
>   </jaxws:asynchronousEndpoint>
> </jaxws:client>
>
> <jaxws:client id="...SomePort">
>
> <jaxws:asynchronousDestination><http:destination...></jaxws:asynchrono
>usDestination> </jaxws:client>
>
> As an added bonus, we can now wire together clients and destinations
> however we want. I wouldn't *have* to create a <conduit> config
> element with the port name inside it. Instead I could simply do:
>
> <jaxws:client id="...SomePort">
>    <jaxws:conduit> <http:conduit... /> </jaxws:conduit>
> </jaxws:client>
>
> It also creates a central place to embed Client configuration - such
> as enabling MTOM or configuring WS-*:
> <jaxws:client id="...SomePort">
>    <jaxws:conduit>...</jaxws:conduit>
>    <jaxws:binding mtomEnabled="true">
>      <jaxws:requestContext>
>        <map><entry key="javax.xml.ws.session.maintain"
> value="true"/></map> </jaxws:requestContext>
>    </jaxws:binding>
>    <jaxws:features>
>      <wsrm:reliability timeout="10000" .../>
>    </jaxws:features>
> </jaxws:client>
>
> Users could still use the <http:conduit id="PORT"/> syntax if they
> wanted to though.
>
> (Note: I haven't written the jaxws:client Spring schema yet, but its
> on my todo list. The feature stuff will hopefully be part of my commit
> with WS-Security)
>
> 6. Bring back Destination.getDestination(EndpointReferenceType)
> This method would be needed for the API that I propose in #1.
>
> 7. Make the JAX-WS dispatch use the client.
>
> ----
>
> In summary:
> a) This simplifies the API. We've created an API to set up decoupled
> endpoints easily. We've reduced the complexity inside Conduits and
> have avoided introducing new complexity onto the Conduit interface to
> specify a decoupled destination.
>
> b) It creates a consistent API for working with decoupled endpoints.
> There is no reason to go writing a new API for setting up decoupled
> endpoints - which is only used sometimes.
>
> c) Dependency Injenction: By putting the Conduit & Destination on the
> Client we've made it much friendlier to people using Spring or other
> DI containers.
>
> d) Improved configuration: I think the jaxws:client is a more natural
> place to setup the conduit and destination configuration as opposed to
> nesting the destination configuration inside the conduit.
>
> e) Setting up decoupled destinations is not the job of the conduit
> IMO. We're giving Conduits a dual task unnecessarily. If all Conduits
> share the same code for setting up decoupled destinations, that is a
> sign to me that we can take it out of the Conduit.
>
> I of course would be volunteering to do all this work.
> --
>
> Alternatives: While Eoghan can elaborate, I believe he would rather
> see 1. The decoupled endpoint remain part of the conduit. He views a
> decoupled endpoint as part of the Conduit contract.
> 2. An API on the Conduit to set up the decoupled endpoint like so:
> Client.get(Conduit.class
> ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> 3. The Client.getConduit/setConduit methods go away and have the
> Conduit be an optional part of the Client
> 4. No Client.setAsynchronousDestination method.
> 5. Keep the decoupled endpoint configuration as part of the conduit
> instead of the client.
>
> Regards,
> - Dan

-- 
J. Daniel Kulp
Principal Engineer
IONA
P: 781-902-8727    C: 508-380-7194
daniel.kulp@iona.com
http://www.dankulp.com/blog

Re: [PROPOSAL] Client and Conduit changes

Posted by Andrea Smyth <an...@iona.com>.
>
>
> 5. Client Configuration
> I would propose that we make the decoupled destination configuration 
> part of
> the Client
>
> <jaxws:client id="...SomePort">
>  <jaxws:asynchronousEndpoint>
>    <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
>  </jaxws:asynchronousEndpoint>
> </jaxws:client>
>
> <jaxws:client id="...SomePort">
>
> <jaxws:asynchronousDestination><http:destination...></jaxws:asynchronousDestination> 
>
> </jaxws:client>
>
> As an added bonus, we can now wire together clients and destinations 
> however
> we want. I wouldn't *have* to create a <conduit> config element with the
> port name inside it. Instead I could simply do:
>
> <jaxws:client id="...SomePort">
>   <jaxws:conduit> <http:conduit... /> </jaxws:conduit>
> </jaxws:client>
>
> It also creates a central place to embed Client configuration - such as
> enabling MTOM or configuring WS-*:
> <jaxws:client id="...SomePort">
>   <jaxws:conduit>...</jaxws:conduit>
>   <jaxws:binding mtomEnabled="true">
>     <jaxws:requestContext>
>       <map><entry key="javax.xml.ws.session.maintain" 
> value="true"/></map>
>     </jaxws:requestContext>
>   </jaxws:binding>
>   <jaxws:features>
>     <wsrm:reliability timeout="10000" .../>
>   </jaxws:features>
> </jaxws:client>

What is the connection between the <wsrm:reliability> element and the 
RMAssertion? Is the timeout attribute in <wsrm:reliability> element 
synonymous with the InactivityTimeout in the RMAssertion?
I would like to see the above way of configuring WS-* features in sync 
with the configuration of these features as envisaged in their resp. 
specs, both at the data level (i.e. reuse of the RMAssertion type for 
example) and for aggregation purposes (use WS-Policy to specify 
optionalities, requirements, express alternatives etc.).
Why not allow <wsp:Policy 
xmlns:wsp="http://www.w3.org/2006/07/ws-policy"> child elements in 
<jaxws:client>?

BTWwhat is actually jaxws specific about these features - or the 
client/conduit injection for that matter? It should be possible to 
inject a conduit into any kind of client (and configure its WS-* 
features) - JAXWS or not.

Andrea.



Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/17/07, Johnson, Eric <Er...@iona.com> wrote:
>
> I've been trying to follow the thread about this stuff, but was getting
> lost in the details. This is a great way to bring clarity.
> I'd be very interested in hearing Eoghan's alternate proposal-or
> rebuttal.
>
> I've commented in-line.
>
> > -----Original Message-----
> > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > Sent: Friday, March 16, 2007 6:20 PM
> > To: cxf-dev@incubator.apache.org
> > Subject: [PROPOSAL] Client and Conduit changes
> >
> > For those of you who haven't been following the long
> > discussion Eoghan and I have been having, I'm going to take a
> > moment to summarize my proposal here.
> > I consider it rather important. If we don't reach any
> > consensus on the proposal (it sucks/doesn't suck) or if
> > Eoghan & I are the only ones who participate, I'll probably
> > start a vote. So do your communal duty and participate so I
> > don't have to do that! :-)
> >
> > I propose the following:
> >
> > 1. API to set an Asynchronous EndpointReference I believe we
> > should create a simple method on the Client which allows the
> > user to specify the asynchronous endpoint that they wish to
> > have used for decoupled responses:
> >
> > Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> >
> > The Client would check to see if this EPR was set. If so, it
> > would call
> > DestinationFactory.getDestination(epr) for the EPR and use
> > that as the asynchronous destination. This would result in a
> > standard way to automatically set up the decoupled
> > destination when using the API.
> >
> > While it has been said that this isn't generic enough for
> > JMS, I don't agree. First, I believe that JMS will eventually
> > get a self contained IRI format which can be stuck in an EPR.
> > We could even create our own proprietary format. Second, JMS
> > is an edge case. There are other transports beside just JMS
> > and HTTP, like XMPP or TCP or FTP which work just fine with
> > URIs. JMS is the odd ball in the sense that historically it
> > has needed stuff outside the EPR.
>
> Just because JMS is the only current edge case I don't think it should
> be dismissed so lightly. There are other possible transport
> impmentations that will need information outside the EPR.
>
>
The only way to address this is casting to some specific JMS class. In
Eoghan's case, I believe he is suggesting that there be a JMSConduitPolicy
class which extends ConduitPolicy which people can use to set up the
decoupled information.  To quote him:

"Other transports would also extend ConduitPolicy with their own client
policy type if necessary and could I guess add any additional info they need
(thus neatly solving the JMS issue). The generic ConduitPolicy could be
exposed via the AbstractConduit. Then programmatic approach (as used for
example in the RM SequenceTest) could then also become generic (i.e. call
AbstractConduit.getConduitPolicy() as opposed to HTTPConduit.getClient() to
get a hold of the policy object)."

Unless I'm completing misinterpreting him, this would become something like:

EndpointReferenceType epr = ... create your EPR;
JMSConduitPolicy policy = new JMSConduitPolicyImpl();
policy.setDecoupledEndpoint(epr);
// configure JMS settings on JMSConduitPolicy
client.setPolicy(ConduitPolicy.class, policy);

I'm suggesting that people simply cast to JMSDestination instead of
introducing more APIs. i.e.:
EndpointReferenceType epr = ... create your EPR;
DestinationFactory factory = ... get DF from Bus;
JMSDestination dest = (JMSDestination) factory.getDestination(epr);
// configure JMS settings on JMSConduitPolicy
client.setAysnchronousDestination(dest);

Either way you can't really get around that JMS needs custom settings that
aren't very amenable to the EPRs. I just don't see why we want to invent
another API (i.e. the ConduitPolicy classes) to manipulate those settings
when we've already got a perfectly good Destination API to do that for us.
Especially when we're telling users that if you want to set up other
destinations that you need to use the Destination API and not the Conduit
API.

- Dan
-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: [PROPOSAL] Client and Conduit changes

Posted by "Johnson, Eric" <Er...@iona.com>.
I've been trying to follow the thread about this stuff, but was getting
lost in the details. This is a great way to bring clarity.
I'd be very interested in hearing Eoghan's alternate proposal-or
rebuttal.

I've commented in-line.

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: Friday, March 16, 2007 6:20 PM
> To: cxf-dev@incubator.apache.org
> Subject: [PROPOSAL] Client and Conduit changes
> 
> For those of you who haven't been following the long 
> discussion Eoghan and I have been having, I'm going to take a 
> moment to summarize my proposal here.
> I consider it rather important. If we don't reach any 
> consensus on the proposal (it sucks/doesn't suck) or if 
> Eoghan & I are the only ones who participate, I'll probably 
> start a vote. So do your communal duty and participate so I 
> don't have to do that! :-)
> 
> I propose the following:
> 
> 1. API to set an Asynchronous EndpointReference I believe we 
> should create a simple method on the Client which allows the 
> user to specify the asynchronous endpoint that they wish to 
> have used for decoupled responses:
> 
> Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> 
> The Client would check to see if this EPR was set. If so, it 
> would call
> DestinationFactory.getDestination(epr) for the EPR and use 
> that as the asynchronous destination. This would result in a 
> standard way to automatically set up the decoupled 
> destination when using the API.
> 
> While it has been said that this isn't generic enough for 
> JMS, I don't agree. First, I believe that JMS will eventually 
> get a self contained IRI format which can be stuck in an EPR. 
> We could even create our own proprietary format. Second, JMS 
> is an edge case. There are other transports beside just JMS 
> and HTTP, like XMPP or TCP or FTP which work just fine with 
> URIs. JMS is the odd ball in the sense that historically it 
> has needed stuff outside the EPR.

Just because JMS is the only current edge case I don't think it should
be dismissed so lightly. There are other possible transport
impmentations that will need information outside the EPR.

> 2. Access to the Conduits and Destinations I would like to 
> add the following methods to the Client:
> 
> void setConduit(Conduit) - this allows a user to easily 
> specify an alternate Conduit.
> void setAsynchronousDestination(Destination) - this allows a 
> user to easily specify a decoupled endpoint. It's address 
> would be used for WS-Addressing interactions. If no Async 
> destination exists, then the Client will only listen on the Conduit.
> Destination getAsynchronousDestination() - utility method to 
> easily get the asynchronous destination
> 
> 3. Client.close();
> We need a way to shutdown the decouled endpoints (regardless 
> of whether or not #1 & #2 are adopted). I think there is 
> pretty good conensus we need a
> Client.close() method which will do this. It will call 
> getConduit().close() and getAsynchronousDestination().shutdown().
> 
> (Ideally we'd like to be able to shut down RM at this same 
> time. I'm going to guess that this would require the addition 
> of a client lifecycle interface which allows RM to listen for 
> Client.close(). This is an issue no matter which route we go 
> though, so I'll defer this conversation for another
> thread)
> 
> 4. Remove the setup of decoupled destinations from inside the 
> Conduit Currently, the Conduits are responsible for setting 
> up the decoupled destinations. We've already got a perfectly 
> good API for creating destinations, lets use it! Creating 
> another API to create decoupled destinations introduces 
> inconsistencies into our APIs. Right now if you want to 
> create different endpoints for receiving ReplyTos and 
> FaultTos you have configure the ReplyTos using the Conduit 
> API and the FaultTos using the destination API. Creating 
> those endpoints in different ways is bad IMO.
> 
> Putting in decoupled destinations inside the Conduit also 
> makes it more complex for transport writers or people trying 
> to understand the API. IMO, people intuitively expect this to 
> be outside the Conduit class.
Given this explanation, I'm +1 on moving the decoupled distination set
up from the conduit. It seems cleaner if it is not part of the conduit.
What is the reason for placing the code in there in the first place? I'm
guessing there was a compelling reason and it would be good to make sure
we are not overiding a good decision for the sake of a clean API.
> 
> 5. Client Configuration
> I would propose that we make the decoupled destination 
> configuration part of the Client
> 
> <jaxws:client id="...SomePort">
>   <jaxws:asynchronousEndpoint>
>     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
>   </jaxws:asynchronousEndpoint>
> </jaxws:client>
> 
> <jaxws:client id="...SomePort">
> 
> <jaxws:asynchronousDestination><http:destination...></jaxws:as
> ynchronousDestination>
> </jaxws:client>
> 
> As an added bonus, we can now wire together clients and 
> destinations however we want. I wouldn't *have* to create a 
> <conduit> config element with the port name inside it. 
> Instead I could simply do:
> 
> <jaxws:client id="...SomePort">
>    <jaxws:conduit> <http:conduit... /> </jaxws:conduit> 
> </jaxws:client>
> 
> It also creates a central place to embed Client configuration 
> - such as enabling MTOM or configuring WS-*:
> <jaxws:client id="...SomePort">
>    <jaxws:conduit>...</jaxws:conduit>
>    <jaxws:binding mtomEnabled="true">
>      <jaxws:requestContext>
>        <map><entry key="javax.xml.ws.session.maintain" 
> value="true"/></map>
>      </jaxws:requestContext>
>    </jaxws:binding>
>    <jaxws:features>
>      <wsrm:reliability timeout="10000" .../>
>    </jaxws:features>
> </jaxws:client>
> 
> Users could still use the <http:conduit id="PORT"/> syntax if 
> they wanted to though.
> 
> (Note: I haven't written the jaxws:client Spring schema yet, 
> but its on my todo list. The feature stuff will hopefully be 
> part of my commit with
> WS-Security)


> 6. Bring back Destination.getDestination(EndpointReferenceType)
> This method would be needed for the API that I propose in #1.
> 
> 7. Make the JAX-WS dispatch use the client.
> 
> ----
> 
> In summary:
> a) This simplifies the API. We've created an API to set up 
> decoupled endpoints easily. We've reduced the complexity 
> inside Conduits and have avoided introducing new complexity 
> onto the Conduit interface to specify a decoupled destination.
> 
> b) It creates a consistent API for working with decoupled 
> endpoints. There is no reason to go writing a new API for 
> setting up decoupled endpoints - which is only used sometimes.
> 
> c) Dependency Injenction: By putting the Conduit & 
> Destination on the Client we've made it much friendlier to 
> people using Spring or other DI containers.
> 
> d) Improved configuration: I think the jaxws:client is a more 
> natural place to setup the conduit and destination 
> configuration as opposed to nesting the destination 
> configuration inside the conduit.
> 
> e) Setting up decoupled destinations is not the job of the 
> conduit IMO.
> We're giving Conduits a dual task unnecessarily. If all 
> Conduits share the same code for setting up decoupled 
> destinations, that is a sign to me that we can take it out of 
> the Conduit.
> 
> I of course would be volunteering to do all this work.
> --
> 
> Alternatives: While Eoghan can elaborate, I believe he would 
> rather see 1. The decoupled endpoint remain part of the 
> conduit. He views a decoupled endpoint as part of the Conduit 
> contract.
I'd like to hear a clear explanation of this point from Eoghan, or
someone else, before saying which was the best approach.
> 2. An API on the Conduit to set up the decoupled endpoint like so:
> Client.get(Conduit.class
> ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> 3. The Client.getConduit/setConduit methods go away and have 
> the Conduit be an optional part of the Client 4. No 
> Client.setAsynchronousDestination method.
> 5. Keep the decoupled endpoint configuration as part of the 
> conduit instead of the client.
> 
> Regards,
> - Dan
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com]
> Sent: 30 March 2007 15:33
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> On 3/30/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > > Sent: 30 March 2007 01:52
> > > To: cxf-dev@incubator.apache.org
> > > Subject: Re: [PROPOSAL] Client and Conduit changes
> > >
> > > On 3/29/07, Glynn, Eoghan <eo...@iona.com> wrote:
> > > >
> > > >
> > > >
> > > > > But where are you diverting it?
> > > >
> > > >
> > > > The diversion would be driven by an interceptor, to a target 
> > > > within the local process space.
> > > >
> > > >
> > > > > How do you want to divert?
> > > >
> > > >
> > > > By dynamically manipulating the trailing interceptor chain.
> > > >
> > > >
> > > > > Why?
> > > >
> > > >
> > > > To avoid unnecessary dispatch overhead where the target
> > > exists within
> > > > the client process space.
> > >
> > >
> > > Unnecessary dispatch overhead? By calling Conduit.open() and 
> > > close()? Are you just trying to avoid serialization?
> >
> >
> > Direct quote from my last mail ...
> >
> > 'The "its not really needed" case would occur when we detect during 
> > the dispatch that marshalling and transport involvement are
> not required.'
> 
> 
> 
> So clearly I'm not *just* talking about calls to Conduit.open() and
> > close() ...
> >
> > On an aside, an open() method doesn't exist in the Conduit
> API, but I
> > assume you mean here the ConduitInitiator.getConduit() call.
> 
> 
> Yes, my bad.
> 
> What I'm talking about is avoiding *any and all* overhead that would 
> be
> > unnecessary if the message is not leaving the current process space.
> > That overhead includes the getting the Conduit,
> 
> 
> Overhead in getting the Conduit happens only once at Client creation.

> And in the case of a local invocation it really results in just a call

> to new LocalConduit(), which I'm sure is not a bottleneck.
> 
> marshalling the message
> 
> 
> A Conduit doesn't imply marshalling. For instance, I've outlined how 
> we could use an ObjectBinding (which we'd want to write for either 
> case) with the local transport. Currently the local transport requires

> you write to the output stream, but this doesn't have to be so. I at 
> least fixed the input side so we can directly invoke a service, but 
> more changes are needed.
> 
> payload & headers,
> 
> 
> These are interceptors, and would be configured as part of the 
> binding. And hence in the local dispatch scenario they would not be 
> part of the Binding, and therefore would not be part of the 
> interceptor chain.
> 
> and possibly applying transformations such as
> > encryption or compression.
> 
> 
> These are up to the user to enable on their endpoint. I don't see why 
> these would be enabled if you're invoking a local endpoint.
> 
> This "overhead" that you're talking about seems completely unrelated 
> to the Conduit/Destination.


Sure, I get what the local transport does.

I'm talking about taking a different approach. That's allowed, right? 

The local transport implies, as I understand it, a "static replacement"
style of approach. So I specify a "local://" URI as the endpoint
address, or my application explicitly sets a LocalConduit instance on
the Client. Also I statically change my config or asserted polices to
exclude interceptors that apply transformations unecessary in the local
case, or change the interceptor impls to detect this case themselves.
Also I engage an ObjectBinding in some way. 

Now that's all very well. But a different idea would be to go more for
"adaptive diversion". 

Here the binding and interceptor chain would be set up exactly the same
way, regardless of whether the target is local or remote. Where the
target really is remote, then everything just works. If the target
happens to be instantiated within the local process space, then I want
to detect this and adapt accordingly, *without any static changes* (to
config, WSDL, policies, code, whatever). Then maybe the target migrates
to another container instance and everything reverts to work as before.

Now this sort of diverted dispatch is just one example where it would
make more sense to delay the Conduit retrieval. The same idea would
apply to any situation in which an interceptor may want to dynamically
re-route the message to a different target. 

CXF is intended to be a flexible framework. The user community is, or
hopefully will be, a broad church. So CXF will accommodate a diversity
of user-level approaches. Right?


> > *snip*
> > > >
> > > > And conversely, setting up the Conduit in the
> > > Client.invoke() is IMO
> > > > *too early* in general. We're only 100% sure we need a
> > > Conduit when we
> > > > get to a point in outbound interceptor chain that
> actually needs
> > > > to use a Conduit for something. This point is the 
> > > > MessageSenderInterceptor. So my proposal is to defer
> getting the
> > > > Conduit unless and until this point is reached.
> > >
> > >
> > > In general?
> >
> >
> > Yes, in general.
> >
> > In the sense that in many cases its OK to get the Conduit in 
> > Client.invoke(), but in other cases it doesn't make sense to do so.
> >
> > So in general its not the right thing to do.
> 
> 
> I don't see how that follows... In general it IS the right thing to do

> and in some use cases that you outline it may not be the right thing 
> to do. But I'm not convinced yet that we can't just create a conduit 
> in general and then not use it.


Lets not get bogged down in the semantics of the phrase "in general".
You obviously understand it to mean "in the usual case". Whereas I
intended to convey more the sense of "with full generality". An approach
does not have full generality if its appropriate for many scenarios, but
not appropriate for other (perhaps niche, but also valid) use-cases.

In any case, of course you can go away and create a conduit and then not
use it. But it's wasteful and unnecessarily constraining. So its clearly
not impossible to create an unused Conduit, just sub-optimal to do so.


> > > If we don't ultimately use this Conduit, this shouldn't be any 
> > > issue. Any resource intensive operations should be delayed until
> > > open() is called.
> >
> >
> > As it happens, that is the case with all our extant Conduit 
> > implementations.
> 
> 
> Now would be a good time to fix that.


I think you may have misunderstood me here. I'm saying all existing CXF
Conduit impls DO in fact delay the heavy-lifting until send() is called
(modulo config retrieval and lightweight tasks like URL creation).

So there's little to fix in that sense. 

My point was that we should not impose this
ConduitInitiator.getConduit() post-condition on all future transport
impls. It would be simpler and more robust for the runtime to just take
more care about when it calls getConduit().


> However, it may not be the case for all future Conduit 
> implementations,
> > and its certainly not part of the Conduit contract as-is.
> >
> > I could for example envisage a defensively-coded Conduit
> probing the
> > target upfront in its ctor so as to fail-fast if a
> connection would be
> > impossible to establish.
> 
> 
> This would be bad. What if the target doesn't exist yet because the 
> server isn't fully intialized. We shouldn't be checking for existance 
> until send() is actually called.
> 
> I can also envisage resources to be shared across Conduit instances
> > being set up in the initial ConduitInitiator.getConduit() call, as 
> > opposed to being deferred to the first Conduit.send().
> >
> > Of course we could spell out a requirement that a Conduit 
> > implementation doesn't do any heavy-lifting until the first send() 
> > occurs. But I could see potential transport authors thinking, why 
> > doesn't the CXF runtime just avoid making the
> > ConduitInitiator.getConduit() call if its not sure it needs
> the Conduit?
> 
> 
> Because we want to make ClientImpl.getConduit() available to people. 
> Seems like a simple enough reason to me.


So that the application can make direct programmatic configuration
changes to the Conduit? As opposed to driving this declaratively via the
Spring config or asserted (WS-)policies?

This sounds like a niche use-case, but in the spirit of accommodating
diversity, I think this style could be supported also. See below for a
specific proposal on how this could be achieved.


> Your arguments are often based on making life easier for potential
> > transport-writers.
> 
> 
> And transport users!
> 
> And here's a case where we can avoid imposing an
> > ambiguous post-condition on ConduitInitiator.getConduit(). By 
> > "ambiguous", I meaning adding javadoc like "don't do
> anything resource
> > intensive until Conduit.send() is called". Whether the transport 
> > author respects this is not verifiable (we're not coding in
> Eiffel),
> > also it could be open to mis-interpretation (e.g. would
> 'resource intensive'
> > include pulling in config values?).
> 
> 
> They can do some set up when the conduit is created. I don't think 
> transports will necessarily have that much over head providing they 
> aren't initializing connections. Since this only happens once when the

> Client is created it shouldn't be a big deal.
> 
> >
> > >
> > > My point is that a user should just be able to do
> > > client.getConduit() and change some transport settings. They 
> > > shouldn't have to explicitly create the Conduit though, which is 
> > > what your proposal does.
> > >
> > > What about just a ClientImpl.setInitializeConduit(false)?
> >
> >
> > That would be fine if the default for initializeConduit was
> false (as
> > I don't think the application should have to make an
> explicit API call
> > to get the correct, IMO, behavior).
> >
> > Also I guess you'd probably want to extend your <client>
> config bean
> > with an <initializeConduit> property (and similarly, I'd advocate 
> > false as the default value).
> 
> 
> I'm sorry, but I can't ever be +1 on this.  


Well a statement like that sortta makes any further discussion
pointless.

However my progress is blocked by this ... so to break the log-jam,
here's a proposal that will allow me the flexibility to do what I need
to do, while allowing you to keep your up-front creation of the Conduit
in the Client. 

So we apply the "strategy pattern" and allow for a configurable
ConduitInitiationStrategy to be used by the Client. This defaults to an
"eager upfront retrieval" strategy. And it allows me to plug in my
"deferred on-demand retrieval" strategy. Even in the on-demand case,
your Client.getConduit() API could force the retreival of the conduit.

So everyone's happy :)

Or?


> We need to have
> the Conduit created on the Client for the user by default.
>
>
> > > Yeah, but they're still going to look at the Conduit
> interface and
> > > wonder about what that method is. And on the other side
> of things,
> > > as a user of the Conduit interface you still need to understand 
> > > Conduit.getBackChannel(). And then if we don't go down
> the route of
> > > removing decoupled destinations from the Conduit, they'll
> also have
> > > to understand the ConduitPolicy interface.
> > >
> > > Do you see my point now?
> >
> >
> > I suppose it just doesn't seem like that big an issue to me, 
> > especially if we make it clear in the javadoc that getBackChannel() 
> > only needs to be overridden in very specific circumstances.
> >
> > Similarly, the transport-writer doesn't really have to
> worry about the
> > mechanics of the ConduitPolicy. Beyond knowing that it factors out 
> > some commonality, and they should extend in their config
> schema *if*
> > they need transport-specific conduit config.
> 
> 
> You're the one who wrote it though, so of course it makes sense :-). 
> There have been several other people though have noted that it is 
> overly complex, and I think we need to listen to them.
> 
> - Dan
> 
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/30/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > Sent: 30 March 2007 01:52
> > To: cxf-dev@incubator.apache.org
> > Subject: Re: [PROPOSAL] Client and Conduit changes
> >
> > On 3/29/07, Glynn, Eoghan <eo...@iona.com> wrote:
> > >
> > >
> > >
> > > > But where are you diverting it?
> > >
> > >
> > > The diversion would be driven by an interceptor, to a target within
> > > the local process space.
> > >
> > >
> > > > How do you want to divert?
> > >
> > >
> > > By dynamically manipulating the trailing interceptor chain.
> > >
> > >
> > > > Why?
> > >
> > >
> > > To avoid unnecessary dispatch overhead where the target
> > exists within
> > > the client process space.
> >
> >
> > Unnecessary dispatch overhead? By calling Conduit.open() and
> > close()? Are you just trying to avoid serialization?
>
>
> Direct quote from my last mail ...
>
> 'The "its not really needed" case would occur when we detect during the
> dispatch that marshalling and transport involvement are not required.'



So clearly I'm not *just* talking about calls to Conduit.open() and
> close() ...
>
> On an aside, an open() method doesn't exist in the Conduit API, but I
> assume you mean here the ConduitInitiator.getConduit() call.


Yes, my bad.

What I'm talking about is avoiding *any and all* overhead that would be
> unnecessary if the message is not leaving the current process space.
> That overhead includes the getting the Conduit,


Overhead in getting the Conduit happens only once at Client creation.  And
in the case of a local invocation it really results in just a call to new
LocalConduit(), which I'm sure is not a bottleneck.

marshalling the message


A Conduit doesn't imply marshalling. For instance, I've outlined how we
could use an ObjectBinding (which we'd want to write for either case) with
the local transport. Currently the local transport requires you write to the
output stream, but this doesn't have to be so. I at least fixed the input
side so we can directly invoke a service, but more changes are needed.

payload & headers,


These are interceptors, and would be configured as part of the binding. And
hence in the local dispatch scenario they would not be part of the Binding,
and therefore would not be part of the interceptor chain.

and possibly applying transformations such as
> encryption or compression.


These are up to the user to enable on their endpoint. I don't see why these
would be enabled if you're invoking a local endpoint.

This "overhead" that you're talking about seems completely unrelated to the
Conduit/Destination.

> *snip*
> > >
> > > And conversely, setting up the Conduit in the
> > Client.invoke() is IMO
> > > *too early* in general. We're only 100% sure we need a
> > Conduit when we
> > > get to a point in outbound interceptor chain that actually needs to
> > > use a Conduit for something. This point is the
> > > MessageSenderInterceptor. So my proposal is to defer getting the
> > > Conduit unless and until this point is reached.
> >
> >
> > In general?
>
>
> Yes, in general.
>
> In the sense that in many cases its OK to get the Conduit in
> Client.invoke(), but in other cases it doesn't make sense to do so.
>
> So in general its not the right thing to do.


I don't see how that follows... In general it IS the right thing to do and
in some use cases that you outline it may not be the right thing to do. But
I'm not convinced yet that we can't just create a conduit in general and
then not use it.


> > If we don't ultimately use this Conduit, this shouldn't be
> > any issue. Any resource intensive operations should be
> > delayed until open() is called.
>
>
> As it happens, that is the case with all our extant Conduit
> implementations.


Now would be a good time to fix that.

However, it may not be the case for all future Conduit implementations,
> and its certainly not part of the Conduit contract as-is.
>
> I could for example envisage a defensively-coded Conduit probing the
> target upfront in its ctor so as to fail-fast if a connection would be
> impossible to establish.


This would be bad. What if the target doesn't exist yet because the server
isn't fully intialized. We shouldn't be checking for existance until send()
is actually called.

I can also envisage resources to be shared across Conduit instances
> being set up in the initial ConduitInitiator.getConduit() call, as
> opposed to being deferred to the first Conduit.send().
>
> Of course we could spell out a requirement that a Conduit implementation
> doesn't do any heavy-lifting until the first send() occurs. But I could
> see potential transport authors thinking, why doesn't the CXF runtime
> just avoid making the ConduitInitiator.getConduit() call if its not sure
> it needs the Conduit?


Because we want to make ClientImpl.getConduit() available to people. Seems
like a simple enough reason to me.

Your arguments are often based on making life easier for potential
> transport-writers.


And transport users!

And here's a case where we can avoid imposing an
> ambiguous post-condition on ConduitInitiator.getConduit(). By
> "ambiguous", I meaning adding javadoc like "don't do anything resource
> intensive until Conduit.send() is called". Whether the transport author
> respects this is not verifiable (we're not coding in Eiffel), also it
> could be open to mis-interpretation (e.g. would 'resource intensive'
> include pulling in config values?).


They can do some set up when the conduit is created. I don't think
transports will necessarily have that much over head providing they aren't
initializing connections. Since this only happens once when the Client is
created it shouldn't be a big deal.

>
> >
> > My point is that a user should just be able to do
> > client.getConduit() and change some transport settings. They
> > shouldn't have to explicitly create the Conduit though, which
> > is what your proposal does.
> >
> > What about just a ClientImpl.setInitializeConduit(false)?
>
>
> That would be fine if the default for initializeConduit was false (as I
> don't think the application should have to make an explicit API call to
> get the correct, IMO, behavior).
>
> Also I guess you'd probably want to extend your <client> config bean
> with an <initializeConduit> property (and similarly, I'd advocate false
> as the default value).


I'm sorry, but I can't ever be +1 on this.  We need to have the Conduit
created on the Client for the user by default.

> >
> > Yeah, but they're still going to look at the Conduit
> > interface and wonder about what that method is. And on the
> > other side of things, as a user of the Conduit interface you
> > still need to understand Conduit.getBackChannel(). And then
> > if we don't go down the route of removing decoupled
> > destinations from the Conduit, they'll also have to
> > understand the ConduitPolicy interface.
> >
> > Do you see my point now?
>
>
> I suppose it just doesn't seem like that big an issue to me, especially
> if we make it clear in the javadoc that getBackChannel() only needs to
> be overridden in very specific circumstances.
>
> Similarly, the transport-writer doesn't really have to worry about the
> mechanics of the ConduitPolicy. Beyond knowing that it factors out some
> commonality, and they should extend in their config schema *if* they
> need transport-specific conduit config.


You're the one who wrote it though, so of course it makes sense :-). There
have been several other people though have noted that it is overly complex,
and I think we need to listen to them.

- Dan


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 30 March 2007 01:52
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> On 3/29/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> >
> > > But where are you diverting it?
> >
> >
> > The diversion would be driven by an interceptor, to a target within 
> > the local process space.
> >
> >
> > > How do you want to divert?
> >
> >
> > By dynamically manipulating the trailing interceptor chain.
> >
> >
> > > Why?
> >
> >
> > To avoid unnecessary dispatch overhead where the target 
> exists within 
> > the client process space.
> 
> 
> Unnecessary dispatch overhead? By calling Conduit.open() and 
> close()? Are you just trying to avoid serialization?


Direct quote from my last mail ...

'The "its not really needed" case would occur when we detect during the
dispatch that marshalling and transport involvement are not required.'

So clearly I'm not *just* talking about calls to Conduit.open() and
close() ... 

On an aside, an open() method doesn't exist in the Conduit API, but I
assume you mean here the ConduitInitiator.getConduit() call.

What I'm talking about is avoiding *any and all* overhead that would be
unnecessary if the message is not leaving the current process space.
That overhead includes the getting the Conduit, marshalling the message
payload & headers, and possibly applying transformations such as
encryption or compression.

Now originally you stated a strong objection to just-in-time retrieval
of the Conduit. You then asked for my use-cases. Which I described
briefly. You asked for more detail. Which I provided. 

So can we now steer the discussion onto the substantive point of whether
it's a good idea to defer the Conduit retrieval until we know its
actually needed?


> *snip*
> >
> > And conversely, setting up the Conduit in the 
> Client.invoke() is IMO 
> > *too early* in general. We're only 100% sure we need a 
> Conduit when we 
> > get to a point in outbound interceptor chain that actually needs to 
> > use a Conduit for something. This point is the 
> > MessageSenderInterceptor. So my proposal is to defer getting the 
> > Conduit unless and until this point is reached.
> 
> 
> In general? 


Yes, in general. 

In the sense that in many cases its OK to get the Conduit in
Client.invoke(), but in other cases it doesn't make sense to do so.

So in general its not the right thing to do.


> In retrieving a Conduit inside the Client creates 
> no problems.


Other than wasted effort, and possibly a premature failure (depending on
how the ConduitInitiator.getConduit() is implemented).


> If we don't ultimately use this Conduit, this shouldn't be 
> any issue. Any resource intensive operations should be 
> delayed until open() is called.


As it happens, that is the case with all our extant Conduit
implementations.

However, it may not be the case for all future Conduit implementations,
and its certainly not part of the Conduit contract as-is.

I could for example envisage a defensively-coded Conduit probing the
target upfront in its ctor so as to fail-fast if a connection would be
impossible to establish. 

I can also envisage resources to be shared across Conduit instances
being set up in the initial ConduitInitiator.getConduit() call, as
opposed to being deferred to the first Conduit.send().

Of course we could spell out a requirement that a Conduit implementation
doesn't do any heavy-lifting until the first send() occurs. But I could
see potential transport authors thinking, why doesn't the CXF runtime
just avoid making the ConduitInitiator.getConduit() call if its not sure
it needs the Conduit? 

Your arguments are often based on making life easier for potential
transport-writers. And here's a case where we can avoid imposing an
ambiguous post-condition on ConduitInitiator.getConduit(). By
"ambiguous", I meaning adding javadoc like "don't do anything resource
intensive until Conduit.send() is called". Whether the transport author
respects this is not verifiable (we're not coding in Eiffel), also it
could be open to mis-interpretation (e.g. would 'resource intensive'
include pulling in config values?).

 
> Call it just-in-time Conduit retrieval. And as with any just-in-time
> > strategy, the pay-off is in avoiding wasted effort when it 
> turns out 
> > that its not really needed, or something else is needed instead.
> >
> > The "its not really needed" case would occur when we detect 
> during the 
> > dispatch that marshalling and transport involvement are not 
> required.
> >
> > The "something else needed instead" case could occur in your "route 
> > inside the interceptor chain" example above.
> >
> > But I wouldn't necessarily preclude upfront setting up of 
> the Conduit 
> > in the Client in the non-default case. For example your convenience
> > Client.setConduit() API to allow the application to easily 
> over-ride 
> > the Conduit for some reason. So retrieval of the Conduit in the 
> > MessageSenderInterceptor could be contingent on a specific 
> Conduit not 
> > having being overridden via the Client. Would that make it more 
> > acceptable to you?
> 
> 
> My point is that a user should just be able to do 
> client.getConduit() and change some transport settings. They 
> shouldn't have to explicitly create the Conduit though, which 
> is what your proposal does.
> 
> What about just a ClientImpl.setInitializeConduit(false)?


That would be fine if the default for initializeConduit was false (as I
don't think the application should have to make an explicit API call to
get the correct, IMO, behavior).

Also I guess you'd probably want to extend your <client> config bean
with an <initializeConduit> property (and similarly, I'd advocate false
as the default value).


> > Once again, what are your use cases here? Please supply some
> > > specific scenarios which require the removal of a Conduit.
> >
> >
> > I have two specific use-cases in my mind, which I labeled 
> (a) and (b) 
> > in my last mail.
> >
> > I've already expanded on (a) above. Is that clear now?
> >
> > Case (b) is where I want to be able to dynamically switch to a 
> > different Conduit from within the interceptor chain. Among 
> many other 
> > potential uses, this would facilitate late-binding to one 
> of a cluster 
> > of target endpoints.
> >
> > > >
> > > > No XML configuration is needed? So you're proposing a 
> > > > (client-less,
> > > > HTTP-based) application must hard-code the DRE address?
> > > >
> > > > What happens if I reorganize by domains? Or my DHCP lease
> > > expires? Or
> > > > I'm assigned a new port range? Or I discover a port clash with 
> > > > some other piece of software? Or my firewall config is changed?
> > > Or the NATS
> > > > setup is changed? Or I want to provision the client app 
> to 100s or 
> > > > 1000s of different hosts without recompiling for each? Or
> > > the client
> > > > app is migrated to a new host? Or the server app is
> > > migrated off-host
> > > > so that a localhost-based DRE no longer works?
> > >
> > >
> > > I see what your saying, but...
> > >
> > > They can just put it in their application configuration. 
> If they're 
> > > already working with CXF they probably have their own 
> configuration 
> > > which will drive their application - whether its UI or 
> database or 
> > > Spring based.
> >
> >
> > Finally, we're on the same page :)
> >
> > That's been my whole "undue burden on client-less 
> applications" point 
> > all along.
> >
> > Under your proposal we'd be giving such applications extra 
> work to do 
> > ... work that is currently handled on its behalf via the 
> Conduit config.
> >
> > Now if the application already has a config mechanism (UI 
> or database 
> > or Spring based as you say), then extending this with a new 
> DRE config 
> > item may not be a huge task.
> >
> > On the other hand however, the application may currently work 
> > perfectly fine without any application-specific config at 
> all, or the 
> > config/DB/UI/whatever may be difficult to change.
> >
> > So you do see now why I think your proposal would impose an extra 
> > burden on such applications?
> 
> 
> Sure, but see my previous message for why this isn't really a 
> big a deal as you make it out to be.
> 
> > Also, the number of people attempting to understand the
> > > transport API or write transports will be much greater than those 
> > > trying to write decoupled applications without the 
> Client. Sure, I 
> > > have no statistics to back that up, but I do have a fair 
> amount of 
> > > experience in the area. Most people won't even setup a decoupled 
> > > endpoint. And the majority of people who do use decoupled 
> endpoints 
> > > will use the Client.
> > >
> > > I would definitely wager a large sum of money that there are more 
> > > people trying to grok or write transports than those writing 
> > > decoupled applications without a Client. By an order of 
> magnitude at 
> > > least. So I have yet to see why this argument should 
> carry that much 
> > > weight.
> > >
> > >
> > > > >
> > > > > When you use the Client, yes, the Client adds some 
> convenience 
> > > > > wrapper methods. When you don't use the Client, you
> > > always use the
> > > > > destination apis to set up the decoupled endpoint.
> > > >
> > > >
> > > > OK, can we be 100% clear here. What exactly are these 
> convenience 
> > > > wrapper methods?
> > > >
> > > > Are you proposing new APIs on Client such as
> > > setFaultToEndpoint() and
> > > > setAcksTo()?
> > >
> > >
> > > No, just the
> > > setAsyncrhronousDestination/setAsyncryhronousEndpoint in 
> my original 
> > > proposal.
> >
> >
> > Great, we've established that.
> >
> > So how would your proposed mechanism be any more consistent when it 
> > comes to setting the faultTo and/or acksTo versus the replyTo?
> >
> > In *both* the current scenario and in your prospoal, a *different* 
> > mechanism is used to set faultTo and/or acksTo versus the replyTo.
> >
> > Hence, both approaches are equally inconsistent on this point.
> >
> > Which is fine by me, as I've argued before that only the replyTo is 
> > canonical.
> 
> 
> I see what you're saying, and if you're comparing the Client 
> to the Conduit, then thats true. But I'm specifically talking 
> about the use case where people are just working with the 
> transport APIs and not the Client. At a transport level, this 
> would give a consistent way to do things. I.e. if I'm just 
> using the Conduit and Destination APIs, there would be a 
> consistent API for setting up decoupled endpoints.
>
>
> > > To understand AbstractConduit you still need to 
> understand Conduit.
> >
> >
> > Have you got that backwards, i.e. to understand Conduit you 
> still need 
> > to understand AbstractConduit?
> 
> 
> If so, I don't think this is necessarily true. One purpose of an
> > abstract base classes is encapsulation of complexity. That is, a 
> > writer of a sub-class doesn't have to be familiar with the 
> > implementation of the super-class, just the contract between them 
> > (i.e. the stuff that's protected and/or abstract in Java terms).
> >
> > For example a trivial implementation of Conduit.getBackChannel() 
> > currently lives in AbstractConduit. This allows someone 
> writing a new 
> > non-decoupled transport to completely ignore the decoupled 
> backchannel 
> > concept.
> >
> 
> Now supposing we go a bit further and add code to the AbstractConduit
> > that creates the DRE (via the DestinationFactory) if a new abstract 
> > ConduitPolicy is configured appropriately.
> >
> > Then someone writing a transport that *does* have a concept of 
> > decoupled back channel, which can set up solely on the basis of an 
> > EPR, also has no extra work to do. That is, they also can just 
> > completely ignore the decoupled backchannel concept.
> 
> 
> Yeah, but they're still going to look at the Conduit 
> interface and wonder about what that method is. And on the 
> other side of things, as a user of the Conduit interface you 
> still need to understand Conduit.getBackChannel(). And then 
> if we don't go down the route of removing decoupled 
> destinations from the Conduit, they'll also have to 
> understand the ConduitPolicy interface.
> 
> Do you see my point now?


I suppose it just doesn't seem like that big an issue to me, especially
if we make it clear in the javadoc that getBackChannel() only needs to
be overridden in very specific circumstances.

Similarly, the transport-writer doesn't really have to worry about the
mechanics of the ConduitPolicy. Beyond knowing that it factors out some
commonality, and they should extend in their config schema *if* they
need transport-specific conduit config.

Cheers,
Eoghan



Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/29/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
>
> > But where are you diverting it?
>
>
> The diversion would be driven by an interceptor, to a target within the
> local process space.
>
>
> > How do you want to divert?
>
>
> By dynamically manipulating the trailing interceptor chain.
>
>
> > Why?
>
>
> To avoid unnecessary dispatch overhead where the target exists within
> the client process space.


Unnecessary dispatch overhead? By calling Conduit.open() and close()? Are
you just trying to avoid serialization?

*snip*
>
> And conversely, setting up the Conduit in the Client.invoke() is IMO
> *too early* in general. We're only 100% sure we need a Conduit when we
> get to a point in outbound interceptor chain that actually needs to use
> a Conduit for something. This point is the MessageSenderInterceptor. So
> my proposal is to defer getting the Conduit unless and until this point
> is reached.


In general? In retrieving a Conduit inside the Client creates no problems.
If we don't ultimately use this Conduit, this shouldn't be any issue. Any
resource intensive operations should be delayed until open() is called.

Call it just-in-time Conduit retrieval. And as with any just-in-time
> strategy, the pay-off is in avoiding wasted effort when it turns out
> that its not really needed, or something else is needed instead.
>
> The "its not really needed" case would occur when we detect during the
> dispatch that marshalling and transport involvement are not required.
>
> The "something else needed instead" case could occur in your "route
> inside the interceptor chain" example above.
>
> But I wouldn't necessarily preclude upfront setting up of the Conduit in
> the Client in the non-default case. For example your convenience
> Client.setConduit() API to allow the application to easily over-ride the
> Conduit for some reason. So retrieval of the Conduit in the
> MessageSenderInterceptor could be contingent on a specific Conduit not
> having being overridden via the Client. Would that make it more
> acceptable to you?


My point is that a user should just be able to do client.getConduit() and
change some transport settings. They shouldn't have to explicitly create the
Conduit though, which is what your proposal does.

What about just a ClientImpl.setInitializeConduit(false)?

> Once again, what are your use cases here? Please supply some
> > specific scenarios which require the removal of a Conduit.
>
>
> I have two specific use-cases in my mind, which I labeled (a) and (b) in
> my last mail.
>
> I've already expanded on (a) above. Is that clear now?
>
> Case (b) is where I want to be able to dynamically switch to a different
> Conduit from within the interceptor chain. Among many other potential
> uses, this would facilitate late-binding to one of a cluster of target
> endpoints.
>
> > >
> > > No XML configuration is needed? So you're proposing a (client-less,
> > > HTTP-based) application must hard-code the DRE address?
> > >
> > > What happens if I reorganize by domains? Or my DHCP lease
> > expires? Or
> > > I'm assigned a new port range? Or I discover a port clash with some
> > > other piece of software? Or my firewall config is changed?
> > Or the NATS
> > > setup is changed? Or I want to provision the client app to 100s or
> > > 1000s of different hosts without recompiling for each? Or
> > the client
> > > app is migrated to a new host? Or the server app is
> > migrated off-host
> > > so that a localhost-based DRE no longer works?
> >
> >
> > I see what your saying, but...
> >
> > They can just put it in their application configuration. If
> > they're already working with CXF they probably have their own
> > configuration which will drive their application - whether
> > its UI or database or Spring based.
>
>
> Finally, we're on the same page :)
>
> That's been my whole "undue burden on client-less applications" point
> all along.
>
> Under your proposal we'd be giving such applications extra work to do
> ... work that is currently handled on its behalf via the Conduit config.
>
> Now if the application already has a config mechanism (UI or database or
> Spring based as you say), then extending this with a new DRE config item
> may not be a huge task.
>
> On the other hand however, the application may currently work perfectly
> fine without any application-specific config at all, or the
> config/DB/UI/whatever may be difficult to change.
>
> So you do see now why I think your proposal would impose an extra burden
> on such applications?


Sure, but see my previous message for why this isn't really a big a deal as
you make it out to be.

> Also, the number of people attempting to understand the
> > transport API or write transports will be much greater than
> > those trying to write decoupled applications without the
> > Client. Sure, I have no statistics to back that up, but I do
> > have a fair amount of experience in the area. Most people
> > won't even setup a decoupled endpoint. And the majority of
> > people who do use decoupled endpoints will use the Client.
> >
> > I would definitely wager a large sum of money that there are
> > more people trying to grok or write transports than those
> > writing decoupled applications without a Client. By an order
> > of magnitude at least. So I have yet to see why this argument
> > should carry that much weight.
> >
> >
> > > >
> > > > When you use the Client, yes, the Client adds some convenience
> > > > wrapper methods. When you don't use the Client, you
> > always use the
> > > > destination apis to set up the decoupled endpoint.
> > >
> > >
> > > OK, can we be 100% clear here. What exactly are these convenience
> > > wrapper methods?
> > >
> > > Are you proposing new APIs on Client such as
> > setFaultToEndpoint() and
> > > setAcksTo()?
> >
> >
> > No, just the
> > setAsyncrhronousDestination/setAsyncryhronousEndpoint in my
> > original proposal.
>
>
> Great, we've established that.
>
> So how would your proposed mechanism be any more consistent when it
> comes to setting the faultTo and/or acksTo versus the replyTo?
>
> In *both* the current scenario and in your prospoal, a *different*
> mechanism is used to set faultTo and/or acksTo versus the replyTo.
>
> Hence, both approaches are equally inconsistent on this point.
>
> Which is fine by me, as I've argued before that only the replyTo is
> canonical.


I see what you're saying, and if you're comparing the Client to the Conduit,
then thats true. But I'm specifically talking about the use case where
people are just working with the transport APIs and not the Client. At a
transport level, this would give a consistent way to do things. I.e. if I'm
just using the Conduit and Destination APIs, there would be a consistent API
for setting up decoupled endpoints.


>
>
> > To understand AbstractConduit you still need to understand Conduit.
>
>
> Have you got that backwards, i.e. to understand Conduit you still need
> to understand AbstractConduit?


If so, I don't think this is necessarily true. One purpose of an
> abstract base classes is encapsulation of complexity. That is, a writer
> of a sub-class doesn't have to be familiar with the implementation of
> the super-class, just the contract between them (i.e. the stuff that's
> protected and/or abstract in Java terms).
>
> For example a trivial implementation of Conduit.getBackChannel()
> currently lives in AbstractConduit. This allows someone writing a new
> non-decoupled transport to completely ignore the decoupled backchannel
> concept.
>

Now supposing we go a bit further and add code to the AbstractConduit
> that creates the DRE (via the DestinationFactory) if a new abstract
> ConduitPolicy is configured appropriately.
>
> Then someone writing a transport that *does* have a concept of decoupled
> back channel, which can set up solely on the basis of an EPR, also has
> no extra work to do. That is, they also can just completely ignore the
> decoupled backchannel concept.


Yeah, but they're still going to look at the Conduit interface and wonder
about what that method is. And on the other side of things, as a user of the
Conduit interface you still need to understand Conduit.getBackChannel(). And
then if we don't go down the route of removing decoupled destinations from
the Conduit, they'll also have to understand the ConduitPolicy interface.

Do you see my point now?
.

- Dan


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 28 March 2007 18:39
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> On 3/28/07, Glynn, Eoghan <eo...@iona.com> wrote:
> 
> >
> > What do you mean by an "abstraction with boundaries of Conduits and 
> > Destinations"?
> >
> > Are the boundaries of which you speak:
> >
> > (a) the Conduit and Destination APIs
> > (b) the lifecycle of, and referers to, the Conduit and Destination 
> > instances
> > (c) something else?
> >
> > As far as I can see, we're *both* proposing changes that would fall 
> > mainly under category (b).
> >
> > Currently the Conduit lifecycle is managed by the Client. 
> And the DRE 
> > lifecycle is managed by the Conduit.
> >
> > You want to change things so that DRE is also managed by the Client.
> > Correct?
> >
> > I want to change things so that neither is managed by the Client.
> >
> > So I think it would be fair to say that we *both* see a 
> reason to go 
> > changing things. Just different things. Or?
> 
> 
> Sure, but its hard for me to know what is motivating your 
> proposal if you do come up with some specific use cases. I'm 
> glad to see that you daded a couple below.


I've expanded below on my (initially perhaps over-terse :) descriptions
of the use cases I've in mind.


> > I don't really see any reason to go changing this.
> >
> > See above.
> >
> > And here's a specific reason ...
> >
> > Having the Client create a Conduit before its actually 
> definite that a 
> > Conduit is required makes it awkward for an interceptor in the 
> > outbound chain to:
> >
> > (a) divert the message in such a way that doesn't require a 
> Conduit at 
> > all
> 
> 
> I have no idea what you're getting at here. Can you please 
> give a use case?


Yes, see below.


> That statement is kind of circular... of course if a conduit 
> is required, you won't be able to divert a message in a way 
> that doesn't require a conduit. 


Just as an aside, I don't agree that my statement was in the least
circular. I'm talking about the case where a Conduit *isn't* required.
But either way, lets not get bogged down on a tangent :)


> But where are you diverting it? 


The diversion would be driven by an interceptor, to a target within the
local process space.


> How do you want to divert?


By dynamically manipulating the trailing interceptor chain.


> Why?


To avoid unnecessary dispatch overhead where the target exists within
the client process space.


> (b) divert the message to a different endpoint, that maybe 
> necessitates
> > a different Conduit instance to the one selected up front by the 
> > Client
> 
> 
> This is where I was going with the Camel example... We could 
> send a message off to camel (or any other routing thingy - 
> synapse or mule might be options for people too). Or if we 
> want to route inside the interceptor chain we can select a 
> new Conduit in any interceptor. Then the 
> MessageSenderInterceptor can use this new Conduit. If you're 
> tyring to change the destination after the 
> messagesenderinterceptor - i.e. mid serialization, I don't 
> think thats very feasible for most bindings/messages.


Sure.

My point all along has been that MessageSenderInterceptor is the place
where we should be retrieving the Conduit. See [1], paragraph beginning:
"I'm thinking we may not even need a Conduit instance at all when
mediating an invocation ...".

I totally agree that it would be *too late* to try to switch Conduits at
a later point in the dispatch, in mid-serialization as you correctly put
it.

And conversely, setting up the Conduit in the Client.invoke() is IMO
*too early* in general. We're only 100% sure we need a Conduit when we
get to a point in outbound interceptor chain that actually needs to use
a Conduit for something. This point is the MessageSenderInterceptor. So
my proposal is to defer getting the Conduit unless and until this point
is reached. 

Call it just-in-time Conduit retrieval. And as with any just-in-time
strategy, the pay-off is in avoiding wasted effort when it turns out
that its not really needed, or something else is needed instead. 

The "its not really needed" case would occur when we detect during the
dispatch that marshalling and transport involvement are not required. 

The "something else needed instead" case could occur in your "route
inside the interceptor chain" example above.

But I wouldn't necessarily preclude upfront setting up of the Conduit in
the Client in the non-default case. For example your convenience
Client.setConduit() API to allow the application to easily over-ride the
Conduit for some reason. So retrieval of the Conduit in the
MessageSenderInterceptor could be contingent on a specific Conduit not
having being overridden via the Client. Would that make it more
acceptable to you?

 
> Once again, what are your use cases here? Please supply some 
> specific scenarios which require the removal of a Conduit.


I have two specific use-cases in my mind, which I labeled (a) and (b) in
my last mail.

I've already expanded on (a) above. Is that clear now?

Case (b) is where I want to be able to dynamically switch to a different
Conduit from within the interceptor chain. Among many other potential
uses, this would facilitate late-binding to one of a cluster of target
endpoints.

 
> > For instance, I've been talking to James Strachan about using
> > > Camel a bit.
> > > Camel can do a bit of routing of CXF messages. On the 
> Client side of 
> > > things, we should be able to send a message in and then get the 
> > > response some time later from Camel (if there is a response). The 
> > > idea is that it can work on whatever the representation - pojos, 
> > > xml, bytes, etc. The boundary into this system from the client 
> > > perspective would still be a transport. Camel can just add a 
> > > MessageObserver on a local:// destination. How the message comes 
> > > into Camel then becomes a matter of the Binding.  For the 
> POJO case, 
> > > I'd like to create an ObjectBinding which doesn't do any 
> > > serialization. It'd also be nice to have a flag so the 
> SOAP binding 
> > > produce a Source object ultimately.
> >
> >
> > Sorry I don't really see the relevance of this to the current 
> > discussion.
> >
> > Maybe I'm just being slow today :)
> >
> > Can you explain why the Camel requirement necessitates the type of 
> > changes you're proposing?
> 
> 
> I was simply talking about how mediation would be possible 
> with Camel as you had stated that one of the requirements for 
> mediation was the removal of the Conduit from the Client 
> class. The example was to show that removing the Conduit is 
> not necessariliy required.
> 
> >
> > > Lets compare the two cases of setting up a decoupled 
> endpoint from 
> > > an XML configuration perspective.
> > >
> > > Case 1: now
> > >
> > >
> > >     <http:conduit id="{
> > > http://cxf.apache.org/greeter_control}GreeterPort.http-conduit">
> > >       <http:client DecoupledEndpoint="
> > > http://localhost:9995/decoupled_endpoint"/>
> > >     </http:conduit>
> > >
> > > Case 2:My Proposal
> > > 2a) No Client: No XML configuration is needed, unless 
> you're using 
> > > JMS.
> >
> >
> > No XML configuration is needed? So you're proposing a (client-less,
> > HTTP-based) application must hard-code the DRE address?
> >
> > What happens if I reorganize by domains? Or my DHCP lease 
> expires? Or 
> > I'm assigned a new port range? Or I discover a port clash with some 
> > other piece of software? Or my firewall config is changed? 
> Or the NATS 
> > setup is changed? Or I want to provision the client app to 100s or 
> > 1000s of different hosts without recompiling for each? Or 
> the client 
> > app is migrated to a new host? Or the server app is 
> migrated off-host 
> > so that a localhost-based DRE no longer works?
> 
> 
> I see what your saying, but...
> 
> They can just put it in their application configuration. If 
> they're already working with CXF they probably have their own 
> configuration which will drive their application - whether 
> its UI or database or Spring based.


Finally, we're on the same page :)

That's been my whole "undue burden on client-less applications" point
all along.

Under your proposal we'd be giving such applications extra work to do
... work that is currently handled on its behalf via the Conduit config.

Now if the application already has a config mechanism (UI or database or
Spring based as you say), then extending this with a new DRE config item
may not be a huge task. 

On the other hand however, the application may currently work perfectly
fine without any application-specific config at all, or the
config/DB/UI/whatever may be difficult to change.

So you do see now why I think your proposal would impose an extra burden
on such applications?

 
> Also, the number of people attempting to understand the 
> transport API or write transports will be much greater than 
> those trying to write decoupled applications without the 
> Client. Sure, I have no statistics to back that up, but I do 
> have a fair amount of experience in the area. Most people 
> won't even setup a decoupled endpoint. And the majority of 
> people who do use decoupled endpoints will use the Client.
> 
> I would definitely wager a large sum of money that there are 
> more people trying to grok or write transports than those 
> writing decoupled applications without a Client. By an order 
> of magnitude at least. So I have yet to see why this argument 
> should carry that much weight.
> 
> 
> > >
> > > When you use the Client, yes, the Client adds some convenience 
> > > wrapper methods. When you don't use the Client, you 
> always use the 
> > > destination apis to set up the decoupled endpoint.
> >
> >
> > OK, can we be 100% clear here. What exactly are these convenience
> > wrapper methods?
> >
> > Are you proposing new APIs on Client such as 
> setFaultToEndpoint() and
> > setAcksTo()?
> 
> 
> No, just the 
> setAsyncrhronousDestination/setAsyncryhronousEndpoint in my
> original proposal.


Great, we've established that.

So how would your proposed mechanism be any more consistent when it
comes to setting the faultTo and/or acksTo versus the replyTo?

In *both* the current scenario and in your prospoal, a *different*
mechanism is used to set faultTo and/or acksTo versus the replyTo.

Hence, both approaches are equally inconsistent on this point.

Which is fine by me, as I've argued before that only the replyTo is
canonical.

 
> > > Is introducing an abstract ConduitPolicy really that big an issue?
> > >
> > >
> > > YES! We've already created very complex APIs for transports.
> > > Its time to simplify.
> >
> >
> > But the complexity you take away with one hand, you add 
> back with the
> > other ... i.e. you're proposing adding a bunch of complexity to the
> > Client.
> >
> > Now I'd anticipate your counter-argument as something like 
> ... yes but
> > we want developers to write their own transports, not their 
> own clients.
> > Fair enough, but I'm saying that transport-writers need not 
> be concerned
> > with handling the DRE logic if its factored out to the 
> AbstractConduit.
> 
> 
> You're completely missing the point. The point is that the 
> whole CONCEPT of
> Conduits and Destinations are overly complex. 


I suppose where I'm coming from is that there are different ways of
mitigating/hiding that complexity.


> To understand AbstractConduit you still need to understand Conduit.


Have you got that backwards, i.e. to understand Conduit you still need
to understand AbstractConduit?

If so, I don't think this is necessarily true. One purpose of an
abstract base classes is encapsulation of complexity. That is, a writer
of a sub-class doesn't have to be familiar with the implementation of
the super-class, just the contract between them (i.e. the stuff that's
protected and/or abstract in Java terms).

For example a trivial implementation of Conduit.getBackChannel()
currently lives in AbstractConduit. This allows someone writing a new
non-decoupled transport to completely ignore the decoupled backchannel
concept.

Now supposing we go a bit further and add code to the AbstractConduit
that creates the DRE (via the DestinationFactory) if a new abstract
ConduitPolicy is configured appropriately.

Then someone writing a transport that *does* have a concept of decoupled
back channel, which can set up solely on the basis of an EPR, also has
no extra work to do. That is, they also can just completely ignore the
decoupled backchannel concept.


> So AbstractConduit doesn't really helpin that regard.

Wouldn't what I've proposed above be helpful, or?

/Eoghan


[1]
http://mail-archives.apache.org/mod_mbox/incubator-cxf-dev/200703.mbox/%
3cFA1787F64A095C4090E76EBAF8B183E071FCAF@emea-ems1.IONAGLOBAL.com%3e

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/28/07, Glynn, Eoghan <eo...@iona.com> wrote:

>
> What do you mean by an "abstraction with boundaries of Conduits and
> Destinations"?
>
> Are the boundaries of which you speak:
>
> (a) the Conduit and Destination APIs
> (b) the lifecycle of, and referers to, the Conduit and Destination
> instances
> (c) something else?
>
> As far as I can see, we're *both* proposing changes that would fall
> mainly under category (b).
>
> Currently the Conduit lifecycle is managed by the Client. And the DRE
> lifecycle is managed by the Conduit.
>
> You want to change things so that DRE is also managed by the Client.
> Correct?
>
> I want to change things so that neither is managed by the Client.
>
> So I think it would be fair to say that we *both* see a reason to go
> changing things. Just different things. Or?


Sure, but its hard for me to know what is motivating your proposal if you do
come up with some specific use cases. I'm glad to see that you daded a
couple below.

> I don't really see any reason to go changing this.
>
> See above.
>
> And here's a specific reason ...
>
> Having the Client create a Conduit before its actually definite that a
> Conduit is required makes it awkward for an interceptor in the outbound
> chain to:
>
> (a) divert the message in such a way that doesn't require a Conduit at
> all


I have no idea what you're getting at here. Can you please give a use case?
That statement is kind of circular... of course if a conduit is required,
you won't be able to divert a message in a way that doesn't require a
conduit. But where are you diverting it? How do you want to divert? Why?

(b) divert the message to a different endpoint, that maybe necessitates
> a different Conduit instance to the one selected up front by the Client


This is where I was going with the Camel example... We could send a message
off to camel (or any other routing thingy - synapse or mule might be options
for people too). Or if we want to route inside the interceptor chain we can
select a new Conduit in any interceptor. Then the MessageSenderInterceptor
can use this new Conduit. If you're tyring to change the destination after
the messagesenderinterceptor - i.e. mid serialization, I don't think thats
very feasible for most bindings/messages.

Once again, what are your use cases here? Please supply some specific
scenarios which require the removal of a Conduit.

> For instance, I've been talking to James Strachan about using
> > Camel a bit.
> > Camel can do a bit of routing of CXF messages. On the Client
> > side of things,
> > we should be able to send a message in and then get the
> > response some time
> > later from Camel (if there is a response). The idea is that
> > it can work on
> > whatever the representation - pojos, xml, bytes, etc. The
> > boundary into this
> > system from the client perspective would still be a
> > transport. Camel can
> > just add a MessageObserver on a local:// destination. How the
> > message comes
> > into Camel then becomes a matter of the Binding.  For the
> > POJO case, I'd
> > like to create an ObjectBinding which doesn't do any
> > serialization. It'd
> > also be nice to have a flag so the SOAP binding produce a
> > Source object
> > ultimately.
>
>
> Sorry I don't really see the relevance of this to the current
> discussion.
>
> Maybe I'm just being slow today :)
>
> Can you explain why the Camel requirement necessitates the type of
> changes you're proposing?


I was simply talking about how mediation would be possible with Camel as you
had stated that one of the requirements for mediation was the removal of the
Conduit from the Client class. The example was to show that removing the
Conduit is not necessariliy required.

>
> > Lets compare the two cases of setting up a decoupled endpoint
> > from an XML
> > configuration perspective.
> >
> > Case 1: now
> >
> >
> >     <http:conduit id="{
> > http://cxf.apache.org/greeter_control}GreeterPort.http-conduit">
> >       <http:client DecoupledEndpoint="
> > http://localhost:9995/decoupled_endpoint"/>
> >     </http:conduit>
> >
> > Case 2:My Proposal
> > 2a) No Client: No XML configuration is needed, unless you're
> > using JMS.
>
>
> No XML configuration is needed? So you're proposing a (client-less,
> HTTP-based) application must hard-code the DRE address?
>
> What happens if I reorganize by domains? Or my DHCP lease expires? Or
> I'm assigned a new port range? Or I discover a port clash with some
> other piece of software? Or my firewall config is changed? Or the NATS
> setup is changed? Or I want to provision the client app to 100s or 1000s
> of different hosts without recompiling for each? Or the client app is
> migrated to a new host? Or the server app is migrated off-host so that a
> localhost-based DRE no longer works?


I see what your saying, but...

They can just put it in their application configuration. If they're already
working with CXF they probably have their own configuration which will drive
their application - whether its UI or database or Spring based.

Also, the number of people attempting to understand the transport API or
write transports will be much greater than those trying to write decoupled
applications without the Client. Sure, I have no statistics to back that up,
but I do have a fair amount of experience in the area. Most people won't
even setup a decoupled endpoint. And the majority of people who do use
decoupled endpoints will use the Client.

I would definitely wager a large sum of money that there are more people
trying to grok or write transports than those writing decoupled applications
without a Client. By an order of magnitude at least. So I have yet to see
why this argument should carry that much weight.


> >
> > When you use the Client, yes, the Client adds some convenience wrapper
> > methods. When you don't use the Client, you always use the
> > destination apis
> > to set up the decoupled endpoint.
>
>
> OK, can we be 100% clear here. What exactly are these convenience
> wrapper methods?
>
> Are you proposing new APIs on Client such as setFaultToEndpoint() and
> setAcksTo()?


No, just the setAsyncrhronousDestination/setAsyncryhronousEndpoint in my
original proposal.

> > Is introducing an abstract ConduitPolicy really that big an issue?
> >
> >
> > YES! We've already created very complex APIs for transports.
> > Its time to simplify.
>
>
> But the complexity you take away with one hand, you add back with the
> other ... i.e. you're proposing adding a bunch of complexity to the
> Client.
>
> Now I'd anticipate your counter-argument as something like ... yes but
> we want developers to write their own transports, not their own clients.
> Fair enough, but I'm saying that transport-writers need not be concerned
> with handling the DRE logic if its factored out to the AbstractConduit.


You're completely missing the point. The point is that the whole CONCEPT of
Conduits and Destinations are overly complex. To understand AbstractConduit
you still need to understand Conduit. So AbstractConduit doesn't really help
in that regard.

Regards,
- Dan


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 28 March 2007 15:40
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> On 3/28/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> > > I see your point - I suppose there could be a flag. But 
> look at it 
> > > the other way around too. If this type of thing is adopted, that 
> > > doesn't mean that we can do client.set(Destination.class, 
> > > myDestination).
> > >
> > > At the moment I'm very strongly against this idea and if you're 
> > > serious about getting it in, I would suggest starting 
> another thread 
> > > outlining your use case so we can discuss possible solutions.
> >
> >
> > Can you outline why you're very strongly against the idea 
> of deferring the
> > creation of a Conduit until we're sure its actually needed?
> 
> 
> I see it as unnecessary. We've defined an abstraction with 
> boundaries of Conduits and Destinations. 


What do you mean by an "abstraction with boundaries of Conduits and
Destinations"?

Are the boundaries of which you speak:

(a) the Conduit and Destination APIs
(b) the lifecycle of, and referers to, the Conduit and Destination
instances
(c) something else?

As far as I can see, we're *both* proposing changes that would fall
mainly under category (b).

Currently the Conduit lifecycle is managed by the Client. And the DRE
lifecycle is managed by the Conduit.

You want to change things so that DRE is also managed by the Client.
Correct?

I want to change things so that neither is managed by the Client.

So I think it would be fair to say that we *both* see a reason to go
changing things. Just different things. Or?


> I don't really see any reason to go changing this.


See above.

And here's a specific reason ...

Having the Client create a Conduit before its actually definite that a
Conduit is required makes it awkward for an interceptor in the outbound
chain to:

(a) divert the message in such a way that doesn't require a Conduit at
all
(b) divert the message to a different endpoint, that maybe necessitates
a different Conduit instance to the one selected up front by the Client

 
> For instance, I've been talking to James Strachan about using 
> Camel a bit.
> Camel can do a bit of routing of CXF messages. On the Client 
> side of things,
> we should be able to send a message in and then get the 
> response some time
> later from Camel (if there is a response). The idea is that 
> it can work on
> whatever the representation - pojos, xml, bytes, etc. The 
> boundary into this
> system from the client perspective would still be a 
> transport. Camel can
> just add a MessageObserver on a local:// destination. How the 
> message comes
> into Camel then becomes a matter of the Binding.  For the 
> POJO case, I'd
> like to create an ObjectBinding which doesn't do any 
> serialization. It'd
> also be nice to have a flag so the SOAP binding produce a 
> Source object
> ultimately.


Sorry I don't really see the relevance of this to the current
discussion.

Maybe I'm just being slow today :)

Can you explain why the Camel requirement necessitates the type of
changes you're proposing?

 
> > > Second, no one will be forced to invent new config
> > > mechanisms. They can use the existing configuration
> > > mechanisms. i.e. they can declare a <destination> and a
> > > <conduit> in their XML if thats the route they want to go.
> > > Then when they grab the Destination/Conduit those will be
> > > configured according to their configuration.
> >
> >
> > It's the grabbing from the configuration that I'm concerned about.
> >
> > What exactly is entailed by the app grabbing from config, 
> plus defining
> > the config schema upfront?
> >
> > Why should application code (that doesn't use a Client) 
> have to concerned
> > at all with managing config?
> >
> 
> It doesn't have to be... See below.
> 
> Why not just allow the decoupled Destination to be picked up 
> via a config
> > mechanism that's provided by the CXF framework?
> >
> > What is guaranteed to exist for a decoupled MEP? A Conduit instance.
> >
> > What is not guaranteed to exist for a decoupled MEP? A 
> Client instance.
> >
> > So it seems to that simple logic dictates that the DRE 
> config should be
> > associated with the one thing we *know* will exist, i.e. 
> the Conduit.
> 
> 
> 
> Lets compare the two cases of setting up a decoupled endpoint 
> from an XML
> configuration perspective.
> 
> Case 1: now
> 
> 
>     <http:conduit id="{
> http://cxf.apache.org/greeter_control}GreeterPort.http-conduit">
>       <http:client DecoupledEndpoint="
> http://localhost:9995/decoupled_endpoint"/>
>     </http:conduit>
> 
> Case 2:My Proposal
> 2a) No Client: No XML configuration is needed, unless you're 
> using JMS. 


No XML configuration is needed? So you're proposing a (client-less,
HTTP-based) application must hard-code the DRE address?

What happens if I reorganize by domains? Or my DHCP lease expires? Or
I'm assigned a new port range? Or I discover a port clash with some
other piece of software? Or my firewall config is changed? Or the NATS
setup is changed? Or I want to provision the client app to 100s or 1000s
of different hosts without recompiling for each? Or the client app is
migrated to a new host? Or the server app is migrated off-host so that a
localhost-based DRE no longer works?


> In which case you add a <jms:destination> to your XML config
> 2b) My proposed client config:
> 
> <jaxws:client id="....">
>   <jaxws:destination><http:destination address="
> http://localhost:9995/decoupled_endpoint"/></jaxws:destination>
> </jaxws:client>


I get it that the Client config is of comparable complexity the Conduit
config.

Now, just for a second, imagine the application doesn't have a Client
instance. But the application cannot hard-code the DRE (see above for a
selection of reasons why this might be so). 

Where does the config come from in that case?


> > > I'm saying that if someone is just using the transport 
> layer (i.e. no
> > > client) and using multiple decoupled endpoints, its more
> > > consistent to just use the Destination* APIs. And its the
> > > same amount of work.
> >
> >
> > By the "Destination* APIs", do you mean 
> DestinationFactory.getDestination
> > ()?
> >
> > Well, that is exactly what would be used to create a 
> different acksTo or
> > faultTo in the current scenario.
> >
> > And it sounds to me like it would also be required in your 
> proposal too
> > (assuming you're not proposing new 
> Client.setAcksToEndpoint() etc. APIs)
> >
> > So I really don't seen what your consistency argument is 
> based on (?)
> >
> > AFAICS in *both* your proposal *and* in the current model, 
> a *different*
> > mechanism must used to set up the replyTo versus the 
> acksTo/faultTo (if
> > these are to be different).
> 
> 
> 
>> Correct me please here if I'm wrong.
> 
> 
> When you use the Client, yes, the Client adds some convenience wrapper
> methods. When you don't use the Client, you always use the 
> destination apis
> to set up the decoupled endpoint.


OK, can we be 100% clear here. What exactly are these convenience
wrapper methods?

Are you proposing new APIs on Client such as setFaultToEndpoint() and
setAcksTo()?


> > Is introducing an abstract ConduitPolicy really that big an issue?
> 
> 
> YES! We've already created very complex APIs for transports. 
> Its time to simplify.


But the complexity you take away with one hand, you add back with the
other ... i.e. you're proposing adding a bunch of complexity to the
Client.

Now I'd anticipate your counter-argument as something like ... yes but
we want developers to write their own transports, not their own clients.
Fair enough, but I'm saying that transport-writers need not be concerned
with handling the DRE logic if its factored out to the AbstractConduit.

 
> I would think it much easier for the CXF framework to support a small
> > extension to its current config schemas, than for a (Client-less)
> > application to have to manage the config of the DRE itself.
> 
> 
> You have yet to show where the burden is for a Client-less 
> application which
> manages a DRE itself. I don't see how its any more complex 
> than what is currently there.


Consider a client-less application that can't hard-code the DRE, as
described above.

Surely it is more complex for such an application to pull in a
configured DRE, that for the Conduit to handle this on its behalf?

/Eoghan




Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/28/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
> > I see your point - I suppose there could be a flag. But look
> > at it the other way around too. If this type of thing is
> > adopted, that doesn't mean that we can do
> > client.set(Destination.class, myDestination).
> >
> > At the moment I'm very strongly against this idea and if
> > you're serious about getting it in, I would suggest starting
> > another thread outlining your use case so we can discuss
> > possible solutions.
>
>
> Can you outline why you're very strongly against the idea of deferring the
> creation of a Conduit until we're sure its actually needed?


I see it as unnecessary. We've defined an abstraction with boundaries of
Conduits and Destinations. I don't really see any reason to go changing
this.

For instance, I've been talking to James Strachan about using Camel a bit.
Camel can do a bit of routing of CXF messages. On the Client side of things,
we should be able to send a message in and then get the response some time
later from Camel (if there is a response). The idea is that it can work on
whatever the representation - pojos, xml, bytes, etc. The boundary into this
system from the client perspective would still be a transport. Camel can
just add a MessageObserver on a local:// destination. How the message comes
into Camel then becomes a matter of the Binding.  For the POJO case, I'd
like to create an ObjectBinding which doesn't do any serialization. It'd
also be nice to have a flag so the SOAP binding produce a Source object
ultimately.


> >
> > Second, no one will be forced to invent new config
> > mechanisms. They can use the existing configuration
> > mechanisms. i.e. they can declare a <destination> and a
> > <conduit> in their XML if thats the route they want to go.
> > Then when they grab the Destination/Conduit those will be
> > configured according to their configuration.
>
>
> It's the grabbing from the configuration that I'm concerned about.
>
> What exactly is entailed by the app grabbing from config, plus defining
> the config schema upfront?
>
> Why should application code (that doesn't use a Client) have to concerned
> at all with managing config?
>

It doesn't have to be... See below.

Why not just allow the decoupled Destination to be picked up via a config
> mechanism that's provided by the CXF framework?
>
> What is guaranteed to exist for a decoupled MEP? A Conduit instance.
>
> What is not guaranteed to exist for a decoupled MEP? A Client instance.
>
> So it seems to that simple logic dictates that the DRE config should be
> associated with the one thing we *know* will exist, i.e. the Conduit.



Lets compare the two cases of setting up a decoupled endpoint from an XML
configuration perspective.

Case 1: now


    <http:conduit id="{
http://cxf.apache.org/greeter_control}GreeterPort.http-conduit">
      <http:client DecoupledEndpoint="
http://localhost:9995/decoupled_endpoint"/>
    </http:conduit>

Case 2:My Proposal
2a) No Client: No XML configuration is needed, unless you're using JMS. In
which case you add a <jms:destination> to your XML config
2b) My proposed client config:

<jaxws:client id="....">
  <jaxws:destination><http:destination address="
http://localhost:9995/decoupled_endpoint"/></jaxws:destination>
</jaxws:client>


> >
> >
> > I'm saying that if someone is just using the transport layer (i.e. no
> > client) and using multiple decoupled endpoints, its more
> > consistent to just use the Destination* APIs. And its the
> > same amount of work.
>
>
> By the "Destination* APIs", do you mean DestinationFactory.getDestination
> ()?
>
> Well, that is exactly what would be used to create a different acksTo or
> faultTo in the current scenario.
>
> And it sounds to me like it would also be required in your proposal too
> (assuming you're not proposing new Client.setAcksToEndpoint() etc. APIs)
>
> So I really don't seen what your consistency argument is based on (?)
>
> AFAICS in *both* your proposal *and* in the current model, a *different*
> mechanism must used to set up the replyTo versus the acksTo/faultTo (if
> these are to be different).



Correct me please here if I'm wrong.


When you use the Client, yes, the Client adds some convenience wrapper
methods. When you don't use the Client, you always use the destination apis
to set up the decoupled endpoint.


> Is introducing an abstract ConduitPolicy really that big an issue?


YES! We've already created very complex APIs for transports. Its time to
simplify.

I would think it much easier for the CXF framework to support a small
> extension to its current config schemas, than for a (Client-less)
> application to have to manage the config of the DRE itself.


You have yet to show where the burden is for a Client-less application which
manages a DRE itself. I don't see how its any more complex than what is
currently there.

- Dan


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.

Dan,

Sorry for the delay in responding to this, but I didn't want to just re-hash my position yet again. Anyway, some further comments inline ...


> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 22 March 2007 20:53
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> On 3/20/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> >
> > > Just because you
> > > want to not require the conduit doesn't mean that there 
> shouldn't be 
> > > conduit/destination properties on the Client.
> > > This is completely orthogonal to the issue.
> >
> >
> > So how would a user suppress the Client's creation of a 
> Conduit if its 
> > only when the dispatch gets as far as some interceptor that the 
> > dispatch is diverted in such as a way as to not require a Conduit? 
> > Note the Conduit is created *up-front* by the Client, before 
> > InterceptorChain.doInterceptor() is called for the outward dispatch.
> 
> 
> I see your point - I suppose there could be a flag. But look 
> at it the other way around too. If this type of thing is 
> adopted, that doesn't mean that we can do 
> client.set(Destination.class, myDestination).
> 
> At the moment I'm very strongly against this idea and if 
> you're serious about getting it in, I would suggest starting 
> another thread outlining your use case so we can discuss 
> possible solutions.


Can you outline why you're very strongly against the idea of deferring the creation of a Conduit until we're sure its actually needed?

 
> > 2. Avoid forcing the usage of a Client instance
> > > >
> > > > In general, if A is to be responsible for maintaining a
> > > reference to
> > > > B, then its reasonable to expect that the existence of a B
> > > implies the
> > > > existence of an A. Otherwise, in some cases an instance of
> > > A will have
> > > > be artificially created, solely to manage the reference to B.
> > > >
> > > > But if a DRE is in use, then the *only* other thing we're
> > > guaranteed
> > > > also exists is the corresponding Conduit.
> > > >
> > > > IMO we should neither require the usage of a Client instance to 
> > > > mediate invocations, nor impose any undue burden on
> > > applications that
> > > > choose to wire up the interceptor chains directly and
> > > initiate dispatch themselves.
> > > >
> > > > An example of an undue burden would be forcing such 
> applications 
> > > > to either always create the DRE *programmatically* via 
> > > > DestinationFactory.getDestination(), or if they want 
> the DRE to be 
> > > > specified declaratively, to manage this configuration 
> themselves.
> > >
> > >
> > > Undue burden? Where is the undue burden?
> >
> >
> > The undue burden is NOT in driving the programmatic API. I 
> agree the 
> > amount of work there is roughly the same.
> >
> > The problem is that there should be declarative mechanism 
> as well as a 
> > programmatic API. The application doesn't necessarily want to 
> > hard-code the DRE address.
> >
> > This declarative mechanism is currently provided by the Conduit 
> > configuration. Any application can take advantage of this, 
> regardless 
> > of how the invocation is dispatched (whether via the 
> Client, Dispatch, 
> > direct InterceptorChain.doIntercept(), whatever) because if it's a 
> > remote invocation, there's *always* going to be a Conduit 
> instance involved.
> >
> > You're proposing moving this config to hang off the Client 
> instead. As 
> > a result the application would be forced to either (a) use 
> the Client 
> > in order to declaratively specify the DRE, or (b) invent and manage 
> > its own config mechanism. Makes sense, or?
> 
> 
> Well first, nearly everyone will be using the Client.
> 
> Second, no one will be forced to invent new config 
> mechanisms. They can use the existing configuration 
> mechanisms. i.e. they can declare a <destination> and a 
> <conduit> in their XML if thats the route they want to go. 
> Then when they grab the Destination/Conduit those will be 
> configured according to their configuration.


It's the grabbing from the configuration that I'm concerned about.

What exactly is entailed by the app grabbing from config, plus defining the config schema upfront?

Why should application code (that doesn't use a Client) have to concerned at all with managing config? 

Why not just allow the decoupled Destination to be picked up via a config mechanism that's provided by the CXF framework?

What is guaranteed to exist for a decoupled MEP? A Conduit instance.

What is not guaranteed to exist for a decoupled MEP? A Client instance.

So it seems to that simple logic dictates that the DRE config should be associated with the one thing we *know* will exist, i.e. the Conduit.

 
> > Also I'd like to respond quickly to a couple of specific
> > > points that Dan
> > > > makes in his proposal:
> > > >
> > > > "Right now if you want to create different endpoints 
> for receiving 
> > > > ReplyTos and FaultTos you have configure the ReplyTos using the 
> > > > Conduit API and the FaultTos using the destination API.
> > > Creating those
> > > > endpoints in different ways is bad IMO."
> > > >
> > > > So how would this be any different under your proposal? Is the 
> > > > implication that in addition to a 
> Client.setAsynchronousEndpoint() 
> > > > API, you'd also add
> > > > Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), and 
> > > > similarly expose <faultToEndpoint> and <acksToEndpoint> 
> elements 
> > > > in your proposed <client> bean?
> > >
> > >
> > > If so, this would expose *way* too much of WS-A and WS-RM 
> semantics 
> > > directly
> > > > in the Client, which should IMO be independent of such QoS
> > > concerns.
> > > > The CXF WS-A and WS-RM layers were specifically designed to be 
> > > > pluggable, so that they could slotted into the runtime
> > > without impact
> > > > on the core APIs. I would be strongly against a move that
> > > breaks this
> > > > ... I mean, what next, Client.setSecurityPolicyToken()??
> > >
> > >
> > > If on the other hand, if you're not suggesting polluting 
> the Client 
> > > with
> > > > those aspects of WS-A & WS-RM, can you explain how your 
> proposal 
> > > > provides a consistent mechanism for specifying the faultTo & 
> > > > acksTo vis-à-vis the replytTo?
> > >
> > >
> > > No, I was more referring to scenarios where someone is 
> not using the 
> > > Client.
> > > The one you seem to be so concerned about in #1.
> >
> >
> > So regardless of whether:
> >
> > (a) we hang the DRE config off the Conduit (as is currently 
> the case) 
> > or the Client (as you propose),
> >
> > or
> >
> > (b) the application chooses to use the Client or some other 
> mechanism 
> > to mediate the invocation
> >
> > Would you agree that if the application wants to set the faultTo or 
> > acksTo to some other address than the replyTo, then they 
> would have to 
> > do so in a way that's not consistent with whatever way the 
> replyTo is set?
> >
> > If so, I think the setting of the faultTo/acksTo is neutral to the 
> > argument, and neither bolsters your case nor mine.
> >
> 
> I'm saying that if someone is just using the transport layer (i.e. no
> client) and using multiple decoupled endpoints, its more 
> consistent to just use the Destination* APIs. And its the 
> same amount of work.


By the "Destination* APIs", do you mean DestinationFactory.getDestination()? 

Well, that is exactly what would be used to create a different acksTo or faultTo in the current scenario.

And it sounds to me like it would also be required in your proposal too (assuming you're not proposing new Client.setAcksToEndpoint() etc. APIs)

So I really don't seen what your consistency argument is based on (?) 

AFAICS in *both* your proposal *and* in the current model, a *different* mechanism must used to set up the replyTo versus the acksTo/faultTo (if these are to be different).

Correct me please here if I'm wrong.

Otherwise, it seems to me there is no consistency argument.

 
> The benefit is that it does not introduce a new ClientPolicy 
> class and does not the Conduit contract.


Is introducing an abstract ConduitPolicy really that big an issue? 

I would think it much easier for the CXF framework to support a small extension to its current config schemas, than for a (Client-less) application to have to manage the config of the DRE itself.

Cheers,
Eoghan



Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/20/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
>
> > Just because you
> > want to not require the conduit doesn't mean that there
> > shouldn't be conduit/destination properties on the Client.
> > This is completely orthogonal to the issue.
>
>
> So how would a user suppress the Client's creation of a Conduit if its
> only when the dispatch gets as far as some interceptor that the dispatch is
> diverted in such as a way as to not require a Conduit? Note the Conduit is
> created *up-front* by the Client, before InterceptorChain.doInterceptor()
> is called for the outward dispatch.


I see your point - I suppose there could be a flag. But look at it the other
way around too. If this type of thing is adopted, that doesn't mean that we
can do client.set(Destination.class, myDestination).

At the moment I'm very strongly against this idea and if you're serious
about getting it in, I would suggest starting another thread outlining your
use case so we can discuss possible solutions.

> 2. Avoid forcing the usage of a Client instance
> > >
> > > In general, if A is to be responsible for maintaining a
> > reference to
> > > B, then its reasonable to expect that the existence of a B
> > implies the
> > > existence of an A. Otherwise, in some cases an instance of
> > A will have
> > > be artificially created, solely to manage the reference to B.
> > >
> > > But if a DRE is in use, then the *only* other thing we're
> > guaranteed
> > > also exists is the corresponding Conduit.
> > >
> > > IMO we should neither require the usage of a Client instance to
> > > mediate invocations, nor impose any undue burden on
> > applications that
> > > choose to wire up the interceptor chains directly and
> > initiate dispatch themselves.
> > >
> > > An example of an undue burden would be forcing such applications to
> > > either always create the DRE *programmatically* via
> > > DestinationFactory.getDestination(), or if they want the DRE to be
> > > specified declaratively, to manage this configuration themselves.
> >
> >
> > Undue burden? Where is the undue burden?
>
>
> The undue burden is NOT in driving the programmatic API. I agree the
> amount of work there is roughly the same.
>
> The problem is that there should be declarative mechanism as well as a
> programmatic API. The application doesn't necessarily want to hard-code the
> DRE address.
>
> This declarative mechanism is currently provided by the Conduit
> configuration. Any application can take advantage of this, regardless of how
> the invocation is dispatched (whether via the Client, Dispatch, direct
> InterceptorChain.doIntercept(), whatever) because if it's a remote
> invocation, there's *always* going to be a Conduit instance involved.
>
> You're proposing moving this config to hang off the Client instead. As a
> result the application would be forced to either (a) use the Client in order
> to declaratively specify the DRE, or (b) invent and manage its own config
> mechanism. Makes sense, or?


Well first, nearly everyone will be using the Client.

Second, no one will be forced to invent new config mechanisms. They can use
the existing configuration mechanisms. i.e. they can declare a <destination>
and a <conduit> in their XML if thats the route they want to go. Then when
they grab the Destination/Conduit those will be configured according to
their configuration.

> Also I'd like to respond quickly to a couple of specific
> > points that Dan
> > > makes in his proposal:
> > >
> > > "Right now if you want to create different endpoints for receiving
> > > ReplyTos and FaultTos you have configure the ReplyTos using the
> > > Conduit API and the FaultTos using the destination API.
> > Creating those
> > > endpoints in different ways is bad IMO."
> > >
> > > So how would this be any different under your proposal? Is the
> > > implication that in addition to a Client.setAsynchronousEndpoint()
> > > API, you'd also add
> > > Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), and
> > > similarly expose <faultToEndpoint> and <acksToEndpoint> elements in
> > > your proposed <client> bean?
> >
> >
> > If so, this would expose *way* too much of WS-A and WS-RM
> > semantics directly
> > > in the Client, which should IMO be independent of such QoS
> > concerns.
> > > The CXF WS-A and WS-RM layers were specifically designed to be
> > > pluggable, so that they could slotted into the runtime
> > without impact
> > > on the core APIs. I would be strongly against a move that
> > breaks this
> > > ... I mean, what next, Client.setSecurityPolicyToken()??
> >
> >
> > If on the other hand, if you're not suggesting polluting the
> > Client with
> > > those aspects of WS-A & WS-RM, can you explain how your proposal
> > > provides a consistent mechanism for specifying the faultTo & acksTo
> > > vis-à-vis the replytTo?
> >
> >
> > No, I was more referring to scenarios where someone is not
> > using the Client.
> > The one you seem to be so concerned about in #1.
>
>
> So regardless of whether:
>
> (a) we hang the DRE config off the Conduit (as is currently the case) or
> the Client (as you propose),
>
> or
>
> (b) the application chooses to use the Client or some other mechanism to
> mediate the invocation
>
> Would you agree that if the application wants to set the faultTo or acksTo
> to some other address than the replyTo, then they would have to do so in a
> way that's not consistent with whatever way the replyTo is set?
>
> If so, I think the setting of the faultTo/acksTo is neutral to the
> argument, and neither bolsters your case nor mine.
>

I'm saying that if someone is just using the transport layer (i.e. no
client) and using multiple decoupled endpoints, its more consistent to just
use the Destination* APIs. And its the same amount of work.

The benefit is that it does not introduce a new ClientPolicy class and does
not the Conduit contract.

- Dan

-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: [PROPOSAL] Client and Conduit changes

Posted by Oisin Hurley <oh...@iona.com>.
I'm getting a little confused - are there two threads interleaving here?

This is an important discussion, and I think that the questions about
archicture [0], and the answers, should be part of a separate thread.  
Then
we can read the proposal thread without distraction.

   --oh

[0] http://www.nabble.com/-PROPOSAL--Client-and-Conduit-changes- 
tf3417149.html

Re: [PROPOSAL] Client and Conduit changes

Posted by Polar Humenn <ph...@iona.com>.
Glynn, Eoghan wrote:
>  
>
>   
>> -----Original Message-----
>> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
>> Sent: 20 March 2007 00:09
>> To: cxf-dev@incubator.apache.org
>> Subject: Re: [PROPOSAL] Client and Conduit changes
>>
>> On 3/17/07, Glynn, Eoghan <eo...@iona.com> wrote:
>>     
>>>
>>> My position is that the Conduit should continue to hold to the 
>>> reference to, and manage the lifecycle of, the decoupled 
>>>       
>> response endpoint (DRE).
>>     
>>> Without rehashing the entire thread, my reasons briefly are:
>>>
>>> 1. Separation of concerns
>>>
>>> The DRE is an aspect of the transport and thus should be 
>>>       
>> created and 
>>     
>>> referenced from within the realm of the transport.
>>>       
>> Then why aren't we creating other decoupled endpoints from 
>> the transport layer? 
>>     
>
>
> Because the DRE is the only canonical back-channel IMO. By canonical, I mean you've got to have a back-channel for decoupled request/response MEPs to occur. 
>
> The faultTo on the other hand, is an added convenience provided by WS-A, but it is not central to the normal decoupled request/response paradigm.
>
> The acksTo is even less central, as its obviously used only for out-of-band RM messaging.
>
> In the normal case, the degrees of freedom presented by the faultTo and acksTo are not required by applications, i.e. they're happy to allow these default to be the same as the DRE. 
>
> In the less usual case where the application wants to set the faultTo and/or acksTo to a different address, then it has to do a bit more work.
>
>
>   
The fact that it is in the standard, means we should architecturally be 
able to support it, no?

You can conceivably set up three different Destinations for an 
"invocation", correct?
I'm not sure on the standard, but logically thinking:

A response message goes to either the Reply-To, or Fault-To but not both,
and an Ack-To goes regardless. Only in the cases where these headers are 
not present does it default to the transport the message came in on, 
correct?

So, that tells me that these Destinations are particular to the 
"invocation" and not the transport.

>> This assumes a 1:1 association which isn't so.
>>     
>
>
> Do you mean a 1:1 association between Conduits and Destinations?
>
> I don't think it does necessarily, rather it depends on how the DestinationFactory is implemented.
>
> Currently DestinationFactory.getDestination() returns a brand new Destination each time, but it could be changed easily so that subsequent calls to getDestination() with the same EndpointInfo get back the same instance, possibly with a ref-count that's decremented in Destination.shutdown(). I think you suggested something similar yourself in the earlier thread. 
>
> I think the assumed association that's actually inappropriate is the one between a Client and Destination, or even between a Client and Conduit. I won't re-hash the reasons for this, as I'm guessing anyone reading this thread will soon lose the will to live if either of us repeat ourselves any further :)
>
>  
>   
>> On the other hand, the purpose of the Client is to set up 
>> interceptor chains
>>     
>>> and dispatch the invocation. Such invocations may NOT 
>>>       
>> require a DRE, 
>>     
>>> or even a Conduit for that matter. Thus I think it 
>>>       
>> inappropriate for 
>>     
>>> the Client to be concerned with the creation of the DRE, and would 
>>> even go one step further and move the Conduit creation to the 
>>> MessageSenderInterceptor, so that a Conduit comes into 
>>>       
>> being only if it really is needed.
>>
>>
>> Then do you want to get rid of 
>> Exchange.getConduit/getDestination or 
>> Message.getConduit/getDestination as well? 
>>     
>
>
> I think there's a big difference here. Exchange/Message.getConduit() are just accessors. Client.getConduit() currently causes the creation of a Conduit. 
>
>
>   
>> Just because you 
>> want to not require the conduit doesn't mean that there 
>> shouldn't be conduit/destination properties on the Client. 
>> This is completely orthogonal to the issue.
>>     
>
>
> So how would a user suppress the Client's creation of a Conduit if its only when the dispatch gets as far as some interceptor that the dispatch is diverted in such as a way as to not require a Conduit? Note the Conduit is created *up-front* by the Client, before InterceptorChain.doInterceptor() is called for the outward dispatch.
>
>   

Well, such is the nature of these interceptors. Who even says you need a 
Message? :)
I guess it really depends on how you would want to adhere to an 
underlying architecture.

When you are a Client, you are expecting the message to go over a 
particular Conduit regardless. An interceptor may divert that for good 
reason, but still the Client "intends" that particular Conduit, quite 
possibly for trust/assurance issues.

If the purpose of this diversion is for local invocation, then perhaps 
there should be a "local" Conduit that the message goes "over" but stays 
in process?

>  
>   
>> 2. Avoid forcing the usage of a Client instance
>>     
>>> In general, if A is to be responsible for maintaining a 
>>>       
>> reference to 
>>     
>>> B, then its reasonable to expect that the existence of a B 
>>>       
>> implies the 
>>     
>>> existence of an A. Otherwise, in some cases an instance of 
>>>       
>> A will have 
>>     
>>> be artificially created, solely to manage the reference to B.
>>>
>>> But if a DRE is in use, then the *only* other thing we're 
>>>       
>> guaranteed 
>>     
>>> also exists is the corresponding Conduit.
>>>
>>> IMO we should neither require the usage of a Client instance to 
>>> mediate invocations, nor impose any undue burden on 
>>>       
>> applications that 
>>     
>>> choose to wire up the interceptor chains directly and 
>>>       
>> initiate dispatch themselves.
>>     
>>> An example of an undue burden would be forcing such applications to 
>>> either always create the DRE *programmatically* via 
>>> DestinationFactory.getDestination(), or if they want the DRE to be 
>>> specified declaratively, to manage this configuration themselves.
>>>       
>> Undue burden? Where is the undue burden?
>>     
>
>
> The undue burden is NOT in driving the programmatic API. I agree the amount of work there is roughly the same.
>
> The problem is that there should be declarative mechanism as well as a programmatic API. The application doesn't necessarily want to hard-code the DRE address. 
>
> This declarative mechanism is currently provided by the Conduit configuration. Any application can take advantage of this, regardless of how the invocation is dispatched (whether via the Client, Dispatch, direct InterceptorChain.doIntercept(), whatever) because if it's a remote invocation, there's *always* going to be a Conduit instance involved. 
>
> You're proposing moving this config to hang off the Client instead. As a result the application would be forced to either (a) use the Client in order to declaratively specify the DRE, or (b) invent and manage its own config mechanism. Makes sense, or?
>
>  
>   
>> Your approach:
>>
>> Conduit conduit = conduitInitiator.getConduit(Endpoint);
>> ConduitPolicy policy = conduit.getConduitPolicy(); 
>> policy.setDecoupledEndpoint (replyToEPR); 
>> conduit.setMessageObserver(myObserver);
>>
>> My approach:
>>
>> Conduit conduit = conduitInitiator.getConduit(Endpoint);
>> DestinationFactory destination = 
>> destinationFactory.getDestination (replyToEPR); 
>> destination.setMessageObser(myObserver);
>> conduit.setMessageObserver(myObserver); // if you need to 
>> listen for back channel messages
>>
>> It is arguably the SAME amount of work. 
>>     
>
>
> Agreed. See above though why this isn't the issue.
>
>
>   
>> The benefit of the 
>> latter is its consistent.
>>
>> 3. Suitability for JMS
>>     
>>> In order to setup a Destination, JMS may require more 
>>>       
>> information than 
>>     
>>> can be easily shoe-horned into an EPR. Stuff like a JNDI provider, 
>>> ConnectionFactory username/password etc.
>>>
>>> Now I don't accept the JMS as odd-man-out argument, especially when 
>>> most of the counter-examples wheeled out ( i.e. XMPP, TCP, 
>>>       
>> FTP) do not 
>>     
>>> currently even exist as CXF transports. I could just as 
>>>       
>> easily make up 
>>     
>>> a list of non-existent transports that suggests that the 
>>> URI-friendliness of HTTP is the exceptional case, but 
>>>       
>> obviously you'd 
>>     
>>> argue my list was hypothetical and proved nothing. And 
>>>       
>> you'd be right 
>>     
>>> :)
>>>
>>> Neither does the "most people just use HTTP" line wash with 
>>>       
>> me. One of 
>>     
>>> the design centres of CXF is to be a multi-transport stack, 
>>>       
>> and that 
>>     
>>> in my book amounts to more than just paying lip-service to 
>>>       
>> non-HTTP transports.
>>
>>
>> Even if there isn't enough information in the JMS EPR to 
>> completely set up a JMS endpoint, it doesn't mean its 
>> completely useless. It can still be a nice way to hang onto 
>> references of a JMS endpoint that I've set up earlier on.
>> For instance, a user could enter in the jms:// EPR in a 
>> configuration screen. By calling 
>> DestinationFactory.getDestination(epr) it would then retrieve 
>> a previously configured instance of the JMS destination.
>>     
>
>
> Sure that could work.
>
> And my point along is that we would have to take some JMS-specific approach like this, and thus lose one of the main purported benefits of your proposal, i.e. that the mechanism for setting up the DRE is consistent across transports.
>
>  
>   
>> Also I'd like to respond quickly to a couple of specific 
>> points that Dan
>>     
>>> makes in his proposal:
>>>
>>> "Right now if you want to create different endpoints for receiving 
>>> ReplyTos and FaultTos you have configure the ReplyTos using the 
>>> Conduit API and the FaultTos using the destination API. 
>>>       
>> Creating those 
>>     
>>> endpoints in different ways is bad IMO."
>>>
>>> So how would this be any different under your proposal? Is the 
>>> implication that in addition to a Client.setAsynchronousEndpoint() 
>>> API, you'd also add
>>> Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), and 
>>> similarly expose <faultToEndpoint> and <acksToEndpoint> elements in 
>>> your proposed <client> bean?
>>>       
>> If so, this would expose *way* too much of WS-A and WS-RM 
>> semantics directly
>>     
>>> in the Client, which should IMO be independent of such QoS 
>>>       
>> concerns. 
>>     
>>> The CXF WS-A and WS-RM layers were specifically designed to be 
>>> pluggable, so that they could slotted into the runtime 
>>>       
>> without impact 
>>     
>>> on the core APIs. I would be strongly against a move that 
>>>       
>> breaks this 
>>     
>>> ... I mean, what next, Client.setSecurityPolicyToken()??
>>>       
>> If on the other hand, if you're not suggesting polluting the 
>> Client with
>>     
>>> those aspects of WS-A & WS-RM, can you explain how your proposal 
>>> provides a consistent mechanism for specifying the faultTo & acksTo 
>>> vis-à-vis the replytTo?
>>>       
>> No, I was more referring to scenarios where someone is not 
>> using the Client.
>> The one you seem to be so concerned about in #1.
>>     
>
>
> So regardless of whether:
>
> (a) we hang the DRE config off the Conduit (as is currently the case) or the Client (as you propose),
>
> or
>
> (b) the application chooses to use the Client or some other mechanism to mediate the invocation
>
> Would you agree that if the application wants to set the faultTo or acksTo to some other address than the replyTo, then they would have to do so in a way that's not consistent with whatever way the replyTo is set?
>
> If so, I think the setting of the faultTo/acksTo is neutral to the argument, and neither bolsters your case nor mine.
>
>
>
>   

Hmmm, It seems that there are default defacto types of Destinations for 
a particular Client. (Reply-To, Fault-To, Acks-To, whatever) These are 
merely defaulted to the Conduit's Destination.

Perhaps, the Client is a MessageObserver to the Conduit's 1:1 
Destination. When a Message comes in on the Conduit, the Client 
MessageObserver dispatches that message depending on response message 
headers (Reply, Fault, Ack, etc) to the appropriate Destination's 
MessageObservers that was default/overridden on the Client.

When the Client makes the invocation, the ProtocolHeaders (Reply-To, 
Fault-To, Ack-To, etc) before dispatching to the interceptors?

Cheers,
-Polar

>> Another point which I strongly disagree with:
>>     
>>> "If all Conduits share the same code for setting up decoupled 
>>> destinations, that is a sign to me that we can take it out 
>>>       
>> of the Conduit."
>>     
>>> I've never come across a design principle that suggests 
>>>       
>> having common 
>>     
>>> code in a common base class is a sign that such code should 
>>>       
>> be moved elsewhere.
>>     
>>> In fact what purpose do common base classes serve, other than to 
>>> factor out commonality from sub-classes?
>>>       
>> Base classes would be another solution to that problem.  I 
>> wasn't trying to say base classes are evil. I was trying to 
>> say that the concept of a decoupled endpoint isn't critical 
>> to the concept of a Conduit, and so I think it should be 
>> taken out. Sometimes you can simplify the classes and then 
>> incorporate more advanced concepts into another class. For 
>> instance, in Microsoft's WCF, you have the IDuplexChannel 
>> which extends the IInputChannel and IOutputChannel.  I don't 
>> think that is so outrageous really...
>>     
>
>
> Agreed, not outrageous, just another way of doing it that happens to suit WCF.
>
> /Eoghan
>   


RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 20 March 2007 00:09
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> On 3/17/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> >
> > My position is that the Conduit should continue to hold to the 
> > reference to, and manage the lifecycle of, the decoupled 
> response endpoint (DRE).
> >
> > Without rehashing the entire thread, my reasons briefly are:
> >
> > 1. Separation of concerns
> >
> > The DRE is an aspect of the transport and thus should be 
> created and 
> > referenced from within the realm of the transport.
> 
> 
> Then why aren't we creating other decoupled endpoints from 
> the transport layer? 


Because the DRE is the only canonical back-channel IMO. By canonical, I mean you've got to have a back-channel for decoupled request/response MEPs to occur. 

The faultTo on the other hand, is an added convenience provided by WS-A, but it is not central to the normal decoupled request/response paradigm.

The acksTo is even less central, as its obviously used only for out-of-band RM messaging.

In the normal case, the degrees of freedom presented by the faultTo and acksTo are not required by applications, i.e. they're happy to allow these default to be the same as the DRE. 

In the less usual case where the application wants to set the faultTo and/or acksTo to a different address, then it has to do a bit more work.


> This assumes a 1:1 association which isn't so.


Do you mean a 1:1 association between Conduits and Destinations?

I don't think it does necessarily, rather it depends on how the DestinationFactory is implemented.

Currently DestinationFactory.getDestination() returns a brand new Destination each time, but it could be changed easily so that subsequent calls to getDestination() with the same EndpointInfo get back the same instance, possibly with a ref-count that's decremented in Destination.shutdown(). I think you suggested something similar yourself in the earlier thread. 

I think the assumed association that's actually inappropriate is the one between a Client and Destination, or even between a Client and Conduit. I won't re-hash the reasons for this, as I'm guessing anyone reading this thread will soon lose the will to live if either of us repeat ourselves any further :)

 
> On the other hand, the purpose of the Client is to set up 
> interceptor chains
> > and dispatch the invocation. Such invocations may NOT 
> require a DRE, 
> > or even a Conduit for that matter. Thus I think it 
> inappropriate for 
> > the Client to be concerned with the creation of the DRE, and would 
> > even go one step further and move the Conduit creation to the 
> > MessageSenderInterceptor, so that a Conduit comes into 
> being only if it really is needed.
> 
> 
> Then do you want to get rid of 
> Exchange.getConduit/getDestination or 
> Message.getConduit/getDestination as well? 


I think there's a big difference here. Exchange/Message.getConduit() are just accessors. Client.getConduit() currently causes the creation of a Conduit. 


> Just because you 
> want to not require the conduit doesn't mean that there 
> shouldn't be conduit/destination properties on the Client. 
> This is completely orthogonal to the issue.


So how would a user suppress the Client's creation of a Conduit if its only when the dispatch gets as far as some interceptor that the dispatch is diverted in such as a way as to not require a Conduit? Note the Conduit is created *up-front* by the Client, before InterceptorChain.doInterceptor() is called for the outward dispatch.

 
> 2. Avoid forcing the usage of a Client instance
> >
> > In general, if A is to be responsible for maintaining a 
> reference to 
> > B, then its reasonable to expect that the existence of a B 
> implies the 
> > existence of an A. Otherwise, in some cases an instance of 
> A will have 
> > be artificially created, solely to manage the reference to B.
> >
> > But if a DRE is in use, then the *only* other thing we're 
> guaranteed 
> > also exists is the corresponding Conduit.
> >
> > IMO we should neither require the usage of a Client instance to 
> > mediate invocations, nor impose any undue burden on 
> applications that 
> > choose to wire up the interceptor chains directly and 
> initiate dispatch themselves.
> >
> > An example of an undue burden would be forcing such applications to 
> > either always create the DRE *programmatically* via 
> > DestinationFactory.getDestination(), or if they want the DRE to be 
> > specified declaratively, to manage this configuration themselves.
> 
> 
> Undue burden? Where is the undue burden?


The undue burden is NOT in driving the programmatic API. I agree the amount of work there is roughly the same.

The problem is that there should be declarative mechanism as well as a programmatic API. The application doesn't necessarily want to hard-code the DRE address. 

This declarative mechanism is currently provided by the Conduit configuration. Any application can take advantage of this, regardless of how the invocation is dispatched (whether via the Client, Dispatch, direct InterceptorChain.doIntercept(), whatever) because if it's a remote invocation, there's *always* going to be a Conduit instance involved. 

You're proposing moving this config to hang off the Client instead. As a result the application would be forced to either (a) use the Client in order to declaratively specify the DRE, or (b) invent and manage its own config mechanism. Makes sense, or?

 
> Your approach:
> 
> Conduit conduit = conduitInitiator.getConduit(Endpoint);
> ConduitPolicy policy = conduit.getConduitPolicy(); 
> policy.setDecoupledEndpoint (replyToEPR); 
> conduit.setMessageObserver(myObserver);
> 
> My approach:
> 
> Conduit conduit = conduitInitiator.getConduit(Endpoint);
> DestinationFactory destination = 
> destinationFactory.getDestination (replyToEPR); 
> destination.setMessageObser(myObserver);
> conduit.setMessageObserver(myObserver); // if you need to 
> listen for back channel messages
> 
> It is arguably the SAME amount of work. 


Agreed. See above though why this isn't the issue.


> The benefit of the 
> latter is its consistent.
> 
> 3. Suitability for JMS
> >
> > In order to setup a Destination, JMS may require more 
> information than 
> > can be easily shoe-horned into an EPR. Stuff like a JNDI provider, 
> > ConnectionFactory username/password etc.
> >
> > Now I don't accept the JMS as odd-man-out argument, especially when 
> > most of the counter-examples wheeled out ( i.e. XMPP, TCP, 
> FTP) do not 
> > currently even exist as CXF transports. I could just as 
> easily make up 
> > a list of non-existent transports that suggests that the 
> > URI-friendliness of HTTP is the exceptional case, but 
> obviously you'd 
> > argue my list was hypothetical and proved nothing. And 
> you'd be right 
> > :)
> >
> > Neither does the "most people just use HTTP" line wash with 
> me. One of 
> > the design centres of CXF is to be a multi-transport stack, 
> and that 
> > in my book amounts to more than just paying lip-service to 
> non-HTTP transports.
> 
> 
> Even if there isn't enough information in the JMS EPR to 
> completely set up a JMS endpoint, it doesn't mean its 
> completely useless. It can still be a nice way to hang onto 
> references of a JMS endpoint that I've set up earlier on.
> For instance, a user could enter in the jms:// EPR in a 
> configuration screen. By calling 
> DestinationFactory.getDestination(epr) it would then retrieve 
> a previously configured instance of the JMS destination.


Sure that could work.

And my point along is that we would have to take some JMS-specific approach like this, and thus lose one of the main purported benefits of your proposal, i.e. that the mechanism for setting up the DRE is consistent across transports.

 
> Also I'd like to respond quickly to a couple of specific 
> points that Dan
> > makes in his proposal:
> >
> > "Right now if you want to create different endpoints for receiving 
> > ReplyTos and FaultTos you have configure the ReplyTos using the 
> > Conduit API and the FaultTos using the destination API. 
> Creating those 
> > endpoints in different ways is bad IMO."
> >
> > So how would this be any different under your proposal? Is the 
> > implication that in addition to a Client.setAsynchronousEndpoint() 
> > API, you'd also add
> > Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), and 
> > similarly expose <faultToEndpoint> and <acksToEndpoint> elements in 
> > your proposed <client> bean?
> 
> 
> If so, this would expose *way* too much of WS-A and WS-RM 
> semantics directly
> > in the Client, which should IMO be independent of such QoS 
> concerns. 
> > The CXF WS-A and WS-RM layers were specifically designed to be 
> > pluggable, so that they could slotted into the runtime 
> without impact 
> > on the core APIs. I would be strongly against a move that 
> breaks this 
> > ... I mean, what next, Client.setSecurityPolicyToken()??
> 
> 
> If on the other hand, if you're not suggesting polluting the 
> Client with
> > those aspects of WS-A & WS-RM, can you explain how your proposal 
> > provides a consistent mechanism for specifying the faultTo & acksTo 
> > vis-à-vis the replytTo?
> 
> 
> No, I was more referring to scenarios where someone is not 
> using the Client.
> The one you seem to be so concerned about in #1.


So regardless of whether:

(a) we hang the DRE config off the Conduit (as is currently the case) or the Client (as you propose),

or

(b) the application chooses to use the Client or some other mechanism to mediate the invocation

Would you agree that if the application wants to set the faultTo or acksTo to some other address than the replyTo, then they would have to do so in a way that's not consistent with whatever way the replyTo is set?

If so, I think the setting of the faultTo/acksTo is neutral to the argument, and neither bolsters your case nor mine.



> Another point which I strongly disagree with:
> >
> > "If all Conduits share the same code for setting up decoupled 
> > destinations, that is a sign to me that we can take it out 
> of the Conduit."
> >
> > I've never come across a design principle that suggests 
> having common 
> > code in a common base class is a sign that such code should 
> be moved elsewhere.
> > In fact what purpose do common base classes serve, other than to 
> > factor out commonality from sub-classes?
> 
> 
> Base classes would be another solution to that problem.  I 
> wasn't trying to say base classes are evil. I was trying to 
> say that the concept of a decoupled endpoint isn't critical 
> to the concept of a Conduit, and so I think it should be 
> taken out. Sometimes you can simplify the classes and then 
> incorporate more advanced concepts into another class. For 
> instance, in Microsoft's WCF, you have the IDuplexChannel 
> which extends the IInputChannel and IOutputChannel.  I don't 
> think that is so outrageous really...


Agreed, not outrageous, just another way of doing it that happens to suit WCF.

/Eoghan

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/17/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
>
> My position is that the Conduit should continue to hold to the reference
> to, and manage the lifecycle of, the decoupled response endpoint (DRE).
>
> Without rehashing the entire thread, my reasons briefly are:
>
> 1. Separation of concerns
>
> The DRE is an aspect of the transport and thus should be created and
> referenced from within the realm of the transport.


Then why aren't we creating other decoupled endpoints from the transport
layer? This assumes a 1:1 association which isn't so.

On the other hand, the purpose of the Client is to set up interceptor chains
> and dispatch the invocation. Such invocations may NOT require a DRE, or even
> a Conduit for that matter. Thus I think it inappropriate for the Client to
> be concerned with the creation of the DRE, and would even go one step
> further and move the Conduit creation to the MessageSenderInterceptor, so
> that a Conduit comes into being only if it really is needed.


Then do you want to get rid of Exchange.getConduit/getDestination or
Message.getConduit/getDestination as well? Just because you want to not
require the conduit doesn't mean that there shouldn't be conduit/destination
properties on the Client. This is completely orthogonal to the issue.

2. Avoid forcing the usage of a Client instance
>
> In general, if A is to be responsible for maintaining a reference to B,
> then its reasonable to expect that the existence of a B implies the
> existence of an A. Otherwise, in some cases an instance of A will have be
> artificially created, solely to manage the reference to B.
>
> But if a DRE is in use, then the *only* other thing we're guaranteed also
> exists is the corresponding Conduit.
>
> IMO we should neither require the usage of a Client instance to mediate
> invocations, nor impose any undue burden on applications that choose to wire
> up the interceptor chains directly and initiate dispatch themselves.
>
> An example of an undue burden would be forcing such applications to either
> always create the DRE *programmatically* via
> DestinationFactory.getDestination(), or if they want the DRE to be
> specified declaratively, to manage this configuration themselves.


Undue burden? Where is the undue burden?

Your approach:

Conduit conduit = conduitInitiator.getConduit(Endpoint);
ConduitPolicy policy = conduit.getConduitPolicy();
policy.setDecoupledEndpoint (replyToEPR);
conduit.setMessageObserver(myObserver);

My approach:

Conduit conduit = conduitInitiator.getConduit(Endpoint);
DestinationFactory destination = destinationFactory.getDestination
(replyToEPR);
destination.setMessageObser(myObserver);
conduit.setMessageObserver(myObserver); // if you need to listen for back
channel messages

It is arguably the SAME amount of work. The benefit of the latter is its
consistent.

3. Suitability for JMS
>
> In order to setup a Destination, JMS may require more information than can
> be easily shoe-horned into an EPR. Stuff like a JNDI provider,
> ConnectionFactory username/password etc.
>
> Now I don't accept the JMS as odd-man-out argument, especially when most
> of the counter-examples wheeled out ( i.e. XMPP, TCP, FTP) do not
> currently even exist as CXF transports. I could just as easily make up a
> list of non-existent transports that suggests that the URI-friendliness of
> HTTP is the exceptional case, but obviously you'd argue my list was
> hypothetical and proved nothing. And you'd be right :)
>
> Neither does the "most people just use HTTP" line wash with me. One of the
> design centres of CXF is to be a multi-transport stack, and that in my book
> amounts to more than just paying lip-service to non-HTTP transports.


Even if there isn't enough information in the JMS EPR to completely set up a
JMS endpoint, it doesn't mean its completely useless. It can still be a nice
way to hang onto references of a JMS endpoint that I've set up earlier on.
For instance, a user could enter in the jms:// EPR in a configuration
screen. By calling DestinationFactory.getDestination(epr) it would then
retrieve a previously configured instance of the JMS destination.

Also I'd like to respond quickly to a couple of specific points that Dan
> makes in his proposal:
>
> "Right now if you want to create different endpoints for receiving
> ReplyTos and FaultTos you have configure the ReplyTos using the Conduit API
> and the FaultTos using the destination API. Creating those endpoints in
> different ways is bad IMO."
>
> So how would this be any different under your proposal? Is the implication
> that in addition to a Client.setAsynchronousEndpoint() API, you'd also add
> Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), and similarly
> expose <faultToEndpoint> and <acksToEndpoint> elements in your proposed
> <client> bean?


If so, this would expose *way* too much of WS-A and WS-RM semantics directly
> in the Client, which should IMO be independent of such QoS concerns. The CXF
> WS-A and WS-RM layers were specifically designed to be pluggable, so that
> they could slotted into the runtime without impact on the core APIs. I would
> be strongly against a move that breaks this ... I mean, what next,
> Client.setSecurityPolicyToken()??


If on the other hand, if you're not suggesting polluting the Client with
> those aspects of WS-A & WS-RM, can you explain how your proposal provides a
> consistent mechanism for specifying the faultTo & acksTo vis-à-vis the
> replytTo?


No, I was more referring to scenarios where someone is not using the Client.
The one you seem to be so concerned about in #1.

Another point which I strongly disagree with:
>
> "If all Conduits share the same code for setting up decoupled
> destinations, that is a sign to me that we can take it out of the Conduit."
>
> I've never come across a design principle that suggests having common code
> in a common base class is a sign that such code should be moved elsewhere.
> In fact what purpose do common base classes serve, other than to factor out
> commonality from sub-classes?


Base classes would be another solution to that problem.  I wasn't trying to
say base classes are evil. I was trying to say that the concept of a
decoupled endpoint isn't critical to the concept of a Conduit, and so I
think it should be taken out. Sometimes you can simplify the classes and
then incorporate more advanced concepts into another class. For instance, in
Microsoft's WCF, you have the IDuplexChannel which extends the IInputChannel
and IOutputChannel.  I don't think that is so outrageous really...

- Dan

-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
I don't think I am the best person to summarize them, but I believe Eoghan's
objections are

1. A Client should not require a Conduit. Hence, we should get rid of
get/setConduit on Client.

2. It is the responsibility of the Conduit to manage the decoupled endpoint.
We should introduce a ClientPolicy object to deal with this instead:

Client.getPolicy(ClientPolicy.class).setDecoupledEndpoint(endpoint);

3. We shouldn't be forced to use a Client for decoupled interactions

I'll let Eoghan make a proper argument for his proposal before I respond...

- Dan

On 3/17/07, Ted Neward <te...@tedneward.com> wrote:
>
> Can you summarize the arguments *against* this proposal? Arguments for
> without arguments against sort of skews the perception pretty strongly....
>
> Ted Neward
> Java, .NET, XML Services
> Consulting, Teaching, Speaking, Writing
> http://www.tedneward.com
>
> > -----Original Message-----
> > From: Dan Diephouse [mailto:dan@envoisolutions.com]
> > Sent: Friday, March 16, 2007 3:20 PM
> > To: cxf-dev@incubator.apache.org
> > Subject: [PROPOSAL] Client and Conduit changes
> >
> > For those of you who haven't been following the long discussion Eoghan
> and
> > I
> > have been having, I'm going to take a moment to summarize my proposal
> > here.
> > I consider it rather important. If we don't reach any consensus on the
> > proposal (it sucks/doesn't suck) or if Eoghan & I are the only ones who
> > participate, I'll probably start a vote. So do your communal duty and
> > participate so I don't have to do that! :-)
> >
> > I propose the following:
> >
> > 1. API to set an Asynchronous EndpointReference
> > I believe we should create a simple method on the Client which allows
> the
> > user to specify the asynchronous endpoint that they wish to have used
> for
> > decoupled responses:
> >
> > Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> >
> > The Client would check to see if this EPR was set. If so, it would call
> > DestinationFactory.getDestination(epr) for the EPR and use that as the
> > asynchronous destination. This would result in a standard way to
> > automatically set up the decoupled destination when using the API.
> >
> > While it has been said that this isn't generic enough for JMS, I don't
> > agree. First, I believe that JMS will eventually get a self contained
> IRI
> > format which can be stuck in an EPR. We could even create our own
> > proprietary format. Second, JMS is an edge case. There are other
> > transports
> > beside just JMS and HTTP, like XMPP or TCP or FTP which work just fine
> > with
> > URIs. JMS is the odd ball in the sense that historically it has needed
> > stuff
> > outside the EPR.
> >
> > 2. Access to the Conduits and Destinations
> > I would like to add the following methods to the Client:
> >
> > void setConduit(Conduit) - this allows a user to easily specify an
> > alternate
> > Conduit.
> > void setAsynchronousDestination(Destination) - this allows a user to
> > easily
> > specify a decoupled endpoint. It's address would be used for
> WS-Addressing
> > interactions. If no Async destination exists, then the Client will only
> > listen on the Conduit.
> > Destination getAsynchronousDestination() - utility method to easily get
> > the
> > asynchronous destination
> >
> > 3. Client.close();
> > We need a way to shutdown the decouled endpoints (regardless of whether
> or
> > not #1 & #2 are adopted). I think there is pretty good conensus we need
> a
> > Client.close() method which will do this. It will call
> > getConduit().close()
> > and getAsynchronousDestination().shutdown().
> >
> > (Ideally we'd like to be able to shut down RM at this same time. I'm
> going
> > to guess that this would require the addition of a client lifecycle
> > interface which allows RM to listen for Client.close(). This is an issue
> > no
> > matter which route we go though, so I'll defer this conversation for
> > another
> > thread)
> >
> > 4. Remove the setup of decoupled destinations from inside the Conduit
> > Currently, the Conduits are responsible for setting up the decoupled
> > destinations. We've already got a perfectly good API for creating
> > destinations, lets use it! Creating another API to create decoupled
> > destinations introduces inconsistencies into our APIs. Right now if you
> > want
> > to create different endpoints for receiving ReplyTos and FaultTos you
> have
> > configure the ReplyTos using the Conduit API and the FaultTos using the
> > destination API. Creating those endpoints in different ways is bad IMO.
> >
> > Putting in decoupled destinations inside the Conduit also makes it more
> > complex for transport writers or people trying to understand the API.
> IMO,
> > people intuitively expect this to be outside the Conduit class.
> >
> > 5. Client Configuration
> > I would propose that we make the decoupled destination configuration
> part
> > of
> > the Client
> >
> > <jaxws:client id="...SomePort">
> >   <jaxws:asynchronousEndpoint>
> >     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
> >   </jaxws:asynchronousEndpoint>
> > </jaxws:client>
> >
> > <jaxws:client id="...SomePort">
> >
> >
> <jaxws:asynchronousDestination><http:destination...></jaxws:asynchronousDe
> > stination>
> > </jaxws:client>
> >
> > As an added bonus, we can now wire together clients and destinations
> > however
> > we want. I wouldn't *have* to create a <conduit> config element with the
> > port name inside it. Instead I could simply do:
> >
> > <jaxws:client id="...SomePort">
> >    <jaxws:conduit> <http:conduit... /> </jaxws:conduit>
> > </jaxws:client>
> >
> > It also creates a central place to embed Client configuration - such as
> > enabling MTOM or configuring WS-*:
> > <jaxws:client id="...SomePort">
> >    <jaxws:conduit>...</jaxws:conduit>
> >    <jaxws:binding mtomEnabled="true">
> >      <jaxws:requestContext>
> >        <map><entry key="javax.xml.ws.session.maintain"
> > value="true"/></map>
> >      </jaxws:requestContext>
> >    </jaxws:binding>
> >    <jaxws:features>
> >      <wsrm:reliability timeout="10000" .../>
> >    </jaxws:features>
> > </jaxws:client>
> >
> > Users could still use the <http:conduit id="PORT"/> syntax if they
> wanted
> > to
> > though.
> >
> > (Note: I haven't written the jaxws:client Spring schema yet, but its on
> my
> > todo list. The feature stuff will hopefully be part of my commit with
> > WS-Security)
> >
> > 6. Bring back Destination.getDestination(EndpointReferenceType)
> > This method would be needed for the API that I propose in #1.
> >
> > 7. Make the JAX-WS dispatch use the client.
> >
> > ----
> >
> > In summary:
> > a) This simplifies the API. We've created an API to set up decoupled
> > endpoints easily. We've reduced the complexity inside Conduits and have
> > avoided introducing new complexity onto the Conduit interface to specify
> a
> > decoupled destination.
> >
> > b) It creates a consistent API for working with decoupled endpoints.
> There
> > is no reason to go writing a new API for setting up decoupled endpoints
> -
> > which is only used sometimes.
> >
> > c) Dependency Injenction: By putting the Conduit & Destination on the
> > Client
> > we've made it much friendlier to people using Spring or other DI
> > containers.
> >
> > d) Improved configuration: I think the jaxws:client is a more natural
> > place
> > to setup the conduit and destination configuration as opposed to nesting
> > the
> > destination configuration inside the conduit.
> >
> > e) Setting up decoupled destinations is not the job of the conduit IMO.
> > We're giving Conduits a dual task unnecessarily. If all Conduits share
> the
> > same code for setting up decoupled destinations, that is a sign to me
> that
> > we can take it out of the Conduit.
> >
> > I of course would be volunteering to do all this work.
> > --
> >
> > Alternatives: While Eoghan can elaborate, I believe he would rather see
> > 1. The decoupled endpoint remain part of the conduit. He views a
> decoupled
> > endpoint as part of the Conduit contract.
> > 2. An API on the Conduit to set up the decoupled endpoint like so:
> > Client.get(Conduit.class
> > ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> > 3. The Client.getConduit/setConduit methods go away and have the Conduit
> > be
> > an optional part of the Client
> > 4. No Client.setAsynchronousDestination method.
> > 5. Keep the decoupled endpoint configuration as part of the conduit
> > instead
> > of the client.
> >
> > Regards,
> > - Dan
> >
> > --
> > Dan Diephouse
> > Envoi Solutions
> > http://envoisolutions.com | http://netzooid.com/blog
> >
> > --
> > No virus found in this incoming message.
> > Checked by AVG Free Edition.
> > Version: 7.5.446 / Virus Database: 268.18.11/722 - Release Date:
> 3/14/2007
> > 3:38 PM
> >
>
> --
> No virus found in this outgoing message.
> Checked by AVG Free Edition.
> Version: 7.5.446 / Virus Database: 268.18.11/722 - Release Date: 3/14/2007
> 3:38 PM
>
>
>


-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/19/07, Johnson, Eric <Er...@iona.com> wrote:
>
> So currently all the Client, and the JAX-WS Dispatch, do in terms of
> messaging duties is wire the interceptor chain together, pass messages
> to the interceptor chain, and receive messages that are pushed back up
> the interceptor chain?
>
> It is the Conduit and transport level code that is responsible for doing
> all of the correlation work?



If that is true, I'm -1 on Dan's proposal. Eoghan's concerns about
> seperation of concerns is well placed. While it makes writing a
> transport thornier, it is the transport layer that owns the thorns.


Well for the deocupled case the Conduit doesn't really need to do much
correlation. I don't really see many thorns there that need to be
encapsulated.

- Dan

-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

RE: [PROPOSAL] Client and Conduit changes

Posted by "Johnson, Eric" <Er...@iona.com>.
So currently all the Client, and the JAX-WS Dispatch, do in terms of
messaging duties is wire the interceptor chain together, pass messages
to the interceptor chain, and receive messages that are pushed back up
the interceptor chain?

It is the Conduit and transport level code that is responsible for doing
all of the correlation work?

If that is true, I'm -1 on Dan's proposal. Eoghan's concerns about
seperation of concerns is well placed. While it makes writing a
transport thornier, it is the transport layer that owns the thorns. 

> -----Original Message-----
> From: Glynn, Eoghan [mailto:eoghan.glynn@iona.com] 
> Sent: Monday, March 19, 2007 6:40 PM
> To: cxf-dev@incubator.apache.org
> Subject: RE: [PROPOSAL] Client and Conduit changes
> 
>  
> 
> > -----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 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.
> 
>  
> > 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.
> 
> 
>  
> > 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.
> 
>  
> > 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.
> 
> 
> > 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.
> 
> 
> > 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. 
> 
> 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.
> 
>  
> >  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. 
> 
>  
> > 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.
> 
>  
> > 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.
> 
> 
> > 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.
> 
> 
> > > 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.
> 
> Cheers,
> Eoghan,.
> 

Re: [PROPOSAL] Client and Conduit changes

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 3/19/07, Glynn, Eoghan <eo...@iona.com> wrote:

>
> > 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.


Just to be clear, this is a constraint we're imposing. Our architecture does
not impose it.

> 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.


Again to be clear, I am not advocating that the Client do the correlations.

> 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?


It should be using the Client. I have an open JIRA for this. The problem
before was that you were forced to use the Bare/Wrapped/RPC interceptors for
databinding, which isn't so amenable to Dispatches.  Now we have a nice way
to disable this, so I don't see it as much of an issue.

> 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.


 I would like it to be one way, but thats a longer discussion... :-)



- Dan



-- 
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog

Re: [PROPOSAL] Client and Conduit changes

Posted by Polar Humenn <ph...@iona.com>.
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,.
>   


RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----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 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.

 
> 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.


 
> 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.

 
> 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.


> 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.


> 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. 

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.

 
>  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. 

 
> 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.

 
> 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.


> 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.


> > 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.

Cheers,
Eoghan,.

Re: [PROPOSAL] Client and Conduit changes

Posted by Polar Humenn <ph...@iona.com>.
Glynn, Eoghan wrote:
>  
>
>   
>> -----Original Message-----
>> From: Polar Humenn [mailto:phumenn@iona.com] 
>> Sent: 19 March 2007 14:25
>> To: cxf-dev@incubator.apache.org
>> Subject: Re: [PROPOSAL] Client and Conduit changes
>>
>> I've got a couple of CXF architectural questions.
>>
>> 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"?

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.

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.

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), 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.

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. 
Therefore The Client should be setting the "response" endpoints 
(Destination? BackChannel? DecoupledEndpoint?), shouldn't it?

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?

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".

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.

 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?).

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?

If the JAX-WS Dispatch doesn't use a client, then what does it use? 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.

> We discussed a couple of these scenarios in the "Client API, EPRs" thread, specifically where the JAX-WS Dispatch mechanism is used, or where the application wires together the interceptor chains itself.
>
>
>
>   
>> Does the client that 
>> send the invocation request get notified of the response, 
>> fault, or ack? 
>>     
>
>
> 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?

Cheers,
-Polar
> This *may* be the Client instance. Or something else entirely.
>
>
>   
>> How are the responses (many?) are correlated 
>> to the client invocation.
>>     
>
> Zero, or 1 depending on the MEP (whether oneway or twoway).
>
> There's also the issue of partial responses (lets not go there on the detail, you can look in the archive for lengthy discussions on this subject). But there 
>
>  
>   
>> Is there actually an object called a "Request" that does this 
>> correlation? Should there be?
>>
>> When I send a "reply-To" or "fault-To" or "ack-To" property 
>> is that on single message? Or is it on a single connection 
>> (for many messages)? 
>> What is the request/response correction based on? Is there an 
>> object in CXF that represents it, or is that done by the 
>> Client, the Conduit, or something else?
>>
>> Cheers,
>> -Polar
>>
>> Glynn, Eoghan wrote:
>>     
>>> My position is that the Conduit should continue to hold to 
>>>       
>> the reference to, and manage the lifecycle of, the decoupled 
>> response endpoint (DRE).
>>     
>>> Without rehashing the entire thread, my reasons briefly are:
>>>
>>> 1. Separation of concernsApache CXF - logged to 
>>> http://dev.rectang.com/logs/codehaus/%23cxf/
>>>
>>> The DRE is an aspect of the transport and thus should be 
>>>       
>> created and referenced from within the realm of the transport.
>>     
>>> On the other hand, the purpose of the Client is to set up 
>>>       
>> interceptor chains and dispatch the invocation. Such 
>> invocations may NOT require a DRE, or even a Conduit for that 
>> matter. Thus I think it inappropriate for the Client to be 
>> concerned with the creation of the DRE, and would even go one 
>> step further and move the Conduit creation to the 
>> MessageSenderInterceptor, so that a Conduit comes into being 
>> only if it really is needed.    
>>     
>>> 2. Avoid forcing the usage of a Client instance
>>>
>>> In general, if A is to be responsible for maintaining a 
>>>       
>> reference to B, then its reasonable to expect that the 
>> existence of a B implies the existence of an A. Otherwise, in 
>> some cases an instance of A will have be artificially 
>> created, solely to manage the reference to B.  
>>     
>>> But if a DRE is in use, then the *only* other thing we're 
>>>       
>> guaranteed also exists is the corresponding Conduit.
>>     
>>> IMO we should neither require the usage of a Client 
>>>       
>> instance to mediate invocations, nor impose any undue burden 
>> on applications that choose to wire up the interceptor chains 
>> directly and initiate dispatch themselves.
>>     
>>> An example of an undue burden would be forcing such 
>>>       
>> applications to either always create the DRE 
>> *programmatically* via DestinationFactory.getDestination(), 
>> or if they want the DRE to be specified declaratively, to 
>> manage this configuration themselves.  
>>     
>>> 3. Suitability for JMS
>>>
>>> In order to setup a Destination, JMS may require more 
>>>       
>> information than can be easily shoe-horned into an EPR. Stuff 
>> like a JNDI provider, ConnectionFactory username/password etc. 
>>     
>>> Now I don't accept the JMS as odd-man-out argument, especially when 
>>> most of the counter-examples wheeled out (i.e. XMPP, TCP, 
>>>       
>> FTP) do not 
>>     
>>> currently even exist as CXF transports. I could just as 
>>>       
>> easily make up 
>>     
>>> a list of non-existent transports that suggests that the 
>>> URI-friendliness of HTTP is the exceptional case, but 
>>>       
>> obviously you'd 
>>     
>>> argue my list was hypothetical and proved nothing. And 
>>>       
>> you'd be right 
>>     
>>> :)
>>>
>>> Neither does the "most people just use HTTP" line wash with 
>>>       
>> me. One of the design centres of CXF is to be a 
>> multi-transport stack, and that in my book amounts to more 
>> than just paying lip-service to non-HTTP transports.  
>>     
>>> Also I'd like to respond quickly to a couple of specific 
>>>       
>> points that Dan makes in his proposal:
>>     
>>> "Right now if you want to create different endpoints for 
>>>       
>> receiving ReplyTos and FaultTos you have configure the 
>> ReplyTos using the Conduit API and the FaultTos using the 
>> destination API. Creating those endpoints in different ways 
>> is bad IMO."
>>     
>>> So how would this be any different under your proposal? Is 
>>>       
>> the implication that in addition to a 
>> Client.setAsynchronousEndpoint() API, you'd also add 
>> Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), 
>> and similarly expose <faultToEndpoint> and <acksToEndpoint> 
>> elements in your proposed <client> bean?
>>     
>>> If so, this would expose *way* too much of WS-A and WS-RM 
>>>       
>> semantics directly in the Client, which should IMO be 
>> independent of such QoS concerns. The CXF WS-A and WS-RM 
>> layers were specifically designed to be pluggable, so that 
>> they could slotted into the runtime without impact on the 
>> core APIs. I would be strongly against a move that breaks 
>> this ... I mean, what next, Client.setSecurityPolicyToken()??
>>     
>>> If on the other hand, if you're not suggesting polluting 
>>>       
>> the Client with those aspects of WS-A & WS-RM, can you 
>> explain how your proposal provides a consistent mechanism for 
>> specifying the faultTo & acksTo vis-à-vis the replytTo?
>>     
>>> Another point which I strongly disagree with:
>>>
>>> "If all Conduits share the same code for setting up 
>>>       
>> decoupled destinations, that is a sign to me that we can take 
>> it out of the Conduit."
>>     
>>> I've never come across a design principle that suggests 
>>>       
>> having common code in a common base class is a sign that such 
>> code should be moved elsewhere. In fact what purpose do 
>> common base classes serve, other than to factor out 
>> commonality from sub-classes?
>>     
>>> Cheers,
>>> Eoghan
>>>
>>>   
>>>       
>>>> -----Original Message-----
>>>> From: Dan Diephouse [mailto:dan@envoisolutions.com]
>>>> Sent: 16 March 2007 22:20
>>>> To: cxf-dev@incubator.apache.org
>>>> Subject: [PROPOSAL] Client and Conduit changes
>>>>
>>>> For those of you who haven't been following the long discussion 
>>>> Eoghan and I have been having, I'm going to take a moment to 
>>>> summarize my proposal here.
>>>> I consider it rather important. If we don't reach any consensus on 
>>>> the proposal (it sucks/doesn't suck) or if Eoghan & I are the only 
>>>> ones who participate, I'll probably start a vote. So do 
>>>>         
>> your communal 
>>     
>>>> duty and participate so I don't have to do that! :-)
>>>>
>>>> I propose the following:
>>>>
>>>> 1. API to set an Asynchronous EndpointReference I believe 
>>>>         
>> we should 
>>     
>>>> create a simple method on the Client which allows the user 
>>>>         
>> to specify 
>>     
>>>> the asynchronous endpoint that they wish to have used for 
>>>>         
>> decoupled 
>>     
>>>> responses:
>>>>
>>>> Client.getAsynchronousEndpoint(EndpointReferenceType epr);
>>>>
>>>> The Client would check to see if this EPR was set. If so, it would 
>>>> call
>>>> DestinationFactory.getDestination(epr) for the EPR and use that as 
>>>> the asynchronous destination. This would result in a 
>>>>         
>> standard way to 
>>     
>>>> automatically set up the decoupled destination when using the API.
>>>>
>>>> While it has been said that this isn't generic enough for JMS, I 
>>>> don't agree. First, I believe that JMS will eventually get a self 
>>>> contained IRI format which can be stuck in an EPR.
>>>> We could even create our own proprietary format. Second, JMS is an 
>>>> edge case. There are other transports beside just JMS and 
>>>>         
>> HTTP, like 
>>     
>>>> XMPP or TCP or FTP which work just fine with URIs. JMS is the odd 
>>>> ball in the sense that historically it has needed stuff 
>>>>         
>> outside the 
>>     
>>>> EPR.
>>>>
>>>> 2. Access to the Conduits and Destinations I would like to add the 
>>>> following methods to the Client:
>>>>
>>>> void setConduit(Conduit) - this allows a user to easily specify an 
>>>> alternate Conduit.
>>>> void setAsynchronousDestination(Destination) - this allows 
>>>>         
>> a user to 
>>     
>>>> easily specify a decoupled endpoint. It's address would be 
>>>>         
>> used for 
>>     
>>>> WS-Addressing interactions. If no Async destination 
>>>>         
>> exists, then the 
>>     
>>>> Client will only listen on the Conduit.
>>>> Destination getAsynchronousDestination() - utility method 
>>>>         
>> to easily 
>>     
>>>> get the asynchronous destination
>>>>
>>>> 3. Client.close();
>>>> We need a way to shutdown the decouled endpoints (regardless of 
>>>> whether or not #1 & #2 are adopted). I think there is pretty good 
>>>> conensus we need a
>>>> Client.close() method which will do this. It will call
>>>> getConduit().close() and getAsynchronousDestination().shutdown().
>>>>
>>>> (Ideally we'd like to be able to shut down RM at this same 
>>>>         
>> time. I'm 
>>     
>>>> going to guess that this would require the addition of a client 
>>>> lifecycle interface which allows RM to listen for Client.close(). 
>>>> This is an issue no matter which route we go though, so I'll defer 
>>>> this conversation for another
>>>> thread)
>>>>
>>>> 4. Remove the setup of decoupled destinations from inside 
>>>>         
>> the Conduit 
>>     
>>>> Currently, the Conduits are responsible for setting up the 
>>>>         
>> decoupled 
>>     
>>>> destinations. We've already got a perfectly good API for creating 
>>>> destinations, lets use it! Creating another API to create 
>>>>         
>> decoupled 
>>     
>>>> destinations introduces inconsistencies into our APIs. 
>>>>         
>> Right now if 
>>     
>>>> you want to create different endpoints for receiving ReplyTos and 
>>>> FaultTos you have configure the ReplyTos using the Conduit API and 
>>>> the FaultTos using the destination API. Creating those 
>>>>         
>> endpoints in 
>>     
>>>> different ways is bad IMO.
>>>>
>>>> Putting in decoupled destinations inside the Conduit also makes it 
>>>> more complex for transport writers or people trying to 
>>>>         
>> understand the 
>>     
>>>> API. IMO, people intuitively expect this to be outside the Conduit 
>>>> class.
>>>>
>>>> 5. Client Configuration
>>>> I would propose that we make the decoupled destination 
>>>>         
>> configuration 
>>     
>>>> part of the Client
>>>>
>>>> <jaxws:client id="...SomePort">
>>>>   <jaxws:asynchronousEndpoint>
>>>>     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
>>>>   </jaxws:asynchronousEndpoint>
>>>> </jaxws:client>
>>>>
>>>> <jaxws:client id="...SomePort">
>>>>
>>>> <jaxws:asynchronousDestination><http:destination...></jaxws:as
>>>> ynchronousDestination>
>>>> </jaxws:client>
>>>>
>>>> As an added bonus, we can now wire together clients and 
>>>>         
>> destinations 
>>     
>>>> however we want. I wouldn't *have* to create a <conduit> config 
>>>> element with the port name inside it.
>>>> Instead I could simply do:
>>>>
>>>> <jaxws:client id="...SomePort">
>>>>    <jaxws:conduit> <http:conduit... /> </jaxws:conduit> 
>>>> </jaxws:client>
>>>>
>>>> It also creates a central place to embed Client configuration
>>>> - such as enabling MTOM or configuring WS-*:
>>>> <jaxws:client id="...SomePort">
>>>>    <jaxws:conduit>...</jaxws:conduit>
>>>>    <jaxws:binding mtomEnabled="true">
>>>>      <jaxws:requestContext>
>>>>        <map><entry key="javax.xml.ws.session.maintain" 
>>>> value="true"/></map>
>>>>      </jaxws:requestContext>
>>>>    </jaxws:binding>
>>>>    <jaxws:features>
>>>>      <wsrm:reliability timeout="10000" .../>
>>>>    </jaxws:features>
>>>> </jaxws:client>
>>>>
>>>> Users could still use the <http:conduit id="PORT"/> syntax if they 
>>>> wanted to though.
>>>>
>>>> (Note: I haven't written the jaxws:client Spring schema 
>>>>         
>> yet, but its 
>>     
>>>> on my todo list. The feature stuff will hopefully be part of my 
>>>> commit with
>>>> WS-Security)
>>>>
>>>> 6. Bring back Destination.getDestination(EndpointReferenceType)
>>>> This method would be needed for the API that I propose in #1.
>>>>
>>>> 7. Make the JAX-WS dispatch use the client.
>>>>
>>>> ----
>>>>
>>>> In summary:
>>>> a) This simplifies the API. We've created an API to set up 
>>>>         
>> decoupled 
>>     
>>>> endpoints easily. We've reduced the complexity inside Conduits and 
>>>> have avoided introducing new complexity onto the Conduit 
>>>>         
>> interface to 
>>     
>>>> specify a decoupled destination.
>>>>
>>>> b) It creates a consistent API for working with decoupled 
>>>>         
>> endpoints. 
>>     
>>>> There is no reason to go writing a new API for setting up 
>>>>         
>> decoupled 
>>     
>>>> endpoints - which is only used sometimes.
>>>>
>>>> c) Dependency Injenction: By putting the Conduit & 
>>>>         
>> Destination on the 
>>     
>>>> Client we've made it much friendlier to people using 
>>>>         
>> Spring or other 
>>     
>>>> DI containers.
>>>>
>>>> d) Improved configuration: I think the jaxws:client is a 
>>>>         
>> more natural 
>>     
>>>> place to setup the conduit and destination configuration 
>>>>         
>> as opposed 
>>     
>>>> to nesting the destination configuration inside the conduit.
>>>>
>>>> e) Setting up decoupled destinations is not the job of the conduit 
>>>> IMO.
>>>> We're giving Conduits a dual task unnecessarily. If all Conduits 
>>>> share the same code for setting up decoupled destinations, 
>>>>         
>> that is a 
>>     
>>>> sign to me that we can take it out of the Conduit.
>>>>
>>>> I of course would be volunteering to do all this work.
>>>> --
>>>>
>>>> Alternatives: While Eoghan can elaborate, I believe he 
>>>>         
>> would rather 
>>     
>>>> see 1. The decoupled endpoint remain part of the conduit. 
>>>>         
>> He views a 
>>     
>>>> decoupled endpoint as part of the Conduit contract.
>>>> 2. An API on the Conduit to set up the decoupled endpoint like so:
>>>> Client.get(Conduit.class
>>>> ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
>>>> 3. The Client.getConduit/setConduit methods go away and have the 
>>>> Conduit be an optional part of the Client 4. No 
>>>> Client.setAsynchronousDestination method.
>>>> 5. Keep the decoupled endpoint configuration as part of 
>>>>         
>> the conduit 
>>     
>>>> instead of the client.
>>>>
>>>> Regards,
>>>> - Dan
>>>>
>>>> --
>>>> Dan Diephouse
>>>> Envoi Solutions
>>>> http://envoisolutions.com | http://netzooid.com/blog
>>>>
>>>>     
>>>>         
>>     


RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.
 

> -----Original Message-----
> From: Polar Humenn [mailto:phumenn@iona.com] 
> Sent: 19 March 2007 14:25
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Client and Conduit changes
> 
> I've got a couple of CXF architectural questions.
> 
> 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.

We discussed a couple of these scenarios in the "Client API, EPRs" thread, specifically where the JAX-WS Dispatch mechanism is used, or where the application wires together the interceptor chains itself.



> Does the client that 
> send the invocation request get notified of the response, 
> fault, or ack? 


Whatever the MessageObserver is set on the Conduit gets to process the response(s).

This *may* be the Client instance. Or something else entirely.


> How are the responses (many?) are correlated 
> to the client invocation.

Zero, or 1 depending on the MEP (whether oneway or twoway).

There's also the issue of partial responses (lets not go there on the detail, you can look in the archive for lengthy discussions on this subject). But there 

 
> Is there actually an object called a "Request" that does this 
> correlation? Should there be?
> 
> When I send a "reply-To" or "fault-To" or "ack-To" property 
> is that on single message? Or is it on a single connection 
> (for many messages)? 
> What is the request/response correction based on? Is there an 
> object in CXF that represents it, or is that done by the 
> Client, the Conduit, or something else?
> 
> Cheers,
> -Polar
> 
> Glynn, Eoghan wrote:
> > My position is that the Conduit should continue to hold to 
> the reference to, and manage the lifecycle of, the decoupled 
> response endpoint (DRE).
> >
> > Without rehashing the entire thread, my reasons briefly are:
> >
> > 1. Separation of concernsApache CXF - logged to 
> > http://dev.rectang.com/logs/codehaus/%23cxf/
> >
> > The DRE is an aspect of the transport and thus should be 
> created and referenced from within the realm of the transport.
> >
> > On the other hand, the purpose of the Client is to set up 
> interceptor chains and dispatch the invocation. Such 
> invocations may NOT require a DRE, or even a Conduit for that 
> matter. Thus I think it inappropriate for the Client to be 
> concerned with the creation of the DRE, and would even go one 
> step further and move the Conduit creation to the 
> MessageSenderInterceptor, so that a Conduit comes into being 
> only if it really is needed.    
> >
> >
> > 2. Avoid forcing the usage of a Client instance
> >
> > In general, if A is to be responsible for maintaining a 
> reference to B, then its reasonable to expect that the 
> existence of a B implies the existence of an A. Otherwise, in 
> some cases an instance of A will have be artificially 
> created, solely to manage the reference to B.  
> >
> > But if a DRE is in use, then the *only* other thing we're 
> guaranteed also exists is the corresponding Conduit.
> >
> > IMO we should neither require the usage of a Client 
> instance to mediate invocations, nor impose any undue burden 
> on applications that choose to wire up the interceptor chains 
> directly and initiate dispatch themselves.
> >
> > An example of an undue burden would be forcing such 
> applications to either always create the DRE 
> *programmatically* via DestinationFactory.getDestination(), 
> or if they want the DRE to be specified declaratively, to 
> manage this configuration themselves.  
> >
> >
> > 3. Suitability for JMS
> >
> > In order to setup a Destination, JMS may require more 
> information than can be easily shoe-horned into an EPR. Stuff 
> like a JNDI provider, ConnectionFactory username/password etc. 
> >
> > Now I don't accept the JMS as odd-man-out argument, especially when 
> > most of the counter-examples wheeled out (i.e. XMPP, TCP, 
> FTP) do not 
> > currently even exist as CXF transports. I could just as 
> easily make up 
> > a list of non-existent transports that suggests that the 
> > URI-friendliness of HTTP is the exceptional case, but 
> obviously you'd 
> > argue my list was hypothetical and proved nothing. And 
> you'd be right 
> > :)
> >
> > Neither does the "most people just use HTTP" line wash with 
> me. One of the design centres of CXF is to be a 
> multi-transport stack, and that in my book amounts to more 
> than just paying lip-service to non-HTTP transports.  
> >
> >
> > Also I'd like to respond quickly to a couple of specific 
> points that Dan makes in his proposal:
> >
> > "Right now if you want to create different endpoints for 
> receiving ReplyTos and FaultTos you have configure the 
> ReplyTos using the Conduit API and the FaultTos using the 
> destination API. Creating those endpoints in different ways 
> is bad IMO."
> >
> > So how would this be any different under your proposal? Is 
> the implication that in addition to a 
> Client.setAsynchronousEndpoint() API, you'd also add 
> Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), 
> and similarly expose <faultToEndpoint> and <acksToEndpoint> 
> elements in your proposed <client> bean?
> >
> > If so, this would expose *way* too much of WS-A and WS-RM 
> semantics directly in the Client, which should IMO be 
> independent of such QoS concerns. The CXF WS-A and WS-RM 
> layers were specifically designed to be pluggable, so that 
> they could slotted into the runtime without impact on the 
> core APIs. I would be strongly against a move that breaks 
> this ... I mean, what next, Client.setSecurityPolicyToken()??
> >
> > If on the other hand, if you're not suggesting polluting 
> the Client with those aspects of WS-A & WS-RM, can you 
> explain how your proposal provides a consistent mechanism for 
> specifying the faultTo & acksTo vis-à-vis the replytTo?
> >
> > Another point which I strongly disagree with:
> >
> > "If all Conduits share the same code for setting up 
> decoupled destinations, that is a sign to me that we can take 
> it out of the Conduit."
> >
> > I've never come across a design principle that suggests 
> having common code in a common base class is a sign that such 
> code should be moved elsewhere. In fact what purpose do 
> common base classes serve, other than to factor out 
> commonality from sub-classes?
> >
> > Cheers,
> > Eoghan
> >
> >   
> >> -----Original Message-----
> >> From: Dan Diephouse [mailto:dan@envoisolutions.com]
> >> Sent: 16 March 2007 22:20
> >> To: cxf-dev@incubator.apache.org
> >> Subject: [PROPOSAL] Client and Conduit changes
> >>
> >> For those of you who haven't been following the long discussion 
> >> Eoghan and I have been having, I'm going to take a moment to 
> >> summarize my proposal here.
> >> I consider it rather important. If we don't reach any consensus on 
> >> the proposal (it sucks/doesn't suck) or if Eoghan & I are the only 
> >> ones who participate, I'll probably start a vote. So do 
> your communal 
> >> duty and participate so I don't have to do that! :-)
> >>
> >> I propose the following:
> >>
> >> 1. API to set an Asynchronous EndpointReference I believe 
> we should 
> >> create a simple method on the Client which allows the user 
> to specify 
> >> the asynchronous endpoint that they wish to have used for 
> decoupled 
> >> responses:
> >>
> >> Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> >>
> >> The Client would check to see if this EPR was set. If so, it would 
> >> call
> >> DestinationFactory.getDestination(epr) for the EPR and use that as 
> >> the asynchronous destination. This would result in a 
> standard way to 
> >> automatically set up the decoupled destination when using the API.
> >>
> >> While it has been said that this isn't generic enough for JMS, I 
> >> don't agree. First, I believe that JMS will eventually get a self 
> >> contained IRI format which can be stuck in an EPR.
> >> We could even create our own proprietary format. Second, JMS is an 
> >> edge case. There are other transports beside just JMS and 
> HTTP, like 
> >> XMPP or TCP or FTP which work just fine with URIs. JMS is the odd 
> >> ball in the sense that historically it has needed stuff 
> outside the 
> >> EPR.
> >>
> >> 2. Access to the Conduits and Destinations I would like to add the 
> >> following methods to the Client:
> >>
> >> void setConduit(Conduit) - this allows a user to easily specify an 
> >> alternate Conduit.
> >> void setAsynchronousDestination(Destination) - this allows 
> a user to 
> >> easily specify a decoupled endpoint. It's address would be 
> used for 
> >> WS-Addressing interactions. If no Async destination 
> exists, then the 
> >> Client will only listen on the Conduit.
> >> Destination getAsynchronousDestination() - utility method 
> to easily 
> >> get the asynchronous destination
> >>
> >> 3. Client.close();
> >> We need a way to shutdown the decouled endpoints (regardless of 
> >> whether or not #1 & #2 are adopted). I think there is pretty good 
> >> conensus we need a
> >> Client.close() method which will do this. It will call
> >> getConduit().close() and getAsynchronousDestination().shutdown().
> >>
> >> (Ideally we'd like to be able to shut down RM at this same 
> time. I'm 
> >> going to guess that this would require the addition of a client 
> >> lifecycle interface which allows RM to listen for Client.close(). 
> >> This is an issue no matter which route we go though, so I'll defer 
> >> this conversation for another
> >> thread)
> >>
> >> 4. Remove the setup of decoupled destinations from inside 
> the Conduit 
> >> Currently, the Conduits are responsible for setting up the 
> decoupled 
> >> destinations. We've already got a perfectly good API for creating 
> >> destinations, lets use it! Creating another API to create 
> decoupled 
> >> destinations introduces inconsistencies into our APIs. 
> Right now if 
> >> you want to create different endpoints for receiving ReplyTos and 
> >> FaultTos you have configure the ReplyTos using the Conduit API and 
> >> the FaultTos using the destination API. Creating those 
> endpoints in 
> >> different ways is bad IMO.
> >>
> >> Putting in decoupled destinations inside the Conduit also makes it 
> >> more complex for transport writers or people trying to 
> understand the 
> >> API. IMO, people intuitively expect this to be outside the Conduit 
> >> class.
> >>
> >> 5. Client Configuration
> >> I would propose that we make the decoupled destination 
> configuration 
> >> part of the Client
> >>
> >> <jaxws:client id="...SomePort">
> >>   <jaxws:asynchronousEndpoint>
> >>     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
> >>   </jaxws:asynchronousEndpoint>
> >> </jaxws:client>
> >>
> >> <jaxws:client id="...SomePort">
> >>
> >> <jaxws:asynchronousDestination><http:destination...></jaxws:as
> >> ynchronousDestination>
> >> </jaxws:client>
> >>
> >> As an added bonus, we can now wire together clients and 
> destinations 
> >> however we want. I wouldn't *have* to create a <conduit> config 
> >> element with the port name inside it.
> >> Instead I could simply do:
> >>
> >> <jaxws:client id="...SomePort">
> >>    <jaxws:conduit> <http:conduit... /> </jaxws:conduit> 
> >> </jaxws:client>
> >>
> >> It also creates a central place to embed Client configuration
> >> - such as enabling MTOM or configuring WS-*:
> >> <jaxws:client id="...SomePort">
> >>    <jaxws:conduit>...</jaxws:conduit>
> >>    <jaxws:binding mtomEnabled="true">
> >>      <jaxws:requestContext>
> >>        <map><entry key="javax.xml.ws.session.maintain" 
> >> value="true"/></map>
> >>      </jaxws:requestContext>
> >>    </jaxws:binding>
> >>    <jaxws:features>
> >>      <wsrm:reliability timeout="10000" .../>
> >>    </jaxws:features>
> >> </jaxws:client>
> >>
> >> Users could still use the <http:conduit id="PORT"/> syntax if they 
> >> wanted to though.
> >>
> >> (Note: I haven't written the jaxws:client Spring schema 
> yet, but its 
> >> on my todo list. The feature stuff will hopefully be part of my 
> >> commit with
> >> WS-Security)
> >>
> >> 6. Bring back Destination.getDestination(EndpointReferenceType)
> >> This method would be needed for the API that I propose in #1.
> >>
> >> 7. Make the JAX-WS dispatch use the client.
> >>
> >> ----
> >>
> >> In summary:
> >> a) This simplifies the API. We've created an API to set up 
> decoupled 
> >> endpoints easily. We've reduced the complexity inside Conduits and 
> >> have avoided introducing new complexity onto the Conduit 
> interface to 
> >> specify a decoupled destination.
> >>
> >> b) It creates a consistent API for working with decoupled 
> endpoints. 
> >> There is no reason to go writing a new API for setting up 
> decoupled 
> >> endpoints - which is only used sometimes.
> >>
> >> c) Dependency Injenction: By putting the Conduit & 
> Destination on the 
> >> Client we've made it much friendlier to people using 
> Spring or other 
> >> DI containers.
> >>
> >> d) Improved configuration: I think the jaxws:client is a 
> more natural 
> >> place to setup the conduit and destination configuration 
> as opposed 
> >> to nesting the destination configuration inside the conduit.
> >>
> >> e) Setting up decoupled destinations is not the job of the conduit 
> >> IMO.
> >> We're giving Conduits a dual task unnecessarily. If all Conduits 
> >> share the same code for setting up decoupled destinations, 
> that is a 
> >> sign to me that we can take it out of the Conduit.
> >>
> >> I of course would be volunteering to do all this work.
> >> --
> >>
> >> Alternatives: While Eoghan can elaborate, I believe he 
> would rather 
> >> see 1. The decoupled endpoint remain part of the conduit. 
> He views a 
> >> decoupled endpoint as part of the Conduit contract.
> >> 2. An API on the Conduit to set up the decoupled endpoint like so:
> >> Client.get(Conduit.class
> >> ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> >> 3. The Client.getConduit/setConduit methods go away and have the 
> >> Conduit be an optional part of the Client 4. No 
> >> Client.setAsynchronousDestination method.
> >> 5. Keep the decoupled endpoint configuration as part of 
> the conduit 
> >> instead of the client.
> >>
> >> Regards,
> >> - Dan
> >>
> >> --
> >> Dan Diephouse
> >> Envoi Solutions
> >> http://envoisolutions.com | http://netzooid.com/blog
> >>
> >>     
> 
> 

Re: [PROPOSAL] Client and Conduit changes

Posted by Polar Humenn <ph...@iona.com>.
I've got a couple of CXF architectural questions.

Must be a Client in order for there to be an invocation 
request/response/fault/ack protocol? Does the client that send the 
invocation request get notified of the response, fault, or ack? How are 
the responses (many?) are correlated to the client invocation.

Is there actually an object called a "Request" that does this 
correlation? Should there be?

When I send a "reply-To" or "fault-To" or "ack-To" property is that on 
single message? Or is it on a single connection (for many messages)? 
What is the request/response correction based on? Is there an object in 
CXF that represents it, or is that done by the Client, the Conduit, or 
something else?

Cheers,
-Polar

Glynn, Eoghan wrote:
> My position is that the Conduit should continue to hold to the reference to, and manage the lifecycle of, the decoupled response endpoint (DRE).
>
> Without rehashing the entire thread, my reasons briefly are:
>
> 1. Separation of concernsApache CXF - logged to http://dev.rectang.com/logs/codehaus/%23cxf/
>
> The DRE is an aspect of the transport and thus should be created and referenced from within the realm of the transport.
>
> On the other hand, the purpose of the Client is to set up interceptor chains and dispatch the invocation. Such invocations may NOT require a DRE, or even a Conduit for that matter. Thus I think it inappropriate for the Client to be concerned with the creation of the DRE, and would even go one step further and move the Conduit creation to the MessageSenderInterceptor, so that a Conduit comes into being only if it really is needed.    
>
>
> 2. Avoid forcing the usage of a Client instance
>
> In general, if A is to be responsible for maintaining a reference to B, then its reasonable to expect that the existence of a B implies the existence of an A. Otherwise, in some cases an instance of A will have be artificially created, solely to manage the reference to B.  
>
> But if a DRE is in use, then the *only* other thing we're guaranteed also exists is the corresponding Conduit.
>
> IMO we should neither require the usage of a Client instance to mediate invocations, nor impose any undue burden on applications that choose to wire up the interceptor chains directly and initiate dispatch themselves.
>
> An example of an undue burden would be forcing such applications to either always create the DRE *programmatically* via DestinationFactory.getDestination(), or if they want the DRE to be specified declaratively, to manage this configuration themselves.  
>
>
> 3. Suitability for JMS
>
> In order to setup a Destination, JMS may require more information than can be easily shoe-horned into an EPR. Stuff like a JNDI provider, ConnectionFactory username/password etc. 
>
> Now I don't accept the JMS as odd-man-out argument, especially when most of the counter-examples wheeled out (i.e. XMPP, TCP, FTP) do not currently even exist as CXF transports. I could just as easily make up a list of non-existent transports that suggests that the URI-friendliness of HTTP is the exceptional case, but obviously you'd argue my list was hypothetical and proved nothing. And you'd be right :) 
>
> Neither does the "most people just use HTTP" line wash with me. One of the design centres of CXF is to be a multi-transport stack, and that in my book amounts to more than just paying lip-service to non-HTTP transports.  
>
>
> Also I'd like to respond quickly to a couple of specific points that Dan makes in his proposal:
>
> "Right now if you want to create different endpoints for receiving ReplyTos and FaultTos you have configure the ReplyTos using the Conduit API and the FaultTos using the destination API. Creating those endpoints in different ways is bad IMO."
>
> So how would this be any different under your proposal? Is the implication that in addition to a Client.setAsynchronousEndpoint() API, you'd also add Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), and similarly expose <faultToEndpoint> and <acksToEndpoint> elements in your proposed <client> bean?
>
> If so, this would expose *way* too much of WS-A and WS-RM semantics directly in the Client, which should IMO be independent of such QoS concerns. The CXF WS-A and WS-RM layers were specifically designed to be pluggable, so that they could slotted into the runtime without impact on the core APIs. I would be strongly against a move that breaks this ... I mean, what next, Client.setSecurityPolicyToken()??
>
> If on the other hand, if you're not suggesting polluting the Client with those aspects of WS-A & WS-RM, can you explain how your proposal provides a consistent mechanism for specifying the faultTo & acksTo vis-à-vis the replytTo?
>
> Another point which I strongly disagree with:
>
> "If all Conduits share the same code for setting up decoupled destinations, that is a sign to me that we can take it out of the Conduit."
>
> I've never come across a design principle that suggests having common code in a common base class is a sign that such code should be moved elsewhere. In fact what purpose do common base classes serve, other than to factor out commonality from sub-classes?
>
> Cheers,
> Eoghan
>
>   
>> -----Original Message-----
>> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
>> Sent: 16 March 2007 22:20
>> To: cxf-dev@incubator.apache.org
>> Subject: [PROPOSAL] Client and Conduit changes
>>
>> For those of you who haven't been following the long 
>> discussion Eoghan and I have been having, I'm going to take a 
>> moment to summarize my proposal here.
>> I consider it rather important. If we don't reach any 
>> consensus on the proposal (it sucks/doesn't suck) or if 
>> Eoghan & I are the only ones who participate, I'll probably 
>> start a vote. So do your communal duty and participate so I 
>> don't have to do that! :-)
>>
>> I propose the following:
>>
>> 1. API to set an Asynchronous EndpointReference I believe we 
>> should create a simple method on the Client which allows the 
>> user to specify the asynchronous endpoint that they wish to 
>> have used for decoupled responses:
>>
>> Client.getAsynchronousEndpoint(EndpointReferenceType epr);
>>
>> The Client would check to see if this EPR was set. If so, it 
>> would call
>> DestinationFactory.getDestination(epr) for the EPR and use 
>> that as the asynchronous destination. This would result in a 
>> standard way to automatically set up the decoupled 
>> destination when using the API.
>>
>> While it has been said that this isn't generic enough for 
>> JMS, I don't agree. First, I believe that JMS will eventually 
>> get a self contained IRI format which can be stuck in an EPR. 
>> We could even create our own proprietary format. Second, JMS 
>> is an edge case. There are other transports beside just JMS 
>> and HTTP, like XMPP or TCP or FTP which work just fine with 
>> URIs. JMS is the odd ball in the sense that historically it 
>> has needed stuff outside the EPR.
>>
>> 2. Access to the Conduits and Destinations I would like to 
>> add the following methods to the Client:
>>
>> void setConduit(Conduit) - this allows a user to easily 
>> specify an alternate Conduit.
>> void setAsynchronousDestination(Destination) - this allows a 
>> user to easily specify a decoupled endpoint. It's address 
>> would be used for WS-Addressing interactions. If no Async 
>> destination exists, then the Client will only listen on the Conduit.
>> Destination getAsynchronousDestination() - utility method to 
>> easily get the asynchronous destination
>>
>> 3. Client.close();
>> We need a way to shutdown the decouled endpoints (regardless 
>> of whether or not #1 & #2 are adopted). I think there is 
>> pretty good conensus we need a
>> Client.close() method which will do this. It will call 
>> getConduit().close() and getAsynchronousDestination().shutdown().
>>
>> (Ideally we'd like to be able to shut down RM at this same 
>> time. I'm going to guess that this would require the addition 
>> of a client lifecycle interface which allows RM to listen for 
>> Client.close(). This is an issue no matter which route we go 
>> though, so I'll defer this conversation for another
>> thread)
>>
>> 4. Remove the setup of decoupled destinations from inside the 
>> Conduit Currently, the Conduits are responsible for setting 
>> up the decoupled destinations. We've already got a perfectly 
>> good API for creating destinations, lets use it! Creating 
>> another API to create decoupled destinations introduces 
>> inconsistencies into our APIs. Right now if you want to 
>> create different endpoints for receiving ReplyTos and 
>> FaultTos you have configure the ReplyTos using the Conduit 
>> API and the FaultTos using the destination API. Creating 
>> those endpoints in different ways is bad IMO.
>>
>> Putting in decoupled destinations inside the Conduit also 
>> makes it more complex for transport writers or people trying 
>> to understand the API. IMO, people intuitively expect this to 
>> be outside the Conduit class.
>>
>> 5. Client Configuration
>> I would propose that we make the decoupled destination 
>> configuration part of the Client
>>
>> <jaxws:client id="...SomePort">
>>   <jaxws:asynchronousEndpoint>
>>     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
>>   </jaxws:asynchronousEndpoint>
>> </jaxws:client>
>>
>> <jaxws:client id="...SomePort">
>>
>> <jaxws:asynchronousDestination><http:destination...></jaxws:as
>> ynchronousDestination>
>> </jaxws:client>
>>
>> As an added bonus, we can now wire together clients and 
>> destinations however we want. I wouldn't *have* to create a 
>> <conduit> config element with the port name inside it. 
>> Instead I could simply do:
>>
>> <jaxws:client id="...SomePort">
>>    <jaxws:conduit> <http:conduit... /> </jaxws:conduit> 
>> </jaxws:client>
>>
>> It also creates a central place to embed Client configuration 
>> - such as enabling MTOM or configuring WS-*:
>> <jaxws:client id="...SomePort">
>>    <jaxws:conduit>...</jaxws:conduit>
>>    <jaxws:binding mtomEnabled="true">
>>      <jaxws:requestContext>
>>        <map><entry key="javax.xml.ws.session.maintain" 
>> value="true"/></map>
>>      </jaxws:requestContext>
>>    </jaxws:binding>
>>    <jaxws:features>
>>      <wsrm:reliability timeout="10000" .../>
>>    </jaxws:features>
>> </jaxws:client>
>>
>> Users could still use the <http:conduit id="PORT"/> syntax if 
>> they wanted to though.
>>
>> (Note: I haven't written the jaxws:client Spring schema yet, 
>> but its on my todo list. The feature stuff will hopefully be 
>> part of my commit with
>> WS-Security)
>>
>> 6. Bring back Destination.getDestination(EndpointReferenceType)
>> This method would be needed for the API that I propose in #1.
>>
>> 7. Make the JAX-WS dispatch use the client.
>>
>> ----
>>
>> In summary:
>> a) This simplifies the API. We've created an API to set up 
>> decoupled endpoints easily. We've reduced the complexity 
>> inside Conduits and have avoided introducing new complexity 
>> onto the Conduit interface to specify a decoupled destination.
>>
>> b) It creates a consistent API for working with decoupled 
>> endpoints. There is no reason to go writing a new API for 
>> setting up decoupled endpoints - which is only used sometimes.
>>
>> c) Dependency Injenction: By putting the Conduit & 
>> Destination on the Client we've made it much friendlier to 
>> people using Spring or other DI containers.
>>
>> d) Improved configuration: I think the jaxws:client is a more 
>> natural place to setup the conduit and destination 
>> configuration as opposed to nesting the destination 
>> configuration inside the conduit.
>>
>> e) Setting up decoupled destinations is not the job of the 
>> conduit IMO.
>> We're giving Conduits a dual task unnecessarily. If all 
>> Conduits share the same code for setting up decoupled 
>> destinations, that is a sign to me that we can take it out of 
>> the Conduit.
>>
>> I of course would be volunteering to do all this work.
>> --
>>
>> Alternatives: While Eoghan can elaborate, I believe he would 
>> rather see 1. The decoupled endpoint remain part of the 
>> conduit. He views a decoupled endpoint as part of the Conduit 
>> contract.
>> 2. An API on the Conduit to set up the decoupled endpoint like so:
>> Client.get(Conduit.class
>> ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
>> 3. The Client.getConduit/setConduit methods go away and have 
>> the Conduit be an optional part of the Client 4. No 
>> Client.setAsynchronousDestination method.
>> 5. Keep the decoupled endpoint configuration as part of the 
>> conduit instead of the client.
>>
>> Regards,
>> - Dan
>>
>> --
>> Dan Diephouse
>> Envoi Solutions
>> http://envoisolutions.com | http://netzooid.com/blog
>>
>>     


Re: [PROPOSAL] Client and Conduit changes

Posted by Willem Jiang <ni...@iona.com>.
Hi

It is complicate for us to let the Conduit and Destination to manage the 
life cycle of DRE.
IMO DRE need to move to the WSAddress or WSRM as the common logical for 
the decouple transport.

If you want to implement a new transport which current CXF transport API 
, you need to know the Conduit/Destination are not equal to the 
traditional network programing model Client/Server . These 
Conduit/Destination have the responsibility to manage the decoupled 
response/request endpoint, which just are another simplified Conduit and 
Destination.

IMO, transport just need to implement the send and receive message 
method and the stream for the stax handling the message.  CXF 's 
DestinationFactory and ConduitFactory already help us to get right 
Conduit and Destination.  If we can fill the gape between DRE and 
traditional Client/Server by creating the DRE in a common decouple 
transport logical, that will be great for the transport writer.

Willem.

Glynn, Eoghan wrote:

>My position is that the Conduit should continue to hold to the reference to, and manage the lifecycle of, the decoupled response endpoint (DRE).
>
>Without rehashing the entire thread, my reasons briefly are:
>
>1. Separation of concerns
>
>The DRE is an aspect of the transport and thus should be created and referenced from within the realm of the transport.
>
>On the other hand, the purpose of the Client is to set up interceptor chains and dispatch the invocation. Such invocations may NOT require a DRE, or even a Conduit for that matter. Thus I think it inappropriate for the Client to be concerned with the creation of the DRE, and would even go one step further and move the Conduit creation to the MessageSenderInterceptor, so that a Conduit comes into being only if it really is needed.    
>
>
>2. Avoid forcing the usage of a Client instance
>
>In general, if A is to be responsible for maintaining a reference to B, then its reasonable to expect that the existence of a B implies the existence of an A. Otherwise, in some cases an instance of A will have be artificially created, solely to manage the reference to B.  
>
>But if a DRE is in use, then the *only* other thing we're guaranteed also exists is the corresponding Conduit.
>
>IMO we should neither require the usage of a Client instance to mediate invocations, nor impose any undue burden on applications that choose to wire up the interceptor chains directly and initiate dispatch themselves.
>
>An example of an undue burden would be forcing such applications to either always create the DRE *programmatically* via DestinationFactory.getDestination(), or if they want the DRE to be specified declaratively, to manage this configuration themselves.  
>
>
>3. Suitability for JMS
>
>In order to setup a Destination, JMS may require more information than can be easily shoe-horned into an EPR. Stuff like a JNDI provider, ConnectionFactory username/password etc. 
>
>Now I don't accept the JMS as odd-man-out argument, especially when most of the counter-examples wheeled out (i.e. XMPP, TCP, FTP) do not currently even exist as CXF transports. I could just as easily make up a list of non-existent transports that suggests that the URI-friendliness of HTTP is the exceptional case, but obviously you'd argue my list was hypothetical and proved nothing. And you'd be right :) 
>
>Neither does the "most people just use HTTP" line wash with me. One of the design centres of CXF is to be a multi-transport stack, and that in my book amounts to more than just paying lip-service to non-HTTP transports.  
>
>
>Also I'd like to respond quickly to a couple of specific points that Dan makes in his proposal:
>
>"Right now if you want to create different endpoints for receiving ReplyTos and FaultTos you have configure the ReplyTos using the Conduit API and the FaultTos using the destination API. Creating those endpoints in different ways is bad IMO."
>
>So how would this be any different under your proposal? Is the implication that in addition to a Client.setAsynchronousEndpoint() API, you'd also add Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), and similarly expose <faultToEndpoint> and <acksToEndpoint> elements in your proposed <client> bean?
>
>If so, this would expose *way* too much of WS-A and WS-RM semantics directly in the Client, which should IMO be independent of such QoS concerns. The CXF WS-A and WS-RM layers were specifically designed to be pluggable, so that they could slotted into the runtime without impact on the core APIs. I would be strongly against a move that breaks this ... I mean, what next, Client.setSecurityPolicyToken()??
>
>If on the other hand, if you're not suggesting polluting the Client with those aspects of WS-A & WS-RM, can you explain how your proposal provides a consistent mechanism for specifying the faultTo & acksTo vis-à-vis the replytTo?
>
>Another point which I strongly disagree with:
>
>"If all Conduits share the same code for setting up decoupled destinations, that is a sign to me that we can take it out of the Conduit."
>
>I've never come across a design principle that suggests having common code in a common base class is a sign that such code should be moved elsewhere. In fact what purpose do common base classes serve, other than to factor out commonality from sub-classes?
>
>Cheers,
>Eoghan
>
>  
>
>>-----Original Message-----
>>From: Dan Diephouse [mailto:dan@envoisolutions.com] 
>>Sent: 16 March 2007 22:20
>>To: cxf-dev@incubator.apache.org
>>Subject: [PROPOSAL] Client and Conduit changes
>>
>>For those of you who haven't been following the long 
>>discussion Eoghan and I have been having, I'm going to take a 
>>moment to summarize my proposal here.
>>I consider it rather important. If we don't reach any 
>>consensus on the proposal (it sucks/doesn't suck) or if 
>>Eoghan & I are the only ones who participate, I'll probably 
>>start a vote. So do your communal duty and participate so I 
>>don't have to do that! :-)
>>
>>I propose the following:
>>
>>1. API to set an Asynchronous EndpointReference I believe we 
>>should create a simple method on the Client which allows the 
>>user to specify the asynchronous endpoint that they wish to 
>>have used for decoupled responses:
>>
>>Client.getAsynchronousEndpoint(EndpointReferenceType epr);
>>
>>The Client would check to see if this EPR was set. If so, it 
>>would call
>>DestinationFactory.getDestination(epr) for the EPR and use 
>>that as the asynchronous destination. This would result in a 
>>standard way to automatically set up the decoupled 
>>destination when using the API.
>>
>>While it has been said that this isn't generic enough for 
>>JMS, I don't agree. First, I believe that JMS will eventually 
>>get a self contained IRI format which can be stuck in an EPR. 
>>We could even create our own proprietary format. Second, JMS 
>>is an edge case. There are other transports beside just JMS 
>>and HTTP, like XMPP or TCP or FTP which work just fine with 
>>URIs. JMS is the odd ball in the sense that historically it 
>>has needed stuff outside the EPR.
>>
>>2. Access to the Conduits and Destinations I would like to 
>>add the following methods to the Client:
>>
>>void setConduit(Conduit) - this allows a user to easily 
>>specify an alternate Conduit.
>>void setAsynchronousDestination(Destination) - this allows a 
>>user to easily specify a decoupled endpoint. It's address 
>>would be used for WS-Addressing interactions. If no Async 
>>destination exists, then the Client will only listen on the Conduit.
>>Destination getAsynchronousDestination() - utility method to 
>>easily get the asynchronous destination
>>
>>3. Client.close();
>>We need a way to shutdown the decouled endpoints (regardless 
>>of whether or not #1 & #2 are adopted). I think there is 
>>pretty good conensus we need a
>>Client.close() method which will do this. It will call 
>>getConduit().close() and getAsynchronousDestination().shutdown().
>>
>>(Ideally we'd like to be able to shut down RM at this same 
>>time. I'm going to guess that this would require the addition 
>>of a client lifecycle interface which allows RM to listen for 
>>Client.close(). This is an issue no matter which route we go 
>>though, so I'll defer this conversation for another
>>thread)
>>
>>4. Remove the setup of decoupled destinations from inside the 
>>Conduit Currently, the Conduits are responsible for setting 
>>up the decoupled destinations. We've already got a perfectly 
>>good API for creating destinations, lets use it! Creating 
>>another API to create decoupled destinations introduces 
>>inconsistencies into our APIs. Right now if you want to 
>>create different endpoints for receiving ReplyTos and 
>>FaultTos you have configure the ReplyTos using the Conduit 
>>API and the FaultTos using the destination API. Creating 
>>those endpoints in different ways is bad IMO.
>>
>>Putting in decoupled destinations inside the Conduit also 
>>makes it more complex for transport writers or people trying 
>>to understand the API. IMO, people intuitively expect this to 
>>be outside the Conduit class.
>>
>>5. Client Configuration
>>I would propose that we make the decoupled destination 
>>configuration part of the Client
>>
>><jaxws:client id="...SomePort">
>>  <jaxws:asynchronousEndpoint>
>>    <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
>>  </jaxws:asynchronousEndpoint>
>></jaxws:client>
>>
>><jaxws:client id="...SomePort">
>>
>><jaxws:asynchronousDestination><http:destination...></jaxws:as
>>ynchronousDestination>
>></jaxws:client>
>>
>>As an added bonus, we can now wire together clients and 
>>destinations however we want. I wouldn't *have* to create a 
>><conduit> config element with the port name inside it. 
>>Instead I could simply do:
>>
>><jaxws:client id="...SomePort">
>>   <jaxws:conduit> <http:conduit... /> </jaxws:conduit> 
>></jaxws:client>
>>
>>It also creates a central place to embed Client configuration 
>>- such as enabling MTOM or configuring WS-*:
>><jaxws:client id="...SomePort">
>>   <jaxws:conduit>...</jaxws:conduit>
>>   <jaxws:binding mtomEnabled="true">
>>     <jaxws:requestContext>
>>       <map><entry key="javax.xml.ws.session.maintain" 
>>value="true"/></map>
>>     </jaxws:requestContext>
>>   </jaxws:binding>
>>   <jaxws:features>
>>     <wsrm:reliability timeout="10000" .../>
>>   </jaxws:features>
>></jaxws:client>
>>
>>Users could still use the <http:conduit id="PORT"/> syntax if 
>>they wanted to though.
>>
>>(Note: I haven't written the jaxws:client Spring schema yet, 
>>but its on my todo list. The feature stuff will hopefully be 
>>part of my commit with
>>WS-Security)
>>
>>6. Bring back Destination.getDestination(EndpointReferenceType)
>>This method would be needed for the API that I propose in #1.
>>
>>7. Make the JAX-WS dispatch use the client.
>>
>>----
>>
>>In summary:
>>a) This simplifies the API. We've created an API to set up 
>>decoupled endpoints easily. We've reduced the complexity 
>>inside Conduits and have avoided introducing new complexity 
>>onto the Conduit interface to specify a decoupled destination.
>>
>>b) It creates a consistent API for working with decoupled 
>>endpoints. There is no reason to go writing a new API for 
>>setting up decoupled endpoints - which is only used sometimes.
>>
>>c) Dependency Injenction: By putting the Conduit & 
>>Destination on the Client we've made it much friendlier to 
>>people using Spring or other DI containers.
>>
>>d) Improved configuration: I think the jaxws:client is a more 
>>natural place to setup the conduit and destination 
>>configuration as opposed to nesting the destination 
>>configuration inside the conduit.
>>
>>e) Setting up decoupled destinations is not the job of the 
>>conduit IMO.
>>We're giving Conduits a dual task unnecessarily. If all 
>>Conduits share the same code for setting up decoupled 
>>destinations, that is a sign to me that we can take it out of 
>>the Conduit.
>>
>>I of course would be volunteering to do all this work.
>>--
>>
>>Alternatives: While Eoghan can elaborate, I believe he would 
>>rather see 1. The decoupled endpoint remain part of the 
>>conduit. He views a decoupled endpoint as part of the Conduit 
>>contract.
>>2. An API on the Conduit to set up the decoupled endpoint like so:
>>Client.get(Conduit.class
>>).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
>>3. The Client.getConduit/setConduit methods go away and have 
>>the Conduit be an optional part of the Client 4. No 
>>Client.setAsynchronousDestination method.
>>5. Keep the decoupled endpoint configuration as part of the 
>>conduit instead of the client.
>>
>>Regards,
>>- Dan
>>
>>--
>>Dan Diephouse
>>Envoi Solutions
>>http://envoisolutions.com | http://netzooid.com/blog
>>
>>    
>>
>
>  
>


RE: [PROPOSAL] Client and Conduit changes

Posted by "Glynn, Eoghan" <eo...@iona.com>.

My position is that the Conduit should continue to hold to the reference to, and manage the lifecycle of, the decoupled response endpoint (DRE).

Without rehashing the entire thread, my reasons briefly are:

1. Separation of concerns

The DRE is an aspect of the transport and thus should be created and referenced from within the realm of the transport.

On the other hand, the purpose of the Client is to set up interceptor chains and dispatch the invocation. Such invocations may NOT require a DRE, or even a Conduit for that matter. Thus I think it inappropriate for the Client to be concerned with the creation of the DRE, and would even go one step further and move the Conduit creation to the MessageSenderInterceptor, so that a Conduit comes into being only if it really is needed.    


2. Avoid forcing the usage of a Client instance

In general, if A is to be responsible for maintaining a reference to B, then its reasonable to expect that the existence of a B implies the existence of an A. Otherwise, in some cases an instance of A will have be artificially created, solely to manage the reference to B.  

But if a DRE is in use, then the *only* other thing we're guaranteed also exists is the corresponding Conduit.

IMO we should neither require the usage of a Client instance to mediate invocations, nor impose any undue burden on applications that choose to wire up the interceptor chains directly and initiate dispatch themselves.

An example of an undue burden would be forcing such applications to either always create the DRE *programmatically* via DestinationFactory.getDestination(), or if they want the DRE to be specified declaratively, to manage this configuration themselves.  


3. Suitability for JMS

In order to setup a Destination, JMS may require more information than can be easily shoe-horned into an EPR. Stuff like a JNDI provider, ConnectionFactory username/password etc. 

Now I don't accept the JMS as odd-man-out argument, especially when most of the counter-examples wheeled out (i.e. XMPP, TCP, FTP) do not currently even exist as CXF transports. I could just as easily make up a list of non-existent transports that suggests that the URI-friendliness of HTTP is the exceptional case, but obviously you'd argue my list was hypothetical and proved nothing. And you'd be right :) 

Neither does the "most people just use HTTP" line wash with me. One of the design centres of CXF is to be a multi-transport stack, and that in my book amounts to more than just paying lip-service to non-HTTP transports.  


Also I'd like to respond quickly to a couple of specific points that Dan makes in his proposal:

"Right now if you want to create different endpoints for receiving ReplyTos and FaultTos you have configure the ReplyTos using the Conduit API and the FaultTos using the destination API. Creating those endpoints in different ways is bad IMO."

So how would this be any different under your proposal? Is the implication that in addition to a Client.setAsynchronousEndpoint() API, you'd also add Client.setFaultToEndpoint() and Client.setAcksToEndpoint(), and similarly expose <faultToEndpoint> and <acksToEndpoint> elements in your proposed <client> bean?

If so, this would expose *way* too much of WS-A and WS-RM semantics directly in the Client, which should IMO be independent of such QoS concerns. The CXF WS-A and WS-RM layers were specifically designed to be pluggable, so that they could slotted into the runtime without impact on the core APIs. I would be strongly against a move that breaks this ... I mean, what next, Client.setSecurityPolicyToken()??

If on the other hand, if you're not suggesting polluting the Client with those aspects of WS-A & WS-RM, can you explain how your proposal provides a consistent mechanism for specifying the faultTo & acksTo vis-à-vis the replytTo?

Another point which I strongly disagree with:

"If all Conduits share the same code for setting up decoupled destinations, that is a sign to me that we can take it out of the Conduit."

I've never come across a design principle that suggests having common code in a common base class is a sign that such code should be moved elsewhere. In fact what purpose do common base classes serve, other than to factor out commonality from sub-classes?

Cheers,
Eoghan

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 16 March 2007 22:20
> To: cxf-dev@incubator.apache.org
> Subject: [PROPOSAL] Client and Conduit changes
> 
> For those of you who haven't been following the long 
> discussion Eoghan and I have been having, I'm going to take a 
> moment to summarize my proposal here.
> I consider it rather important. If we don't reach any 
> consensus on the proposal (it sucks/doesn't suck) or if 
> Eoghan & I are the only ones who participate, I'll probably 
> start a vote. So do your communal duty and participate so I 
> don't have to do that! :-)
> 
> I propose the following:
> 
> 1. API to set an Asynchronous EndpointReference I believe we 
> should create a simple method on the Client which allows the 
> user to specify the asynchronous endpoint that they wish to 
> have used for decoupled responses:
> 
> Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> 
> The Client would check to see if this EPR was set. If so, it 
> would call
> DestinationFactory.getDestination(epr) for the EPR and use 
> that as the asynchronous destination. This would result in a 
> standard way to automatically set up the decoupled 
> destination when using the API.
> 
> While it has been said that this isn't generic enough for 
> JMS, I don't agree. First, I believe that JMS will eventually 
> get a self contained IRI format which can be stuck in an EPR. 
> We could even create our own proprietary format. Second, JMS 
> is an edge case. There are other transports beside just JMS 
> and HTTP, like XMPP or TCP or FTP which work just fine with 
> URIs. JMS is the odd ball in the sense that historically it 
> has needed stuff outside the EPR.
> 
> 2. Access to the Conduits and Destinations I would like to 
> add the following methods to the Client:
> 
> void setConduit(Conduit) - this allows a user to easily 
> specify an alternate Conduit.
> void setAsynchronousDestination(Destination) - this allows a 
> user to easily specify a decoupled endpoint. It's address 
> would be used for WS-Addressing interactions. If no Async 
> destination exists, then the Client will only listen on the Conduit.
> Destination getAsynchronousDestination() - utility method to 
> easily get the asynchronous destination
> 
> 3. Client.close();
> We need a way to shutdown the decouled endpoints (regardless 
> of whether or not #1 & #2 are adopted). I think there is 
> pretty good conensus we need a
> Client.close() method which will do this. It will call 
> getConduit().close() and getAsynchronousDestination().shutdown().
> 
> (Ideally we'd like to be able to shut down RM at this same 
> time. I'm going to guess that this would require the addition 
> of a client lifecycle interface which allows RM to listen for 
> Client.close(). This is an issue no matter which route we go 
> though, so I'll defer this conversation for another
> thread)
> 
> 4. Remove the setup of decoupled destinations from inside the 
> Conduit Currently, the Conduits are responsible for setting 
> up the decoupled destinations. We've already got a perfectly 
> good API for creating destinations, lets use it! Creating 
> another API to create decoupled destinations introduces 
> inconsistencies into our APIs. Right now if you want to 
> create different endpoints for receiving ReplyTos and 
> FaultTos you have configure the ReplyTos using the Conduit 
> API and the FaultTos using the destination API. Creating 
> those endpoints in different ways is bad IMO.
> 
> Putting in decoupled destinations inside the Conduit also 
> makes it more complex for transport writers or people trying 
> to understand the API. IMO, people intuitively expect this to 
> be outside the Conduit class.
> 
> 5. Client Configuration
> I would propose that we make the decoupled destination 
> configuration part of the Client
> 
> <jaxws:client id="...SomePort">
>   <jaxws:asynchronousEndpoint>
>     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
>   </jaxws:asynchronousEndpoint>
> </jaxws:client>
> 
> <jaxws:client id="...SomePort">
> 
> <jaxws:asynchronousDestination><http:destination...></jaxws:as
> ynchronousDestination>
> </jaxws:client>
> 
> As an added bonus, we can now wire together clients and 
> destinations however we want. I wouldn't *have* to create a 
> <conduit> config element with the port name inside it. 
> Instead I could simply do:
> 
> <jaxws:client id="...SomePort">
>    <jaxws:conduit> <http:conduit... /> </jaxws:conduit> 
> </jaxws:client>
> 
> It also creates a central place to embed Client configuration 
> - such as enabling MTOM or configuring WS-*:
> <jaxws:client id="...SomePort">
>    <jaxws:conduit>...</jaxws:conduit>
>    <jaxws:binding mtomEnabled="true">
>      <jaxws:requestContext>
>        <map><entry key="javax.xml.ws.session.maintain" 
> value="true"/></map>
>      </jaxws:requestContext>
>    </jaxws:binding>
>    <jaxws:features>
>      <wsrm:reliability timeout="10000" .../>
>    </jaxws:features>
> </jaxws:client>
> 
> Users could still use the <http:conduit id="PORT"/> syntax if 
> they wanted to though.
> 
> (Note: I haven't written the jaxws:client Spring schema yet, 
> but its on my todo list. The feature stuff will hopefully be 
> part of my commit with
> WS-Security)
> 
> 6. Bring back Destination.getDestination(EndpointReferenceType)
> This method would be needed for the API that I propose in #1.
> 
> 7. Make the JAX-WS dispatch use the client.
> 
> ----
> 
> In summary:
> a) This simplifies the API. We've created an API to set up 
> decoupled endpoints easily. We've reduced the complexity 
> inside Conduits and have avoided introducing new complexity 
> onto the Conduit interface to specify a decoupled destination.
> 
> b) It creates a consistent API for working with decoupled 
> endpoints. There is no reason to go writing a new API for 
> setting up decoupled endpoints - which is only used sometimes.
> 
> c) Dependency Injenction: By putting the Conduit & 
> Destination on the Client we've made it much friendlier to 
> people using Spring or other DI containers.
> 
> d) Improved configuration: I think the jaxws:client is a more 
> natural place to setup the conduit and destination 
> configuration as opposed to nesting the destination 
> configuration inside the conduit.
> 
> e) Setting up decoupled destinations is not the job of the 
> conduit IMO.
> We're giving Conduits a dual task unnecessarily. If all 
> Conduits share the same code for setting up decoupled 
> destinations, that is a sign to me that we can take it out of 
> the Conduit.
> 
> I of course would be volunteering to do all this work.
> --
> 
> Alternatives: While Eoghan can elaborate, I believe he would 
> rather see 1. The decoupled endpoint remain part of the 
> conduit. He views a decoupled endpoint as part of the Conduit 
> contract.
> 2. An API on the Conduit to set up the decoupled endpoint like so:
> Client.get(Conduit.class
> ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> 3. The Client.getConduit/setConduit methods go away and have 
> the Conduit be an optional part of the Client 4. No 
> Client.setAsynchronousDestination method.
> 5. Keep the decoupled endpoint configuration as part of the 
> conduit instead of the client.
> 
> Regards,
> - Dan
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 

RE: [PROPOSAL] Client and Conduit changes

Posted by Ted Neward <te...@tedneward.com>.
Can you summarize the arguments *against* this proposal? Arguments for
without arguments against sort of skews the perception pretty strongly....

Ted Neward
Java, .NET, XML Services
Consulting, Teaching, Speaking, Writing
http://www.tedneward.com

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com]
> Sent: Friday, March 16, 2007 3:20 PM
> To: cxf-dev@incubator.apache.org
> Subject: [PROPOSAL] Client and Conduit changes
> 
> For those of you who haven't been following the long discussion Eoghan and
> I
> have been having, I'm going to take a moment to summarize my proposal
> here.
> I consider it rather important. If we don't reach any consensus on the
> proposal (it sucks/doesn't suck) or if Eoghan & I are the only ones who
> participate, I'll probably start a vote. So do your communal duty and
> participate so I don't have to do that! :-)
> 
> I propose the following:
> 
> 1. API to set an Asynchronous EndpointReference
> I believe we should create a simple method on the Client which allows the
> user to specify the asynchronous endpoint that they wish to have used for
> decoupled responses:
> 
> Client.getAsynchronousEndpoint(EndpointReferenceType epr);
> 
> The Client would check to see if this EPR was set. If so, it would call
> DestinationFactory.getDestination(epr) for the EPR and use that as the
> asynchronous destination. This would result in a standard way to
> automatically set up the decoupled destination when using the API.
> 
> While it has been said that this isn't generic enough for JMS, I don't
> agree. First, I believe that JMS will eventually get a self contained IRI
> format which can be stuck in an EPR. We could even create our own
> proprietary format. Second, JMS is an edge case. There are other
> transports
> beside just JMS and HTTP, like XMPP or TCP or FTP which work just fine
> with
> URIs. JMS is the odd ball in the sense that historically it has needed
> stuff
> outside the EPR.
> 
> 2. Access to the Conduits and Destinations
> I would like to add the following methods to the Client:
> 
> void setConduit(Conduit) - this allows a user to easily specify an
> alternate
> Conduit.
> void setAsynchronousDestination(Destination) - this allows a user to
> easily
> specify a decoupled endpoint. It's address would be used for WS-Addressing
> interactions. If no Async destination exists, then the Client will only
> listen on the Conduit.
> Destination getAsynchronousDestination() - utility method to easily get
> the
> asynchronous destination
> 
> 3. Client.close();
> We need a way to shutdown the decouled endpoints (regardless of whether or
> not #1 & #2 are adopted). I think there is pretty good conensus we need a
> Client.close() method which will do this. It will call
> getConduit().close()
> and getAsynchronousDestination().shutdown().
> 
> (Ideally we'd like to be able to shut down RM at this same time. I'm going
> to guess that this would require the addition of a client lifecycle
> interface which allows RM to listen for Client.close(). This is an issue
> no
> matter which route we go though, so I'll defer this conversation for
> another
> thread)
> 
> 4. Remove the setup of decoupled destinations from inside the Conduit
> Currently, the Conduits are responsible for setting up the decoupled
> destinations. We've already got a perfectly good API for creating
> destinations, lets use it! Creating another API to create decoupled
> destinations introduces inconsistencies into our APIs. Right now if you
> want
> to create different endpoints for receiving ReplyTos and FaultTos you have
> configure the ReplyTos using the Conduit API and the FaultTos using the
> destination API. Creating those endpoints in different ways is bad IMO.
> 
> Putting in decoupled destinations inside the Conduit also makes it more
> complex for transport writers or people trying to understand the API. IMO,
> people intuitively expect this to be outside the Conduit class.
> 
> 5. Client Configuration
> I would propose that we make the decoupled destination configuration part
> of
> the Client
> 
> <jaxws:client id="...SomePort">
>   <jaxws:asynchronousEndpoint>
>     <wsa:Address>http://my.decoupled/endpoint</wsa:Address>
>   </jaxws:asynchronousEndpoint>
> </jaxws:client>
> 
> <jaxws:client id="...SomePort">
> 
> <jaxws:asynchronousDestination><http:destination...></jaxws:asynchronousDe
> stination>
> </jaxws:client>
> 
> As an added bonus, we can now wire together clients and destinations
> however
> we want. I wouldn't *have* to create a <conduit> config element with the
> port name inside it. Instead I could simply do:
> 
> <jaxws:client id="...SomePort">
>    <jaxws:conduit> <http:conduit... /> </jaxws:conduit>
> </jaxws:client>
> 
> It also creates a central place to embed Client configuration - such as
> enabling MTOM or configuring WS-*:
> <jaxws:client id="...SomePort">
>    <jaxws:conduit>...</jaxws:conduit>
>    <jaxws:binding mtomEnabled="true">
>      <jaxws:requestContext>
>        <map><entry key="javax.xml.ws.session.maintain"
> value="true"/></map>
>      </jaxws:requestContext>
>    </jaxws:binding>
>    <jaxws:features>
>      <wsrm:reliability timeout="10000" .../>
>    </jaxws:features>
> </jaxws:client>
> 
> Users could still use the <http:conduit id="PORT"/> syntax if they wanted
> to
> though.
> 
> (Note: I haven't written the jaxws:client Spring schema yet, but its on my
> todo list. The feature stuff will hopefully be part of my commit with
> WS-Security)
> 
> 6. Bring back Destination.getDestination(EndpointReferenceType)
> This method would be needed for the API that I propose in #1.
> 
> 7. Make the JAX-WS dispatch use the client.
> 
> ----
> 
> In summary:
> a) This simplifies the API. We've created an API to set up decoupled
> endpoints easily. We've reduced the complexity inside Conduits and have
> avoided introducing new complexity onto the Conduit interface to specify a
> decoupled destination.
> 
> b) It creates a consistent API for working with decoupled endpoints. There
> is no reason to go writing a new API for setting up decoupled endpoints -
> which is only used sometimes.
> 
> c) Dependency Injenction: By putting the Conduit & Destination on the
> Client
> we've made it much friendlier to people using Spring or other DI
> containers.
> 
> d) Improved configuration: I think the jaxws:client is a more natural
> place
> to setup the conduit and destination configuration as opposed to nesting
> the
> destination configuration inside the conduit.
> 
> e) Setting up decoupled destinations is not the job of the conduit IMO.
> We're giving Conduits a dual task unnecessarily. If all Conduits share the
> same code for setting up decoupled destinations, that is a sign to me that
> we can take it out of the Conduit.
> 
> I of course would be volunteering to do all this work.
> --
> 
> Alternatives: While Eoghan can elaborate, I believe he would rather see
> 1. The decoupled endpoint remain part of the conduit. He views a decoupled
> endpoint as part of the Conduit contract.
> 2. An API on the Conduit to set up the decoupled endpoint like so:
> Client.get(Conduit.class
> ).getClientPolicy().setDecoupledEndpoint(EndpointReferenceType)
> 3. The Client.getConduit/setConduit methods go away and have the Conduit
> be
> an optional part of the Client
> 4. No Client.setAsynchronousDestination method.
> 5. Keep the decoupled endpoint configuration as part of the conduit
> instead
> of the client.
> 
> Regards,
> - Dan
> 
> --
> Dan Diephouse
> Envoi Solutions
> http://envoisolutions.com | http://netzooid.com/blog
> 
> --
> No virus found in this incoming message.
> Checked by AVG Free Edition.
> Version: 7.5.446 / Virus Database: 268.18.11/722 - Release Date: 3/14/2007
> 3:38 PM
> 

-- 
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.5.446 / Virus Database: 268.18.11/722 - Release Date: 3/14/2007
3:38 PM