利用spring集成的带有JMS转换器的ActiveMQ AMQP

利用spring集成的带有JMS转换器的ActiveMQ AMQP,jms,activemq,spring-integration,amqp,Jms,Activemq,Spring Integration,Amqp,我正试图利用ActiveMQ的AMQP和JMS transformer来启动并运行一个基本应用程序。我的客户端库是SpringIntegration,但是,我无法在这种配置中启动并运行基本示例 有关ActiveMQ的JMS transformer over AMQP的详细信息: 主测试应用程序 @IntegrationComponentScan @SpringBootApplication public class SpringCloudStreamJmsActivemqSenderExampl

我正试图利用ActiveMQ的AMQP和JMS transformer来启动并运行一个基本应用程序。我的客户端库是SpringIntegration,但是,我无法在这种配置中启动并运行基本示例

有关ActiveMQ的JMS transformer over AMQP的详细信息:

主测试应用程序

@IntegrationComponentScan
@SpringBootApplication
public class SpringCloudStreamJmsActivemqSenderExampleApplication implements CommandLineRunner {

    @Bean
    public ConnectionFactory connectionFactory() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL("tcp://localhost:61616");
        connectionFactory.setUserName("admin");
        connectionFactory.setPassword("admin");
        return connectionFactory;
    }

    @Bean
    public ConnectionFactory connectionFactoryAMQP() {
        ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
        connectionFactory.setBrokerURL("tcp://localhost:5672");
        connectionFactory.setUserName("admin");
        connectionFactory.setPassword("admin");
        return connectionFactory;
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudStreamJmsActivemqSenderExampleApplication.class, args);
    }

    @Autowired
    JmsGateway gateway;

    @Override
    public void run(String... strings) throws Exception {
        gateway.sendMessage("Hi");
    }

    @Bean(name = PollerMetadata.DEFAULT_POLLER)
    public PollerMetadata poller() {
        return Pollers.fixedDelay(1, TimeUnit.SECONDS).get();
    }

    @Bean(name = "outboundChannel")
    MessageChannel myOutBoundChannel() {
        return new QueueChannel();
    }

    @Bean(name = "inboundChannel")
    MessageChannel myInboundChannel() {
        return new QueueChannel();
    }

    @Bean(name = "errorChannel")
    MessageChannel myErrorChannel() {
        return new DirectChannel();
    }

    @Bean
    IntegrationFlow jmsInboundFlow() {
        return IntegrationFlows.from(Jms
                .inboundGateway(connectionFactoryAMQP())
                .destination("myCoolQueue")
                .errorChannel(myErrorChannel()))
                    .handle(this::print)
                .get();
    }

    @Bean
    IntegrationFlow jmsOutboundFlow() {
        return IntegrationFlows.from(myOutBoundChannel())
                .handle(Jms.outboundAdapter(connectionFactory())
                .destination("myCoolQueue"))
                .get();
    }

    @Bean
    IntegrationFlow customErrorFlow() {
        return IntegrationFlows.from(myErrorChannel())
                    .handle(this::printStackTrace)
                .get();
    }

    private void print(Message message) {
        System.out.println("Message payload: " + message.getPayload());
        //throw new RuntimeException("broke it");
    }

    private void printStackTrace(Message errorMessage) {
        ((ErrorMessage)errorMessage).getPayload().printStackTrace();
    }
}
消息网关

@MessagingGateway
interface JmsGateway {
    @Gateway(requestChannel = "outboundChannel")
    void sendMessage(String message);
}
ActiveMQ.xml

<transportConnectors>
    <transportConnector name="openwire" uri="tcp://0.0.0.0:0?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="amqp" uri="amqp://0.0.0.0:0?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;transport.transformer=jms"/>
    <transportConnector name="mqtt" uri="mqtt://0.0.0.0:0?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
    <transportConnector name="ws" uri="ws://0.0.0.0:0?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600"/>
</transportConnectors>

ActiveMQ客户端只使用ActiveMQ本机协议OpenWire,因此尝试将其连接到AMQP端口将不起作用,连接尝试将失败。您需要使用AMQP客户端连接到代理上的AMQP端口,以便通过AMQP发送和接收消息。该项目有许多AMQPV1.0客户端可供选择。如果您想坚持使用JMS类型的客户端API,那么客户端就是适合您的。

ActiveMQ客户端只使用ActiveMQ本机协议OpenWire,因此尝试将其连接到AMQP端口将不起作用,连接尝试将失败。您需要使用AMQP客户端连接到代理上的AMQP端口,以便通过AMQP发送和接收消息。该项目有许多AMQPV1.0客户端可供选择。如果您想坚持使用JMS类型的客户机API,那么客户机就是适合您的客户机。

您必须通过两种方式更改Bean定义:

JNDI

@Bean
public ConnectionFactory connectionFactoryAMQP() {
    String factoryName = "myFactoryLookup";
    Properties props = new Properties();
    props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
    props.setProperty("connectionfactory." + factoryName, "amqp://localhost:5672");
    props.put("property.connectionfactory." + factoryName + ".username", "admin");
    props.put("property.connectionfactory." + factoryName + ".password", "admin");
    InitialContext ic = new InitialContext(props);
    ConnectionFactory connectionFactory = (ConnectionFactory) ic.lookup(factoryName );
    return connectionFactory;
}
@Bean
public ConnectionFactory connectionFactoryAMQP() {
        org.apache.qpid.jms.JmsConnectionFactory connectionFactory = new JmsConnectionFactory();
        connectionFactory.setRemoteURI("amqp://localhost:5672");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
    return connectionFactory;
}

