1

I have a Camel route that sends a message through Soap-endpoint.

I wanted to log in and out messages + some custom data in SOAP. So I added interceptors for CxfEnpoint bean.

@Bean
public CxfEndpoint myEndpoint(){
    CxfEndpoint cxfEndpoint = new CxfEndpoint();
    cxfEndpoint.setAddress("myuri");
    cxfEndpoint.setServiceClass(SomeType.class);
    cxfEndpoint.setDataFormat(DataFormat.POJO);
    cxfEndpoint.setLoggingFeatureEnabled(true);

    //LoggingINInterceptor
    cxfEndpoint.getInInterceptors().add(new Interceptor<Message>() {
        @Override
        public void handleMessage(Message message) throws Fault {
            LOGGER.info("Request body: ${body}"); ;
        }

        @Override
        public void handleFault(Message message) {
            LOGGER.info("Request fault body: ${body}"); ;
        }
    });

    //LoggingOutInterceptor
    cxfEndpoint.getOutInterceptors().add(new Interceptor<Message>() {
        @Override
        public void handleMessage(Message message) throws Fault {
             LOGGER.info("Response body: ${body}");
        }

        @Override
        public void handleFault(Message message) {
            LOGGER.info("Response fault body: ${body}"); ;
        }
    });
    return cxfEndpoint;
}

Route is as follows:

from("direct:myroute").routeId("cxf_myroute")
        .streamCaching()
        .setHeader(CxfConstants.OPERATION_NAME, constant("MyOperationName"))
        .log(LoggingLevel.INFO, "Call to cxf")
        .to("cxf:bean:myEndpoint").id("call_ws")
        .log(LoggingLevel.INFO, "Response from cxf")
        .process(responseProcessor).id("response_transform").end();

I get exception:

{"timestamp":"2018-07-12T11:53:39.423+00:00","level":"ERROR","logger_name":"org.apache.camel.processor.DefaultErrorHandler","stack_trace":"java.lang.ClassCastException: myapp.RouteConfiguration$2 cannot be cast to org.apache.cxf.phase.PhaseInterceptor\r\n\tat org.apache.cxf.phase.PhaseInterceptorChain.add(PhaseInterceptorChain.java:232)\r\n\tat org.apache.cxf.phase.PhaseInterceptorChain.add(PhaseInterceptorChain.java:223)\r\n\tat org.apache.cxf.phase.PhaseInterceptorChain.add(PhaseInterceptorChain.java:214)\r\n\tat org.apache.cxf.phase.PhaseChainCache.getChain(PhaseChainCache.java:89)\r\n\tat org.apache.cxf.phase.PhaseChainCache.get(PhaseChainCache.java:71)\r\n\tat org.apache.cxf.endpoint.ClientImpl.setupInterceptorChain(ClientImpl.java:966)\r\n\tat org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:486)\r\n\tat org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:420)\r\n\tat org.apache.camel.component.cxf.CxfProducer.process(CxfProducer.java:133)\r\n\tat org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)\r\n\tat org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)\r\n\tat org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)\r\n\tat org.apache.camel.processor.Pipeline.process(Pipeline.java:138)\r\n\tat org.apache.camel.processor.Pipeline.process(Pipeline.java:101)\r\n\tat org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)\r\n\tat org.apache.camel.component.direct.DirectBlockingProducer.process(DirectBlockingProducer.java:53)\r\n\tat org.apache.camel.processor.SendProcessor.process(SendProcessor.java:148)\r\n\tat org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:548)\r\n\tat org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)\r\n\tat org.apache.camel.processor.Pipeline.process(Pipeline.java:138)\r\n\tat org.apache.camel.processor.Pipeline.process(Pipeline.java:101)\r\n\tat org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:201)\r\n\tat org.apache.camel.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:97)\r\n\tat org.apache.camel.http.common.CamelServlet.doService(CamelServlet.java:194)\r\n\tat org.apache.camel.http.common.CamelServlet.service(CamelServlet.java:73)\r\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:790)\r\n\tat io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)\r\n\tat 

I also looked at using LoggingInInterceptor / LoggingOutInterceptor (How to log Apache CXF Soap Request and Soap Response using Log4j) , but couldn't find a way for adding custom logic or even custom text.

Any help appreciated.

P.S. I know I can put logs in my route directly, but they will contain a not marshalled body yet and no-Soap headers, so it's not an option.

Ermintar
  • 1,322
  • 3
  • 22
  • 39

1 Answers1

1

For removing exception do like this :

//LoggingINInterceptor
    cxfEndpoint.getInInterceptors().add(new LoggingInInterceptor() {
        @Override
        public void handleMessage(Message message) throws Fault {
            LOGGER.info("Request body: ${body}");
        }

        @Override
        public void handleFault(Message message) {
            LOGGER.info("Request fault body: ${body}");
        }
    });

    //LoggingOutInterceptor
    cxfEndpoint.getOutInterceptors().add(new LoggingOutInterceptor() {
        @Override
        public void handleMessage(Message message) throws Fault {
            LOGGER.info("Response body: ${body}");
        }

        @Override
        public void handleFault(Message message) {
            LOGGER.info("Response fault body: ${body}");
        }
    });

For custom logging just disable logging feature and do what you want with message in overrided methods. How cxf do this you can see in logging method LoggingInInterceptor\LoggingOutInterceptor class.

c0ld
  • 770
  • 4
  • 15
  • Looks like inside custom handlers $ is not valid. I recieve message: "message":"Response body: ${body}". Is there a way to get nPayload from Message object? – Ermintar Jul 12 '18 at 15:49
  • CXF will show you payload by default when you enable logging feature. To receive payload just read it from inputstream using message.getContent(InputStream.class) method. – c0ld Jul 13 '18 at 08:51
  • getContent(InputStream.class) returns stream, but in order to log it one should make a copy of the stream and use message.setContent(copiedStream). Otherwise, later phases will not be able to read stream, that was already used. – Ermintar Jul 24 '18 at 13:57
  • See logInputStream method in org.apache.cxf.interceptor.LoggingInInterceptor as default logging implemenation. – Ermintar Jul 24 '18 at 13:59
  • I know , thats why i wrote in my post "How cxf do this you can see in logging method LoggingInInterceptor\LoggingOutInterceptor class" =) – c0ld Jul 24 '18 at 14:08