How to consume a message from a remote MQ queue using MDB on Jboss servers

Asked

Viewed 597 times

3

I have an EJB class that writes a message in a JMS queue and would like to consume this message from a Messagedrivenbean (MDB) installed on another server.

My class successfully writes in the JMS queue, but the server does not consume the message. No error is shown, the message is queued without being consumed.

The user guest was created. Tests are being performed on two instances of Jboss on my local machine running on different ports.

When the MDB is in the same EAR of the EJB client (local), it works.

My environment is Jboss EAP 7.1 with Java 8.

EJB class that writes in the queue:

@Stateless
public class ManagerService {

    public void writeQueue() throws NamingException {

        InitialContext context = new InitialContext();
        ConnectionFactory factory = (ConnectionFactory)context.lookup("java:/jms/birt_connectionFactory");
        Queue queue = (Queue)context.lookup("java:/jms/birt_queue");

        try(JMSContext jmsContext = factory.createContext("guest", "guest")) {

            JMSProducer producerPDF = jmsContext.createProducer();

            String message = "Hello distant world!";
            producerPDF.send(queue, message);
            System.out.println("PDF sender: " + message);
        }
    }
}

Class MDB receiving the message:

@MessageDriven(activationConfig = {
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
    @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "java:/jms/birt_queue"),
    @ActivationConfigProperty(propertyName = "connectionFactoryLookup", propertyValue = "java:/jms/birt_connectionFactory"),
    @ActivationConfigProperty(propertyName = "user", propertyValue = "guest"),
    @ActivationConfigProperty(propertyName = "password", propertyValue = "guest"),
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "7"),
    @ActivationConfigProperty(propertyName = "connectionParameters", propertyValue = "host=127.0.0.1;port=8180")
})
public class PDFQueueReceiver implements MessageListener {

    @Override
    public void onMessage(Message message) {

        TextMessage textMessage = (TextMessage)message;

        try {      
            System.out.println("Remote PDF receiver: " + textMessage.getText());
        }
        catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

Jboss client server standalone.xml

<subsystem xmlns="urn:jboss:domain:messaging-activemq:2.0">
    <server name="default">
        <security-setting name="#">
            <role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
        </security-setting>
        <address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
        <http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/>
        <http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
            <param name="batch-delay" value="50"/>
        </http-connector>
        <in-vm-connector name="in-vm" server-id="0">
            <param name="buffer-pooling" value="false"/>
        </in-vm-connector>
        <http-acceptor name="http-acceptor" http-listener="default"/>
        <http-acceptor name="http-acceptor-throughput" http-listener="default">
            <param name="batch-delay" value="50"/>
            <param name="direct-deliver" value="false"/>
        </http-acceptor>
        <in-vm-acceptor name="in-vm" server-id="0">
            <param name="buffer-pooling" value="false"/>
        </in-vm-acceptor>
        <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
        <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>

        <jms-queue name="birt_queue" entries="java:/jms/birt_queue" durable="false"/>

        <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/>
        <connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>

        <connection-factory name="birt_connectionFactory" entries="java:/jms/birt_connectionFactory" connectors="http-connector"/>
        <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>
    </server>
</subsystem>
  • tried switching connectionParameters to the server ip instead of 127.0.0.1 ?

  • @André, I am doing the tests in two instances of Jboss on my local machine running on different doors, so I put 127.0.0.1. Anyway, I just put the real machine IP to test and it didn’t work.

  • 1

    I saw that you did not create a remote connector, you will need, follow an example link http://www.mastertheboss.com/jboss-server/jboss-jms/connecting-to-an-external-wildfly-jms-server

  • @André, thanks for the indication, she helped me as a starting point to reach a solution.

1 answer

1


Follows the resolution of the problem in question.

Heed: this solution does not take into account important factors for a project in production, such as security, better architecture, balancing, etc.

First step: server (A) configuration that will generate messages in your local queue:

In the archive standalone.xml of the server that will produce the messages in your local queue should be created:

  • A socket-binding to provide a gateway for the remote consumer of messages.
  • A remote-acceptorof the queue system connected to the socket-binding created for the queue to be published.
  • A jms-queue(local queue) that will receive the messages. Important: to be public, the queue name must start with java:jboss/exported/

standalone.xml of the server containing the queue:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:2.0">
    <server name="default">
        ...
        <remote-acceptor name="birt-messaging-acceptor" socket-binding="birt-messaging"/>
        ...
        <jms-queue name="birt_queue" entries="java:jboss/exported/jms/queue/birt_queue" durable="false"/>
        ...
        </server>
</subsystem>
...
<socket-binding-group name="standard-sockets" default-interface="public">
    ...
    <socket-binding name="birt-messaging" port="4751"/>
    ...
</socket-binding-group>

Step 2: Server configuration (B) that will consume messages remotely through a MessageDrivenBean:

In the archive standalone.xml of the server that will consume messages from the remote queue should be created:

  • A outbound-socket-binding which specifies the address of the remote server.
  • A remote-connector of the queue system connected to the outbound-socket-binding.
  • A connection-factory connected to the remote-connector, which will be used by MessageDrivenBean.
  • A jms-queue with the same name as the remote queue, which will serve as a front.

standalone.xml of the server containing the MessageDrivenBean that will consume the remote queue:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:2.0">
    <server name="default">
        ...
        <remote-connector name="birt-connector" socket-binding="birt-messaging"/>
        ...
        <jms-queue name="birt_queue" entries="java:jboss/exported/jms/queue/birt_queue" durable="false"/>
        ...
        <connection-factory name="BirtConnectionFactory" entries="java:jboss/exported/jms/BirtConnectionFactory" connectors="birt-connector"/>
    </server>
</subsystem>
...
<socket-binding-group name="standard-sockets" default-interface="public">
    ...
    <outbound-socket-binding name="birt-messaging">
        <remote-destination host="localhost" port="4751"/>
    </outbound-socket-binding>
</socket-binding-group>

Step 3: Create the classes that will write in the queue and consume queued messages.

EJB class installed on the Server(A) that writes messages in the queue:

@Stateless
public class ManagerService {

    @Inject
    private JMSContext jmsContext;

    @Resource(lookup = "java:jboss/exported/jms/queue/birt_queue")
    private Queue queue;

    public void writeQueue() {

        JMSProducer producerPDF = jmsContext.createProducer();
        String message = "Hello distant world!";
        producerPDF.send(queue, message);
        System.out.println("PDF sender: " + message);
    }
}

MDB class installed on the server(B) that consumes messages from the remote queue:

@MessageDriven(name = "PDFQueueReceiver", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/queue/birt_queue"),
@ActivationConfigProperty(propertyName = "connectionFactoryLookup", propertyValue = "java:jboss/exported/jms/BirtConnectionFactory"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "user", propertyValue = "guest"),
@ActivationConfigProperty(propertyName = "password",propertyValue = "guest")
})
public class PDFQueueReceiver implements MessageListener {

    @Override
    public void onMessage(Message message) {

        TextMessage textMessage = (TextMessage)message;
        try {
            System.out.println("Remote PDF receiver: " + textMessage.getText());
        }
        catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.