In this section, we consider a SOAP/HTTP-to-JMS bridge use case: that is, you want to create a route that transforms a synchronous operation invocation (over SOAP/HTTP) into an asynchronous message delivery (by pushing the message onto a JMS queue). In this way, it becomes possible to process the incoming operation invocations at a later time, by pulling messages off the JMS queue.
Figure 9 shows the general outline of a bridge that can transform synchronous SOAP/HTTP invocations into asynchronous JMS message deliveries.
As shown in Figure 9, the route for transforming synchronous SOAP/HTTP to asynchronous JMS works as follows:
The WS client invokes a synchronous operation on the Camel CXF endpoint at the start of the route. The Camel CXF endpoint then creates an initial InOut exchange at the start of the route, where the body of the exchange message contains a payload in XML format.
The
inOnlyDSL command pushes a copy of the XML payload onto a JMS queue, so that it can be processed offline at some later time.The
transformDSL command constructs an immediate response to send back to the client, where the response has the form of an XML string.The route explicitly converts the XML string to the
javax.xml.transform.sax.SAXSourcetype.The response is sent back to the WS client, thus completing the synchronous operation invocation.
Evidently, this transformation can only work, if the original operation invocation has no return value. Otherwise, it would be impossible to generate a response message before the request has been processed.
You can use Apache ActiveMQ as the JMS implementation. A convenient
approach to use in this demonstration is to embed the Apache ActiveMQ
broker in the bridge bundle. Simply define an
amq:broker element in the Spring XML file, as
follows:
<beans xmlns="http://www.springframework.org/schema/beans"
...
xmlns:amq="http://activemq.apache.org/schema/core"
...>
<amq:broker brokerName="CxfPayloadDemo" persistent="false">
<amq:transportConnectors>
<amq:transportConnector name="openwire" uri="tcp://localhost:51616"/>
<amq:transportConnector name="vm" uri="vm:local"/>
</amq:transportConnectors>
</amq:broker>
...
</beans>![]() | Note |
|---|---|
This broker instance is created with the
|
Because the broker is co-located with the bridge route (in the same JVM), the most efficient way to connect to the broker is to use the VM (Virtual Machine) transport. Configure the Apache ActiveMQ component as follows, to connect to the co-located broker using the VM protocol:
<beans ...>
...
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent">
<property name="brokerURL" value="vm:local"/>
</bean>
...
</beans>![]() | Note |
|---|---|
By defining the bean with an |
For example, you could define a route that implements the
SOAP/HTTP-to-JMS bridge specifically for the
updateCustomer operation from the
CustomerService SEI, as follows:
<when>
<simple>${in.header.operationName} == 'updateCustomer'</simple>
<log message="Placing update customer message onto queue."/>
<inOnly uri="activemq:queue:CustomerUpdates?jmsMessageType=Text"/>
<transform>
<constant>
<![CDATA[
<ns2:updateCustomerResponse xmlns:ns2="http://demo.fusesource.com/wsdl/CustomerService/"/>
]]>
</constant>
</transform>
<convertBodyTo type="javax.xml.transform.sax.SAXSource"/>
</when>Note how the message payload is sent to the JMS queue using
the inOnly DSL command instead of the
to DSL command. When you send a message using
the to DSL command, the default behavior is to use
the same invocation mode as the current exchange. But the
current exchange has an InOut MEP, which
means that the to DSL command would wait forever
for a response message from JMS.
The invocation mode we want to use when sending the payload to
the JMS queue is InOnly (asynchronous), and
we can force this mode by inserting the inOnly DSL
command into the route.
![]() | Note |
|---|---|
By specifying the option,
|
The transform DSL command uses an expression to
set the body of the exchange's Out message
and this message is then used as the response to the client.
Your first impulse when defining a response in XML format might
be to use a DOM API, but in this example, the response is
specified as a string literal. This approach has the advantage
of being both efficient and very easy to program.
The final step of processing, which consists of converting the XML string to a DOM object, is performed by Apache Camel's implicit type conversion mechanism.
In this example, the reply message (like the request message)
is required to be of type,
javax.xml.transform.sax.SAXSource. In the last
step of the route, therefore, you must convert the message body
from String type to
javax.xml.transform.sax.SAXSource type, by
invoking the convertBodyTo DSL command.
The implementation of the String to SAXSource
conversion is provided by a custom type converter, as described
in TypeConverter for SAXSource.







![[Note]](imagesdb/note.gif)


