IBM MQ als Entwickler-Instanz

ibm-mq-title

Und wieder mal ein Projekt mit asynchroner Kommunikation über IBM MQ hieß es früher nicht schon mal WebSphereMQ oder MQ Series? Nun gut, die Welt dreht sich weiter. Ein beständiger Faktor ist die große Bedeutung von Message-Queues, um Anwendungen voneinander zu separieren. Eine Entwickler-Instanz steht temporär der Entwicklung nicht zur Verfügung: Hier müssen erst noch die Berechtigungen geklärt werden. Kein Beinbruch  mein Entwicklerrechner ist gut ausgestattet und IBM bietet ein Docker-Image an!

IBM MQ als Container starten

Um alles aus einem Hause zu haben, installiere ich eine virtuelle Maschine mit RedHat8 und darauf das Podman-Paket. Schon kann es losgehen.

Listing 1: docker  Image für IBM MQ über Docker laden

[root@localhost ~]# docker pull ibmcom/mq 

Listing 2: docker  Listing zeigt das heruntergeladene Image

[root@localhost ~]# docker image ls
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
REPOSITORY           TAG     IMAGE ID      CREATED       SIZE
…
docker.io/ibmcom/mq  latest  3545f67ca057  5 weeks ago   952 MB
 

Beim Start des Images sind einige Parameter mitzugeben.

Listing 3: docker  Start von IBM MQ

[root@localhost ~]# docker run  --log-driver=journald  --env LICENSE=accept    --env MQ_QMGR_NAME=QM1    --publish 1414:1414    --publish 9443:9443  docker.io/ibmcom/mq 

Ich starte das Image in einem Terminalfenster  so kann ich mir problemlos die Log-Meldungen ansehen. Ich habe durch die Umgebungsvariablen beim Start des Containers definiert, dass der Queue-Manager QM1 heißt und der Connection-Port wie gewohnt  1414 ist.

MQ-Konfiguration ermitteln

Was kann ich mit dem Standard-Image anfangen? Dazu muss ich erst einmal ein wenig MQ-Administration ergoogeln. Ein Universal (?)-Werkzeug ist wohl die MQ-Service-Konsole. Also verbinde ich mich mit dem Container. Dazu ermittle ich als erstes die CONTAINER ID.

Listing 4: docker  Starten eines Prozesses im MQ-Container

[root@localhost MY_MQ2]# docker ps
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
CONTAINER ID  IMAGE                       COMMAND  CREATED        STATUS            PORTS                   NAMES
d63194a782c9  docker.io/ibmcom/mq:latest           8 minutes ago  Up 8 minutes ago  0.0.0.0:1414->1414/tcp  pedantic_curran
[root@localhost MY_MQ2]# docker exec -it d63194a782c9 bash
 

In der bash dann in das Verzeichnis /opt/mqm/bin wechseln und die MQ-Service-Konsole starten.

Listing 5: bash  Starten der MQ-Service-Konsole

bash-4.4$ cd /opt/mqm/bin
bash-4.4$ ./runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2020.
Starting MQSC for queue manager QM1.
 

Nun gehe ich auf die Suche nach der bereitgestellten Konfiguration. Dabei suche ich nach brauchbaren Informationen zu den Parametern, die ich für eine Client-Verbindung zum Queue-Manager benötige. Als Erstes kommt mir der Channel in den Sinn. Ich verstehe unter dem Channel einen Verbindungskanal also in meinem Fall für die Netzwerkverbindung zwischen Client und Server. Das Programm runmqsc starte ich mit dem Namen des Queue-Managers in der Erwartung, dass alle Angaben sich genau auf diesen Queue-Manager beziehen.

Listing 6: runmqsc Auflisten aller vorhandenen Channel

bash-4.4$ ./runmqsc QM1
5724-H72 (C) Copyright IBM Corp. 1994, 2020.
Starting MQSC for queue manager QM1.


display channel(*)
     1 : display channel(*)
AMQ8414I: Display Channel details.
   CHANNEL(DEV.ADMIN.SVRCONN)              CHLTYPE(SVRCONN)
AMQ8414I: Display Channel details.
   CHANNEL(DEV.APP.SVRCONN)                CHLTYPE(SVRCONN)
…
 

Unter den vielen eingerichteten Channels identifiziere ich zwei, die mir bekannt vorkommen. DEV.APP.SVRCONN wird in den Beispielanwendungen von IBM für die Client-Verbindung verwendet. Gut  dann benötige ich noch eine Queue.

Listing 7: runmqsc Auflistung der Server-Queues

display queue(*)
     2 : display queue(*)
AMQ8409I: Display Queue details.
   QUEUE(DEV.DEAD.LETTER.QUEUE)            TYPE(QLOCAL)
