Search code examples
web-servicessoapthread-safetyjax-wssoaphandler

Thread Safety in Jax-WS Request-Response Payload Logging


I am working on a SoapHandler implementation. Basically my aim is to get both request and response payloads and insert them to the database.

Although I can get the request and response payloads, I couldn't make sure if my code is working thread-safe. In other words, I am not sure if responses match with the proper requests.

public boolean handleMessage(SOAPMessageContext mContext) {

    boolean isResponse = (Boolean) mContext
            .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

    if (!isResponse) {
        try {
            mContext.put("currentStream", new ByteArrayOutputStream());
            mContext.getMessage().writeTo((OutputStream) mContext.get("currentStream"));

        } catch (SOAPException | IOException e) {
            e.printStackTrace();
        }
    } else {
        try {
            mContext.getMessage().writeTo(
                    (OutputStream) mContext.get("currentStream"));
            System.out.println(((OutputStream) mContext.get("currentStream"))
                    .toString());
            ((OutputStream) mContext.get("currentStream")).flush();
        } catch (SOAPException | IOException e) {
            e.printStackTrace();
        }
    }

    return true;
}

I found this in JCP specs:

9.3.3 Handler Implementation Considerations

Handler instances may be pooled by a JAX-RPC runtime system. All instances of a specific handler are considered equivalent by a JAX-RPC runtime system and any instance may be chosen to handle a particular message. Different handler instances may be used to handle each messages of an MEP. Different threads may be used for each handler in a handler chain, for each message in an MEP or any combination of the two. Handlers should not rely on thread local state to share information. Handlers should instead use the message context, see section 9.4.

9.4 Message Context

Handlers are invoked with a message context that provides methods to access and modify inbound and outbound messages and to manage a set of properties. Different types of handler are invoked with different types of message context. Sections 9.4.1 and 9.4.2 describe MessageContext and LogicalMessageContext respectively. In addition, JAX-RPC bindings 12 may define a message context subtype for their particular protocol binding that provides access to protocol specific features. Section10.3 describes the message context subtype for the JAX-RPC SOAP binding.

http://download.oracle.com/otn-pub/jcp/jaxrpc-2.0-edr2-spec-oth-JSpec/jaxrpc-2_0-edr2-spec.pdf?AuthParam=1431341511_1ac4403a34d7db108bce79eda126df49

Does this imply that a new MessageContext object is created for each request (in which case I think the code will be thread safe), or the same MessageContext object can be used for multiple requests (then my code will not be thread safe).

Any help / alternative solution will be appreciated.


Solution

  • Rule of thumb: a FooContext object is contextual by definition, relating to a specific execution context. EJBContext relating to a single EJB; FacesContext relating to a single Faces request context; SOAPMessageContext relating to a single SOAPMessage. From the JSR-109 documentation:

    The container must share the same MessageContext instance across all Handler instances and the target endpoint that are invoked during a single request and response or fault processing on a specific node.

    So, you can be sure that there's one new SOAPMessageContext instance per request. Within the context of a single request however, that instance is yours to mangle. So the question really is, what do you mean by "threadsafety"? Do you plan to have multiple threads processing a single SOAPMessageContext during each request? I don't recommend it

    EDIT: While the specification doesn't state in black and white that a MessageContext is threadsafe, it's implied throughout the specification. The following is an excerpt from the section of the spec that states what's possible on a MessageContext, within a handler:

    Handlers may manipulate the values and scope of properties within the message context as desired. E.g. ... a handler in a server-side SOAP binding might add application scoped properties tot he message context from the contents of a header in a request SOAP message...


    SOAP handlers are passed a SOAPMessageContext when invoked. SOAPMessageContext extends MessageContext with methods to obtain and modify the SOAP message payload

    The specification won't be expecting programmers to modify the content of the context if it weren't safe to do so.