简体   繁体   中英

Error in connection with messaging queue in Quarkus

I am trying to consume/write to a messaging queue in Quarkus, but have been unable to do so. I have an example code with which I can connect to the queue but it is made with the com.ibm.mq.allclient library based on javax.jms,

    <dependency>
      <groupId>com.ibm.mq</groupId>
      <artifactId>com.ibm.mq.allclient</artifactId>
      <version>9.0.4.0</version>
    </dependency>

and to connect use the parameters: hostname, port, name, channel, queuename.

The example code, using the com.ibm.mq.allclient library to create the connections for consumption and writing, is as follows:

import com.ibm.mq.jms.MQQueue;
import com.ibm.mq.jms.MQQueueConnection;
import com.ibm.mq.jms.MQQueueConnectionFactory;
import com.ibm.mq.jms.MQQueueSession;

import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.TextMessage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClass {

    private static Logger logger = LoggerFactory.getLogger(MyClass.class);

    private MQQueueConnection connectionRq;
    private MQQueueConnection connectionRs;

    public void initConnection(){
        
        try {
            MQQueueConnectionFactory connectionFactoryRq = new MQQueueConnectionFactory();
            connectionFactoryRq.setHostName("localhost");
            connectionFactoryRq.setPort(5672);
            connectionFactoryRq.setTransportType(1);
            connectionFactoryRq.setQueueManager("QM_NAME");
            connectionFactoryRq.setChannel("CHANNEL");

            MQQueueConnectionFactory connectionFactoryRs = new MQQueueConnectionFactory();
            connectionFactoryRs.setHostName("localhost");
            connectionFactoryRs.setPort(5672);
            connectionFactoryRs.setTransportType(1);
            connectionFactoryRs.setQueueManager("QM_NAME");
            connectionFactoryRs.setChannel("CHANNEL");

            connectionRq = (MQQueueConnection) connectionFactoryRq.createQueueConnection();
            connectionRs = (MQQueueConnection) connectionFactoryRs.createQueueConnection();


        } catch (Exception e) {
            logger.info(e.getMessage());
        }
    }

    public String sendMessage(String msg, String correlativeId){
        
        String corId = null;
        MQQueueSession sessionRq = null;
        MQQueueSession sessionRs = null;
        MessageProducer producer = null;
        try {
            sessionRq = (MQQueueSession) connectionRq.createQueueSession(false, 1);
            MQQueue queueRq = (MQQueue) sessionRq.createQueue("queue:///QUEUENAME.RQ");
            queueRq.setMessageBodyStyle(1);
            queueRq.setTargetClient(1);

            sessionRs = (MQQueueSession) connectionRs.createQueueSession(false, 1);
            MQQueue queueRs = (MQQueue) sessionRs.createQueue("queue:///QUEUENAME.RS");

            producer = sessionRq.createProducer(queueRq);

            Message messageRq = sessionRq.createTextMessage(msg);
            messageRq.setJMSReplyTo(queueRs);
            messageRq.setIntProperty("JMS_IBM_Character_Set", 819);
            messageRq.setIntProperty("JMS_IBM_Encoding", 273);
            messageRq.setIntProperty("JMS_IBM_MsgType", 8);
            messageRq.setJMSMessageID(correlativeId);
            messageRq.setJMSCorrelationIDAsBytes(correlativeId.getBytes());
            messageRq.setJMSPriority(1);
            messageRq.setJMSType("Datagram");

            producer.send(messageRq);

            corId = messageRq.getJMSCorrelationID();
        } catch (Exception e) {
            logger.info(e.getMessage());
        }  finally {
            try {
                sessionRq.close();
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
            try {
                sessionRs.close();
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
            try {
                producer.close();
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
        }
        return corId;
    }

    public String consumerMessage(String correlativeId){

        String msg = null;
        MQQueueSession sessionRs = null;
        MessageConsumer consumer = null;
        try {
            sessionRs = (MQQueueSession) connectionRs.createQueueSession(false, 1);
            MQQueue queueRs = (MQQueue) sessionRs.createQueue("queue:///QUEUENAME.RS");
            consumer = sessionRs.createConsumer(queueRs, "JMSCorrelationID='" + correlativeId + "'");
            connectionRs.start();
            Message messageRs = consumer.receive(10000L);
            msg = ((TextMessage) messageRs).getText();
        } catch (Exception e) {
            logger.info(e.getMessage());
        }  finally {
            try {
                sessionRs.close();
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
            try {
                consumer.close();
            } catch (Exception e) {
                logger.info(e.getMessage());
            }
        }
        return msg;
    }

    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.initConnection();
        String corId = myClass.sendMessage("Test Message Send", "UNIQUE");
        String message = myClass.consumerMessage(corId);
        logger.info("The message: " + message);
    }
}

The code above works fine, the problem is that the library is not compatible with the native Quarkus compiler.

For the connection with the MQ in Quarkus I am using the library:

    <dependency>
      <groupId>org.amqphub.quarkus</groupId>
      <artifactId>quarkus-qpid-jms</artifactId>
    </dependency>

In the application.properties I assign:

quarkus.qpid-jms.url=amqp://localhost:5672

And when trying to run the sample project in: Quarkus Qpid JMS Quickstart throws me the following error:

__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
2022-03-17 12:02:31,489 INFO  [org.acm.jms.PriceConsumer] (pool-11-thread-1) Writing MQ Client...
2022-03-17 12:02:31,486 INFO  [org.acm.jms.PriceConsumer] (pool-10-thread-1) Reading MQ Client...
2022-03-17 12:02:31,757 INFO  [io.quarkus] (Quarkus Main Thread) jms-quickstart 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.7.2.Final) started in 4.626s. Listening on: http://localhost:8080
2022-03-17 12:02:31,758 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2022-03-17 12:02:31,759 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, qpid-jms, resteasy, smallrye-context-propagation, vertx]
2022-03-17 12:02:34,068 ERROR [org.apa.qpi.jms.JmsConnection] (pool-11-thread-1) Failed to connect to remote at: amqp://localhost:5672
2022-03-17 12:02:34,068 ERROR [org.apa.qpi.jms.JmsConnection] (pool-10-thread-1) Failed to connect to remote at: amqp://localhost:5672

I know that it is most likely a configuration error and I am missing something, but I am new to Quarkus and I have already read and tried so many things that I have already collapsed.

I appreciate any kind of help as it would be great, or at least documentation or something to guide me is also welcome.

Documentation consulted:

You are getting a connection failure when you try to connect to localhost:5672 . This implies that you do not have anything listening on that TCP/IP port. The instructions you reference have a template MQSC script which sets up the required resources needed on the queue manager to allow an AMQP connection. This script can be found here .

The most pertinent commands within this script for your specific reported problem are likely these (although I suggest you run the whole script):

START SERVICE(SYSTEM.AMQP.SERVICE)
START CHANNEL(SYSTEM.DEF.AMQP)

What version of IBM MQ are you using for your queue manager?

Because before IBM MQ v9.2.1, it only supported Pub/Sub via AMQP. If you want to use point-to-point topology (getting/putting to a queue) then you need your queue manager to be at least MQ v9.2.1. See here .

The first paragraph has the blue label "v9.2.1". That means when the feature was introduced to IBM MQ.

Now you can fake it, by setting up an administrative topic object that points to a queue then use AMQP Pub/Sub to access the queue but it would be far simpler to upgrade your queue manager to the MQ v9.2.1 or higher. The current IBM MQ CD release is v9.2.5.

Note: The LTS release of IBM MQ v9.2 does not have the feature yet. It will be included in the next major release of MQ (ie v9.3 or whatever it will be called).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM