-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathamqsdlh.js
executable file
·199 lines (164 loc) · 5.74 KB
/
amqsdlh.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
"use strict";
/*
Copyright (c) IBM Corporation 2017, 2018
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.
Contributors:
Mark Taylor - Initial Contribution
*/
/*
* This is an example of a Node.js program to show how to use the Dead Letter
* Header methods in an MQ program
*
* The queue and queue manager name can be given as parameters on the
* command line. Defaults are coded in the program.
*
* A single message is put, containing a "hello" and timestamp. It is preceded
* by a DLH structure as would normally be done when an application cannot
* process a received message. The message is then retrieved and printed.
*
* Each MQI call prints its success or failure.
*
*/
// Import the MQ package
const mq = require("ibmmq");
const MQC = mq.MQC; // Want to refer to this export directly for simplicity
// Import any other packages needed
const StringDecoder = require("string_decoder").StringDecoder;
const decoder = new StringDecoder("utf8");
// The queue manager and queue to be used. These can be overridden on command line.
let qMgr = "QM1";
let qName = "DEV.QUEUE.1";
function formatErr(err) {
return "MQ call failed in " + err.message;
}
// Define some functions that will be used from the main flow
function putMessage(hObj) {
const msg = "Hello from Node at " + new Date();
const mqmd = new mq.MQMD(); // Defaults are fine.
const pmo = new mq.MQPMO();
// Describe how the Put should behave
pmo.Options = MQC.MQPMO_NO_SYNCPOINT |
MQC.MQPMO_NEW_MSG_ID |
MQC.MQPMO_NEW_CORREL_ID;
// Don't normally need to set this for text messages, but as we're not
// putting a retrieved message to the DLQ (instead creating the msg from
// scratch) then we need to say up front what type it is.
mqmd.Format = MQC.MQFMT_STRING;
// Create a DLH and allow it to modify MQMD chaining fields like the CCSID
const mqdlh = new mq.MQDLH(mqmd);
// Fill in something for why the message is put to the DLQ
mqdlh.Reason = MQC.MQRC_NOT_AUTHORIZED;
mqdlh.DestQName = "DEST.QUEUE";
mqdlh.DestQMgrName = "DEST.QMGR";
// Create the full message by concatenating buffers into a single block
const fullMsg = Buffer.concat([mqdlh.getBuffer(),Buffer.from(msg)]);
// And put the message
mq.Put(hObj,mqmd,pmo,fullMsg,function (err) {
if (err) {
console.log(formatErr(err));
} else {
console.log("MQPUT successful");
}
});
}
// This function retrieves messages from the queue without waiting.
// Will just use a synchronous Get for simplicity in the flow as it's
// not what we're demonstrating in this sample.
function getMessage(hObj) {
const buf = Buffer.alloc(1024);
const mqmd = new mq.MQMD();
const gmo = new mq.MQGMO();
gmo.Options = MQC.MQGMO_NO_SYNCPOINT |
MQC.MQGMO_NO_WAIT |
MQC.MQGMO_CONVERT |
MQC.MQGMO_FAIL_IF_QUIESCING;
try {
const len = mq.GetSync(hObj,mqmd,gmo,buf);
console.log("MQGET successful");
const format = mqmd.Format;
// If the message has a DLH then
// parse and print it.
if (format == MQC.MQFMT_DEAD_LETTER_HEADER) {
const hdr = mq.MQDLH.getHeader(buf);
console.log("DLH is %j",hdr);
printMessage(hdr.Format,buf.subarray(hdr.StrucLength),len-hdr.StrucLength);
} else {
printMessage(format,buf,len);
}
} catch (err) {
if (err.mqrc == MQC.MQRC_NO_MSG_AVAILABLE) {
console.log("no more messages");
} else {
console.log(formatErr(err));
}
}
}
function printMessage(format,buf,len) {
if (format=="MQSTR") {
console.log("message len=%d <%s>", len,decoder.write(buf.slice(0,len)));
} else {
console.log("binary message: " + buf);
}
}
// When we're done, close queues and connections
function cleanup(hConn,hObj) {
mq.Close(hObj, 0, function (err) {
if (err) {
console.log(formatErr(err));
} else {
// console.log("MQCLOSE successful");
}
mq.Disc(hConn, function (err) {
if (err) {
console.log(formatErr(err));
} else {
// console.log("MQDISC successful");
}
});
});
}
// The program really starts here.
// Connect to the queue manager. If that works, the callback function
// opens the queue, and then we can put a message.
console.log("Sample AMQSDLH.JS start");
// Get command line parameters
const myArgs = process.argv.slice(2); // Remove redundant parms
if (myArgs[0]) {
qName = myArgs[0];
}
if (myArgs[1]) {
qMgr = myArgs[1];
}
const cno = new mq.MQCNO();
cno.Options = MQC.MQCNO_NONE; // use MQCNO_CLIENT_BINDING to connect as client
mq.Connx(qMgr, cno, function (err,hConn) {
if (err) {
console.log(formatErr(err));
} else {
console.log("MQCONN to %s successful ", qMgr);
// Define what we want to open, and how we want to open it.
const od = new mq.MQOD();
od.ObjectName = qName;
od.ObjectType = MQC.MQOT_Q;
const openOptions = MQC.MQOO_OUTPUT | MQC.MQOO_INPUT_AS_Q_DEF;
mq.Open(hConn,od,openOptions,function (err,hObj) {
if (err) {
console.log(formatErr(err));
} else {
console.log("MQOPEN of %s successful",qName);
// Assume queue is empty when we start
putMessage(hObj); // Put an initial message
getMessage(hObj); // And get it back
}
cleanup(hConn,hObj);
});
}
});