Два администратора очередей с разными каналами не допускаются - PullRequest
0 голосов
/ 01 августа 2020

Я использую spring boot 2.3.2 с ibm mq. Я использую файл настроек mq.

ibm.mq.queueManager=
ibm.mq.channel=
ibm.mq.connName
ibm.mq.user
ibm.mq.password
ibm.mq.useIBMCipherMappings=false
ibm.mq.userAuthenticationMQCSP=false
ibm.mq.sslCipherSuite=TLS_RSA_WITH_AES_128_CBC_SHA256

, который отлично работает.

Мне нужно создать еще одну фабрику, чтобы иметь возможность подключаться к другому каналу. Поэтому я хотел бы создать аналогичный, который создается по умолчанию, но с другим именем канала.

Итак, я создал класс конфигурации

@EnableJms
@Configuration
public class JmsConfig {
@Bean
    public MQQueueConnectionFactory jmsMQConnectionFactoryPayment() throws JMSException {
        MQQueueConnectionFactory connectionFactory = new MQQueueConnectionFactory();
        connectionFactory.setQueueManager("AD_TEST");
        connectionFactory.setChannel("FROM.PAYMENTMNG");
        connectionFactory.setConnectionNameList("wmqd1.int.test.com(1818),wmqd2.int.test.com(1818)");


        connectionFactory.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, false);

        connectionFactory.setStringProperty(WMQConstants.WMQ_SSL_CIPHER_SUITE, "TLS_RSA_WITH_AES_128_CBC_SHA256");
        connectionFactory.setIntProperty(CommonConstants.WMQ_CONNECTION_MODE, CommonConstants.WMQ_CM_CLIENT);


        System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", String.valueOf(Boolean.FALSE));

        connectionFactory.createConnection("123", "123");
        return connectionFactory;
    }

    @Bean
    JmsListenerContainerFactory<?> jmsContainerFactoryPayment() throws JMSException {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(jmsMQConnectionFactoryPayment());
        return factory;
    }

    @Bean("payment")
    JmsTemplate jmsTemplatePayment() throws JMSException {
        JmsTemplate template = new JmsTemplate();
        template.setConnectionFactory(jmsMQConnectionFactoryPayment());
        return template;
    }


}

В классе, который у меня есть

@JmsListener(destination="xxx", containerFactory="jmsContainerFactoryPayment"){
    ....
}

Когда я запускаю приложение, я получаю

com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: E Failed to connect to queue manager 'AD_TEST' with connection mode 'Client' and host name 'wmqd1.int.test.com(1818),wmqd2.int.test.com(1818)'.

                at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:489) ~[com.ibm.mq.allclient-9.2.0.0.jar:9.2.0.0 - p920-L200710.DE]

                at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:215) ~[com.ibm.mq.allclient-9.2.0.0.jar:9.2.0.0 - p920-L200710.DE]

                at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:450) ~[com.ibm.mq.allclient-9.2.0.0.jar:9.2.0.0 - p920-L200710.DE]

                at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:8475) ~[com.ibm.mq.allclient-9.2.0.0.jar:9.2.0.0

Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ  call failed with compcode '2' ('MQCC_FAILED') ; reason '2538' ('MQRC_HOST_NOT_AVAILABLE').

                at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203) ~[com.ibm.mq.allclient-9.2.0.0.jar:9.2.0.0 - p920-L200710.DE]

                ... 51 common frames omitted

Кажется, у нас не может быть двух диспетчеров очередей с одним и тем же хостом, но с разными каналами

1 Ответ

1 голос
/ 05 августа 2020

Я настроил Spring Boot с IBM MQ, чтобы проверить это. Начиная с образца, представленного в этом IBM Messaging GitHub Repo , я добавил два дополнительных слушателя следующим образом.

Сначала я добавил некоторые дополнительные свойства в application.properties файл

my.mq.queueManager=QM2
my.mq.channel=DEV.APP.SVRCONN
my.mq.connName=localhost(1415)
my.mq.user=<your_user_name>
my.mq.password=<your_password>

