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

Reply via email to