OK I'm going to take one last shot at clarifying this use-case ... deep
breath :)
You've set me a *lot* of questions (nobody expects the spanish
inquisition :), so please excuse the brevity of my answers as I've
already burned a lot of time on this, and I don't have much more to
spare ...
-----Original Message-----
From: Dan Diephouse [mailto:[EMAIL PROTECTED]
Sent: 02 April 2007 05:41
To: [email protected]
Subject: Re: In Process Dispatch [was Re: [PROPOSAL] Client
and Conduit changes]
To follow up with my own email... (feel free to cut and paste
into another message so you don't have to reply to two emails)
First I've pasted in your set of questions for your previous mail ...
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.
OK, this clarifies what you're looking to do for me quite a
bit. If you're looking to do an in process dispatch with an
existing endpoint that has been created (i.e. an HTTP
endpoint) that is a completely different story.
It doesn't matter if it's a HTTP endpoint, or any other transport for
that matter. We'd short-circuit the dispatch so that a transport is not
involved in any capacity.
It isn't very
clear to me how the mechanics of such a thing would work.
Could you maybe supply a little more information about how
you would see the following working:
How would we determine if the endpoint is in the local
process space? For instance, if I have a Client talking to an
HTTP Server endpoint, how does it know to shortcut and talk
to the server directly?
If the endpoint has been publish()ed in the local process space, then an
interceptor can detect this via the ServerRegistry.
Would the Binding interceptors would be run?
Nope.
Would your solution require the modification of the current
binding interceptors to support auto-detection of in process dispatch?
Nope.
How do we determine which user level interceptors to run?
We'd only run "logical" interceptors, and by-pass everything from the
protocol layer on down thru' the chain.
Say I enable WS-Security - what mechanisms would there be to
determine that it should not be run for the local invocation
case?
The interceptors are simply by-passed. We can do this without
introducing a security hole as its all happening with the local process
space. So trust is implied.
However we can mark the Message via a property as originating from
within the local process space. So that logical-level security
interceptors on the receiving side can make decisions on that basis.
But we wouldn't force the intensely paranoid to use this mechanism if
they find the by-passing of security to be objectionable ... i.e. the
application developer/deployer would have to make a conscious decision
to enable this adaptive behavior.
Or what if a user writes a transformation interceptor.
How would the transformation be performed or would it not be?
It wouldn't.
If a server requires HTTP security, will we just bypass it?
Yes. Trust is implied.
For instance, lets say that we have a website which
communicates with its backend via a soap service. The client
uses the website's username/password to authenticate against
the server. If we just bypass that authentication, that would
be a security hole.
Are you talking about a delegation of credentials scenario? i.e. client
-invokes-> mid-tier -invokes-> backend, where the username/passwd for
the first invocation are delegated onto the second leg?
If so, then this can still be achieved, by passing the creds via the
BindingProvider.USERNAME/PASSWORD_PROPERTY or the AuthorizationPolicy
set on the Message.
Also, if the mid-tier->backend leg is protected by HTTP basic auth, then
even if the creds weren't available to the mid-tier, this wouldn't open
a security hole. The backend should reject the forwarded message with
401 or 403 or some-such.
What if the server & the client use different databindings?
Data-bindings don't come into the picture.
On the client side, when do we make the decision about
whether or not the endpoint is "in process"? During a client
creation?
No.
Or during each invocation?
Yes.
Can the decision happen mid invocation?
Well the decision would be made in an interceptor, if that's what you
mean by mid-invocation.
[First Impressions]
My first impression (based on what I understand you're trying
to achieve at this point) is that any solution:
a) Will require the use of different binding interceptors.
No. The binding interceptors don't need to change. Instead they'd be
by-passed.
Obviously we don't want to go invoking soap interceptors for
a local dispatch.
Obviously.
b) Will have some major affects on how their service is
invoked and possibly some security issues. It sounds like the
user should make a conscious decision about whether or not to use it.
Yep, of course they should. And they would do so by configuring an extra
interceptor into the chain to drive this. Which would have the effect of
using an optimized form of dispatch *if and only if* the target happens
to currently exist in the local process space. If, on the other hand,
the target really is remote, then the normal route is followed.
So this wouldn't be foisted on anyone. But neither does the user have to
*statically* choose either a local or remote style of dispatch. Once
they've enabled the adaptive selection mechanism, then it just works.
c) Will have to make the decision about whether or not the
Client is invoking a local service or a remote service before
the interceptor chain is invoked.
I disagree.
In other words, we will
have to add logic to the Client to detect this.
Disagree, it can be done in an interceptor.
If this is
done during the interceptor chain we may already have invoked
binding interceptors.
Isn't that phases are for?
We could just ensure this extra interceptor is run before any
binding-level interceptors.
d) Does not implicitly require that we ditch
Conduits/Destinations for in this type of in process
dispatching (if you agree to b, I think this follows
relatively easily. Proposed solution below.)
It doesn't *require* that we "ditch Conduits/Destinations". Its just a
different way of doing it. It might not be the way you would have chosen
to implement it, but remember ... broad church, diversity of ideas and
all that ...
After re-reading your emails, it seems that you want to
select this at invocation time, not at client creation time.
Yes.
I don't think we can do this after the chain has been
dispatched. If we did so this would mean we change our
Bindings pretty extensively to support detection.
I don't think the bindings need to change at all.
This would
complicate binding creation and seems pretty unnecessary
since this is what bindings are for - to control how a
service is bound to a protocol. It also could be disastrous
as we might have already written part of the message.
Not if the interceptor traversal phases are used correctly.
So it seems to imply that a per invocation approach would
require changes to the ClientImpl class. If we selected that
we want to use in process dispatch via a URI or flag or some
other mechanism then we would need to find a different
binding and use that instead.
I don't think the Client needs to be involved in the decision making.
I'm not sure why we wouldn't want to use a
Conduit/Destination still. They seem like a perfectly good
way to dispatch a message from a client to a service. Why
should we invent another one?
Getting as far the Conduit on the outbound chain implies that we've
traversed a bunch of other unnecessary stuff, the whole point of the
exercise being to avoid this.
Also, on the Conduit auto-init issue, if we have logic inside
ClientImpl.invoke to detect whether or not we're doing an
in-process dispatch, can't we use that same logic to
determine whether or not we should auto-create the Conduit?
Because, I don't think we need the inprocess-dispatch detection logic in
the Client. The whole point of an interceptor architecture is to allow
arbitrary "processing units" to swapped in and out of the dispatch
chain.
I'm envisioning that a user sets an endpoint address of
"endpoint:fooEndpoint". We can detect that this property has
been set inside the ClientImpl and not create the Conduit. We
can create that Conduit in MessageSenderInterceptor. The
same applies if they're using a different remote endpoint as well.
The whole point is to allow apps take advantage of this without any
static changes (like requiring the app to set a "endpoint:fooEndpoint"
property).
Can you detail more about how you see the logic inside
ClientImpl chainging?
IMO the Client doesn't need to be involved in the in-process dispatch
detection.
The only Client change required is in the conduit retrieval as outlined
in my "Pluggable Conduit Initiation Strategy" mail.
Cheers,
Eoghan
- Dan
--
Dan Diephouse
Envoi Solutions
http://envoisolutions.com | http://netzooid.com/blog