You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by "Glynn, Eoghan" <eo...@iona.com> on 2007/04/02 13:35:20 UTC

[PROPOSAL] Pluggable Conduit Initiation Strategy


Dan,

The previous thread has bifurcated outta control :-0 and is getting
impossible for anyone else to follow.

So to put some order on this, I'm starting a fresh thread on which I'll
spell out in simple terms what I'm proposing to do in terms of the
conduit retrieval strategy.

In a separate email, I'll attempt to respond to the scrutiny you're
imposing on the in-process dispatch use-case. 

So please don't respond on this thread with further requests for
clarification on the in-process use-case. That's just one of several
potential applications of this mechanism. So lets keep this
[sub-]discussion focused on:

(a) the merits or otherwise of this proposed change

(b) why you want to force the coupling of the Client and Conduit in
*ALL* cases

Now the idea is simply to apply the strategy pattern so as to allow a
pluggable conduit retrieval strategy. The default strategy would be to
follow the current implementation and get the Conduit upfront from
within ClientImpl.invoke(). Another potential strategy would be to defer
retrieving the Conduit until we're sure we actually need it, i.e. in the
MessageSenderInterceptor. Currently on the requestor-side, the
MessageSenderInterceptor checks Message.getConduit(), then
Exchange.getConduit() in order to retrieve the conduit. Since
Message.setConduit() is called nowhere, I'd also propose dropping this
for the sake of cleanliness (but I'm not hung on that, if you really
want to keep Message.getConduit()). However the main change would be in
the implementation of Exchange.getConduit(). Instead of being a straight
accessor to a private field, this would instead look more like:

public class ExchangeImpl implements Exchange {
   public Conduit getConduit() {
       return get(ConduitInitiationStrategy.class) != null
              ? get(ConduitInitiationStrategy.class).getConduit(this)
              : null;
   }
}

In ClientImpl.invoke(), the main change is simply to call:

   exchange.put(ConduitInitiationStrategy.class, conduitStrategy);

instead of 

   exchange.setConduit(initedConduit);

The conduitStrategy would as I said before default to a upfront
retrieval. However this mechanism would provide the flexibility to
inject an alternate strategy via Spring. 

And let me preempt your first objection, that this is unnecessary.
Wearing my CXF user hat, I want to build logic that requires more
flexibility than is provided by a tightly coupled Client and Conduit. So
there is a user requirement for this. The user being me. Who's currently
blocked by this log-jam, and so is proposing what I think is a very
reasonable compromise position. In particular, note that I've conceded
that the default behavior should remain as is.

Also let me preempt another likely objection, that this introduces too
much complexity. IMO it's a simple mechanism that in the default case
will have no impact on the current entanglement between Client and
Conduit. So in the normal case, there is no appreciable complexity for
you to deal with. Everything works just the same by default, rightly or
wrongly. So I don't think it could be fairly characterized as a
far-reaching architectural change to CXF.

Cheers,
Eoghan

Re: [PROPOSAL] Pluggable Conduit Initiation Strategy

Posted by Dan Diephouse <da...@envoisolutions.com>.
Please see my last message where I ask two very specific questions about
this. I'm not opposed to delaying creation of a Conduit in some
circumstances. I think the threads are getting too conflated (should we
*require* a Conduit during dispatch vs. should we be able to lazy init a
Conduit), which is partially my fault, so maybe this is part of the
confusion going on...

- Dan

On 4/2/07, Andrea Smyth < andrea.smyth@iona.com> wrote:
>
>
> >
> > Are we not happy with our ability to select a different Conduit inside
> > the
> > MessageSenderInterceptor? I don't see how this could be an issue. Just
> > set a
> > new Conduit on the Exchange in a previous interceptor.
>
> Hi Dan,
>
> Maybe I am missing something here - but doesn't the fact that any
> interceptor run before the MessageSenderInterceptor can set the conduit
> prove that the client - conduit coupling is very loose indeed?
> In the presence of such an interceptor, it makes perfect sense to me to
> not initialise a conduit upfront if it's possible/certain that this is
> never going to be used.
> In that case I don't understand your objections aginst the proposed
> strategy pattern.
>
> Cheers,
> Andrea.
>
>


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

