Hi Mandy

Thanks, we've just talked with Dan on #apache-cxf, Dan explained the way your code adds out interceptors is correct, thanks for the example.

I guess the only remaining question is whether adding fault interceptors is needed (question 3), I believe it is application-specific, there's no requirement to match adding the new out bound interceptor with an out fault one, so unless some dynamism is expected at out fault chain too then it is not needed

Thanks, Sergey

On 07/06/16 14:56, Mandy Warren wrote:
Thanks for the fast reply Sergey.

So, I am accessing the PhaseInterceptorChain in a class called by a JAX-WS service. 
So imagine class HelloWorldImpl from 
http://cxf.apache.org/docs/a-simple-jax-ws-service.html 
<http://cxf.apache.org/docs/a-simple-jax-ws-service.html> is calling it i.e:


@WebService(endpointInterface = "demo.hw.server.HelloWorld",
             serviceName = "HelloWorld")
public class HelloWorldImpl implements HelloWorld {
     Map<Integer, User> users = new LinkedHashMap<Integer, User>();


     public String sayHi(String text) {

        // imagine I open a session here
        …
        // now I need to register my GenericOutboundInterceptor to close that 
session

Interceptor interceptor = new GenericOutboundInterceptor();

     Collection<Interceptor> interceptorAsList = new ArrayList<>(1);
     interceptorAsList.add(interceptor);

     // register the specified CallbackAction only on the out & fault 
interceptors for this request/response
     // to ensure no impact on other messages
     Message message = PhaseInterceptorChain.getCurrentMessage();

     Collection<Interceptor> outInterceptors = 
(Collection<Interceptor>)message.get(Message.OUT_INTERCEPTORS);
     if (null!=outInterceptors) {
         outInterceptors.add(interceptor);
     } else {
         message.put(Message.OUT_INTERCEPTORS, interceptorAsList);
     }

     Collection<Interceptor> faultInterceptors = 
(Collection<Interceptor>)message.get(Message.FAULT_OUT_INTERCEPTORS);
     if (null!=faultInterceptors) {
         faultInterceptors.add(interceptor);
     } else {
         message.put(Message.FAULT_OUT_INTERCEPTORS, interceptorAsList);
     }
     }

Hope this clarifies how I use it.

Thanks
Mandy

On 7 Jun 2016, at 10:12, Sergey Beryozkin <[email protected]> wrote:

Hi Mandy

Dan may provide more details later on, few comments below in meantime:
On 06/06/16 23:08, Mandy Warren wrote:
Hi,

We currently register a number of interceptors against the endpoint when our 
Rest service starts up. I have a specific scenario whereby when I call a 
backend system I need to create a new “session” and ensure this session is 
deleted when the response is returned to the client. The session is only 
created on some GETs (the first GET goes to the backend and subsequent ones go 
to a cache) so I want to dynamically register an interceptor for a specific 
request/response combination.

I came across https://issues.apache.org/jira/browse/CXF-2015 
<https://issues.apache.org/jira/browse/CXF-2015> which helped me build the 
following code to achieve what I wanted:-

     Interceptor interceptor = new GenericOutboundInterceptor();

     Collection<Interceptor> interceptorAsList = new ArrayList<>(1);
     interceptorAsList.add(interceptor);

     // register the specified CallbackAction only on the out & fault 
interceptors for this request/response
     // to ensure no impact on other messages
     Message message = PhaseInterceptorChain.getCurrentMessage();

     Collection<Interceptor> outInterceptors = 
(Collection<Interceptor>)message.get(Message.OUT_INTERCEPTORS);
     if (null!=outInterceptors) {
         outInterceptors.add(interceptor);
     } else {
         message.put(Message.OUT_INTERCEPTORS, interceptorAsList);
     }

     Collection<Interceptor> faultInterceptors = 
(Collection<Interceptor>)message.get(Message.FAULT_OUT_INTERCEPTORS);
     if (null!=faultInterceptors) {
         faultInterceptors.add(interceptor);
     } else {
         message.put(Message.FAULT_OUT_INTERCEPTORS, interceptorAsList);
     }
}

It all works but I just had a few questions:

1. Am I using the correct way to access the message i.e. via 
PhaseInterceptorChain.getCurrentMessage()?
Where do you access it from, from inside a service method which creates a 
client proxy in scope of the current invocation ?

PhaseInterceptorChain.getCurrentMessage() is the right way to access the 
current message outside of the CXF interceptor code, but it will return a 
non-null message only (AFAIK) when the code is running in scope of the current 
request. Furthermore, this message would be the current inbound message which 
will not be used by the client proxy doing the follow-up outbound call.
Perhaps I'm missing something, may be you can prototype some pseudo code which 
will make it clearer how the end to end flow should work ?

2. I added the null checks in as the message seemed to have no existing 
interceptors which surprised me as I had assumed it would have referenced the 
ones registered on the endpoint but I guess they are different?

I believe this property represents only the dynamically registered interceptors
3. Do I need to register the new interceptor on the fault chain too?

Not sure, probably not
4. Is there any need to manually remove the interceptor?

I don't think so, it will be GC-ed once the exchange completes

Thanks, Sergey
Many thanks

Mandy







Reply via email to