Apache Camel : How to call java webservice

· ☕ 6 min read · ✍️ Dinesh

I have made up my mind to get rid of WSO2 ESB at my office. It is clumsy, buggy, hard to test, no body wants to work on it and the documentation is horrible. I looked at various alternative and Apache Camel was free and easy to set up and work with me.

To cut the story short, I was able to run most of the example but was struggling with CXF to call a third party service hosted at a random url. The documentation on the website is focused on exposing web service built in Camel. I was finally able to figure this out with a couple of slide show on slideshare.

Here’s the scenario: I have a third party webservice hosted on the web which gives you the the conversion rate between two currencies. I am going to call this web service and log the response.

As usual I will start from scratch. My webservice is hosted at this url -http://www.webservicex.net/CurrencyConvertor.asmx?WSDL. This webservice exposes a operation called - “ConversionRate”.

I am using Fuse Ide(free - Developer version) but you can use Intellij Or Eclipse.

Prerequisites - Must have Maven.

Step 1: Create a new Camel-Spring project.

Step 2: Add the following dependencies in your pom.xml. “camel-cxf”

1
2
3
4
5
6
7
8
9
<scope><dependency>

      <groupId>org.apache.camel</groupId>

      <artifactId>camel-cxf</artifactId>

      <version>2.10.0.redhat-60024</version>

    </dependency></scope>

My pom.xml looks like this -

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266

<!-?xml version="1.0" encoding="UTF-8"?>

 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  

   <modelVersion>4.0.0</modelVersion>

  

   <groupId>com.mycompany</groupId>

   <artifactId>camel-spring</artifactId>

   <packaging>jar</packaging>

   <version>1.0.0-SNAPSHOT</version>

   <name>A Camel Spring Route</name>

   <url>http://www.myorganization.org</url>

   <properties>

     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

   </properties>

   <repositories>

     <repository>

      <id>release.fusesource.org</id>

       FuseSource Release Repository

       <url>http://repo.fusesource.com/nexus/content/repositories/releases</url>

       <snapshots>

         <enabled>false</enabled>

       </snapshots>

       <releases>

         <enabled>true</enabled>

       </releases>

     </repository>

     <repository>

       <id>snapshot.fusesource.org</id>

       FuseSource Snapshot Repository

       <url>http://repo.fusesource.com/nexus/content/repositories/snapshots</url>

       <snapshots>

         <enabled>true</enabled>

       </snapshots>

       <releases>

         <enabled>false</enabled>

       </releases>

     </repository>

   </repositories>

   <pluginRepositories>

     <pluginRepository>

       <id>release.fusesource.org</id>

       FuseSource Release Repository

       <url>http://repo.fusesource.com/nexus/content/repositories/releases</url>

       <snapshots>

         <enabled>false</enabled>

       </snapshots>

       <releases>

         <enabled>true</enabled>

       </releases>

     </pluginRepository>

     <pluginRepository>

       <id>snapshot.fusesource.org</id>

       FuseSource Snapshot Repository

       <url>http://repo.fusesource.com/nexus/content/repositories/snapshots</url>

       <snapshots>

         <enabled>true</enabled>

       </snapshots>

       <releases>

         <enabled>false</enabled>

       </releases>

     </pluginRepository>  

   </pluginRepositories>

  

   <dependencies>

     <dependency>

       <groupId>org.apache.camel</groupId>

       <artifactId>camel-core</artifactId>

       <version>2.10.0.redhat-60024</version>

     </dependency>

     <dependency>

       <groupId>org.apache.camel</groupId>

       <artifactId>camel-spring</artifactId>

       <version>2.10.0.redhat-60024</version>

     </dependency>

     <!- logging ->

     <dependency>

       <groupId>org.slf4j</groupId>

       <artifactId>slf4j-api</artifactId>

       <version>1.6.6</version>

     </dependency>

     <dependency>

       <groupId>org.slf4j</groupId>

       <artifactId>slf4j-log4j12</artifactId>

       <version>1.6.6</version>

     </dependency>

     <dependency>

       <groupId>log4j</groupId>

       <artifactId>log4j</artifactId>

       <version>1.2.17</version>

     </dependency>

     <!- testing ->

     <dependency>

       <groupId>org.apache.camel</groupId>

       <artifactId>camel-test-spring</artifactId>

       <version>2.10.0.redhat-60024</version>

       <scope>test</scope>

     </dependency>

 <dependency>

       <groupId>org.apache.camel</groupId>

       <artifactId>camel-cxf</artifactId>

       <version>2.10.0.redhat-60024</version>

     </dependency>

   </dependencies>

   <build>

     <defaultGoal>install</defaultGoal>

     <plugins>

       <plugin>

         <groupId>org.apache.maven.plugins</groupId>

         <artifactId>maven-compiler-plugin</artifactId>

         <version>2.5.1</version>

         <configuration>

           <source>1.6</source>

           <target>1.6</target>

         </configuration>

       </plugin>

       <plugin>

         <groupId>org.apache.maven.plugins</groupId>

         <artifactId>maven-resources-plugin</artifactId>

         <version>2.4.3</version>

         <configuration>

           <encoding>UTF-8</encoding>

         </configuration>

       </plugin>

       <!- allows the route to be ran via mvn camel:run ->

       <plugin>

         <groupId>org.apache.camel</groupId>

         <artifactId>camel-maven-plugin</artifactId>

         <version>2.10.0.redhat-60024</version>

       </plugin>

     </plugins>

   </build>

 </project>

