By kswaughs | Tuesday, March 8, 2016

Camel soap web service client

To consume a soap web service, first generate the stubs and data types from existing wsdl document using wsdl2java command. I have a HelloWorld service running on my machine and after running wsdl2java command, below web service client components are generated in the following packages.

com/kswaughs/poc/acct/
    HelloWorldImplService.class [ Web service client class]
    HelloWorld.class [ web service interface ]
    AcctRequest.class [ request data type ]
    AcctResponse.class [ response data type ]
 
wsdl/
    HelloWorld.wsdl [ wsdl document ]

In this below example, I will explain how to configure camel cxf endpoint using above classes and make a web service call using java DSL routing for building a web service request AcctRequest.java, parsing the web service response AcctResponse.java.

Step 1 : Write a service client class to build the web service request and parse web service response.

SoapSvcClient.java
package com.kswaughs.outbound;

import com.kswaughs.poc.acct.AcctRequest;
import com.kswaughs.poc.acct.AcctResponse;
import com.kswaughs.beans.UserResp;

public class SoapSvcClient {
 
    // Build web service request
    public AcctRequest buildSoapReq(String reqId) {
  
        AcctRequest acctReq = new AcctRequest();
  
        acctReq.setCustNumber(reqId);
  
        System.out.println("Soap Request built successfully");
  
        return acctReq;
    }

    // Read web service response and build a pojo response
    public UserResp parseSoapResp(AcctResponse soapResp) {
  
        UserResp resp = new UserResp();
        resp.setId(soapResp.getCustNumber());
        resp.setName(soapResp.getCustName());
        resp.setBalance(String.valueOf(soapResp.getBalance()));
  
        System.out.println("Soap Response parsed successfully");
  
        return resp;
    }
}

Step 2 : Define all your beans and endpoint in camel context.

camel-context.xml
<?xml version="1.0" encoding="UTF-8"?>

<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"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://camel.apache.org/schema/cxf
        http://camel.apache.org/schema/cxf/camel-cxf.xsd
        http://cxf.apache.org/jaxrs
        http://cxf.apache.org/schemas/jaxrs.xsd
        http://camel.apache.org/schema/spring
        http://camel.apache.org/schema/spring/camel-spring.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">


    <bean id="myRouter" class="com.kswaughs.router.MyRouter" />
    <bean id="userSvcClient" class="com.kswaughs.outbound.SoapSvcClient" />

    <!-- Using Java DSL Router -->
    <camelContext id="firstCtx" xmlns="http://camel.apache.org/schema/spring">
    <routeBuilder ref="myRouter" />
    </camelContext>
 
    <cxf:cxfEndpoint id="accountEndpoint" address="http://localhost:3333/wspoc/user"
        wsdlURL="/wsdl/HelloWorld.wsdl"
        serviceClass="com.kswaughs.poc.acct.HelloWorld"
        endpointName="ws:HelloWorldImplPort"
        serviceName="ws:HelloWorldImplService" 
        xmlns:ws="http://acct.poc.kswaughs.com/" 
        loggingFeatureEnabled="true">
        <cxf:properties>
            <entry key="dataFormat" value="POJO"/>
        </cxf:properties>
    </cxf:cxfEndpoint>
</beans>

Step 3 : Define the Router using Java DSL

MyRouter.java
package com.kswaughs.router;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.cxf.common.message.CxfConstants;
import org.springframework.stereotype.Component;

    @Component
    public class MyRouter extends RouteBuilder {

    @Override
    public void configure() throws Exception {
  
        from("direct:getUserDetails")
            .bean("userSvcClient", "buildSoapReq")
            .setHeader(CxfConstants.OPERATION_NAME, constant("getAccountInfo"))
            .to("cxf:bean:accountEndpoint")
            .bean("userSvcClient", "parseSoapResp");
   
    }
}

Step 4 : Start the camel context and test your application.

CamelApp.java
package com.kswaughs.app;

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.kswaughs.beans.UserResp;

public class CamelApp {

    public static void main(String[] args) {

        try {
            ApplicationContext springCtx = new 
                ClassPathXmlApplicationContext("camel-context.xml");

            CamelContext context = springCtx
                .getBean("firstCtx", CamelContext.class);
   
            context.start();
    
            ProducerTemplate producerTemplate = context.createProducerTemplate();
   
            UserResp resp = producerTemplate
                .requestBody("direct:getUserDetails", "12345", UserResp.class);
   
            System.out.println("resp:"+resp);

            context.stop();
  
        } catch (Exception e) {     
            e.printStackTrace();    
        } 
        finally {  }
 
    }

}

Console Output

 
Soap Request built successfully
INFO|03/02/2016 15:26:49 990|Outbound Message
---------------------------
ID: 1
Address: http://localhost:3333/wspoc/user
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], breadcrumbId=[ID-PC223152-53569-1456912608587-0-1], SOAPAction=[""]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:getAccountInfo xmlns:ns1="http://acct.poc.kswaughs.com/"><arg0><custNumber>12345</custNumber></arg0></ns1:getAccountInfo></soap:Body></soap:Envelope>
--------------------------------------
INFO|03/02/2016 15:26:50 011|Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml;charset="utf-8"
Headers: {Content-type=[text/xml;charset="utf-8"], Transfer-encoding=[chunked]}
Payload: <?xml version="1.0" encoding="UTF-8"?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getAccountInfoResponse xmlns:ns2="http://acct.poc.kswaughs.com/"><return><balance>200</balance><custName>kswaughs</custName><custNumber>12345</custNumber></return></ns2:getAccountInfoResponse></S:Body></S:Envelope>
--------------------------------------
Soap Response parsed successfully
resp:UserResp [id=12345, name=kswaughs, balance=200]

Maven dependencies

pom.xml
<properties>
    <camelspring.version>2.16.0</camelspring.version>  
    <spring.version>4.1.6.RELEASE</spring.version>
</properties>

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-core</artifactId>
    <version>${camelspring.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-cxf</artifactId>
    <version>${camelspring.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-spring</artifactId>
    <version>${camelspring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>

Recommend this on