You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Andrei Shakirin <as...@talend.com> on 2014/01/27 18:36:18 UTC

Using MessageContext in AsyncHandler

Hi,

I have a requirement to set message context properties on the service side in asynchronous handler. The values of these properties are dependent on business code.
Normally it works this way: 
public class ServiceProviderHandler implements Provider<StreamSource> {
    @Resource
    private WebServiceContext wsContext;
   ...
    public StreamSource invoke(StreamSource request) {
     ...
      wsContext.getMessageContext().put(propName, propValue);
    ...
   }
}

getMessageContext() returns current message context based on thread local.

Therefore the code doesn't works if wsContext.getMessageContext() is called form another thread in case of async handler:

    public Future<?> invokeAsync(final StreamSource s, final AsyncHandler<Source> asyncHandler) {
        final ServerAsyncResponse<Source> r = new ServerAsyncResponse<Source>();
        new Thread() {
            public void run() {
               ...
                // wsContext.getMessageContext() is null here
                r.set(response);
                asyncHandler.handleResponse(r);
            }
        }.start();
        return r;
    }

The question is there elegant way to set message context props in another thread.
Seems that ServerAsyncResponse has appropriate context method, can be used for these purposes, but it still not implemented:
    /**
     * Currently unused
     */
    public Map<String, Object> getContext() {
        return null;
    }

Sure it is still possible to implement that using threads synchronization, but this a bit complicate and not user friendly.
Is it really lacking functionality or I missing something?

Regards,
Andrei.


RE: Using MessageContext in AsyncHandler

Posted by Andrei Shakirin <as...@talend.com>.
There is more trivial solution here: just save the context into local variable in invoking thread and pass it to the custom thread:

@WebServiceProvider
@ServiceMode(value = Service.Mode.PAYLOAD)
public class ServiceProviderHandler implements Provider<StreamSource> {
    @Resource
    private WebServiceContext wsContext;    public Future<?> invokeAsync(final StreamSource s, final AsyncHandler<Source> asyncHandler) {
        System.out.println("*** Called async ***");
        final ServerAsyncResponse<Source> r = new ServerAsyncResponse<Source>();
        final MessageContext msgContext = wsContext.getMessageContext();
        new Thread() {
            public void run() {
                StreamSource response = new StreamSource(this.getClass().getResourceAsStream("/test.xml"));
                r.set(response);
                msgContext.put("testProperty", "testValue");
                asyncHandler.handleResponse(r);
            }
        }.start();
        return r;
    }

Regards,
Andrei.

> -----Original Message-----
> From: Andrei Shakirin [mailto:ashakirin@talend.com]
> Sent: Montag, 27. Januar 2014 18:36
> To: users@cxf.apache.org
> Subject: Using MessageContext in AsyncHandler
> 
> Hi,
> 
> I have a requirement to set message context properties on the service side
> in asynchronous handler. The values of these properties are dependent on
> business code.
> Normally it works this way:
> public class ServiceProviderHandler implements Provider<StreamSource> {
>     @Resource
>     private WebServiceContext wsContext;
>    ...
>     public StreamSource invoke(StreamSource request) {
>      ...
>       wsContext.getMessageContext().put(propName, propValue);
>     ...
>    }
> }
> 
> getMessageContext() returns current message context based on thread
> local.
> 
> Therefore the code doesn't works if wsContext.getMessageContext() is
> called form another thread in case of async handler:
> 
>     public Future<?> invokeAsync(final StreamSource s, final
> AsyncHandler<Source> asyncHandler) {
>         final ServerAsyncResponse<Source> r = new
> ServerAsyncResponse<Source>();
>         new Thread() {
>             public void run() {
>                ...
>                 // wsContext.getMessageContext() is null here
>                 r.set(response);
>                 asyncHandler.handleResponse(r);
>             }
>         }.start();
>         return r;
>     }
> 
> The question is there elegant way to set message context props in another
> thread.
> Seems that ServerAsyncResponse has appropriate context method, can be
> used for these purposes, but it still not implemented:
>     /**
>      * Currently unused
>      */
>     public Map<String, Object> getContext() {
>         return null;
>     }
> 
> Sure it is still possible to implement that using threads synchronization, but
> this a bit complicate and not user friendly.
> Is it really lacking functionality or I missing something?
> 
> Regards,
> Andrei.