Re: [PROPOSAL] Pluggable Conduit Initiation Strategy

Posted by Polar Humenn <ph...@iona.com>.
Dan Diephouse wrote:
> On 4/2/07, Polar Humenn <ph...@iona.com> wrote:
>>
>> You are right, but this situation should be sured up some more.
>> One of two approaches should be selected. Either:
>>
>> 1. The Client selects/configures the Conduit according to its
>> requirements, and it
>>    *cannot* be changed. (i.e. no calls to "setConduit" should exist
>> anywhere in the
>>    public API).
>
>
> This isn't feasible unless we select detect the new endpoint address 
> inside
> the Conduit itself. Which I thought we decided was less than ideal?

I have thought about this, and have implemented http/s such that it can 
handle that. It just can't handle "protocol" switches. The requirement 
from the Client is that the "conduit" is the abstraction that is 
delivering the message and the client can place constraints on that. 
It's the way in which you talk to the endpoint. We just allow for 
address overrides. The advent of TrustDecider callbacks alleviate any 
concerns the application may have about the ENDPOINT_ADDRESS override, 
or redirects.

>
> 2. The Client sets a Conduit selection/configuration policy that 
> *cannot* be
>>     changed, and interceptors can only get a conduit from Conduit 
>> factory
>>     that adheres to that policy.
>
>
> Could the overridden endpoint address be a completely different 
> transport?

That of course, begs the question "What is a transport?" I don't think 
we have sufficiently defined that term.

> Then there isn't really feasible way to handle this as there isn't a 
> way to
> copy Conduit configurations. For instance, my HTTP configuration for 
> trust
> doesn't really translate well to a JMS configuraiton.
>

Right. Currently, I keep address overrides with in the HTTP conduit. 
Note that this is only specific to the HTTPConduit implementation, and 
not in general.

Cheers,
-Polar
> - Dan
>
>


Re: [PROPOSAL] Pluggable Conduit Initiation Strategy

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 4/2/07, Polar Humenn <ph...@iona.com> wrote:
>
> You are right, but this situation should be sured up some more.
> One of two approaches should be selected. Either:
>
> 1. The Client selects/configures the Conduit according to its
> requirements, and it
>    *cannot* be changed. (i.e. no calls to "setConduit" should exist
> anywhere in the
>    public API).


This isn't feasible unless we select detect the new endpoint address inside
the Conduit itself. Which I thought we decided was less than ideal?

2. The Client sets a Conduit selection/configuration policy that *cannot* be
>     changed, and interceptors can only get a conduit from Conduit factory
>     that adheres to that policy.


Could the overridden endpoint address be a completely different transport?
Then there isn't really feasible way to handle this as there isn't a way to
copy Conduit configurations. For instance, my HTTP configuration for trust
doesn't really translate well to a JMS configuraiton.

- Dan


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

Re: [PROPOSAL] Pluggable Conduit Initiation Strategy

Posted by Polar Humenn <ph...@iona.com>.
You are right, but this situation should be sured up some more.
One of two approaches should be selected. Either:

1. The Client selects/configures the Conduit according to its 
requirements, and it
   *cannot* be changed. (i.e. no calls to "setConduit" should exist 
anywhere in the
   public API).

2. The Client sets a Conduit selection/configuration policy that *cannot* be
    changed, and interceptors can only get a conduit from Conduit factory
    that adheres to that policy.

Otherwise, the client has no hope in getting any of its requirements 
satisfied by the
underlying architecture.

Cheers,
-Polar

Andrea Smyth wrote:
>
>>
>> Are we not happy with our ability to select a different Conduit 
>> inside the
>> MessageSenderInterceptor? I don't see how this could be an issue. 
>> Just set a
>> new Conduit on the Exchange in a previous interceptor.
>
> Hi Dan,
>
> Maybe I am missing something here - but doesn't the fact that any 
> interceptor run before the MessageSenderInterceptor can set the 
> conduit prove that the client - conduit coupling is very loose indeed?
> In the presence of such an interceptor, it makes perfect sense to me 
> to not initialise a conduit upfront if it's possible/certain that this 
> is never going to be used.
> In that case I don't understand your objections aginst the proposed 
> strategy pattern.
>
> Cheers,
> Andrea.
>


