Pavel
Pavel

Reputation: 76

Call web service from Camel

I would like to call web service from Camel. But I receive null everytime I call the service. Could you please help me finding a solution?

The service is running on tomcat and I can test it with soapUI. Here is the request from SoapUI.

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"     xmlns:hel="http://helloworld.localhost">
    <soapenv:Header/>
       <soapenv:Body>
          <hel:HelloWorldRequest>
               <hel:input>Pavel</hel:input>
          </hel:HelloWorldRequest>
       </soapenv:Body>
    </soapenv:Envelope>

and the response returns Hello Pavel. I followed the CamelInAction guide with creating contract first web service. I am able to run the route which reads a file and send it to web service.

The code of the route is the following.

public class FileToWsRoute extends RouteBuilder {
public void configure() { 
    from("file://src/data?noop=false")
    .process(new FileProcessor())
    .to("cxf:bean:helloWorld");
    }

}

The FileProcessor class looks like this:

public class FileProcessor implements Processor {

public void process(Exchange exchange) throws Exception {

    System.out.println("We just downloaded: " 
            + exchange.getIn().getHeader("CamelFileName"));
    String text = 
    "<?xml version='1.0' ?>" 
    +"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:hel=\"http://helloworld.localhost\">"
    +"<soapenv:Header/>"
    +   "<soapenv:Body>"
    +     " <hel:HelloWorldRequest>"
    +        " <hel:input>WhatsUP</hel:input>"
    +     " </hel:HelloWorldRequest>"
    +   "</soapenv:Body>"
    +"</soapenv:Envelope>";

    exchange.getIn().setBody(text);
}
}

In next version I would like to generate a request through the objects generated by cxf-codegen-plugin (HalloWorld.java, HelloWorldImpl.java, HelloWorldRequest.java, HelloWorldResponse.java, HelloWorldService.java, ObjectFactory.java, package-info.java).

In the camel-cxf.xml I have:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:cxf="http://camel.apache.org/schema/cxf"
   xsi:schemaLocation="
     http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://camel.apache.org/schema/cxf 
     http://camel.apache.org/schema/cxf/camel-cxf.xsd">

  <import resource="classpath:META-INF/cxf/cxf.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
  <import resource="classpath:META-INF/cxf/cxf-extension-http-jetty.xml"/>

  <cxf:cxfEndpoint id="helloWorld"
               address="http://localhost:8080/ode/processes/HelloWorld"
               serviceClass="localhost.helloworld.HelloWorld"
               wsdlURL="wsdl/HelloWorld.wsdl"/>
</beans>

To read response from the web service I am using this route.

public class WsToQueueRoute extends RouteBuilder {
    public void configure() { 
    from("cxf:bean:helloWorld")
    .to("seda:incomingOrders")
    .transform().constant("OK");
    }

}

The last route gets data from seda...

public class QueueToProcessRoute extends RouteBuilder {
public void configure() { 
    from("seda:incomingOrders")
    .process(new PrintResult());
    }

}

...and prints the result.

public class PrintResult implements Processor {

public void process(Exchange exchange) throws Exception {

    System.out.println("Data received: " 
            + exchange.getIn().getBody(String.class));
}

}

The output from the execution is: Data received: null

I would expect some XML file which I could parse with cxf objects. Could you please help me finding the problem?

Thank you

Pavel

Upvotes: 1

Views: 7935

Answers (2)

Pavel
Pavel

Reputation: 76

The problems with this example were in classes FileProcessor and PrintResult. I have also simplified the example, so I'am using only one route FileToWsRoute for now.

public class FileToWsRoute extends RouteBuilder {
public void configure() { 
    from("file://src/data?noop=true")
    .process(new FileProcessor())
    .to("cxf:bean:helloWorld")
    .process(new PrintResult());
    }
}

The FileProcessor has changed to this.

public class FileProcessor implements Processor {

public void process(Exchange exchange) throws Exception {
        HelloWorldRequest hs = new HelloWorldRequest();
        hs.setInput("Pavel");
        exchange.getOut().setBody(hs);
    }
}  

The PrintProcessor has changed to this.

public class PrintResult implements Processor {
public void process(Exchange exchange) throws Exception {
    MessageContentsList msgList = (MessageContentsList) exchange.getIn().getBody();
    HelloWorldResponse resp = (HelloWorldResponse) msgList.get(0);
    String result = resp.getResult();       
       System.out.println("Data received: " + result);
    }

}

I think this is a good example for others who struggles with camel and web servcices.

Upvotes: 3

Paulius Matulionis
Paulius Matulionis

Reputation: 23415

The problem might be with the data format sent to your process method. What I would try is adding camel cxf properties to the endpoint like this:

<cxf:properties>
    <entry key="dataFormat" value="POJO"/> 
</cxf:properties>

By changing dataformat to POJO you should receive your message. So your camel cxf endpoint should look like this:

  <cxf:cxfEndpoint id="helloWorld"
               address="http://localhost:8080/ode/processes/HelloWorld"
               serviceClass="localhost.helloworld.HelloWorld"
               wsdlURL="wsdl/HelloWorld.wsdl">
    <cxf:properties>
        <entry key="dataFormat" value="POJO"/> 
    </cxf:properties>
  </cxf:cxfEndpoint>

I had the similar problem once, and this solved my problem, but I was using camel all in Spring not java classes.

If this does not work try adding parameter: ?dataFormat=POJO to your route like this:

from("cxf:bean:helloWorld?dataFormat=POJO")

Upvotes: 0

Related Questions