0

I use TestContainers with ibm mq image in it. Through config I set host, port, user=app, default passw0rd, manager = QM1. I also have more custom queues and besides default DEV.QUEUE.1 - 3 ,created by container, I gotta start up mine. I found such operator like withCommand, accepting String argument, and try to set it like .withCommand("sh","-c","runmqsc QM1 | define qlocal(LQ1) | end") https://www.ibm.com/docs/en/ibm-mq/7.5?topic=75-creating-queue-called-lq1 Unfortunately, it seems not starting with it.

My full snap of code related:

 @Container
    static GenericContainer<?> mqContainer = new GenericContainer<>(DockerImageName.parse("ibmcom/mq"))
            .withEnv("LICENSE", "accept")
            .withEnv("MQ_QMGR_NAME", "QM1")
     /*       .withCommand("sh","-c","runmqsc")*/
            
            .withExposedPorts(1414)
            .withStartupTimeout(Duration.of(1, ChronoUnit.HALF_DAYS))
            .withLogConsumer(new Slf4jLogConsumer(log));
JoshMc
  • 10,239
  • 2
  • 19
  • 38
tarmogoyf
  • 298
  • 3
  • 17
  • I suppose I should enter valid command on startup time to set custom queue and grant app user needed privileges for it. – tarmogoyf Dec 27 '21 at 13:19
  • 1
    This let's you run MQSC commands at startup: https://stackoverflow.com/questions/70480034/ibm-mq-kubernetes-helm-kdb#comment124606341_70480034 – JoshMc Dec 27 '21 at 14:38
  • 1
    Your command should be more like this `.withCommand("sh","-c","echo 'define qlocal(LQ1)' | runmqsc QM1")` – JoshMc Dec 27 '21 at 14:40
  • Command does not work and container hangs forever . Writing extra script for configuring a queue seems incredibly inconvinient way of configuration. – tarmogoyf Dec 29 '21 at 08:48

2 Answers2

2

ibmcom/mq image already covers this scenario. Create a mqsc script with all custom resources. Copy this script in /etc/mq folder. All resources defined in script will be created on startup.

See Customizing the queue manager configuration for details.

Talijanac
  • 1,087
  • 9
  • 20
1

Your problem

Presumably you want .withCommand() to override the default CMD of the Dockerfile. But, since the IBM MQ Dockerfile uses an ENTRYPOINT, I would guess that, instead of overriding the command, it will be appending the parameters as arguments after the command specified in the ENTRYPOINT.
This blog explains it well (but has some mistakes): https://www.bmc.com/blogs/docker-cmd-vs-entrypoint/

It seems you understand that you need to use piping to get the "define qlocal(LQ1)" into runmqsc, but you haven't quite grasped how piping works and unfortunately what you have written is not correct, so I would recommend you find some more information on it.

A solution

You can use mqContainer.execInContainer("bash", "-c", "echo 'define qlocal(LQ1)' | runmqsc QM1") instead of the .withCommand() line. However you will need to run it after you start the container and wait until the container is up and MQ is running, which can be done by repeatedly calling mqContainer.execInContainer("chkmqready") until it has a return code of 0. Just like the tests for the container does in its Go code: https://github.com/ibm-messaging/mq-container/blob/d7c7b52492c6b1ae600bf3b8ccd9724ffd45e361/test/docker/docker_api_test_util.go#L634
There is probably a more elegant way to wait for the startup using https://www.testcontainers.org/features/startup_and_waits/ but I will leave that to you if desired.

Alternate solution

Build a personal version of the MQ container yourself. https://www.ibm.com/docs/en/ibm-mq/9.2?topic=image-building-sample-configured-mq-queue-manager

rrama
  • 214
  • 1
  • 11