Re: [PROPOSAL] Pluggable Conduit Initiation Strategy

Posted by Andrea Smyth <an...@iona.com>.
>
> Are we not happy with our ability to select a different Conduit inside 
> the
> MessageSenderInterceptor? I don't see how this could be an issue. Just 
> set a
> new Conduit on the Exchange in a previous interceptor.

Hi Dan,

Maybe I am missing something here - but doesn't the fact that any 
interceptor run before the MessageSenderInterceptor can set the conduit 
prove that the client - conduit coupling is very loose indeed?
In the presence of such an interceptor, it makes perfect sense to me to 
not initialise a conduit upfront if it's possible/certain that this is 
never going to be used.
In that case I don't understand your objections aginst the proposed 
strategy pattern.

Cheers,
Andrea.


RE: [PROPOSAL] Pluggable Conduit Initiation Strategy

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

> -----Original Message-----
> From: Dan Diephouse [mailto:dan@envoisolutions.com] 
> Sent: 02 April 2007 15:28
> To: cxf-dev@incubator.apache.org
> Subject: Re: [PROPOSAL] Pluggable Conduit Initiation Strategy
> 
> On 4/2/07, Glynn, Eoghan <eo...@iona.com> wrote:
> >
> >
> >
> > Dan,
> >
> > The previous thread has bifurcated outta control :-0 and is getting 
> > impossible for anyone else to follow.
> >
> > So to put some order on this, I'm starting a fresh thread on which 
> > I'll spell out in simple terms what I'm proposing to do in terms of 
> > the conduit retrieval strategy.
> >
> > In a separate email, I'll attempt to respond to the scrutiny you're 
> > imposing on the in-process dispatch use-case.
> 
> 
> Great.
> 
> So please don't respond on this thread with further requests for
> > clarification on the in-process use-case. That's just one 
> of several 
> > potential applications of this mechanism. So lets keep this 
> > [sub-]discussion focused on:
> 
> 
> I would love to hear the other potential applications of this 
> mechanisms.


Well I mentioned other use-cases in my mails last week. Direct quotes:

"an interceptor in the outbound chain to ... divert the message to a
different endpoint, that maybe necessitates a different Conduit instance
to the one selected up front by the Client"

"where I want to be able to dynamically switch to a different Conduit
from within the interceptor chain ... this would facilitate late-binding
to one of a cluster of target endpoints."

Are you saying that you missed/ignored this in the previous threads, or
you want to hear more use-cases, or more detail, or what?


> (a) the merits or otherwise of this proposed change
> >
> > (b) why you want to force the coupling of the Client and Conduit in
> > *ALL* cases
> 
> 
> Here is in a nutshell why I view that we should keep usage of 
> the Conduit with the Client.
> 
> The Client produces a request in the form of a message, xml 
> document, pojo, etc which must be dispatched somewhere. That 
> is, the thing produced must at some point leave the system of 
> the Client and go to somewhere else. 


IMO the message thingy *doesn't* have to leave the "system of the
client" in the in-process dispatch case. Unless of course you
artificially demarcate the "system of the client" to be something other
than the obvious candidates, i.e. the local process space or the domain
of the Bus instance.


> Now this sounds 
> *exactly* like what a Conduit is for. It provides a boundary 
> between the Client and the thing ultimately receiving a 
> request. 


Well in my view the Client is responsible for assembling the interceptor
chain, and dispatching the outbound message on that. So the boundary
abutted by the client is the interceptor chain, not the Conduit.

And I wouldn't be surprised if that's the conceptual picture that a lot
of other people also carry around in their heads ... i.e. a typical
stack, with the Client on top, in the middle a chain of interceptors
covering the spectrum from logical to protocol, and a Conduit at the
base. That just my understanding, I'm not forcing it on anyone though.  

