Как настроить ответ на запрос с двух разных маршрутов в Apache Camel?

в настоящее время я работаю с верблюдом Apache. В моем приложении у меня есть 2 маршрута.

Первый маршрут содержит HTTP в качестве входных данных, некоторые процессы и WMQ (этот WMQ используется только для записи)

На втором маршруте у меня есть WMQ (используется только для чтения) для тега from и некоторых процессов сопоставления.

Что я хочу сделать, так это отправить ответ от WMQ по моему второму маршруту на мой HTTP по моему первому маршруту.

Как это сделать?

Вот моя конфигурация на данный момент.

<?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>

Заранее спасибо.


person pokopang    schedule 11.06.2014    source источник


Ответы (1)


Используйте шаблон InOut:

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

Используя InOut, Camel отправит ответ обратно в очередь JMSReplyTo. Дополнительные сведения см. в документах Camel.

Простая установка будет выглядеть следующим образом:

<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>

Отправка Hello пользователю direct:start приведет к следующему сообщению в журнале:

Received body in sending route: Hello, World!
person Peter Keller    schedule 11.06.2014
comment
но в моем случае mq в первом маршруте отличается от mq во втором потоке. Как я отправляю в своем вопросе, первая очередь (LSMH.ZKSEAP.SERVICEBUS) используется только для записи, а вторая очередь (ZKSEAP.LSMH.SERVICEBUS) используется только для чтения. - person pokopang; 12.06.2014
comment
@pokopang Отправьте второе сообщение jms:queue:ZKSEAP.LSMH.SERVICEBUS, используя шаблон InOut рядом с сообщением, которое вы уже отправили jms:queue:LSMH.ZKSEAP.SERVICEBUS (и, возможно, вам также следует выбрать более подходящие имена для ваших очередей JMS...) - person Peter Keller; 12.06.2014
comment
Я не могу этого сделать, так как в процессе очереди есть операция SOAP, результат будет другим. Я имею в виду, что я пишу запрос в jms:queue:LSMH.ZKSEAP.SERVICEBUS, затем, когда я получу ответ, я прочитаю его из jms:queue:ZKSEAP.LSMH.SERVICEBUS. Вот почему, если я сделаю так, как вы сказали, то я получу сообщение запроса, а не ответное сообщение. - person pokopang; 12.06.2014
comment
@pokopang Я думаю, вам нужно реорганизовать свои маршруты и использовать InOut, когда требуется обратная связь. - person Peter Keller; 12.06.2014
comment
как его рефакторить? не могли бы вы привести пример? спасибо - person pokopang; 12.06.2014
comment
@pokopang Если jms:queue:ZKSEAP.LSMH.SERVICEBUS не должен вызываться маршрутом jetty, то, я думаю, вам нужна система рабочего процесса, которая организует ваши задания. - person Peter Keller; 12.06.2014
comment
Не могли бы вы привести пример системы рабочего процесса? Я действительно новичок в Apache Camel - person pokopang; 12.06.2014
comment
Когда я говорю о системе рабочего потока, я имею в виду, что вы не можете использовать Apache Camel в одиночку. Возможно, Activiti сможет удовлетворить ваши потребности. Существует также компонент, который можно использовать в сочетании с Camel: activiti.org/userguide/index. html#bpmnCamelTask - person Peter Keller; 12.06.2014
comment
Значит, нельзя использовать верблюда в одиночку? И тогда нет ли другого пути, кроме использования шаблона inOut для процесса запрос-ответ? - person pokopang; 12.06.2014
comment
@pokopang Самое простое решение — использовать одну единственную очередь JMS вместе с шаблоном InOut, как показано в первом маршруте моего примера. Ваша внешняя служба, прочитавшая сообщение из Queue.w, должна прочитать заголовок JMSReplyTo JMS из сообщения и отправить его обратно в эту очередь. Самые простые решения чаще всего являются лучшими решениями... - person Peter Keller; 12.06.2014
comment
@pokopang ... и если вам нужна синхронная обратная связь, вообще не используйте JMS. - person Peter Keller; 13.06.2014
comment
недостаточно, если я просто установлю опцию: answerTo=Queue.r в моем Queue.w? если да, то в чем причина? Спасибо - person pokopang; 13.06.2014
comment
@pokopang Требуется шаблон InOut. Установка заголовка JMSReplyTo позволяет явно указать имя очереди обратной связи. Согласно camel.apache.org/jms.html: JmsProducer обнаруживает InOut и предоставляет Заголовок JMSReplyTo с назначением ответа, которое будет использоваться. По умолчанию Camel использует временную очередь, но вы можете использовать параметр replyTo на конечной точке, чтобы указать фиксированную очередь ответов (подробнее о фиксированной очереди ответов см. ниже). - person Peter Keller; 13.06.2014