Статьи

Соединение между JMS и RabbitMQ (AMQP) с помощью Spring Integration

Один старый клиент недавно спросил меня, есть ли у меня решение о том, как интегрировать существующую инфраструктуру JMS в Websphere MQ с RabbitMQ.

Хотя я знаю, что у RabbitMQ есть плагин shovel, который может соединять экземпляры Rabbit, я еще не нашел хорошего плагина для перенаправления JMS <-> AMQP.
Первое, что мне пришло в голову, — это использовать посредничество Spring Integration, поскольку SI имеет отличную поддержку как для JMS, так и для Rabbit.

Любопытно, что я начал PoC, и это результат. Он принимает сообщения из очереди JMS и перенаправляет их на обмен AMQP, который связан с очередью, которую должно прослушивать приложение потребителя. В качестве JMS-провайдера я использовал внешний экземпляр HornetQ в JBoss 6.1, но я на 100% уверен, что для Websphere MQ будет одинаковая настройка, поскольку они оба реализуют JMS.

Имейте в виду, что я еще не настраивал производительность и не настраивал QoS, так как это всего лишь подтверждение концепции. Для реальной установки вам, вероятно, придется подумать о гарантиях доставки в зависимости от производительности и т

. Д. Код скоро будет доступен в ближайшем к вам репозитории GitHub.

SpringContext в XML:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:int-amqp="http://www.springframework.org/schema/integration/amqp"
    xmlns:rabbit="http://www.springframework.org/schema/rabbit"
    xmlns:int-jms="http://www.springframework.org/schema/integration/jms"
    xmlns:int="http://www.springframework.org/schema/integration"
    xsi:schemaLocation="http://www.springframework.org/schema/integration/amqp http://www.springframework.org/schema/integration/amqp/spring-integration-amqp-2.1.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
        http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.1.xsd
        http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        
    <beans:bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <beans:property name="environment">
            <beans:props>
                <beans:prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</beans:prop>
                <beans:prop key="java.naming.provider.url">jnp://localhost:1099</beans:prop>
                <beans:prop key="java.naming.factory.url.pkgs">org.jnp.interfaces:org.jboss.naming</beans:prop>
            </beans:props>
        </beans:property>
    </beans:bean>

    <beans:bean id="jmsQueueConnectionFactory"
      class="org.springframework.jndi.JndiObjectFactoryBean">
        <beans:property name="jndiTemplate">
            <beans:ref bean="jndiTemplate"/>
        </beans:property>
        <beans:property name="jndiName">
            <beans:value>ConnectionFactory</beans:value>
        </beans:property>
    </beans:bean>

    <!-- Channels and adapters for SI -->
    <int-jms:message-driven-channel-adapter connection-factory="jmsQueueConnectionFactory" destination-name="myJmsQueue" channel="rabbitChannel"/>
    <channel id="rabbitChannel"/>
    <int-amqp:outbound-channel-adapter channel="rabbitChannel" exchange-name="fromJmsExchange" amqp-template="rabbitTemplate"/>
    
    <!-- Connectivity to Rabbit -->
    <rabbit:template id="rabbitTemplate" connection-factory="cf"/>
    <rabbit:connection-factory id="cf" host="localhost"/>
    
    <!-- Rabbit entities, to be created at context startup -->
    <rabbit:admin connection-factory="cf"/>
    <rabbit:queue name="fromJMS"/>
    <rabbit:direct-exchange name="fromJmsExchange">
        <rabbit:bindings>
            <rabbit:binding queue="fromJMS"/>
        </rabbit:bindings>
    </rabbit:direct-exchange>
</beans:beans>

Maven POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.rl</groupId>
    <artifactId>si.jmstorabbit</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>si.jmstorabbit</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <hornet.version>2.2.5.Final</hornet.version>
        <spring.integration.version>2.1.0.RELEASE</spring.integration.version>
    </properties>

    <repositories>
        <repository>
            <id>springsource-release</id>
            <url>http://repository.springsource.com/maven/bundles/release</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>springsource-external</id>
            <url>http://repository.springsource.com/maven/bundles/external</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
    <dependency>
       <groupId>org.springframework.integration</groupId>
       <artifactId>spring-integration-core</artifactId>
       <version>${spring.integration.version}</version>
    </dependency>
    <dependency>
       <groupId>org.springframework.integration</groupId>
       <artifactId>spring-integration-file</artifactId>
       <version>${spring.integration.version}</version>
    </dependency>
    <dependency>
       <groupId>org.springframework.integration</groupId>
       <artifactId>spring-integration-amqp</artifactId>
       <version>${spring.integration.version}</version>
    </dependency>
    <dependency>
       <groupId>org.springframework.integration</groupId>
       <artifactId>spring-integration-jms</artifactId>
       <version>${spring.integration.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.0.7.RELEASE</version>
    </dependency>
    
    <dependency>
        <groupId>jboss</groupId>
        <artifactId>jnp-client</artifactId>
        <version>4.2.2.GA</version>
    </dependency>
            
    
    <dependency>
            <groupId>org.hornetq</groupId>
            <artifactId>hornetq-core-client</artifactId>
            <version>${hornet.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hornetq</groupId>
            <artifactId>hornetq-jms-client</artifactId>
            <version>${hornet.version}</version>
        </dependency>
        <dependency>
            <groupId>org.hornetq</groupId>
            <artifactId>hornetq-jms</artifactId>
            <version>${hornet.version}</version>
        </dependency>
           <dependency>
            <groupId>jboss</groupId>
            <artifactId>jboss-common-client</artifactId>
            <version>3.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.jboss.netty</groupId>
            <artifactId>netty</artifactId>
            <version>3.2.7.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.jms</groupId>
            <artifactId>jms</artifactId>
            <version>1.1</version>
        </dependency>
  </dependencies>
  
</project>