Skip to content

Commit b0e2f52

Browse files
authored
Merge pull request #6 from instana/ibmmq-update-test-jar
Add source code of IBM MQ test tool
2 parents 1a97004 + 10b7069 commit b0e2f52

File tree

4 files changed

+334
-0
lines changed

4 files changed

+334
-0
lines changed

ibmmq/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,14 @@ For example, ./testMQ.sh -m qmName -a /opt/mqm/java/lib64 -q SYSTEM.ADMIN.ACCOUN
3434
{: codeblock}
3535

3636
For example, ./testMQ.sh -m qmName -h 1.2.3.4 -p 1801 -c SYSTEM.AUTO.SVRCONN -u root -z dummyPwd -q AAA
37+
38+
## Rebuild the IBM MQ connection test JAR file
39+
40+
If you need to update the `./testMQ.jar` file, you can modify the source code in the `src` directory, and run the following command to trigger the rebuild:
41+
42+
```
43+
mvn clean package
44+
```
45+
{: codeblock}
46+
47+
The new `testMQ-1.0-SNAPSHOT.jar` file is generated in the `target` directory. You can replace the `testMQ.jar` file with the `./target/testMQ-1.0-SNAPSHOT.jar` file and use the IBM MQ connection test tool `./testMQ.sh` with the new `testMQ.jar`file.

ibmmq/pom.xml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>com.ibm.mq</groupId>
8+
<artifactId>testMQ</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<maven.compiler.source>11</maven.compiler.source>
13+
<maven.compiler.target>11</maven.compiler.target>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
</properties>
16+
<dependencies>
17+
<dependency>
18+
<groupId>com.ibm.mq</groupId>
19+
<artifactId>com.ibm.mq.allclient</artifactId>
20+
<version>9.3.0.0</version>
21+
</dependency>
22+
<dependency>
23+
<groupId>org.slf4j</groupId>
24+
<artifactId>slf4j-api</artifactId>
25+
<version>2.0.7</version>
26+
</dependency>
27+
</dependencies>
28+
29+
<build>
30+
<plugins>
31+
<plugin>
32+
<artifactId>maven-assembly-plugin</artifactId>
33+
<executions>
34+
<execution>
35+
<phase>package</phase>
36+
<goals>
37+
<goal>single</goal>
38+
</goals>
39+
</execution>
40+
</executions>
41+
<configuration>
42+
<archive>
43+
<manifest>
44+
<addClasspath>true</addClasspath>
45+
<classpathPrefix>lib/</classpathPrefix>
46+
<mainClass>com.ibm.mq.MQPutGet</mainClass>
47+
</manifest>
48+
</archive>
49+
<appendAssemblyId>false</appendAssemblyId>
50+
<descriptorRefs>
51+
<descriptorRef>jar-with-dependencies</descriptorRef>
52+
</descriptorRefs>
53+
</configuration>
54+
</plugin>
55+
</plugins>
56+
</build>
57+
58+
</project>
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
package com.ibm.mq;
2+
3+
import com.ibm.mq.constants.CMQC;
4+
import com.ibm.mq.constants.CMQCFC;
5+
import com.ibm.mq.constants.MQConstants;
6+
import com.ibm.mq.headers.pcf.PCFMessage;
7+
import com.ibm.mq.headers.pcf.PCFMessageAgent;
8+
9+
import javax.net.ssl.KeyManagerFactory;
10+
import javax.net.ssl.SSLContext;
11+
import javax.net.ssl.SSLSocketFactory;
12+
import javax.net.ssl.TrustManagerFactory;
13+
import java.io.BufferedReader;
14+
import java.io.File;
15+
import java.io.FileInputStream;
16+
import java.io.IOException;
17+
import java.io.InputStream;
18+
import java.io.InputStreamReader;
19+
import java.lang.reflect.Field;
20+
import java.security.GeneralSecurityException;
21+
import java.security.KeyStore;
22+
import java.security.SecureRandom;
23+
import java.util.Hashtable;
24+
25+
public class MQPutGet {
26+
private static final String ALL_QUEUES_WILDCARD = "*";
27+
28+
private static void usage() {
29+
System.out.println("==================================================================================");
30+
System.out.println("If you want to try local binding. The usage is: ");
31+
System.out.println(" java -jar ./testMQ.jar -m <qmgr-name> -a <lib-path> [-q <queueName>]");
32+
System.out.println("");
33+
System.out.println("If you want to try client binding. The usage is:");
34+
System.out.println(" java -jar ./testMQ.jar -m <qmgr-name> -h <host> -p <port> -c <channel> [-u <user>] [-z <password>] " + "[-q <queueName>] [-k <keystore>] [-w <keystore-password>] -s [<ciph-suite>]");
35+
System.out.println("==================================================================================");
36+
}
37+
38+
public static boolean isEmpty(CharSequence cs) {
39+
return cs == null || cs.length() == 0;
40+
}
41+
42+
private static boolean isNotBlank(CharSequence cs) {
43+
return !isEmpty(cs);
44+
}
45+
46+
private static boolean isIbmJre() {
47+
String javaHome = System.getProperty("java.home");
48+
String javaPath = javaHome + File.separator + "bin" + File.separator + "java";
49+
String javaVendor = null;
50+
51+
String[] command = {javaPath, "-XshowSettings:properties", "-version"};
52+
try {
53+
Process process = new ProcessBuilder(command).start();
54+
55+
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
56+
String line;
57+
while ((line = reader.readLine()) != null) {
58+
if (line.trim().contains("java.vendor =")) {
59+
String[] arr = line.split("=");
60+
if (arr.length == 2) {
61+
javaVendor = arr[1].trim();
62+
}
63+
}
64+
}
65+
66+
if (javaVendor != null && javaVendor.equalsIgnoreCase("ibm")) {
67+
return true;
68+
}
69+
70+
} catch (IOException e) {
71+
e.printStackTrace();
72+
}
73+
74+
return false;
75+
}
76+
77+
private static void addMqLibPath(String s) {
78+
System.out.println("Add library path " + s);
79+
80+
try {
81+
// This enables the java.library.path to be modified at runtime
82+
// From a Sun engineer at http://forums.sun.com/thread.jspa?threadID=707176
83+
Field field = ClassLoader.class.getDeclaredField("usr_paths");
84+
field.setAccessible(true);
85+
String[] paths = (String[]) field.get(null);
86+
for (String path : paths) {
87+
if (s.equals(path)) {
88+
return;
89+
}
90+
}
91+
92+
String[] tmp = new String[paths.length + 1];
93+
System.arraycopy(paths, 0, tmp, 0, paths.length);
94+
tmp[paths.length] = s;
95+
field.set(null, tmp);
96+
} catch (IllegalAccessException | NoSuchFieldException e) {
97+
System.out.println("Cannot add library path: " + e.getMessage());
98+
System.out.println("Cannot add library path. Stacktrace: " + e);
99+
}
100+
101+
System.setProperty("java.library.path", System.getProperty("java.library.path") + File.pathSeparator + s);
102+
}
103+
104+
105+
private static SSLContext getSSLContext(String keystoreFile, String keystorePassword) throws GeneralSecurityException, IOException {
106+
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
107+
try (InputStream in = new FileInputStream(keystoreFile)) {
108+
keystore.load(in, keystorePassword.toCharArray());
109+
}
110+
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
111+
keyManagerFactory.init(keystore, keystorePassword.toCharArray());
112+
113+
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
114+
trustManagerFactory.init(keystore);
115+
116+
SSLContext sslContext = SSLContext.getInstance("TLS");
117+
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
118+
119+
return sslContext;
120+
}
121+
122+
private static Hashtable<String, Object> getProps(String channel, String host, Integer port, String username, String password, String keystore, String keystorePassword, String cipherSuite) throws MQException, GeneralSecurityException, IOException {
123+
Hashtable<String, Object> queueManagerProps = new Hashtable<>();
124+
if (isNotBlank(channel)) {
125+
queueManagerProps.put(CMQC.CHANNEL_PROPERTY, channel);
126+
}
127+
if (isNotBlank(host)) {
128+
queueManagerProps.put(CMQC.HOST_NAME_PROPERTY, host);
129+
}
130+
if (port != null) {
131+
queueManagerProps.put(CMQC.PORT_PROPERTY, port);
132+
}
133+
if (isNotBlank(username)) {
134+
queueManagerProps.put(CMQC.USER_ID_PROPERTY, username);
135+
}
136+
if (isNotBlank(password)) {
137+
queueManagerProps.put(CMQC.PASSWORD_PROPERTY, password);
138+
}
139+
140+
if (isNotBlank(keystore) && isNotBlank(keystorePassword) && isNotBlank(cipherSuite)) {
141+
SSLContext sslContext = getSSLContext(keystore, keystorePassword);
142+
SSLSocketFactory sf = sslContext.getSocketFactory();
143+
queueManagerProps.put(MQConstants.SSL_SOCKET_FACTORY_PROPERTY, sf);
144+
145+
queueManagerProps.put(MQConstants.SSL_CIPHER_SUITE_PROPERTY, cipherSuite);
146+
queueManagerProps.put(CMQC.TRANSPORT_PROPERTY, CMQC.TRANSPORT_MQSERIES_CLIENT);
147+
}
148+
149+
return queueManagerProps;
150+
}
151+
152+
public static void main(String[] args) {
153+
if (args.length == 0 || args[0].equalsIgnoreCase("-help")) {
154+
usage();
155+
System.exit(0);
156+
}
157+
158+
String libPath = null;
159+
String qmgr = null;
160+
String host = null;
161+
String port = null;
162+
String channel = null;
163+
String user = null;
164+
String password = null;
165+
String queueName = null;
166+
String keystore = null;
167+
String keystorePassword = null;
168+
String cipherSuite = null;
169+
170+
char c = ' ';
171+
172+
for (int i = 0; i < args.length; i++) {
173+
if (args[i].startsWith("-")) {
174+
c = args[i].charAt(1);
175+
176+
switch (c) {
177+
case 'a':
178+
libPath = args[++i];
179+
break;
180+
case 'm':
181+
qmgr = args[++i];
182+
break;
183+
case 'h':
184+
host = args[++i];
185+
break;
186+
case 'p':
187+
port = args[++i];
188+
break;
189+
case 'c':
190+
channel = args[++i];
191+
break;
192+
case 'u':
193+
user = args[++i];
194+
break;
195+
case 'z':
196+
password = args[++i];
197+
break;
198+
case 'q':
199+
queueName = args[++i];
200+
break;
201+
case 's':
202+
cipherSuite = args[++i];
203+
break;
204+
case 'k':
205+
keystore = args[++i];
206+
break;
207+
case 'w':
208+
keystorePassword = args[++i];
209+
break;
210+
}
211+
}
212+
}
213+
214+
215+
boolean localBinding = false;
216+
if (qmgr != null && libPath != null) {
217+
localBinding = true;
218+
} else if (qmgr != null && host != null && port != null && channel != null) {
219+
localBinding = false;
220+
} else {
221+
usage();
222+
System.exit(0);
223+
}
224+
225+
if (!isIbmJre()) {
226+
System.setProperty("com.ibm.mq.cfg.useIBMCipherMappings", "false");
227+
}
228+
229+
try {
230+
MQQueueManager qm;
231+
232+
System.out.println("==================================================================================");
233+
234+
if (localBinding) {
235+
System.out.println("Connect to Queue Manager " + qmgr + " with local binding mode.");
236+
addMqLibPath(libPath);
237+
qm = new MQQueueManager(qmgr);
238+
} else {
239+
System.out.println("Connect to Queue Manager " + qmgr + " with client binding mode.");
240+
qm = new MQQueueManager(qmgr, getProps(channel, host, Integer.parseInt(port), user, password, keystore, keystorePassword, cipherSuite));
241+
}
242+
243+
PCFMessageAgent agent = new PCFMessageAgent(qm);
244+
245+
PCFMessage getQueuesRequest = new PCFMessage(CMQCFC.MQCMD_INQUIRE_Q);
246+
if (queueName != null) {
247+
getQueuesRequest.addParameter(CMQC.MQCA_Q_NAME, queueName);
248+
} else {
249+
getQueuesRequest.addParameter(CMQC.MQCA_Q_NAME, ALL_QUEUES_WILDCARD);
250+
}
251+
getQueuesRequest.addParameter(CMQC.MQIA_Q_TYPE, CMQC.MQQT_LOCAL);
252+
253+
PCFMessage[] queues = agent.send(getQueuesRequest);
254+
for (PCFMessage queueInfo : queues) {
255+
String tmpQueueName = queueInfo.getStringParameterValue(CMQC.MQCA_Q_NAME);
256+
int queueDepthInt = queueInfo.getIntParameterValue(CMQC.MQIA_CURRENT_Q_DEPTH);
257+
System.out.println("Queue name: " + tmpQueueName + ", current depth: " + queueDepthInt);
258+
}
259+
260+
qm.disconnect();
261+
} catch (Exception e) {
262+
e.printStackTrace();
263+
}
264+
}
265+
}

ibmmq/testMQ.jar

5.14 MB
Binary file not shown.

0 commit comments

Comments
 (0)