I agree that the design is easy to understand, but there are consequences 
from making the client stateful. Right now, multiple threads 
(request-handling code) can share a single client object to send messages 
to another resource. By storing custom headers in the client object prior 
to method invocation, we create a number of issues around synchronization; 
since adding the headers and invoking the method are not part of an atomic 
operation, it's possible that two threads sharing a client object can 
interrupt each other and cause messages to be sent out with the wrong 
headers.

The solutions to this are:

1. Document the fact that the client is not thread-safe and instruct users 
to wrap all uses of client objects in a synchronized() block.

2. Document the fact that the client is not thread-safe and instruct users 
to create a new client object for each new request (or session).

3. Keep the client stateless, but add better overloaded methods for custom 
headers in invoke().

4. Keep the client stateless, but provide a code generation option/flag 
that causes wsdl2java to create an extra Element[] parameter for custom 
headers. Something like:

        wsdl2java -wsdl MyResource.wsdl -headers


I think that #1 is problematic because it goes against the "principle of 
least surprise"; in other words, I don't think most people will read the 
muse-core JavaDoc prior to trying to use the code, nor should they really 
have to.

#2 may be a performance problem for large-transaction enviroments. If a 
resource is sending out a lot of notifications, for example, that's a lot 
of object creation/throw away for the heap.

#3 is the current solution, and is not easy to use. It was a quick hack 
that should be replaced/improved.

I think that #4 would be fairly easy to implement, assuming it was a 
resource-wide flag. The presence of the flag would just indicate to 
wsdl2java that it should add an extra parameter named "Element[] 
customHeaders" at the time of code generation. You could then use the same 
code you'd be using to build the header elements (for addHeaders()) and 
supply them directly to the method being invoked. The next request would 
not be affected by the header usage.

Thoughts? Or another idea?



"José Antonio Sánchez" <[EMAIL PROTECTED]> wrote on 12/14/2006 10:31:48 
AM:

> What I did was to add a list of Element named "headers" to the proxy
> class and two new methods (addHeader(Element) and removeHeaders()),
> then I changed the invoke method to include that headers. That is the
> code of a modified operation:
> 
> private Vector<Element> headers = new Vector<Element>();
> 
> 
>    public void addHeaderElement(Element header) {
>       headers.add(header);
> 
>    }
> 
>    public void removeAllHeaders() {
>       headers.removeAllElements();
>    }
> 
>    public String install(URI packageLocation)
>       throws SoapFault
>    {
>       Object[] params = new Object[1];
> 
>       params[0] = packageLocation;
> 
>       ProxyHandler handler = getHandler("install");
>       Element body = handler.toXML(params);
>       Element[] a = {};
>       Element[] elementHeaders = headers.toArray(a);
>       Element retElement = 
invoke(handler.getAction(),body,elementHeaders);
>       return (String)handler.fromXML(retElement);
>    }
> 
> I don't think adding that two operations to an upper level (say
> AbstractResourceClient) would be too much trouble.
> 
> On 12/12/06, Daniel Jemiolo <[EMAIL PROTECTED]> wrote:
> > We added some support for this in 2.1, although it may not be perfect
> > (suggestions are welcome). Here's the JavaDoc on the method that 
clients
> > can call down to in order to send custom headers with their request:
> >
> >
> > http://ws.apache.org/muse/docs/2.1.
> 
0/javadoc/org/apache/muse/core/AbstractResourceClient.html#invoke(java.lang.
> String,%20org.w3c.dom.Element,%20org.w3c.dom.Element[])
> >
> >
> > You can change the generated client method implementation to use this
> > invoke() instead of the normal one, giving you the opportunity to 
provide
> > custom headers.
> >
> > One issue with providing the headers through some other means
> > (addHeader(), etc.) is that the clients are stateless. Any alternative
> > would either need to handle this stateless-ness or suggest a stateful
> > solution that isn't too hard to use.
> >
> > Dan
> >
> >
> >
> > "José Antonio Sánchez" <[EMAIL PROTECTED]> wrote on 12/12/2006 
12:16:24
> > PM:
> >
> > > When I generate a client stub in Axis2 I can use the method
> > > stub._getServiceClient().addHeader(OMElement element) to add a 
custom
> > > element to the request's SOAP header but I cannot find something
> > > similar in the Muse proxy. Is there a way to use a generated proxy 
and
> > > to add a custom element to the header?
> > > If there is no direct method to do this, is it safe to use a
> > > ResourceParameter in the EndpointReference to send that custom
> > > message?
> > > --
> > > Saludos.
> > > José Antonio Sánchez
> > >
> > > 
---------------------------------------------------------------------
> > > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > > For additional commands, e-mail: [EMAIL PROTECTED]
> > >
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
> >
> 
> 
> -- 
> Saludos.
> José Antonio Sánchez
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to