Step 2: Under src/main.resources/META-INF folder(if not there then create one) create file called camel-context.xml Your camel file should like this -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 <?xml version="1.0" encoding="UTF-8"?>

 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.xsd

         http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd

         http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">

 <cxf:<span class="hiddenSpellError">cxfEndpoint id="wsdlEndpoint"

                      address="http://www.webservicex.net/CurrencyConvertor.asmx"

                      endpointName="c:SOAPOverHTTP"

                      serviceName="c:CurrencyConvertor"

                      xmlns:s="http://www.webserviceX.NET"/>

   

   <camelContext xmlns="http://camel.apache.org/schema/spring">

   <route>

         here is a sample which processes the input files

          (leaving them in place - see the &#8216;noop' flag)

          then performs content based routing on the message using XPath</description>

         src/data/order?noop=true"/>

         <log message="${body}"/>

         wsdl&serviceName={http://www.webserviceX.NET/}CurrencyConvertor&portName={http://www.webserviceX.NET/}CurrencyConvertorSoap&dataFormat=MESSAGE"/>

          <log message="${body}"/>

     </route>

 </camelContext>

  

 </beans>

Step 4: Place the payload or input data xml in src/data/input/order.xml. The order.xml should like this -

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET/">

    <soapenv:Header/>

    <soapenv:Body>

       <web:ConversionRate>

          <web:FromCurrency>AUD</web:FromCurrency>

          <web:ToCurrency>USD</web:ToCurrency>

       </web:ConversionRate>

    <!-<span class="hiddenSpellError">soapenv:Body>->

</soapenv:Envelope>

That’s it!!!!
The interesting part is all in the camel-context.xml. Here’s what is happening in this file

src/data/order?noop=true”/>

This line reads the file order.xml. The option noop=true makes the file to be read again and again. By default this values is false. If this value is false, then after one read, camel marks it as read and when you run the example for second time, it will not read this file.

This line will simply log the contents of order.xml.

serviceName={http://www.webserviceX.NET/}CurrencyConvertor&portName={http://www.webserviceX.NET/}CurrencyConvertorSoap&dataFormat=MESSAGE”/>

This line tells cxf component that it needs to call the webservice -  

http://www.webservicex.net/CurrencyConvertor.asmx?wsdl

-URL - is the url of the wsdl 

http://www.webservicex.net/CurrencyConvertor.asmx?wsdl

serviceName - is the name of the service. Remember it is the name of teh service not the oepration!! The value between {} is the namespace. If you do not want to write {http://….} then add another tag_xmlns >  {http://www.webserviceX.NET/}CurrencyConvertor. 
portName - is the name of the port.

portName={http://www.webserviceX.NET/}CurrencyConvertorSoap. This is again preceded by {http://…} which is the namespace value. This value is defined in the wsdl as -wsdl:port name="CurrencyConvertorSoap" binding="tns:CurrencyConvertorSoap"

The last piece is dataFormatdataFormat=MESSAGE This tells that the body is of type message.

Part 2 - In production you would want to avoid writing cxf in the above format as it is prone to error because the string value is very long and difficult to test independently and cannot be reused if you want to call the service in another route. So the best way is to define this as cxf endpoint. All you need to do is slightly modify the camel-context.xml

  1. Add this(be sure to remove the earlier version of <to uri="cxf….")
  1. Define the cxf endpoint called wsdlEndpoint (You call it whatever you want).
1
2
3
4
5
6
7
8
9
 <cxf:<span class="hiddenSpellError">cxfEndpoint id="wsdlEndpoint"

                     address="http://www.webservicex.net/CurrencyConvertor.asmx"

                     endpointName="c:SOAPOverHTTP"

                     serviceName="c:CurrencyConvertor"

                     xmlns:s="http://www.webserviceX.NET"/>

That’s it.

Now just run the app. This will print the following-

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 [ead #0 - file://src/data/order] route1                         INFO

<soapenv:Header/>

<soapenv:Body>

<web:ConversionRate>

<web:FromCurrency>AUD</web:FromCurrency>

<web:ToCurrency>USD</web:ToCurrency>

</web:ConversionRate>

</soapenv:Body>->

</soapenv:Envelope>->


~ Enjoy Cameling ….

Share this post
Support the author with

Dinesh Arora
WRITTEN BY
Dinesh
Developer