Skip to content

Commit 11e642f

Browse files
committed
MQCB/MQCTL and MQBEGIN complete the MQI implementation
1 parent dbdf3b2 commit 11e642f

File tree

15 files changed

+758
-12
lines changed

15 files changed

+758
-12
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## December 2018 - v3.3.0
4+
* All relevant API calls now automatically set FAIL_IF_QUIESCING
5+
* Samples updated to use "defer" instead of just suggesting it
6+
* Add support for MQCB/MQCTL callback functions
7+
* Add support for MQBEGIN transaction management
8+
39
## November 2018 - v3.2.0
410
* Added GetPlatform to mqmetric so it can be used as a label/tag in collectors
511
* Added sample programs demonstrating specific operations such as put/get of message

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,9 @@ At this point, you should have a compiled copy of the program in `$GOPATH/bin`.
123123

124124
## Limitations
125125

126-
Almost all of the MQI verbs are now available through the `ibmmq` package.
127-
Currently unavailable verbs include:
126+
All regular MQI verbs are now available through the `ibmmq` package.
128127

129-
* MQCB/MQCTL
130-
131-
There are also no structure handlers for message headers such as MQRFH2 or MQDLH.
128+
There are no structure handlers for message headers such as MQRFH2 or MQDLH.
132129

133130
## History
134131

ibmmq/mqi.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ package ibmmq
5151
#include <string.h>
5252
#include <cmqc.h>
5353
#include <cmqxc.h>
54+
5455
*/
5556
import "C"
5657

@@ -219,6 +220,7 @@ func (x *MQQueueManager) Disc() error {
219220
var mqrc C.MQLONG
220221
var mqcc C.MQLONG
221222

223+
savedConn := x.hConn
222224
C.MQDISC(&x.hConn, &mqcc, &mqrc)
223225

224226
mqreturn := MQReturn{MQCC: int32(mqcc),
@@ -230,6 +232,8 @@ func (x *MQQueueManager) Disc() error {
230232
return &mqreturn
231233
}
232234

235+
cbRemoveConnection(savedConn)
236+
233237
return nil
234238
}
235239

@@ -248,7 +252,7 @@ func (x *MQQueueManager) Open(good *MQOD, goOpenOptions int32) (MQObject, error)
248252
}
249253

250254
copyODtoC(&mqod, good)
251-
mqOpenOptions = C.MQLONG(goOpenOptions)
255+
mqOpenOptions = C.MQLONG(goOpenOptions) | C.MQOO_FAIL_IF_QUIESCING
252256