And hey, it doesn't unduly concern me that you have a different picture
and see a tight coupling between Client and Conduit. Fine, I'm proposing
you can keep that tight coupling in the default case. But what I don't
understand is why you're insisting on this being the one-and-only good,
right & true way.


> > And let me preempt your first objection, that this is unnecessary.
> > Wearing my CXF user hat, I want to build logic that requires more 
> > flexibility than is provided by a tightly coupled Client 
> and Conduit. 
> > So there is a user requirement for this. The user being me. Who's 
> > currently blocked by this log-jam, and so is proposing what 
> I think is 
> > a very reasonable compromise position. In particular, note 
> that I've 
> > conceded that the default behavior should remain as is.
> 
> 
> I'm not trying to thwart your user requirement. But I reserve 
> the right to understand such a requirement before saying that 
> we should definitely integrate this into CXF.


And in the absence of this understanding condensing in your mind, what?


> Less is often 
> more, so if the current mechanisms are sufficient, why should 
> we introduce new ones?  


Are you really telling me that every change you've introduced yourself,
or suggestion from the user community that you've championed, has
under-gone this level of scrutiny?

I detect a certain amount of bar-raising going on.

There are plenty of cases in the code, or currently in the works, where
alternate means are introduced for achieving similar ends.


> You have done nothing to show that 
> there are use cases that absolutely require that you don't 
> use a Conduit. 


Done nothing? 

I've spent an inordinate amount of time trying to explain this to you.

It is not that I've an *absolute* requirement not to use a Conduit.

I just want the freedom to choose which Conduit is used (if any) from
within the interceptor chain. Not to have one (possibly redundant or
wrong) foisted on me by the Client. 

Please explain why you don't want this flexibility to be supported by
CXF?

Your preferred upfront retrieval would still be the default. What do you
care if I build some logic on top of CXF that retrieves the Conduit at a
slightly later point in time?


> This is supposed to be a proposal and you just 
> waved your hands saying its not needed. 


Speaking of hand-waving ... I haven't heard any good reasons as to why
you're insisting that the Conduit *MUST* be retrieved upfront in the
Client in *ALL* cases. Why so intransigent on this point?


> I'm simply saying I 
> would like to understand what they are. Maybe you're right, 
> and your other thread on in-process dispatch will show me why 
> its required that we ditch the Conduit & 
> MessageSenderInterceptor for some invocations.
> 
> My stance is that conduits are pretty flexible really, so I 
> don't see what limitations they impose.


The limitations are not in the Conduits themselves. I just want the
flexibility to retrieve the target Conduit at a later stage in the
dispatch.

 
> Is sending occurring at the wrong time? If you're not happy 
> with when the dispatching is occurring (i.e. its a different 
> phase), just stick the MessageSenderInterceptor in a different phase.
> 
> Do you not want to use the bundled Conduits? Write your own.


I'm perfectly happy with the bundled Conduits. I wrote a chunk of that
code myself. 

I just want the flexibility to only use a Conduit when its required, and
not to be forced to prematurely retrieve one when it may turn out that I
want to use a different one instead.


> Are we not happy with our ability to select a different 
> Conduit inside the MessageSenderInterceptor? I don't see how 
> this could be an issue. Just set a new Conduit on the 
> Exchange in a previous interceptor.
> 
> What exactly do you find so limiting about the Conduit abstraction?


One last time ... Its not the Conduit abstraction that limiting. Its
being forced to select a Conduit upfront in the Client.

/Eoghan

Re: [PROPOSAL] Pluggable Conduit Initiation Strategy

Posted by Dan Diephouse <da...@envoisolutions.com>.
On 4/2/07, Glynn, Eoghan <eo...@iona.com> wrote:
>
>
>
> Dan,
>
> The previous thread has bifurcated outta control :-0 and is getting
> impossible for anyone else to follow.
>
> So to put some order on this, I'm starting a fresh thread on which I'll
> spell out in simple terms what I'm proposing to do in terms of the
> conduit retrieval strategy.
>
> In a separate email, I'll attempt to respond to the scrutiny you're
> imposing on the in-process dispatch use-case.


