[ https://issues.apache.org/jira/browse/CXF-8911?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17782899#comment-17782899 ]
Peter Palaga edited comment on CXF-8911 at 11/4/23 3:52 PM: ------------------------------------------------------------ Sorry for the late response and thanks for the ideas, [~reta] and [~dufoli]! {quote} {code} public interface AsyncResponseListenerFactory { AsyncResponseListener create(); } public interface AsyncResponseListener { void onBeforeReceived(HttpResponse response); void onAfterReceived(HttpResponse response); } CXFResponseCallback responseCallback = new CXFResponseCallback() { @Override public void responseReceived(HttpResponse response) { listener.onBeforeReceived(response); setHttpResponse(response); listener.onAfterReceived(response); } }; {code} {quote} I think this would not work, because I need to "be on the stack" of the code called by {{setHttpResponse(response);}}. But your earlier proposal with {{interface AsyncResponseCallbackFactory}} would work. I could do something like {code} class AsyncResponseCallbackFactory implements AsyncResponseCallbackFactory { AsyncResponseCallback create() { ThreadContext threadContext = Arc.container().select(ThreadContext.class).get(); /* * We need to call this threadContext.contextualConsumer() here in the constructor to store the context * because consumeResponse() is called from another thread where the context is not available anymore */ BiConsumer<HttpResponse, CXFResponseCallback> contextualConsumer = threadContext.contextualConsumer( (HttpResponse response, CXFResponseCallback callback) -> callback.responseReceived(response)); return new MyAsyncResponseCallback(contextualConsumer); } } class MyAsyncResponseCallback implements AsyncResponseCallback { final BiConsumer<HttpResponse, CXFResponseCallback> contextualConsumer; MyAsyncResponseCallback(BiConsumer<HttpResponse, CXFResponseCallback> contextualConsumer) { this.contextualConsumer = contextualConsumer; } void responseReceived(HttpResponse response, CXFResponseCallback callback) { contextualConsumer.accept(response, callback); } } {code} Could you perhaps draft a CXF pull request so that I can check that it really works? was (Author: ppalaga): Sorry for the late response and thanks for the ideas, [~reta] and [~dufoli]! {quote} {code} public interface AsyncResponseListenerFactory { AsyncResponseListener create(); } public interface AsyncResponseListener { void onBeforeReceived(HttpResponse response); void onAfterReceived(HttpResponse response); } CXFResponseCallback responseCallback = new CXFResponseCallback() { @Override public void responseReceived(HttpResponse response) { listener.onBeforeReceived(response); setHttpResponse(response); listener.onAfterReceived(response); } }; {code} {quote} I think this would not work, because I need to "be on the stack" of the code called by {{setHttpResponse(response);}}. But your earlier proposal with {{interface AsyncResponseCallbackFactory} }} would work. I could do something like {code} class AsyncResponseCallbackFactory implements AsyncResponseCallbackFactory { AsyncResponseCallback create() { ThreadContext threadContext = Arc.container().select(ThreadContext.class).get(); /* * We need to call this threadContext.contextualConsumer() here in the constructor to store the context * because consumeResponse() is called from another thread where the context is not available anymore */ BiConsumer<HttpResponse, CXFResponseCallback> contextualConsumer = threadContext.contextualConsumer( (HttpResponse response, CXFResponseCallback callback) -> callback.responseReceived(response)); return new MyAsyncResponseCallback(contextualConsumer); } } class MyAsyncResponseCallback implements AsyncResponseCallback { final BiConsumer<HttpResponse, CXFResponseCallback> contextualConsumer; MyAsyncResponseCallback(BiConsumer<HttpResponse, CXFResponseCallback> contextualConsumer) { this.contextualConsumer = contextualConsumer; } void responseReceived(HttpResponse response, CXFResponseCallback callback) { contextualConsumer.accept(response, callback); } } {code} Could you perhaps draft a CXF pull request so that I can check that it really works? > Allow creating a custom CXFHttpAsyncResponseConsumer > ---------------------------------------------------- > > Key: CXF-8911 > URL: https://issues.apache.org/jira/browse/CXF-8911 > Project: CXF > Issue Type: New Feature > Reporter: Peter Palaga > Priority: Major > > We recently got a [bug > report|https://github.com/quarkiverse/quarkus-cxf/issues/947] in Quarkus CXF > complaining about non-working context propagation with CXF HC5 client. > The problem was that if the client is called in context of a Quarkus REST > endpoint, whose vert.x thread has the request context setup properly, the > request scoped beans are then not accessible e.g. from > ContainerRequestFilters which run in in a different thread. > To make it work, we would need wrap the creation of > CXFHttpAsyncResponseConsumer in some code storing the context of the creation > thread into a wrapping method that can then be executed by some other thread. > I was able to do this by overriding some default classes. What I did can be > seen around here: > https://github.com/quarkiverse/quarkus-cxf/pull/950/files#diff-568a3d75d004f9f41c6130854755ebb2beae2f30308cc45aa98492d09bac2ecc > This solution is by no means elegant and I wonder whether it would be > feasible to implement some new API to allow creating custom > CXFHttpAsyncResponseConsumers? > Maybe we could introduce some kind of CXFHttpAsyncResponseConsumerFactory? > I am quite new to CXF internals, so I'd be thankful for any hints how to > proceed. -- This message was sent by Atlassian Jira (v8.20.10#820010)