工厂

@Bean
public ConnectionFactory connectionFactoryAMQP() {
    String factoryName = "myFactoryLookup";
    Properties props = new Properties();
    props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
    props.setProperty("connectionfactory." + factoryName, "amqp://localhost:5672");
    props.put("property.connectionfactory." + factoryName + ".username", "admin");
    props.put("property.connectionfactory." + factoryName + ".password", "admin");
    InitialContext ic = new InitialContext(props);
    ConnectionFactory connectionFactory = (ConnectionFactory) ic.lookup(factoryName );
    return connectionFactory;
}
@Bean
public ConnectionFactory connectionFactoryAMQP() {
        org.apache.qpid.jms.JmsConnectionFactory connectionFactory = new JmsConnectionFactory();
        connectionFactory.setRemoteURI("amqp://localhost:5672");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
    return connectionFactory;
}
添加此依赖项


org.apache.qpid
qpid jms客户端
0.9.0

在activemq.xml中添加端口

 <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?transport.transformer=jms"/>


transport.transformer=jms仅用于在AMQP transport和ActiveMQ之间将jms消息从代理端的AMQP消息转换为AMQP消息,当代理通过AMQP传输接收AMQP消息时,它将从AMQP消息转换为JMS消息;当消息通过AMQP传输发送给消费者时,它将从JMS转换为AMQP消息。

您必须通过两种方式更改Bean定义:

JNDI

@Bean
public ConnectionFactory connectionFactoryAMQP() {
    String factoryName = "myFactoryLookup";
    Properties props = new Properties();
    props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
    props.setProperty("connectionfactory." + factoryName, "amqp://localhost:5672");
    props.put("property.connectionfactory." + factoryName + ".username", "admin");
    props.put("property.connectionfactory." + factoryName + ".password", "admin");
    InitialContext ic = new InitialContext(props);
    ConnectionFactory connectionFactory = (ConnectionFactory) ic.lookup(factoryName );
    return connectionFactory;
}
@Bean
public ConnectionFactory connectionFactoryAMQP() {
        org.apache.qpid.jms.JmsConnectionFactory connectionFactory = new JmsConnectionFactory();
        connectionFactory.setRemoteURI("amqp://localhost:5672");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
    return connectionFactory;
}

工厂

@Bean
public ConnectionFactory connectionFactoryAMQP() {
    String factoryName = "myFactoryLookup";
    Properties props = new Properties();
    props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.qpid.jms.jndi.JmsInitialContextFactory");
    props.setProperty("connectionfactory." + factoryName, "amqp://localhost:5672");
    props.put("property.connectionfactory." + factoryName + ".username", "admin");
    props.put("property.connectionfactory." + factoryName + ".password", "admin");
    InitialContext ic = new InitialContext(props);
    ConnectionFactory connectionFactory = (ConnectionFactory) ic.lookup(factoryName );
    return connectionFactory;
}
@Bean
public ConnectionFactory connectionFactoryAMQP() {
        org.apache.qpid.jms.JmsConnectionFactory connectionFactory = new JmsConnectionFactory();
        connectionFactory.setRemoteURI("amqp://localhost:5672");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
    return connectionFactory;
}
添加此依赖项


org.apache.qpid
qpid jms客户端
0.9.0

在activemq.xml中添加端口

 <transportConnector name="amqp" uri="amqp://0.0.0.0:5672?transport.transformer=jms"/>


transport.transformer=jms仅用于在AMQP transport和ActiveMQ之间将jms消息从代理端的AMQP消息转换为AMQP消息,当代理通过AMQP传输接收AMQP消息时,它将从AMQP消息转换为JMS消息;当消息通过AMQP传输发送给消费者时,它将从JMS转换为AMQP消息。

我认为这在应用程序中不起作用。您应该了解ApacheQPID项目,以了解如何通过JMS API连接到AMQP1.0代理。在这里了解如何创建工厂我不熟悉它,但我认为您误解了transformer的功能。它不会更改amqp端口上的协议。它似乎将通过AMQP发送的消息(例如,从QPID Proton)映射到JMS消息,以便JMS消费者(通过OpenWire)可以使用它,反之亦然。JMS transformer将AMQP消息的头映射到JMS消息头,并将AMQP消息体映射到JMS体,因为AMQP和JMS具有不同的结构和定义。JMS超过AMQP我认为这在前额是行不通的。您应该了解ApacheQPID项目,以了解如何通过JMS API连接到AMQP1.0代理。在这里了解如何创建工厂我不熟悉它,但我认为您误解了transformer的功能。它不会更改amqp端口上的协议。它似乎将通过AMQP发送的消息(例如,从QPID Proton)映射到JMS消息,以便JMS消费者(通过OpenWire)可以使用它,反之亦然。JMS transformer将AMQP消息的头映射到JMS消息头,并将AMQP消息体映射到JMS体,因为AMQP和JMS具有不同的结构和定义。JMS over amqpTim这是否意味着AMQP设置上的JMS transformer选项不允许JMS客户端连接,但允许支持JMS消息格式?Tim这是否意味着AMQP设置上的JMS transformer选项不允许JMS客户端连接,但是允许支持JMS消息格式吗?非常感谢您提供的工厂示例和JMS传输转换器解释。现在,我的代码已经准备好并顺利运行。非常感谢您提供的工厂示例和JMS transport Transformer解释。现在,我的代码已安装并顺利运行。