From 3c13b5b10dd0cd4c67bf8a6d53ecb04b9041b411 Mon Sep 17 00:00:00 2001 From: Hannah-Jones997 Date: Thu, 23 Oct 2025 14:05:33 +0100 Subject: [PATCH] Added the java samples --- Java-MQ/README.md | 143 ++++++++++++++++++ Java-MQ/dependency-reduced-pom.xml | 48 ++++++ Java-MQ/env.json | 48 ++++++ Java-MQ/pom.xml | 88 +++++++++++ .../ibm/mq/samples/java/BasicConsumer.java | 89 +++++++++++ .../com/ibm/mq/samples/java/BasicGet.java | 52 +++++++ .../ibm/mq/samples/java/BasicMQFunctions.java | 118 +++++++++++++++ .../ibm/mq/samples/java/BasicProducer.java | 95 ++++++++++++ .../com/ibm/mq/samples/java/BasicPub.java | 56 +++++++ .../com/ibm/mq/samples/java/BasicPut.java | 55 +++++++ .../com/ibm/mq/samples/java/BasicRequest.java | 76 ++++++++++ .../ibm/mq/samples/java/BasicResponse.java | 93 ++++++++++++ .../com/ibm/mq/samples/java/BasicSub.java | 50 ++++++ .../com/ibm/mq/samples/java/MQDetails.java | 101 +++++++++++++ .../ibm/mq/samples/java/SampleEnvSetter.java | 108 +++++++++++++ Java-MQ/target/maven-archiver/pom.properties | 3 + .../compile/default-compile/createdFiles.lst | 11 ++ .../compile/default-compile/inputFiles.lst | 11 ++ 18 files changed, 1245 insertions(+) create mode 100644 Java-MQ/README.md create mode 100644 Java-MQ/dependency-reduced-pom.xml create mode 100644 Java-MQ/env.json create mode 100644 Java-MQ/pom.xml create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicConsumer.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicGet.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicMQFunctions.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicProducer.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPub.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPut.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicRequest.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicResponse.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicSub.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/MQDetails.java create mode 100644 Java-MQ/src/main/java/com/ibm/mq/samples/java/SampleEnvSetter.java create mode 100644 Java-MQ/target/maven-archiver/pom.properties create mode 100644 Java-MQ/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 Java-MQ/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst diff --git a/Java-MQ/README.md b/Java-MQ/README.md new file mode 100644 index 00000000..5d48adb8 --- /dev/null +++ b/Java-MQ/README.md @@ -0,0 +1,143 @@ +# IBM Java-MQ Samples + +This project provides a set of base Java samples for interacting with IBM MQ using the IBM MQ classes for Java (non-JMS). These include basic examples for put/get, publish/subscribe, and request/response messaging patterns. + +## Samples Included + +Each sample is located under: + +``` +src/main/java/com/ibm/mq/samples/java/ +``` + +- `BasicPut.java` – Puts a message onto a queue +- `BasicGet.java` – Gets a message from a queue +- `BasicPub.java` – Publishes a message to a queue (persisted publish) +- `BasicSub.java` – Subscribes and receives messages from a queue +- `BasicRequest.java` – Sends a message with a dynamic reply-to queue +- `BasicResponse.java` – Responds to requests received from a queue +- `BasicProducer.java` – Produces a message to a queue (used by request wrappers) +- `BasicConsumer.java` – Consumes a message from a queue (used by request/response logic) +- `MQDetails.java` – POJO to hold MQ connection configuration +- `SampleEnvSetter.java` – Utility to parse `env.json` and load MQ endpoint configurations +- Wrapper Classes (used internally for iterating over endpoints): + - `BasicPutWrapper.java` + - `BasicGetWrapper.java` + - `BasicPubWrapper.java` + - `BasicSubWrapper.java` + - `BasicRequestWrapper.java` + - `BasicResponseWrapper.java` + +> **Note**: Wrapper classes are utility helpers and should not be run directly. +## Prerequisites + +- Java 8 or higher +- Apache Maven +- IBM MQ installed and running (locally or remotely) + +## Project Setup + +This is a standard Maven project. All dependencies and build instructions are managed through `pom.xml`. + +### Building the Project + +To build the project and download dependencies: + +```bash +mvn clean package +``` + +## Running the Samples + +Ensure that your environment configuration file (`env.json`) is properly set up. + +## Using a CCDT File + +Instead of manually specifying connection parameters in `env.json`, you can use a **Client Channel Definition Table (CCDT)** JSON file to define connection configurations. This is useful when connecting to IBM MQ instances in cloud or enterprise environments. + +Set the environment variable `MQCCDTURL` to point to the CCDT file: + +```bash +export MQCCDTURL=file:/absolute/path/to/ccdt.json +``` + +> **Note (Windows):** Use `set` instead of `export`: +> +> ```cmd +> set MQCCDTURL=file:C:\path\to\ccdt.json +> ``` +The sample will detect `MQCCDTURL` and automatically use it for connection settings. When `MQCCDTURL` is set and starts with `file://`, the program prioritizes CCDT-based configuration and skips `host`, `channel`, and `port` in `env.json`. +Make sure your CCDT file defines the appropriate connection information such as **channel name**, **queue manager**, and **connection name list**. +## Run Instructions +All samples should be run using the following format: +```bash +mvn exec:java \ + -Dexec.mainClass="com.ibm.mq.samples.java." \ + -Dexec.args="-Dcom.ibm.mq.cfg.jmqiDisableAsyncThreads=true" \ + -Dexec.jvmArgs="-DENV_FILE=./env.json" +``` +### Put +The number at the end of args is the number of messages you want to put to the queue, to change the number of message you put, simply change the number at the end of the argument. + +```bash +mvn exec:java \ + -Dexec.mainClass="com.ibm.mq.samples.java.BasicPut" \ + -Dexec.args="-Dcom.ibm.mq.cfg.jmqiDisableAsyncThreads=true 5" \ + -Dexec.jvmArgs="-DENV_FILE=./env.json" +``` +### Get +The number at the end of args is the number of messages you want to get from the queue, to change the number of message you get, simply change the number at the end of the argument. + +```bash +mvn exec:java \ + -Dexec.mainClass="com.ibm.mq.samples.java.BasicGet" \ + -Dexec.args="-Dcom.ibm.mq.cfg.jmqiDisableAsyncThreads=true 5" \ + -Dexec.jvmArgs="-DENV_FILE=./env.json" +``` + +### Publish/Subscribe + +**First terminal (subscriber):** + +```bash +mvn exec:java \ + -Dexec.mainClass="com.ibm.mq.samples.java.BasicSub" \ + -Dexec.args="-Dcom.ibm.mq.cfg.jmqiDisableAsyncThreads=true" \ + -Dexec.jvmArgs="-DENV_FILE=./env.json" +``` + +**Second terminal (publisher):** + +```bash +mvn exec:java \ + -Dexec.mainClass="com.ibm.mq.samples.java.BasicPub" \ + -Dexec.args="-Dcom.ibm.mq.cfg.jmqiDisableAsyncThreads=true" \ + -Dexec.jvmArgs="-DENV_FILE=./env.json" +``` + +### Request/Response + +**First terminal (response):** + +```bash +mvn exec:java \ + -Dexec.mainClass="com.ibm.mq.samples.java.BasicResponse" \ + -Dexec.args="-Dcom.ibm.mq.cfg.jmqiDisableAsyncThreads=true" \ + -Dexec.jvmArgs="-DENV_FILE=./env.json" +``` + +**Second terminal (request):** + +```bash +mvn exec:java \ + -Dexec.mainClass="com.ibm.mq.samples.java.BasicRequest" \ + -Dexec.args="-Dcom.ibm.mq.cfg.jmqiDisableAsyncThreads=true" \ + -Dexec.jvmArgs="-DENV_FILE=./env.json" +``` + +## Notes + +- The environment can be configured using either `env.json` or a CCDT file via the `MQCCDTURL` environment variable. +- Samples like `BasicResponse` and `BasicSub` are long-running and wait for messages until terminated or a timeout occurs. +- **Wrapper classes** are designed to iterate over all endpoints in `env.json`, but are not meant to be executed directly from the command line. +- Make sure all relevant queues and topics are pre-created in your IBM MQ queue manager. \ No newline at end of file diff --git a/Java-MQ/dependency-reduced-pom.xml b/Java-MQ/dependency-reduced-pom.xml new file mode 100644 index 00000000..349f96ce --- /dev/null +++ b/Java-MQ/dependency-reduced-pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + com.ibm.mq.samples + base-mq-java + mq-dev-patterns + 1.0.0 + https://github.com/ibm-messaging/mq-dev-patterns/ + + + + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + com.ibm.mq.samples.jms.BasicSampleDriver + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + + 1.8 + true + 1.8 + UTF-8 + + diff --git a/Java-MQ/env.json b/Java-MQ/env.json new file mode 100644 index 00000000..a58cb19c --- /dev/null +++ b/Java-MQ/env.json @@ -0,0 +1,48 @@ +{ + "MQ_ENDPOINTS": [{ + "HOST": "127.0.0.1", + "PORT": "1415", + "CHANNEL": "DEV.APP.SVRCONN", + "QMGR": "*QM1TLS", + "APP_USER": "app", + "APP_PASSWORD": "passw0rd", + "QUEUE_NAME": "DEV.QUEUE.1", + "BACKOUT_QUEUE": "DEV.QUEUE.2", + "MODEL_QUEUE_NAME": "DEV.APP.MODEL.QUEUE", + "DYNAMIC_QUEUE_PREFIX": "APP.REPLIES.*", + "TOPIC_NAME": "dev/", + "CIPHER": "TLS_RSA_WITH_AES_128_CBC_SHA256", + "CIPHER_SUITE": "TLS_RSA_WITH_AES_128_CBC_SHA256", + "KEY_REPOSITORY": "../keys/clientkey" + },{ + "HOST": "127.0.0.1", + "PORT": "1414", + "CHANNEL": "DEV.APP.SVRCONN", + "QMGR": "*QMGroupA", + "APP_USER": "app", + "APP_PASSWORD": "passw0rd", + "QUEUE_NAME": "DEV.QUEUE.1", + "BACKOUT_QUEUE": "DEV.QUEUE.2", + "MODEL_QUEUE_NAME": "DEV.APP.MODEL.QUEUE", + "DYNAMIC_QUEUE_PREFIX": "APP.REPLIES.*", + "TOPIC_NAME": "dev/" + },{ + "HOST": "127.0.0.1", + "PORT": "1416", + "CHANNEL": "DEV.APP.SVRCONN", + "QMGR": "*QMGroupB", + "APP_USER": "app", + "APP_PASSWORD": "passw0rd", + "QUEUE_NAME": "DEV.QUEUE.1", + "BACKOUT_QUEUE": "DEV.QUEUE.2", + "MODEL_QUEUE_NAME": "DEV.APP.MODEL.QUEUE", + "DYNAMIC_QUEUE_PREFIX": "APP.REPLIES.*", + "TOPIC_NAME": "dev/" + }], + "JWT_ISSUER" : { + "JWT_TOKEN_ENDPOINT":"https:///realms/master/protocol/openid-connect/token", + "JWT_TOKEN_USERNAME":"app", + "JWT_TOKEN_PWD":"passw0rd", + "JWT_TOKEN_CLIENTID":"admin-cli" + } +} \ No newline at end of file diff --git a/Java-MQ/pom.xml b/Java-MQ/pom.xml new file mode 100644 index 00000000..e7e1f891 --- /dev/null +++ b/Java-MQ/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + com.ibm.mq.samples + base-mq-java + 1.0.0 + jar + + mq-dev-patterns + https://github.com/ibm-messaging/mq-dev-patterns/ + + + UTF-8 + 1.8 + 1.8 + true + + + + + + com.ibm.mq + com.ibm.mq.allclient + 9.4.3.0 + + + + + org.json + json + 20240303 + + + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + com.ibm.mq.samples.jms.BasicSampleDriver + + + + + *:* + + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + + + + + + + + + + \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicConsumer.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicConsumer.java new file mode 100644 index 00000000..402eff70 --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicConsumer.java @@ -0,0 +1,89 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import java.io.IOException; +import java.util.Hashtable; + +import com.ibm.mq.MQDestination; +import com.ibm.mq.MQException; +import com.ibm.mq.MQGetMessageOptions; +import com.ibm.mq.MQMessage; +import com.ibm.mq.MQQueue; +import com.ibm.mq.MQTopic; +import com.ibm.mq.constants.MQConstants; + +public class BasicConsumer { + + public static final String CONSUMER_GET = "queue"; + public static final String CONSUMER_SUB = "topic"; + public static final String CONSUMER_REQUEST = "model_queue"; + + public Boolean getMessage(MQDetails details, Hashtable props, MQDestination destination, String mode) { + + MQMessage msg = new MQMessage(); + MQGetMessageOptions gmo = new MQGetMessageOptions(); + + switch (mode) { + case CONSUMER_GET: + gmo.options = MQConstants.MQGMO_NO_WAIT | + MQConstants.MQGMO_CONVERT | + MQConstants.MQGMO_FAIL_IF_QUIESCING; + break; + case CONSUMER_SUB: + gmo.options = MQConstants.MQGMO_NO_SYNCPOINT | + MQConstants.MQGMO_WAIT | + MQConstants.MQGMO_CONVERT | + MQConstants.MQGMO_FAIL_IF_QUIESCING; + gmo.waitInterval = MQConstants.MQWI_UNLIMITED; + break; + case CONSUMER_REQUEST: + gmo.options = MQConstants.MQGMO_WAIT | MQConstants.MQGMO_CONVERT; + gmo.waitInterval = 10000; + break; + default: + break; + } + + try { + // Get message + if (destination instanceof MQQueue) { + ((MQQueue) destination).get(msg, gmo); + } else if (destination instanceof MQTopic) { + ((MQTopic) destination).get(msg, gmo); + } else { + System.err.println("Unsupported MQDestination type."); + return false; + } + + String str = msg.readStringOfByteLength(msg.getDataLength()); + System.out.println("Received message: " + str); + } catch (MQException mqe) { + if (mqe.reasonCode == MQConstants.MQRC_NO_MSG_AVAILABLE) { + System.out.println("No more messages."); + return false; + } else { + System.err.println("Error retrieving message: " + mqe); + return false; + } + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicGet.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicGet.java new file mode 100644 index 00000000..67b2d3e4 --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicGet.java @@ -0,0 +1,52 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import com.ibm.mq.MQQueue; +import com.ibm.mq.constants.MQConstants; + +public class BasicGet { + + public static final int DEFAULTGETVALUE = 1; + + public static void main(String[] args) { + + BasicMQFunctions mqFunctions = new BasicMQFunctions(); + BasicConsumer basicConsumer = new BasicConsumer(); + + // How many messages to get from queue, if not specified use default value + int count = (args.length > 1) ? Integer.parseInt(args[1]) : DEFAULTGETVALUE; + + // Connect, get messages, disconnect + try { + int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF; + MQQueue queue = mqFunctions.connectQueue(openOptions); + MQDetails details = mqFunctions.getFirstDetails(); + + while (count > 0) { + basicConsumer.getMessage(details, mqFunctions.getProps(), queue, BasicConsumer.CONSUMER_GET); + count--; + } + + } catch (com.ibm.mq.MQException e) { + System.out.println("Could not connect to queue manager — reason code: " + e.getReason()); + } catch (Exception e) { + System.out.println("Unexpected error for endpoint: " + e.getMessage()); + } finally { + mqFunctions.close(); + } + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicMQFunctions.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicMQFunctions.java new file mode 100644 index 00000000..7570020a --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicMQFunctions.java @@ -0,0 +1,118 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import java.util.Hashtable; + +import com.ibm.mq.MQException; +import com.ibm.mq.MQQueue; +import com.ibm.mq.MQQueueManager; +import com.ibm.mq.MQTopic; +import com.ibm.mq.constants.MQConstants; + +public class BasicMQFunctions { + + MQDetails firstDetails = null; + MQQueueManager qMgr = null; + MQQueue queue = null; + SampleEnvSetter envSetter = null; + Hashtable props = new Hashtable<>(); + + public BasicMQFunctions() { + envSetter = new SampleEnvSetter(); + envSetter.setEnvValues(); + } + + public Hashtable buildConnection() { + + int numOfEndpoints = envSetter.getDetails().size(); + + props = envSetter.getProps().get(1); + + // Remove this env port and host + props.remove(MQConstants.HOST_NAME_PROPERTY); + props.remove(MQConstants.PORT_PROPERTY); + + // Build connection string + StringBuilder connList = new StringBuilder(); + for (int i = 0; i < numOfEndpoints; i++) { + firstDetails = envSetter.getDetails().get(i); + connList.append(firstDetails.getHOST()).append("(").append(firstDetails.getPORT()).append("),"); + } + // Remove last comma + connList.setLength(connList.length() - 1); + + // Put into properties + props.put("connectionString", connList.toString()); + + return props; + } + + public MQQueueManager connect() throws MQException { + Hashtable props = buildConnection(); + firstDetails = envSetter.getDetails().get(1); + + if (qMgr == null) { + qMgr = new MQQueueManager(firstDetails.getQMGR(), props); + System.out.println("Connected to queue manager: " + firstDetails.getQMGR()); + } + + return qMgr; + } + + public MQQueue connectQueue(int openOptions) throws MQException { + connect(); + + queue = qMgr.accessQueue(firstDetails.getQUEUE_NAME(), openOptions); + System.out.println("Queue opened: " + firstDetails.getQUEUE_NAME()); + + return queue; + } + + public MQTopic connectTopic(int topicOpenOptions, int openOptions) throws MQException { + + String topicName = "dev/"; + String topicObject = "DEV.BASE.TOPIC"; + + connect(); + + // Accessing the topic + MQTopic topic = qMgr.accessTopic(topicName, topicObject, openOptions, topicOpenOptions); + System.out.println("Connected to topic:" + topic.getName()); + return topic; + } + + public MQDetails getFirstDetails() { + return firstDetails; + } + + public Hashtable getProps() { + return props; + } + + public void close() { + try { + if (queue != null) { + queue.close(); + } + if (qMgr != null) { + qMgr.disconnect(); + } + } catch (MQException me) { + me.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicProducer.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicProducer.java new file mode 100644 index 00000000..c022cd64 --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicProducer.java @@ -0,0 +1,95 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import java.io.IOException; +import java.util.Hashtable; + +import com.ibm.mq.MQDestination; +import com.ibm.mq.MQException; +import com.ibm.mq.MQMessage; +import com.ibm.mq.MQPutMessageOptions; +import com.ibm.mq.MQQueue; +import com.ibm.mq.MQTopic; +import com.ibm.mq.constants.MQConstants; + +public class BasicProducer { + + public static final String PRODUCER_PUT = "queue"; + public static final String PRODUCER_PUBLISH = "topic"; + public static final String PRODUCER_RESPONSE = "model_queue"; + + public Boolean putMessage(MQDetails details, Hashtable props, MQDestination destination, String mode, String message, String replyToQueueName) { + + MQMessage mqMessage = new MQMessage(); + MQPutMessageOptions pmo = new MQPutMessageOptions(); + + try { + // Write the payload + mqMessage.writeString(message); + + // Set common message properties + mqMessage.format = MQConstants.MQFMT_STRING; + + switch (mode) { + case PRODUCER_PUT: + mqMessage.persistence = MQConstants.MQPER_PERSISTENT; + break; + case PRODUCER_PUBLISH: + mqMessage.persistence = MQConstants.MQPER_PERSISTENT; + pmo.options = MQConstants.MQPMO_NO_SYNCPOINT | + MQConstants.MQPMO_NEW_MSG_ID | + MQConstants.MQPMO_NEW_CORREL_ID; + break; + case PRODUCER_RESPONSE: + mqMessage.persistence = MQConstants.MQPER_NOT_PERSISTENT; + if (replyToQueueName != null && !replyToQueueName.isEmpty()) { + mqMessage.replyToQueueName = replyToQueueName; + } + break; + + default: + System.err.println("Invalid producer mode."); + return false; + } + + // Send message + if (destination instanceof MQQueue) { + ((MQQueue) destination).put(mqMessage, pmo); + } else if (destination instanceof MQTopic) { + ((MQTopic) destination).put(mqMessage, pmo); + } else { + System.err.println("Unsupported MQDestination type."); + return false; + } + + System.out.println("Message sent: " + message); + return true; + + } catch (MQException mqe) { + System.err.println("MQException during put: " + mqe.getMessage()); + return false; + + } catch (IOException ioe) { + System.err.println("IOException during put: " + ioe.getMessage()); + return false; + } + } + + void putMessage(MQQueue queue, String PRODUCER_PUT, String sampleMessage, Object object) { + throw new UnsupportedOperationException("Not supported yet."); + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPub.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPub.java new file mode 100644 index 00000000..df8afc6c --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPub.java @@ -0,0 +1,56 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import java.time.Instant; + +import com.ibm.mq.MQTopic; +import com.ibm.mq.constants.CMQC; +import com.ibm.mq.constants.MQConstants; + +/* + I think this needs to use a topic not a queue and thus needs looking at again +*/ + +public class BasicPub { + + public static void main(String[] args) { + + MQTopic topic; + + BasicProducer producer = new BasicProducer(); + BasicMQFunctions mqFunctions = new BasicMQFunctions(); + + try { + int openOptions = MQConstants.MQOO_OUTPUT | MQConstants.MQOO_FAIL_IF_QUIESCING; + int openAs = CMQC.MQTOPIC_OPEN_AS_PUBLICATION; + topic = mqFunctions.connectTopic(openOptions, openAs); + MQDetails details = mqFunctions.getFirstDetails(); + + String payload = "{\"Greeting\": \"Hello from Java publisher at " + Instant.now() + "\"}"; + + producer.putMessage(details, mqFunctions.getProps(), topic, BasicProducer.PRODUCER_PUT, payload, null); + + } catch (com.ibm.mq.MQException e) { + System.out.println("Could not connect to queue manager — reason code: " + e.getReason()); + } catch (Exception e) { + System.out.println("Unexpected error for endpoint: " + e.getMessage()); + } finally { + mqFunctions.close(); + } + System.out.println("Sample MQ PUB application ending"); + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPut.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPut.java new file mode 100644 index 00000000..322b477c --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPut.java @@ -0,0 +1,55 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import com.ibm.mq.MQQueue; +import com.ibm.mq.constants.MQConstants; + +public class BasicPut { + + public static final int DEFAULTPUTVALUE = 1; + + public static void main(String[] args) { + + BasicMQFunctions mqFunctions = new BasicMQFunctions(); + BasicProducer basicProducer = new BasicProducer(); + + String sampleMessage = "You are putting messages!"; + + // How many messages to put to queue, if not specified use default value + int count = (args.length > 0) ? Integer.parseInt(args[1]) : DEFAULTPUTVALUE; + + // Connect using the connection string + try { + int openOptions = MQConstants.MQOO_OUTPUT | MQConstants.MQOO_FAIL_IF_QUIESCING; + MQQueue queue = mqFunctions.connectQueue(openOptions); + MQDetails details = mqFunctions.getFirstDetails(); + + // Put messages on the queue + while (count > 0) { + basicProducer.putMessage(details, mqFunctions.getProps(), queue, BasicProducer.PRODUCER_PUT, sampleMessage, null); + count--; + } + } catch (com.ibm.mq.MQException e) { + System.out.println("Could not connect to queue manager — reason code: " + e.getReason()); + System.out.println(e.getMessage()); + } catch (Exception e) { + System.out.println("Unexpected error: " + e.getMessage()); + } finally { + mqFunctions.close(); + } + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicRequest.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicRequest.java new file mode 100644 index 00000000..cb9289f0 --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicRequest.java @@ -0,0 +1,76 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import java.time.Instant; + +import com.ibm.mq.MQMessage; +import com.ibm.mq.MQPutMessageOptions; +import com.ibm.mq.MQQueue; +import com.ibm.mq.MQQueueManager; +import com.ibm.mq.constants.MQConstants; + +public class BasicRequest { + + public static void main(String[] args) { + + MQQueueManager qMgr = null; + + BasicMQFunctions mqFunctions = new BasicMQFunctions(); + + try { + + int openOptions = MQConstants.MQOO_OUTPUT; + MQQueue requestQueue = mqFunctions.connectQueue(openOptions); + + MQDetails details = mqFunctions.getFirstDetails(); + + qMgr= mqFunctions.connect(); + MQQueue replyQueue = qMgr.accessQueue(details.getMODEL_QUEUE_NAME(), MQConstants.MQOO_INPUT_EXCLUSIVE, null, details.getDYNAMIC_QUEUE_PREFIX(), null); + + String dynamicReplyQueueName = replyQueue.getName(); + System.out.println("Opened dynamic reply-to queue: " + dynamicReplyQueueName); + + MQMessage request = new MQMessage(); + request.format = MQConstants.MQFMT_STRING; + request.replyToQueueName = dynamicReplyQueueName; + request.messageType = MQConstants.MQMT_REQUEST; + + String payload = "{\"Greeting\": \"Hello from Java Requester at " + Instant.now() + "\"}"; + request.writeString(payload); + + MQPutMessageOptions pmo = new MQPutMessageOptions(); + pmo.options = MQConstants.MQPMO_NO_SYNCPOINT; + + requestQueue.put(request, pmo); + System.out.println("Sent request message to queue: " + details.getQUEUE_NAME()); + System.out.println("Waiting for reply on: " + dynamicReplyQueueName); + + boolean keepReading = true; + BasicConsumer bc = new BasicConsumer(); + + while (keepReading) { + keepReading = bc.getMessage(details, mqFunctions.getProps(), replyQueue, BasicConsumer.CONSUMER_REQUEST); + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + mqFunctions.close(); + } + System.exit(0); + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicResponse.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicResponse.java new file mode 100644 index 00000000..d6e81fe0 --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicResponse.java @@ -0,0 +1,93 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import com.ibm.mq.MQException; +import com.ibm.mq.MQGetMessageOptions; +import com.ibm.mq.MQMessage; +import com.ibm.mq.MQPutMessageOptions; +import com.ibm.mq.MQQueue; +import com.ibm.mq.MQQueueManager; +import com.ibm.mq.constants.MQConstants; + +public class BasicResponse { + + public static void main(String[] args) { + + BasicMQFunctions mqFunctions = new BasicMQFunctions(); + + try { + + int openOptions = MQConstants.MQOO_INPUT_AS_Q_DEF | MQConstants.MQOO_OUTPUT | MQConstants.MQOO_INQUIRE; + MQQueue queue = mqFunctions.connectQueue(openOptions); + + boolean keepRunning = true; + + while (keepRunning) { + MQMessage requestMsg = new MQMessage(); + MQGetMessageOptions gmo = new MQGetMessageOptions(); + gmo.options = MQConstants.MQGMO_WAIT | MQConstants.MQGMO_CONVERT; + gmo.waitInterval = 10000; // wait 10 seconds + + try { + queue.get(requestMsg, gmo); + String body = requestMsg.readStringOfByteLength(requestMsg.getDataLength()); + System.out.println("Received request: " + body); + + // Get reply-to queue name + String replyToQueue = requestMsg.replyToQueueName; + if (replyToQueue == null || replyToQueue.isEmpty()) { + System.out.println("No reply-to queue specified. Skipping response."); + continue; + } + + // Create a response message + MQMessage responseMsg = new MQMessage(); + responseMsg.format = MQConstants.MQFMT_STRING; + responseMsg.messageType = MQConstants.MQMT_REPLY; + String replyPayload = "{\"Response\": \"Reply to message: " + body + "\"}"; + responseMsg.writeString(replyPayload); + + MQPutMessageOptions pmo = new MQPutMessageOptions(); + pmo.options = MQConstants.MQPMO_NO_SYNCPOINT; + + // Put the message to the dynamic reply queue + MQQueueManager qMgr = mqFunctions.connect(); + MQQueue replyQueue = qMgr.accessQueue(replyToQueue, MQConstants.MQOO_OUTPUT); + replyQueue.put(responseMsg, pmo); + replyQueue.close(); + + System.out.println("Sent reply to: " + replyToQueue); + System.out.println("Reply payload: " + replyPayload); + + } catch (MQException mqe) { + if (mqe.reasonCode == MQConstants.MQRC_NO_MSG_AVAILABLE) { + System.out.println("No more messages. Exiting..."); + keepRunning = false; + } else { + System.err.println("MQ error getting/putting message: " + mqe.getMessage()); + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + } finally { + mqFunctions.close(); + } + System.exit(0); + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicSub.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicSub.java new file mode 100644 index 00000000..145396f2 --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicSub.java @@ -0,0 +1,50 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import com.ibm.mq.MQTopic; +import com.ibm.mq.constants.CMQC; +import com.ibm.mq.constants.MQConstants; + +public class BasicSub { + + public static void main(String[] args) { + + MQTopic topic; + + BasicMQFunctions mqFunctions = new BasicMQFunctions(); + MQDetails details = mqFunctions.getFirstDetails(); + + try { + // Topic options + int topicOpenOptions = MQConstants.MQSO_CREATE | MQConstants.MQSO_NON_DURABLE; + int openAs = CMQC.MQTOPIC_OPEN_AS_SUBSCRIPTION; + topic = mqFunctions.connectTopic(topicOpenOptions, openAs); + + boolean keepReading = true; + BasicConsumer bc = new BasicConsumer(); + + bc.getMessage(details, mqFunctions.getProps(), topic, BasicConsumer.CONSUMER_SUB); + + } catch (com.ibm.mq.MQException e) { + System.out.println("Could not connect to queue manager — reason code: " + e.getReason()); + } catch (Exception e) { + System.out.println("Unexpected error for endpoint: " + e.getMessage()); + } finally { + mqFunctions.close(); + } + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/MQDetails.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/MQDetails.java new file mode 100644 index 00000000..df79c2e3 --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/MQDetails.java @@ -0,0 +1,101 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import org.json.JSONObject; + +public class MQDetails { + + private String QMGR; + private String QUEUE_NAME; + private String HOST; + private String PORT; + private String CHANNEL; + private String USER; + private String PASSWORD; + private String KEY_REPOSITORY; + private String CIPHER; + private String MODEL_QUEUE_NAME; + private String DYNAMIC_QUEUE_PREFIX; + + public MQDetails buildMQDetails(JSONObject endpoint) { + this.QMGR = endpoint.getString("QMGR"); + this.QUEUE_NAME = endpoint.getString("QUEUE_NAME"); + this.HOST = endpoint.getString("HOST"); + this.PORT = String.valueOf(endpoint.getInt("PORT")); + this.CHANNEL = endpoint.getString("CHANNEL"); + this.USER = endpoint.getString("APP_USER"); + this.PASSWORD = endpoint.getString("APP_PASSWORD"); + this.KEY_REPOSITORY = endpoint.optString("KEY_REPOSITORY", ""); + this.CIPHER = endpoint.optString("CIPHER", ""); + this.MODEL_QUEUE_NAME = endpoint.optString("MODEL_QUEUE_NAME", ""); + this.DYNAMIC_QUEUE_PREFIX = endpoint.optString("DYNAMIC_QUEUE_PREFIX", ""); + + return this; + } + + public String getQMGR() { + return QMGR; + } + + public String getQUEUE_NAME() { + return QUEUE_NAME; + } + + public String getHOST() { + return HOST; + } + + public String getPORT() { + return PORT; + } + + public String getCHANNEL() { + return CHANNEL; + } + + public String getUSER() { + return USER; + } + + public String getPASSWORD() { + return PASSWORD; + } + + public String getKEY_REPOSITORY() { + return KEY_REPOSITORY; + } + + public String getCIPHER() { + return CIPHER; + } + + public String getMODEL_QUEUE_NAME() { + return MODEL_QUEUE_NAME; + } + + public String getDYNAMIC_QUEUE_PREFIX() { + return DYNAMIC_QUEUE_PREFIX; + } + + @Override + public String toString() { + return "MQDetails [QMGR=" + QMGR + ", QUEUE_NAME=" + QUEUE_NAME + ", HOST=" + HOST + ", PORT=" + PORT + + ", CHANNEL=" + CHANNEL + ", USER=" + USER + ", PASSWORD=" + PASSWORD + ", KEY_REPOSITORY=" + + KEY_REPOSITORY + ", CIPHER=" + CIPHER + ", MODEL_QUEUE_NAME=" + MODEL_QUEUE_NAME + + ", DYNAMIC_QUEUE_PREFIX=" + DYNAMIC_QUEUE_PREFIX + "]"; + } +} \ No newline at end of file diff --git a/Java-MQ/src/main/java/com/ibm/mq/samples/java/SampleEnvSetter.java b/Java-MQ/src/main/java/com/ibm/mq/samples/java/SampleEnvSetter.java new file mode 100644 index 00000000..0e865d0a --- /dev/null +++ b/Java-MQ/src/main/java/com/ibm/mq/samples/java/SampleEnvSetter.java @@ -0,0 +1,108 @@ +/* +* (c) Copyright IBM Corporation 2025 +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package com.ibm.mq.samples.java; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import org.json.JSONArray; +import org.json.JSONObject; + +import com.ibm.mq.constants.MQConstants; + +public class SampleEnvSetter { + + private JSONArray endpoints; + private List details; + private List> props; + + public SampleEnvSetter() { + this.details = new ArrayList<>(); + this.props = new ArrayList<>(); + } + + public void setEnvValues() { + + loadEnv("env.json"); + + for (int i = 0; i < endpoints.length(); i++) { + System.out.println("Processing endpoint " + i); + JSONObject point = endpoints.getJSONObject(i); + MQDetails details = new MQDetails(); + this.details.add(details.buildMQDetails(point)); + this.props.add(getEnvValues(details)); + } + + System.out.println("Sample MQ GET application ending"); + + } + + private void loadEnv(String path) { + try { + String content = new String(Files.readAllBytes(Paths.get(path))); + JSONObject env = new JSONObject(content); + this.endpoints = env.getJSONArray("MQ_ENDPOINTS"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private Hashtable getEnvValues(MQDetails details) { + + System.out.println(details); + + Hashtable props = new Hashtable<>(); + String ccdtUrl = System.getenv("MQCCDTURL"); + + if (ccdtUrl != null && ccdtUrl.startsWith("file://")) { + String ccdtPath = ccdtUrl.replace("file://", ""); + System.setProperty("MQCCDTURL", ccdtPath); + System.out.println("Using CCDT at: " + ccdtPath); + } else { + props.put(MQConstants.HOST_NAME_PROPERTY, details.getHOST()); + props.put(MQConstants.PORT_PROPERTY, Integer.parseInt(details.getPORT())); + props.put(MQConstants.CHANNEL_PROPERTY, details.getCHANNEL()); + } + + props.put(MQConstants.USER_ID_PROPERTY, details.getUSER()); + props.put(MQConstants.PASSWORD_PROPERTY, details.getPASSWORD()); + props.put(MQConstants.TRANSPORT_PROPERTY, MQConstants.TRANSPORT_MQSERIES_CLIENT); + + if (!details.getKEY_REPOSITORY().isEmpty()) { + props.put(MQConstants.SSL_CIPHER_SUITE_PROPERTY, details.getCIPHER()); + System.setProperty("com.ibm.mq.ssl.keyStore", details.getKEY_REPOSITORY()); + System.setProperty("com.ibm.mq.ssl.keyStorePassword", ""); + } + return props; + } + + public List getDetails() { + return details; + } + + public List> getProps() { + return props; + } + + @Override + public String toString() { + return "SampleEnvSetter [details=" + details.size() + ", props=" + props.size() + "]"; + } + +} \ No newline at end of file diff --git a/Java-MQ/target/maven-archiver/pom.properties b/Java-MQ/target/maven-archiver/pom.properties new file mode 100644 index 00000000..0e2feb47 --- /dev/null +++ b/Java-MQ/target/maven-archiver/pom.properties @@ -0,0 +1,3 @@ +artifactId=base-mq-java +groupId=com.ibm.mq.samples +version=1.0.0 diff --git a/Java-MQ/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/Java-MQ/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 00000000..ae95ddfe --- /dev/null +++ b/Java-MQ/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,11 @@ +com/ibm/mq/samples/java/BasicPub.class +com/ibm/mq/samples/java/BasicGet.class +com/ibm/mq/samples/java/BasicProducer.class +com/ibm/mq/samples/java/BasicResponse.class +com/ibm/mq/samples/java/BasicSub.class +com/ibm/mq/samples/java/SampleEnvSetter.class +com/ibm/mq/samples/java/BasicRequest.class +com/ibm/mq/samples/java/BasicConsumer.class +com/ibm/mq/samples/java/BasicMQFunctions.class +com/ibm/mq/samples/java/BasicPut.class +com/ibm/mq/samples/java/MQDetails.class diff --git a/Java-MQ/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/Java-MQ/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 00000000..7854340f --- /dev/null +++ b/Java-MQ/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,11 @@ +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicConsumer.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicGet.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicMQFunctions.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicProducer.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPub.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicPut.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicRequest.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicResponse.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/BasicSub.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/MQDetails.java +/Users/hannah/mq-dev/mq-dev-patterns/Java-MQ/src/main/java/com/ibm/mq/samples/java/SampleEnvSetter.java