AMQ8409I: Display Queue details.
   QUEUE(DEV.QUEUE.1)                      TYPE(QLOCAL)
AMQ8409I: Display Queue details.
   QUEUE(DEV.QUEUE.2)                      TYPE(QLOCAL)
AMQ8409I: Display Queue details.
   QUEUE(DEV.QUEUE.3)                      TYPE(QLOCAL)
…
 

Die Vielzahl der eingerichteten Queues überrascht mich; dass eine Dead-Letter-Queue mit dem Namen DEV.DEAD.LETTER.QUEUE eingerichtet ist, finde ich gut so etwas brauche ich auf jeden Fall. Die Queue DEV.QUEUE.1 sieht so aus, als könnte ich die für einen Test verwenden. Vielleicht ist ja schon alles paletti und ich kann direkt loslegen.

Testprogramm ausführen

Auf der Seite https://developer.ibm.com/components/ibm-mq/tutorials/mq-develop-mq-jms/ finde ich einen Link zur Klasse JmsPutGet. Darin sind auch die Parameter APP_USER und APP_PASSWORD anzupassen. Die lasse ich erst einmal leer  und es funktioniert!

Listing 8: JMSPutGet.java  Nachrichten können eingestellt und ermittelt werden

Sent message:

  JMSMessage class: jms_text
  JMSType:          null
  JMSDeliveryMode:  2
  JMSDeliveryDelay: 0
  JMSDeliveryTime:  1598159282221
  JMSExpiration:    0
  JMSPriority:      4
  JMSMessageID:     ID:414d5120514d31202020202020202020b809415f021f3224
  JMSTimestamp:     1598159282221
  JMSCorrelationID: null
  JMSDestination:   queue:///DEV.QUEUE.1
  JMSReplyTo:       null
  JMSRedelivered:   false
    JMSXAppID: JmsPutGet (JMS)             
    JMSXDeliveryCount: 0
    JMSXUserID: app         
    JMS_IBM_PutApplType: 28
    JMS_IBM_PutDate: 20200822
    JMS_IBM_PutTime: 15541531
Your lucky number today is 184

Received message:
Your lucky number today is 184
SUCCESS
 

Nachspann

Ganz ehrlich: Dargestellt habe ich nur die Zusammenfassung von ungefähr acht Stunden Arbeit. Ich konnte mir nicht vorstellen, dass der Zugriff auf MQ ohne User/Kennwort möglich ist also habe ich erst mal root als Application-User angegeben.

Listing 9: JMSPutGet.java - Verbindungsfehler wenn ich root als AppUser angebe

Überprüfen Sie, ob der angegebene Benutzername und das angegebene Kennwort für den Warteschlangenmanager richtig sind, zu dem eine Verbindung hergestellt wird.  Weitere Informationen erhalten Sie in den Fehlerprotokollen des Warteschlangenmanagers und im Abschnitt IBM MQ schützen im IBM Knowledge Center. 
	at com.ibm.msg.client.jms.DetailedJMSSecurityException.getUnchecked(DetailedJMSSecurityException.java:270)
	at com.ibm.msg.client.jms.internal.JmsErrorUtils.convertJMSException(JmsErrorUtils.java:173)
	at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createContext(JmsConnectionFactoryImpl.java:515)
	at de.ordix.sk.jms.IbmJmsExample.main(IbmJmsExample.java:75)
Caused by: com.ibm.mq.MQException: JMSCMQ0001: Der IBM MQ-Aufruf ist mit Beendigungscode '2' ('MQCC_FAILED') und Ursache '2035' ('MQRC_NOT_AUTHORIZED') fehlgeschlagen.
	at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
 

Auf der Standardausgabe des Docker-Images lese ich für diesen Fall.

Listing 10: Ausgabe des IBM MQ Docker-Containers wenn ich root als AppUser angebe

2020-08-22T16:17:29.799Z AMQ5534E: User ID 'root' authentication failed [CommentInsert1(root), CommentInsert2(JmsPutGet (JMS)), CommentInsert3(Pipe returned 2035 [FAILED])]
2020-08-22T16:17:29.799Z AMQ5542I: The failed authentication check was caused by the queue manager CONNAUTH CHCKCLNT(REQDADM) configuration. [CommentInsert1(root), CommentInsert2(DEV.AUTHINFO), CommentInsert3(CHCKCLNT(REQDADM))]
 

Danach bin ich mit der Dokumentation von MQ, Startpunkt https://www.ibm.com/support/knowledgecenter/de/SSFKSJ_9.0.0/com.ibm.mq.con.doc/q114495_.html auf die Reise gegangen und habe mich durchgewurschtelt, bis ich einen autorisierten Zugriff auf meine MQ bekommen habe…

By accepting you will be accessing a service provided by a third-party external to https://blog.ordix.de/