CXF Proxy Example
Available as of Camel 2.5
This example is located in the examples/camel-example-cxf-proxy directory of the Camel distribution.
There is a README.txt file with instructions how to run it.
If you use maven then you can easily run it from the command line using:
About
This example demonstrates how you can use CXF to proxy a real web service. For example in this case we want Camel to validate and enrich the input message before its send to the real web service. We do this to ensure the data is correct and that missing information is added automatic by Camel. In real life you may want to do this in case a client send bad/faulty data to a web service, and its costly/not possible to update and fix that client. Instead lets fix it by a proxy with Camel.
![]() | Pure HTTP proxy If you want a pure http based proxy then you can use Jetty or SERVLET as front end in Camel. Then delegate those incoming HTTP requests to the real web service. You may want to do this if you want a simple straight thru proxy where the message should not be altered by Camel.
By using the CXF component you get access to all the web service features Apache CXF provides, where as with Jetty its just pure HTTP proxy. |
Implementation
Since this is a example it provides both the Camel application and the real web service in the same JVM. In your use-case the real webs ervice will be hosted on another server etc.
Spring XML
In the Spring XML file we have define the CXF proxy endpoint using the <cxf:cxfEndpoint> tag.
And the real web service is the Spring bean with the id realWebService.
As you can see in the Camel route we use a CXF consumer to proxy the web service. Then we route the message to the enrich bean which validates and add the missing information. Then we just use the HTTP component to send the web service request to the real web service.
The reply from the real web service is then logged and use as reply for the proxied web service as well.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
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/spring http://camel.apache.org/schema/spring/camel-spring.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"/>
<!-- in a real use-case the real web service would be located on another server
but we simulate this in the same JVM -->
<bean id="realWebService" class="org.apache.camel.example.cxf.proxy.RealWebServiceBean"
init-method="start" destroy-method="stop">
<property name="url" value="http://localhost:9081/real-webservice"/>
</bean>
<bean id="enrichBean" class="org.apache.camel.example.cxf.proxy.EnrichBean"/>
<cxf:cxfEndpoint id="reportIncident"
address="http://localhost:9080/camel-example-cxf-proxy/webservices/incident"
endpointName="s:ReportIncidentEndpoint"
serviceName="s:ReportIncidentEndpointService"
wsdlURL="etc/report_incident.wsdl"
xmlns:s="http://reportincident.example.camel.apache.org"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:reportIncident?dataFormat=MESSAGE"/>
<to uri="log:input"/>
<to uri="bean:enrichBean"/>
<to uri="http://localhost:9081/real-webservice?throwExceptionOnFailure=false"/>
<to uri="log:output"/>
</route>
</camelContext>
</beans>
Enrich bean
The enrich bean is Java code which in our simple example will just set the incidentId parameter to the fixed value of 456. In your implementation you can of course do a lot more.
public class EnrichBean {
public Document enrich(Document doc) {
Node node = doc.getElementsByTagName("incidentId").item(0);
String incident = node.getTextContent();
node.setTextContent("456");
System.out.println("Incident was " + incident + ", changed to 456");
return doc;
}
}
Running the example
You start the example from the command line using the maven goal mvn jetty:run. There is also a build.xml file for ANT users.
You can also start the Camel application from your IDE, by running the org.apache.camel.example.cxf.proxy.MyMain main class.
You can then use SoapUI or another web service client and send a request to the http://localhost:9080/camel-example-cxf-proxy/webservices/incident url. The wsdl is located at: http://localhost:9080/camel-example-cxf-proxy/webservices/incident?wsdl.
The console should then output progress.
Sample output
Here is some sample output from the console:
2010-09-26 12:20:46,974 [main ] INFO DefaultCamelContext - Apache Camel 2.5-SNAPSHOT (CamelContext: camel-1) started in 0.858 seconds
2010-09-26 12:20:55,685 [tp-1790017034-1] INFO input - Exchange[ExchangePattern:InOut, BodyType:null, Body:<soapenv:Envelope xmlns:soapenv="http: xmlns:rep="http://reportincident.example.camel.apache.org">
<soapenv:Header/>
<soapenv:Body>
<rep:inputReportIncident>
<incidentId></incidentId>
<incidentDate>2010-09-26</incidentDate>
<givenName>Ibsen</givenName>
<familyName>Claus</familyName>
<summary>Bla bla</summary>
<details>More bla</details>
<email>davscl...@apache.org</email>
<phone>12345678</phone>
</rep:inputReportIncident>
</soapenv:Body>
</soapenv:Envelope>]
Incident was , changed to 456
Invoked real web service: id=456 by Ibsen Claus
2010-09-26 12:20:55,997 [tp-1790017034-1] INFO output - Exchange[ExchangePattern:InOut, BodyType:org.apache.camel.converter.stream.CachedOutputStream.WrappedInputStream, Body:
<soap:Envelope xmlns:soap="http:>
<soap:Body>
<ns2:outputReportIncident xmlns:ns2="http:>
<code>OK;456</code>
</ns2:outputReportIncident>
</soap:Body>
</soap:Envelope>]
See Also