253257
C.MQOPEN(x.hConn,
254258
(C.PMQVOID)(unsafe.Pointer(&mqod)),
@@ -288,6 +292,9 @@ func (object *MQObject) Close(goCloseOptions int32) error {
288292

289293
mqCloseOptions = C.MQLONG(goCloseOptions)
290294

295+
savedHConn := object.qMgr.hConn
296+
savedHObj := object.hObj
297+
291298
C.MQCLOSE(object.qMgr.hConn, &object.hObj, mqCloseOptions, &mqcc, &mqrc)
292299

293300
mqreturn := MQReturn{MQCC: int32(mqcc),
@@ -299,6 +306,7 @@ func (object *MQObject) Close(goCloseOptions int32) error {
299306
return &mqreturn
300307
}
301308

309+
cbRemoveHandle(savedHConn, savedHObj)
302310
return nil
303311

304312
}
@@ -373,6 +381,33 @@ func (subObject *MQObject) Subrq(gosro *MQSRO, action int32) error {
373381
return nil
374382
}
375383

384+
/*
385+
Begin is the function to start a two-phase XA transaction coordinated by MQ
386+
*/
387+
func (x *MQQueueManager) Begin(gobo *MQBO) error {
388+
var mqrc C.MQLONG
389+
var mqcc C.MQLONG
390+
var mqbo C.MQBO
391+
392+
copyBOtoC(&mqbo, gobo)
393+
394+
C.MQBEGIN(x.hConn, (C.PMQVOID)(unsafe.Pointer(&mqbo)), &mqcc, &mqrc)
395+
396+
copyBOfromC(&mqbo, gobo)
397+
398+
mqreturn := MQReturn{MQCC: int32(mqcc),
399+
MQRC: int32(mqrc),
400+
verb: "MQBEGIN",
401+
}
402+
403+
if mqcc != C.MQCC_OK {
404+
return &mqreturn
405+
}
406+
407+
return nil
408+
409+
}
410+
376411
/*
377412
Cmit is the function to commit an in-flight transaction
378413
*/

ibmmq/mqiBO.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package ibmmq
2+
3+
/*
4+
Copyright (c) IBM Corporation 2018
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
Contributors:
19+
Mark Taylor - Initial Contribution
20+
*/
21+
22+
/*
23+
24+
#include <stdlib.h>
25+
#include <string.h>
26+
#include <cmqc.h>
27+
28+
*/
29+
import "C"
30+
31+
/*
32+
This module contains the Begin Options structure
33+
*/
34+
35+
type MQBO struct {
36+
Options int32
37+
}
38+
39+
func NewMQBO() *MQBO {
40+
bo := new(MQBO)
41+
bo.Options = int32(C.MQBO_NONE)
42+
return bo
43+
}
44+
45+
func copyBOtoC(mqbo *C.MQBO, gobo *MQBO) {
46+
setMQIString((*C.char)(&mqbo.StrucId[0]), "BO ", 4)
47+
mqbo.Version = 1
48+
mqbo.Options = C.MQLONG(gobo.Options)
49+
}
50+
51+
func copyBOfromC(mqbo *C.MQBO, gobo *MQBO) {
52+
gobo.Options = int32(mqbo.Options)
53+
return
54+
}

ibmmq/mqiCBC.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package ibmmq
2+
3+
/*
4+
Copyright (c) IBM Corporation 2018
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
Contributors:
19+
Mark Taylor - Initial Contribution
20+
*/
21+
22+
/*
23+
24+
#include <stdlib.h>
25+
#include <string.h>
26+
#include <cmqc.h>
27+
28+
*/
29+
import "C"
30+
31+
/*
32+
MQCBC is a structure containing the MQ Callback Context
33+
The CompCode and Reason in the C structure are not included here. They
34+
are set in an independent MQReturn structure passed to the callback. Similarly
35+
for the hObj
36+
*/
37+
type MQCBC struct {
38+
CallType int32
39+
CallbackArea []byte // These byte arrays are saved/restored in parent function
40+
ConnectionArea []byte
41+
State int32
42+
DataLength int32
43+
BufferLength int32
44+
Flags int32
45+
ReconnectDelay int32
46+
}
47+
48+
/*
49+
NewMQCBC creates a MQCBC structure. There are no default values
50+
as the structure is created within MQ.
51+
*/
52+
func NewMQCBC() *MQCBC {
53+
cbc := new(MQCBC)
54+
return cbc
55+
}
56+
57+
/*
58+
Since we do not create the structure, there's no conversion for it into
59+
a C format
60+
*/
61+
func copyCBCtoC(mqcbc *C.MQCBC, gocbc *MQCBC) {
62+
return
63+
}
64+
65+
/*
66+
But we do need a conversion process from C
67+
*/
68+
func copyCBCfromC(mqcbc *C.MQCBC, gocbc *MQCBC) {
69+
gocbc.CallType = int32(mqcbc.CallType)
70+
gocbc.State = int32(mqcbc.State)
71+
gocbc.DataLength = int32(mqcbc.DataLength)
72+
gocbc.BufferLength = int32(mqcbc.BufferLength)
73+
gocbc.Flags = int32(mqcbc.Flags)
74+
gocbc.ReconnectDelay = int32(mqcbc.ReconnectDelay)
75+
// ConnectionArea and CallbackArea are restored outside this function
76+
77+
return
78+
}

ibmmq/mqiCBD.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package ibmmq
2+
3+
/*
4+
Copyright (c) IBM Corporation 2018
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
Contributors:
19+
Mark Taylor - Initial Contribution
20+
*/
21+
22+
/*
23+
24+
#include <stdlib.h>
25+
#include <string.h>
26+
#include <cmqc.h>
27+
28+
*/
29+
import "C"
30+
31+
/*
32+
MQCBD is a structure containing the MQ Callback Descriptor
33+
*/
34+
type MQCBD struct {
35+
CallbackType int32
36+
Options int32
37+
CallbackArea []byte
38+
CallbackFunction MQCB_FUNCTION
39+
CallbackName string
40+
MaxMsgLength int32
41+
}
42+
43+
/*
44+
NewMQCBD fills in default values for the MQCBD structure
45+
*/
46+
func NewMQCBD() *MQCBD {
47+
cbd := new(MQCBD)
48+
cbd.CallbackType = C.MQCBT_MESSAGE_CONSUMER
49+
cbd.Options = C.MQCBDO_NONE
50+
cbd.CallbackArea = nil
51+
cbd.CallbackFunction = nil
52+
cbd.CallbackName = ""
53+
cbd.MaxMsgLength = C.MQCBD_FULL_MSG_LENGTH
54+
55+
return cbd
56+
}
57+
58+
func copyCBDtoC(mqcbd *C.MQCBD, gocbd *MQCBD) {
59+
60+
setMQIString((*C.char)(&mqcbd.StrucId[0]), "CBD ", 4)
61+
mqcbd.Version = C.MQCBD_VERSION_1
62+
63+
mqcbd.CallbackType = C.MQLONG(gocbd.CallbackType)
64+
mqcbd.Options = C.MQLONG(gocbd.Options) | C.MQCBDO_FAIL_IF_QUIESCING
65+
// CallbackArea is always set to NULL here. The user's values are saved/restored elsewhere
66+
mqcbd.CallbackArea = (C.MQPTR)(C.NULL)
67+
68+
setMQIString((*C.char)(&mqcbd.CallbackName[0]), gocbd.CallbackName, 128) // There's no MQI constant for the length
69+
70+
mqcbd.MaxMsgLength = C.MQLONG(gocbd.MaxMsgLength)
71+
72+
return
73+
}
74+
75+
func copyCBDfromC(mqcbd *C.MQCBD, gocbd *MQCBD) {
76+
// There are no modified output parameters
77+
return
78+
}

ibmmq/mqiCTLO.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package ibmmq
2+
3+
/*
4+
Copyright (c) IBM Corporation 2018
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
Contributors:
19+
Mark Taylor - Initial Contribution
20+
*/
21+
22+
/*
23+
24+
#include <stdlib.h>
25+
#include <string.h>
26+
#include <cmqc.h>
27+
28+
*/
29+
import "C"
30+
31+
/*
32+
MQCTLO is a structure containing the MQ Control Options
33+
*/
34+
type MQCTLO struct {
35+
ConnectionArea []byte
36+
Options int32
37+
}
38+
39+
/*
40+
NewMQCTLO creates a MQCTLO structure.
41+
*/
42+
func NewMQCTLO() *MQCTLO {
43+
ctlo := new(MQCTLO)
44+
ctlo.Options = C.MQCTLO_NONE
45+
ctlo.ConnectionArea = nil
46+
return ctlo
47+
}
48+
49+
func copyCTLOtoC(mqctlo *C.MQCTLO, goctlo *MQCTLO) {
50+
setMQIString((*C.char)(&mqctlo.StrucId[0]), "CTLO", 4)
51+
mqctlo.Version = C.MQCTLO_VERSION_1
52+
mqctlo.Options = (C.MQLONG)(goctlo.Options) | C.MQCTLO_FAIL_IF_QUIESCING
53+
// Always pass NULL to the C function as the real array is saved/restored in the Go layer
54+
mqctlo.ConnectionArea = (C.MQPTR)(C.NULL)
55+
return
56+
}
57+
58+
func copyCTLOfromC(mqctlo *C.MQCTLO, goctlo *MQCTLO) {
59+
// There are no output fields for this structure
60+
return
61+
}

ibmmq/mqiMQGMO.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ func copyGMOtoC(mqgmo *C.MQGMO, gogmo *MQGMO) {
8080

8181
setMQIString((*C.char)(&mqgmo.StrucId[0]), "GMO ", 4)
8282
mqgmo.Version = C.MQLONG(gogmo.Version)
83-
mqgmo.Options = C.MQLONG(gogmo.Options)
83+
mqgmo.Options = C.MQLONG(gogmo.Options) | C.MQGMO_FAIL_IF_QUIESCING
8484
mqgmo.WaitInterval = C.MQLONG(gogmo.WaitInterval)
8585
mqgmo.Signal1 = C.MQLONG(gogmo.Signal1)
8686
mqgmo.Signal2 = C.MQLONG(gogmo.Signal2)

0 commit comments

Comments
 (0)