Я оставил Application.java без изменений, скопировал Listener.java, чтобы создать ListenerTwo.java и ListenerThree.java. Затем я добавил в образец новый класс ListenerBeanConfig.java.

ListenerTwo.java было изменено для привязки к новой ConnectionFactory конфигурации listenerTwoFactory, которая создается позже.

@JmsListener(destination = Application.qName, containerFactory = "listenerTwoFactory")

ListenerThree.java был изменен для привязки к новой конфигурации listenerThreeFactory, а Queue

@JmsListener(destination = "DEV.QUEUE.2", containerFactory = "listenerThreeFactory")

Объявление класса ListenerBeanConfig.java было аннотировано, чтобы я мог получить доступ к своим свойствам, добавив строки для каждого свойства, например, queueManager, channel, connName и c. и предоставляя методы установки для каждого из них, например,

@Configuration
@EnableJms
@ConfigurationProperties(prefix="my.mq")
public class ListenerBeanConfig {

    String connName;
public void setConnName(String value) {
    System.out.println("connName is set to: "+value);
    connName = value;
  }

Я зарегистрировал два новых Listener beans

@Bean
  public ListenerTwo myListenerTwo() {
    return new ListenerTwo();
  }

@Bean
  public ListenerThree myListenerThree() {
    return new ListenerThree();
  }

Затем я создал новые конфигурации фабрики соединений listenerTwoFactory и listenerThreeFactory

Для listenerTwoFactory я использовал классы JMS, предоставленные com.ibm.mq.jms в конфигурации Spring Boot

JmsConnectionFactory cf;

@Bean
  public DefaultJmsListenerContainerFactory listenerTwoFactory() {
  DefaultJmsListenerContainerFactory containerFactory = new DefaultJmsListenerContainerFactory();
  try {
    JmsFactoryFactory ff = JmsFactoryFactory.getInstance(WMQConstants.WMQ_PROVIDER);
    cf = ff.createConnectionFactory();
    cf.setStringProperty(WMQConstants.WMQ_CONNECTION_NAME_LIST, connName);
    cf.setStringProperty(WMQConstants.WMQ_CHANNEL, channel);
    cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE, WMQConstants.WMQ_CM_CLIENT);
    cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, queueManager);
    cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME, "Spring Boot ListenerTwo");
    cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP, true);
    cf.setStringProperty(WMQConstants.USERID, user);
    cf.setStringProperty(WMQConstants.PASSWORD, password);
  } catch (JMSException jmsex) {
    System.out.println(jmsex);
  }
  containerFactory.setConnectionFactory(cf);
  return containerFactory;
}

Для listenerThreeFactory я использовал помощник MQ JMS классы из com.ibm.mq.spring.boot.

@Bean
public DefaultJmsListenerContainerFactory listenerThreeFactory() {
    MQConfigurationProperties myProps = new MQConfigurationProperties();
    myProps.setUser(user);
    myProps.setChannel(channel);
    myProps.setConnName(connName);
    myProps.setPassword(password);
    myProps.setQueueManager(queueManager);
    //No customizer
    MQConnectionFactoryFactory mqcff = new MQConnectionFactoryFactory(myProps,null);
    MQConnectionFactory mqcf = mqcff.createConnectionFactory(MQConnectionFactory.class);
    DefaultJmsListenerContainerFactory containerFactory = new DefaultJmsListenerContainerFactory();
    containerFactory.setConnectionFactory(mqcf);
    return containerFactory;
}

Наконец, я скомпилировал и запустил новый образец конфигурации. Используя IBM MQ Console для двух экземпляров администратора очередей IBM MQ docker, я помещаю сообщения в QM1: DEV.QUEUE.1 и QM2: DEV.QUEUE.1, DEV.QUEUE.2. На терминале увидите следующий вывод.

========================================
Received message is: message 1
========================================

========================================
ListenerTwo received message is: message 2
========================================

========================================
ListenerThree received message is: message 3
========================================

Также протестировано со всеми тремя слушателями, подключенными к QM2 через два разных канала: DEV.APP.SVRCONN и DEV.APP.SVRCONN.TWO.

Я уверен, что есть - гораздо более элегантные способы управления дополнительными свойствами.

...