0

currently I am working with apache camel. In my application I have 2 routes.

The first route contain HTTP as the input, some processes, and WMQ (this WMQ used for write only)

On the second route, I have WMQ (used for read only) for the from tag and some mapping processes.

What I want to do is sending the response from the WMQ on my second route to my HTTP on my first route.

How to do so?

Here is my configuration so far.

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

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" default-init-method="init" xmlns:util="http://www.springframework.org/schema/util" xmlns:osgi="http://www.springframework.org/schema/osgi" xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xs http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://www.springframework.org/schema/osgi  http://www.springframework.org/schema/osgi/spring-osgi.xsd">

    <import resource="classpath:/META-INF/spring/components.xml"/>

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

        <dataFormats>
            <xmljson id="xmljson" forceTopLevelObject="true" skipNamespaces="true" removeNamespacePrefixes="true"/>
        </dataFormats>

        <route>
            <from uri="jetty:http://localhost:8888/uebermittleAusweisdaten"/>
            <process ref="TransformToXML"/>
            <to uri ="xslt:soap-template.xsl"/>
            <setHeader headerName="CamelJmsDestinationName">
                <constant>queue:///Queue.w?targetClient=1</constant>    
            </setHeader>
            <setHeader headerName="JMS_IBM_Character_Set">
                <constant>ISO8859_1</constant>    
            </setHeader>
            <to uri="jms:queue:Queue.w"/>
            <inOut uri="mock:result"/>
        </route>
        <route>
            <from uri="jms:queue:queue.r"/>
            <marshal ref="xmljson"/>
            <setHeader headerName="CamelJmsDestinationName">
                <constant>mock:result</constant>    
            </setHeader>
            <to uri="stream:out"/>
        </route>

    </camelContext>

</beans>

Thanks in advance.

pokopang
  • 507
  • 1
  • 11
  • 27

1 Answers1

0

Use the InOut pattern:

<to uri="jms:queue:LSMH.ZKSEAP.SERVICEBUS" pattern="InOut" />

Using InOut, Camel will send the reply back to the JMSReplyTo queue, see the Camel docs for further infos.

A simple setup would look as follows:

<route>
    <from uri="direct:start" />
    <to uri="jms:myQueue" pattern="InOut" />
    <log message="Received body in sending route: ${body}" />
</route>
<route>
    <from uri="jms:myQueue" />
    <setBody><simple>${body}, World!</simple></setBody>
</route>

Sending Hello to direct:start would lead to following log message:

Received body in sending route: Hello, World!
Peter Keller
  • 7,526
  • 2
  • 26
  • 29
  • but, in my case, the mq in the first route is different with the mq in the second flow. As I post in my question, the 1st queue (LSMH.ZKSEAP.SERVICEBUS) only used for write and the second queue (ZKSEAP.LSMH.SERVICEBUS) only used for read. – pokopang Jun 12 '14 at 06:07
  • @pokopang Send a second message to `jms:queue:ZKSEAP.LSMH.SERVICEBUS` using the `InOut` pattern beside the message you already send to `jms:queue:LSMH.ZKSEAP.SERVICEBUS` (and perhaps you should choose better names for your JMS queues as well...) – Peter Keller Jun 12 '14 at 06:32
  • I can not do so, since there is SOAP operation on the queue process, the result would be different. I mean, I write the request to jms:queue:LSMH.ZKSEAP.SERVICEBUS, then when I got the response, I will read it from jms:queue:ZKSEAP.LSMH.SERVICEBUS. That's why, if I do it like what you said, then the one that I get is the request message, not the response message. – pokopang Jun 12 '14 at 07:03
  • @pokopang I guess you have to refactor your routes and use `InOut` when feedback is needed. – Peter Keller Jun 12 '14 at 09:45
  • how to refactor it? could you please give me an example? thanks – pokopang Jun 12 '14 at 09:47
  • @pokopang If `jms:queue:ZKSEAP.LSMH.SERVICEBUS` must not be invoked by the `jetty` route, then I guess you need a workflow system that orchestrates your jobs. – Peter Keller Jun 12 '14 at 14:38
  • could you please give me an example about the workflow system? I am really new to apache camel – pokopang Jun 12 '14 at 14:40
  • When I say "worflow system" I mean, you can't use Apache Camel alone. Perhaps, Activiti may support your needs. There is also a component that can be used in combination with Camel: http://activiti.org/userguide/index.html#bpmnCamelTask – Peter Keller Jun 12 '14 at 14:44
  • So, it is not possible to use camel alone? And then is there no other way besides using inOut pattern for request-reply process? – pokopang Jun 12 '14 at 14:48
  • @pokopang The simplest solution is to use one single JMS queue together with the `InOut` pattern as shown in the first route of my example. Your external service that read the message from `Queue.w` must read the `JMSReplyTo` JMS header from the message and send it back to that queue. The simplest solutions are most often the best solutions... – Peter Keller Jun 12 '14 at 18:54
  • @pokopang ...and if you need synchronous feedback, don't use JMS at all. – Peter Keller Jun 13 '14 at 06:36
  • is it not enough if I just set the option: replyTo=Queue.r in my Queue.w? if yes, what is the reason? Thanks – pokopang Jun 13 '14 at 07:43
  • @pokopang The `InOut` pattern is needed. Setting the `JMSReplyTo` header let's you explicitly set the name of the feedback queue. According to http://camel.apache.org/jms.html: "The JmsProducer detects the InOut and provides a JMSReplyTo header with the reply destination to be used. By default Camel uses a temporary queue, but you can use the replyTo option on the endpoint to specify a fixed reply queue (see more below about fixed reply queue)." – Peter Keller Jun 13 '14 at 08:23