Great.

So please don't respond on this thread with further requests for
> clarification on the in-process use-case. That's just one of several
> potential applications of this mechanism. So lets keep this
> [sub-]discussion focused on:


I would love to hear the other potential applications of this mechanisms.


(a) the merits or otherwise of this proposed change
>
> (b) why you want to force the coupling of the Client and Conduit in
> *ALL* cases


Here is in a nutshell why I view that we should keep usage of the Conduit
with the Client.

The Client produces a request in the form of a message, xml document, pojo,
etc which must be dispatched somewhere. That is, the thing produced must at
some point leave the system of the Client and go to somewhere else. Now this
sounds *exactly* like what a Conduit is for. It provides a boundary between
the Client and the thing ultimately receiving a request. What this thing
receiving the request is doesn't matter - in process server or a remote
host.


Since
> Message.setConduit() is called nowhere, I'd also propose dropping this
> for the sake of cleanliness (but I'm not hung on that, if you really
> want to keep Message.getConduit()).


I don't care either way really.


However the main change would be in
> the implementation of Exchange.getConduit (). Instead of being a straight
> accessor to a private field, this would instead look more like:
>
> public class ExchangeImpl implements Exchange {
>    public Conduit getConduit() {
>        return get(ConduitInitiationStrategy.class ) != null
>               ? get(ConduitInitiationStrategy.class).getConduit(this)
>               : null;
>    }
> }
>
> In ClientImpl.invoke(), the main change is simply to call:
>
>    exchange.put(ConduitInitiationStrategy.class , conduitStrategy);
>
> instead of
>
>    exchange.setConduit(initedConduit);
>
> The conduitStrategy would as I said before default to a upfront
> retrieval. However this mechanism would provide the flexibility to
> inject an alternate strategy via Spring.
>
> And let me preempt your first objection, that this is unnecessary.
> Wearing my CXF user hat, I want to build logic that requires more
> flexibility than is provided by a tightly coupled Client and Conduit. So
> there is a user requirement for this. The user being me. Who's currently
> blocked by this log-jam, and so is proposing what I think is a very
> reasonable compromise position. In particular, note that I've conceded
> that the default behavior should remain as is.


I'm not trying to thwart your user requirement. But I reserve the right to
understand such a requirement before saying that we should definitely
integrate this into CXF. Less is often more, so if the current mechanisms
are sufficient, why should we introduce new ones?  You have done nothing to
show that there are use cases that absolutely require that you don't use a
Conduit. This is supposed to be a proposal and you just waved your hands
saying its not needed. I'm simply saying I would like to understand what
they are. Maybe you're right, and your other thread on in-process dispatch
will show me why its required that we ditch the Conduit &
MessageSenderInterceptor for some invocations.

My stance is that conduits are pretty flexible really, so I don't see what
limitations they impose.

Is sending occurring at the wrong time? If you're not happy with when the
dispatching is occurring (i.e. its a different phase), just stick the
MessageSenderInterceptor in a different phase.

Do you not want to use the bundled Conduits? Write your own.

Are we not happy with our ability to select a different Conduit inside the
MessageSenderInterceptor? I don't see how this could be an issue. Just set a
new Conduit on the Exchange in a previous interceptor.

What exactly do you find so limiting about the Conduit abstraction?

Regards,

- Dan


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

Re: [PROPOSAL] Pluggable Conduit Initiation Strategy

Posted by Andrea Smyth <an...@iona.com>.
>MessageSenderInterceptor. Currently on the requestor-side, the
>MessageSenderInterceptor checks Message.getConduit(), then
>Exchange.getConduit() in order to retrieve the conduit. Since
>Message.setConduit() is called nowhere, I'd also propose dropping this
>for the sake of cleanliness (but I'm not hung on that, if you really
>want to keep Message.getConduit()). 
>
+1 on that - I just wasted (probably not for the first time) some 
debugging cycle trying to understand why a conduit reference was null 
until I realised I had obtained it via Message.getConduit() instead of 
Exchange.getConduit()...

Andrea.