Как настроить STOMP Transformer для OpenMQ/Glassfish

Я написал базовый преобразователь сообщений для преобразования объектных сообщений в текстовые сообщения. Я не являюсь экспертом по Java/OpenMQ/Glassfish

Transformer прекрасно компилируется, НО теперь мне нужно настроить STOMP Bridge, чтобы использовать его... Я не могу найти в Интернете никаких примеров того, как это сделать.

Я скопировал свой StompTransformer.class в C:\glassfish3\glassfish\domains\domain1\lib\ext и все необходимые банки в: C:\glassfish3\glassfish\domains\domain1\lib\applibs (не уверен, что это правильно место)

Я добавил следующее в config.properties:

imq.bridge.admin.user=admin
imq.bridge.stomp.messageTransformer=StompTransformer
imq.bridge.admin.password=admin
imq.bridge.activelist=stomp
imq.bridge.enabled=true

Я попытался прочитать документацию: https://docs.oracle.com/cd/E19587-01/821-0027/gjdnl/index.html >>> Настройка моста JMS

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

Вот код трансформера:

import java.util.*;
import javax.jms.*;
import com.sun.messaging.bridge.service.MessageTransformer;
import com.thoughtworks.xstream.XStream;

 public class StompTransformer extends MessageTransformer <Message, Message> {

 public Message transform(Message message, 
                          boolean readOnly,
                          String charsetName,
                          String source, 
                          String target,
                          Properties properties)
                          throws Exception {

    Message m = message;
    if (source.equals(SUN_MQ)) { //from Java Message Queue to STOMP client

        if (message instanceof ObjectMessage) {

            //create a new TextMessage for message to be transformed to
            TextMessage tm = (TextMessage)createJMSMessage(JMSMessageType.TEXTMESSAGE);

            //convert message to the TextMessage
            XStream xstream = new XStream();
            tm.setText(xstream.toXML(message));
            m = tm;
        }
    }
    return m;
 }
}

person usernametaken    schedule 08.12.2014    source источник
comment
Какую версию OpenMQ вы используете?   -  person mjn    schedule 09.12.2014
comment
Вы тестировали его с автономной установкой OpenMQ вместо GlassFish 3 (GF вводит больше возможных ошибок конфигурации, в то время как автономный OpenMQ не мешает GF)   -  person mjn    schedule 09.12.2014
comment
К сожалению, у меня нет выбора. Это для интеграции с другой системой от другого поставщика (QMatic Queuing). Мне нужно захватить события очереди и обобщить их для приложения панели мониторинга, но события очереди имеют тип ObjectMessage, а мое приложение не java   -  person usernametaken    schedule 09.12.2014
comment
Я использую OpenMQ 4.5.2 и GlassFish 3.1.2 (сборка 23)   -  person usernametaken    schedule 09.12.2014


Ответы (1)


С OpenMQ 4.5.2 (работает автономно, не встроен в GlassFish) я протестировал преобразование сообщений в этом проекте.

<?xml version="1.0" encoding="UTF-8"?>
<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>com.habarisoft</groupId>
    <artifactId>OpenMQMessageTransformer</artifactId>
    <version>1.1-SNAPSHOT</version>

    <packaging>jar</packaging>

    <dependencies>       
        <dependency>
            <groupId>org.glassfish.mq</groupId>
            <artifactId>imq</artifactId>
            <version>4.5.2</version>
        </dependency>                                            
        <dependency>
            <groupId>org.glassfish.mq</groupId>
            <artifactId>jms</artifactId>
            <version>4.5.2</version>
        </dependency>        
        <dependency>
            <groupId>org.glassfish.mq</groupId>
            <artifactId>imqjmsbridge</artifactId>
            <version>4.5.2</version>
            <type>jar</type>
        </dependency>
    </dependencies>
</project>

И этот класс трансформатора:

package com.habarisoft.mqtr;

import java.util.*;
import javax.jms.*;

import com.sun.messaging.bridge.service.MessageTransformer;

public class StompTransformer extends MessageTransformer<Message, Message> {

