At this moment, we have all the binding related work done in the reference
binding Invoker and service binding Listener. To make it possible to plugin
code that deals with binding native message in the context of the binding,
we probably have to split the "Invoker" and "Listener" into a "pipeline".
For example, we have the Axis2BindingInvoker handles the following:
1) Create SOAPEnvelope
2) Create MessageContext with Options
3) Handle some QoS at the SOAP/Axis2 level
4) Create OperationClient
5) Call the OperationClient.execute() to dispatch the request.
We need to find out a good balance to regroup the functionalities with
reasonable pluggability. This can be exercised by writing up a few sample
logic that needs to access the binding specific message and context.
BTW, +1 to enhance the Message interface with getHeaders() so that Message
can carry non-business contextual data through the invocation chain.
Thanks,
Raymond
From: Simon Laws
Sent: Monday, September 08, 2008 5:25 AM
To: [email protected] ; [EMAIL PROTECTED]
Subject: Request Response Binding - was: Re: Tuscany data binding framework
enhancements
Ok so we've established that this stuff shouldn't be referred to as
Databinding alone so I've renamed the page [1]. Let's move on and work out
what we need to make this work...
A couple of points on the words added by Raymond and Ant:
Addition of native message data to the Tuscany message does open up the
possibility of adding interceptors to process the message but this doesn't
work so well on the reference side. Consider the following:
Reference -> interceptor -> binding -----> binding -> interceptor ->
service
In the policy example (different from operation selection etc but works for
demonstrating my point here) I have interceptors that do generic message
processing, e.g. on the reference side
public Message invoke(Message msg) {
// could call out here to some 3rd part system to get credentials
msg.getQoSContext().put(BasicAuthenticationPolicy.BASIC_AUTHENTICATION_USERNAME,
policy.getUserName());
msg.getQoSContext().put(BasicAuthenticationPolicy.BASIC_AUTHENTICATION_PASSWORD,
policy.getPassword());
return getNext().invoke(msg);
}
and on the service side
public Message invoke(Message msg) {
String username =
(String)msg.getQoSContext().get(BasicAuthenticationPolicy.BASIC_AUTHENTICATION_USERNAME);
String password =
(String)msg.getQoSContext().get(BasicAuthenticationPolicy.BASIC_AUTHENTICATION_PASSWORD);
if (username != null) {
System.out.println("Username: " + username + " Password: " +
password);
// could call out here to some 3rd part system to do whatever
you
// need to turn credentials into a principal
msg.getQoSContext().put(Message.QOS_CTX_SECURITY_PRINCIPAL,
username);
}
return getNext().invoke(msg);
}
But this means there has to be code in the binding to extract this info from
the message or put this info into the message, e.g. in the
Axis2BindingInvoker
if (basicAuthenticationPolicy != null) {
Axis2BasicAuthenticationReferenceBindingConfigurator.setOperationOptions(operationClient,
msg, basicAuthenticationPolicy);
}
And in the Axis2ServiceProvider
if (basicAuthenticationPolicy != null) {
Axis2BasicAuthenticationServiceBindingConfigurator.parseHTTPHeader(inMC,
msg, basicAuthenticationPolicy);
}
If for this request/response binding were to put native message content in
the tuscany message then we could implement interceptors on the service side
to pull out the approrpiate parts but on the reference side we would have to
do some generic processing and then extend the binding to read the generic
message and turn it into binding specific configuration. The binding
configuration structures are only available within the binding on the
reference side. It seems a little asymetric.
Now this may be what is being suggested but it would seem more appropriate
if we separated the current listeners/invokers up in so that their function
is spread amongs message mapping, fault mapping, etc functions. If we were
to stick with the tuscany message interface we would have to pass suitable
structures from one to the other in order to complete the processing.
Leading on from this we seem to need to hold header info in the Tuscany
message. I've added the following to the message interface to support some
policy experiments I've been doing but am open to suggestions...
Map<String, Object> getHeader();
Simon
[1]
http://cwiki.apache.org/confluence/display/TUSCANYWIKI/Request+Response+Binding