CXF Example
CXF example for routing messages with different transports
The Camel CXF example is a demo of the camel-cxf component to show how to route messages between CXF endpoints, with one endpoint consuming a SOAP over HTTP request while the other providing a SOAP over JMS request for the actual CXF Service endpoint. The Camel router just routs the SOAP over HTTP CXF client request to the SOAP over JMS CXF service.
To run the example see instructions in the README.txt file in the camel-example-cxf directory under examples.
We start with creating a CamelContext - which is a container for Components, Routes etc:
CamelContext context = new DefaultCamelContext();
Here is code for starting the JMS broker and the CXF server:
JmsBroker broker = new JmsBroker();
Server server = new Server();
try {
broker.start();
server.start();
Now we setup the router for the two endpoint URIs which we mentioned before, ROUTER_ENDPOINT_URI is the endpoint for consuming the request of SOAP over HTTP, SERVICE_ENDPOINT_URI is the endpoint for providing the request for the SOAP over JMS service.
context.addRoutes(new RouteBuilder() {
public void configure() {
errorHandler(noErrorHandler());
from(ROUTER_ENDPOINT_URI).to(SERVICE_ENDPOINT_URI);
}
});
context.start();
Client client = new Client(ROUTER_ADDRESS + "?wsdl");
Then we start up the camel context and create the CXF client to kick off the request.
CXF example for using Camel transport
Since Camel has lots of components and is a great mediation rule engine, we can leverage these Camel features in CXF by using the Camel transport. Here is an example to show how to use the Camel transport in CXF.
In this example, we setup a load balance Camel context in the Camel destination.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://cxf.apache.org/transports/camel"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/transports/camel http://cxf.apache.org/transports/camel.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/cxfEndpoint.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
">
<bean id = "roundRobinRef" class="org.apache.camel.processor.loadbalancer.RoundRobinLoadBalancer" />
<camelContext id="dest_context" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="jetty:http://localhost:9091/GreeterContext/GreeterPort"/>
<loadBalance ref="roundRobinRef">
<to uri="direct:EndpointA"/>
<to uri="direct:EndpointB"/>
</loadBalance>
</route>
</camelContext>
<camel:destination name="{http://apache.org/hello_world_soap_http}CamelPort.camel-destination">
<camel:camelContextRef>dest_context</camel:camelContextRef>
</camel:destination>
</beans>
When CXF loads this configuration, it will publish the CXF endpoint to the Camel endpoint that is found in the Camel context.
SpringBusFactory bf = new SpringBusFactory();
BusFactory.setDefaultBus(null);
Bus bus = bf.createBus("/org/apache/camel/example/camel/transport/CamelDestination.xml");
BusFactory.setDefaultBus(bus);
The code below shows how to publish the endpoint to different Camel context endpoints. You can specify the Camel endpoint URI as the endpoint address parameter.
GreeterImpl implementor = new GreeterImpl();
implementor.setSuffix("EndpointA");
String address = "camel:;
endpointA = Endpoint.publish(address, implementor);
implementor = new GreeterImpl();
implementor.setSuffix("EndpointB");
address = "camel:;
endpointB = Endpoint.publish(address, implementor);
CXF example for using the WebServiceProvider API
JAX-WS provides the WebServiceProvider API to meet the requirements of XML-level message handling. This example shows how to route a SOAP Message from a WebServiceProvider implementation to bean endpoint in the Camel context. Basically, we still pass the WebServiceProvider implementor as SEI, and the CxfConsumer will pass the SOAP Message in a list of parameters to the Camel router for further processing.
First, let's have a look at the Camel context's configuration. Here we start a CxfConsumer to listen to the address and pass SOAP messages to the test bean.
<!--
If you want to run this example in a Tomcat container which needs the servlet transport,
please replace the cxf-extension-http-jetty.xml with cxf-servlet.xml
-->
<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" />
<bean id = "testBean" class="org.apache.camel.example.cxf.provider.TesterBean" />
<cxf:cxfEndpoint id="soapMessageEndpoint"
serviceClass="org.apache.camel.example.cxf.provider.GreeterProvider"
address="http://localhost:9000/GreeterContext/SOAPMessageService"
wsdlURL="wsdl/hello_world.wsdl"
endpointName="s:SoapOverHttpRouter"
serviceName="s:SOAPService"
xmlns:s="http://apache.org/hello_world_soap_http"/>
<camelContext id="test_context" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxf:bean:soapMessageEndpoint"/>
<to uri="bean:testBean?method=processSOAP"/>
</route>
</camelContext>
Below is the WebServiceProvider implementor's annotation. In this code, we just want to handle SOAPMessages in the Message mode:
@WebServiceProvider()
@ServiceMode(Mode.MESSAGE)
Since the CXF-Camel component will replace the CXF invoker to call the processor when starting a CXF endpoint, the CXF-Camel consumer will never call the provider implementor's invoke method here.
public class GreeterProvider implements Provider<SOAPMessage> {
public SOAPMessage invoke(SOAPMessage message) {
throw new UnsupportedOperationException("Placeholder method");
}
}
Now we can implement the bean for handling the invocation of the SOAP message:
public class TesterBean {
public SOAPMessage processSOAP(Exchange exchange) {
SOAPMessage soapMessage = (SOAPMessage)exchange.getIn().getBody(List.class).get(0);
if (soapMessage == null) {
System.out.println("Incoming null message detected...");
return createDefaultSoapMessage("Greetings from Apache Camel!!!!", "null");
}
try {
SOAPPart sp = soapMessage.getSOAPPart();
SOAPEnvelope se = sp.getEnvelope();
SOAPBody sb = se.getBody();
String requestText = sb.getFirstChild().getTextContent();
System.out.println(requestText);
return createDefaultSoapMessage("Greetings from Apache Camel!!!!", requestText);
} catch (Exception e) {
e.printStackTrace();
return createDefaultSoapMessage("Greetings from Apache Camel!!!!", e.getClass().getName());
}
}
public static SOAPMessage createDefaultSoapMessage(String responseMessage, String requestMessage) {
try {
SOAPMessage soapMessage = MessageFactory.newInstance().createMessage();
SOAPBody body = soapMessage.getSOAPPart().getEnvelope().getBody();
QName payloadName = new QName("http:, "greetMeResponse", "ns1");
SOAPBodyElement payload = body.addBodyElement(payloadName);
SOAPElement message = payload.addChildElement("responseType");
message.addTextNode(responseMessage + " Request was " + requestMessage);
return soapMessage;
} catch (SOAPException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}