    @Override
    public Message transform(Message message,
            boolean readOnly,
            String charsetName,
            String source,
            String target,
            Properties properties)
            throws Exception {

        System.out.println("transform ...");

        Message m = message;
        if (source.equals(SUN_MQ)) { //from Java Message Queue to STOMP client

            if (message instanceof ObjectMessage) {

                //create a new TextMessage for message to be transformed to
                TextMessage tm = (TextMessage) createJMSMessage(JMSMessageType.TEXTMESSAGE);

                tm.setText("<converted object>");
                m = tm;
            }
        }
        return m;
    }
}

Сгенерированный JAR-файл должен находиться в каталоге lib/ext вместе с другими необходимыми JAR-файлами зависимостей (обратите внимание, что это было протестировано с автономной установкой Open MQ).

и эта конфигурация брокера для моста STOMP:

imq.bridge.admin.user=admin
imq.instanceconfig.version=300
imq.bridge.stomp.messageTransformer=com.habarisoft.mqtr.StompTransformer
imq.bridge.admin.password=admin
imq.bridge.activelist=stomp
imq.bridge.enabled=true

Затем я запустил клиент STOMP, прослушивающий входящие сообщения в очереди TOOL.DEFAULT, и использовал клиент JMS для генерации объектных сообщений:

import java.util.Date;
import javax.jms.Queue;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;

public class Main {

    public static void main(String[] args) throws JMSException {

        ConnectionFactory cf = new com.sun.messaging.ConnectionFactory();

        Connection conn = cf.createConnection("admin", "admin");
        conn.start();

        Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue("TOOL.DEFAULT");
        MessageProducer producer = session.createProducer(queue);

        Date date = new Date();

        ObjectMessage msg = session.createObjectMessage(date);
        producer.send(msg);
        conn.close();

    }
}

Если клиентский код JMS отправляет объектное сообщение во время прослушивания клиентом STOMP, окно консоли, в котором запущен посредник, успешно записывает

transform ...

сообщение. Но затем он регистрирует ошибку, жалуясь на нулевой пункт назначения JMS:

Dez 10, 2014 8:04:39 AM
WARNUNG: [BSS2009]: Nachricht ID:8-192.168.56.1(ea:8a:dc:e5:15:7c)-58027-1418195
079856 kann nicht an Abonnent {98F4744E-6E12-44CC-8336-36A9BA7CDC77} ausgeliefer
t werden: JMS destination null !
javax.jms.JMSException: JMS destination null !
        at com.sun.messaging.bridge.service.stomp.StompProtocolHandler.toStompDe
stination(StompProtocolHandler.java:832)
        at com.sun.messaging.bridge.service.stomp.StompProtocolHandler.toStompFr
ameMessage(StompProtocolHandler.java:893)
        at com.sun.messaging.bridge.service.stomp.StompConnection.toStompFrameMe
ssage(StompConnection.java:438)
        at com.sun.messaging.bridge.service.stomp.StompSubscriberSession.onMessa
ge(StompSubscriberSession.java:127)
        at com.sun.messaging.jmq.jmsclient.MessageConsumerImpl.deliverAndAcknowl
edge(MessageConsumerImpl.java:358)
        at com.sun.messaging.jmq.jmsclient.MessageConsumerImpl.onMessage(Message
ConsumerImpl.java:287)
        at com.sun.messaging.jmq.jmsclient.SessionReader.deliver(SessionReader.j
ava:119)
        at com.sun.messaging.jmq.jmsclient.ConsumerReader.run(ConsumerReader.jav
a:192)
        at java.lang.Thread.run(Thread.java:745)

Dez 10, 2014 8:04:39 AM

Я не исследовал это дальше, но похоже, что для создания преобразованного сообщения требуется больше кода, чем показано в файле OpenMQ JavaDoc для преобразователя.

Но результаты тестов показывают, что трансформатор вызывается, и приведенный пример можно использовать в качестве отправной точки.


Обновлять:

Если архитектура системы находится под вашим контролем, то может быть проще вставить клиентское приложение Java (JMS) в поток сообщений, которое преобразует объектное сообщение в текстовое сообщение и повторно отправляет его в отдельный пункт назначения, который STOMP клиент потребляет.

person mjn    schedule 10.12.2014