CXF Proxy ExampleThis example is located in the examples/camel-example-cxf-proxy directory of the Camel distribution. If you use Maven then you can easily run it from the command line using: mvn camel:run AboutThis example demonstrates how CXF can be used to proxy a real web service. For this example we want Camel to validate and enrich the input message before it's sent to the actual web service. We do this to ensure the data is correct and to have Camel automatically add in any missing information. In real life you may wish to use a proxy in cases where clients are sending bad/faulty data to a web service, and it's costly/not possible to update and fix those clients.
ImplementationFor this simple example both the Camel application and the real web service are in the same JVM. In production work the real web service may often be hosted on another server, etc. Spring XMLIn the Spring XML file we have defined the CXF proxy endpoint using the <cxf:cxfEndpoint> tag. 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 EnrichBean which validates and adds the missing information. Then we just use the HTTP component to send the web service request to the real web service. <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" 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://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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"> <!-- spring property placeholder, ignore resource not found as the file resource is for unit testing --> <context:property-placeholder location="classpath:incident.properties,file:target/custom.properties" ignore-resource-not-found="true"/> <!-- Use a bean to start and stop the real web service (is not Camel specific) --> <!-- In a real use-case the real web service would be probably 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"> <!-- url of the real web service we have proxied --> <property name="url" value="http://localhost:${real.port}/real-webservice"/> </bean> <!-- bean that enriches the SOAP request --> <bean id="enrichBean" class="org.apache.camel.example.cxf.proxy.EnrichBean"/> <!-- this is the CXF web service we use as the front end --> <cxf:cxfEndpoint id="reportIncident" address="http://localhost:${proxy.port}/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"/> <!-- this is the Camel route which proxies the real web service and forwards SOAP requests to it --> <camelContext xmlns="http://camel.apache.org/schema/spring"> <!-- property which contains port number --> <propertyPlaceholder id="properties" location="classpath:incident.properties,file:target/custom.properties"/> <endpoint id="callRealWebService" uri="http://localhost:${real.port}/real-webservice?throwExceptionOnFailure=false"/> <route> <!-- CXF consumer using MESSAGE format --> <from uri="cxf:bean:reportIncident?dataFormat=MESSAGE"/> <!-- log input received --> <to uri="log:input"/> <!-- enrich the input by ensure the incidentId parameter is set --> <to uri="bean:enrichBean"/> <!-- send proxied request to real web service --> <to ref="callRealWebService"/> <!-- log answer from real web service --> <to uri="log:output"/> </route> </camelContext> </beans> Enrich beanThe 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(); // here we enrich the document by changing the incident id to another value // you can of course do a lot more in your use-case node.setTextContent("456"); System.out.println("Incident was " + incident + ", changed to 456"); return doc; } } Running the exampleYou start the example from the command line using the Maven goal mvn camel:run. 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. After making a SOAP request, check the console to see the SOAP request and response: Sample outputHere is a 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://schemas.xmlsoap.org/soap/envelope/" xmlns:rep="http://reportincident.example.camel.apache.org"> <soapenv:Header/> <soapenv:Body> <rep:inputReportIncident> <incidentId>63</incidentId> <incidentDate>2010-09-26</incidentDate> <givenName>Claus</givenName> <familyName>Ibsen</familyName> <summary>Bla bla</summary> <details>More bla</details> <email>davsclaus@apache.org</email> <phone>12345678</phone> </rep:inputReportIncident> </soapenv:Body> </soapenv:Envelope>] Incident was 63, changed to 456 Invoked real web service: id=456 by Claus Ibsen 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://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:outputReportIncident xmlns:ns2="http://reportincident.example.camel.apache.org"> <code>OK;456</code> </ns2:outputReportIncident> </soap:Body> </soap:Envelope>] See Also |