xlogger
xlogger

Reputation: 119

Apache Camel CXF endpoint null reply

I followed chapter 7 of Camel in Action book and implemented a CXF route.

<cxf:cxfEndpoint 
    id="orderEndpoint" 
    address="http://localhost:9000/order/"
    serviceClass="test.order.OrderEndpoint" 
    wsdlURL="wsdl/order.wsdl" />


<camelContext xmlns="http://camel.apache.org/schema/spring">
    <route>
        <!-- Expose route as web service endpoint -->
        <from uri="cxf:bean:orderEndpoint" />
        <to uri="log:orderEndpoint_MsgIn" />
        <to uri="seda:incomingOrders" />
        <transform>
            <constant>OK</constant>
        </transform>
        <to uri="log:orderEndpoint_MsgOut" />
    </route>

    <!-- test route -->
    <route>
        <from uri="seda:incomingOrders" />
        <to uri="mock:end" />
    </route>
</camelContext>

Then I implemented a java console class to test the route

public static void main(String[] args) throws Exception{
    Main main = new Main(); 
    AbstractApplicationContext context = new ClassPathXmlApplicationContext(
            "META-INF/spring/cxfWsComponentTestContext.xml"
            );

    main.setApplicationContext(context);

    main.start();
    ProducerTemplate producer = main.getCamelTemplate();

    List<Object> params = new ArrayList<Object>();
    params.add("motor");
    params.add(1);
    params.add("honda");

    String reply = producer.requestBody("cxf:bean:orderEndpoint", params, String.class);
    LOG.info("Received reply from orderEndpoint = " + reply);

    Thread.sleep(10000);

    main.stop();

} 

Expect that the console log should display

"Received reply from orderEndpoint = OK"

However, I got

"Received reply from orderEndpoint = null" 

In the console log I can see that the entry

"orderEndpoint_MsgOut           INFO  Exchange[ExchangePattern: InOut, BodyType: String, Body: OK]"

which means that the Web service should have generated reply message "OK", but I'm not sure why this reply message was not carry over as a return value of the requestBody() method call...

I downloaded Camel in Action chapter 7's sample code and run the Junit test case, it was able to return the result as expected... I tried to compare the route definitions and source code with mine but not able to spot any difference so far...

Would like to see if anyone can give some clues on this.

--- Edit 1 ---

I have updated the route definition and remain only the route as below

    <route>
        <from uri="cxf:bean:orderEndpoint" />
        <transform>
            <constant>OK</constant>
        </transform>
        <to uri="seda:incomingOrders" />
    </route>

And updated the main method

    producer.requestBody("cxf:bean:orderEndpoint", params, String.class);
    ConsumerTemplate consumer = producer.getCamelContext().createConsumerTemplate();
    Exchange reply = consumer.receive("seda:incomingOrders");
    LOG.info("Received reply from seda:incomingOrders = " + reply);

However, it failed with timeout exception

org.apache.camel.ExchangeTimedOutException: The OUT message was not received within: 30000 millis. Exchange[Message: OK]
at org.apache.camel.component.seda.SedaProducer.process(SedaProducer.java:144)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:129)
at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:118)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:80)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.cxf.CxfConsumer$1.asyncInvoke(CxfConsumer.java:95)
at org.apache.camel.component.cxf.CxfConsumer$1.invoke(CxfConsumer.java:75)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$2.run(ServiceInvokerInterceptor.java:126)
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:131)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:251)
at org.apache.cxf.transport.http_jetty.JettyHTTPDestination.doService(JettyHTTPDestination.java:234)
at org.apache.cxf.transport.http_jetty.JettyHTTPHandler.handle(JettyHTTPHandler.java:70)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1129)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1065)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:497)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)

Upvotes: 3

Views: 1668

Answers (1)

Djee
Djee

Reputation: 50

You are requesting the body of the CXF endpoint. If you look at your route, you can see that you set the content of the body in the transform tag, which comes after in the route definition. Therefore, it is logical that you don't get OK as a result of requestBody(). The same applies to your seda endpoint. I'd bet that the Logged body for orderEndpoint_MsgIn is different from OK.

Concerning your log at orderEndpoint_MsgOut being correct, it is because you log the body after the transform step.

In order to receive OK, you can use this route :

<route>
    <from uri="cxf:bean:orderEndpoint" />
    <transform>
        <constant>OK</constant>
    </transform>
    <wireTap uri="seda:incomingOrders" />
</route>

And use ConsumerTemplate with the seda endpoint :

ConsumerTemplate consumer = producer.getCamelContext().createConsumerTemplate();
String reply = consumer.receive("seda:incomingOrders");
LOG.info("Received reply from seda = " + reply);

You should use this code between the requestBody() and the main.stop().

For an explanation on the use of wireTap rather than to, see this post

Upvotes: 2

Related Questions