first commit
This commit is contained in:
190
vendor/github.com/ibm-messaging/mq-golang/LICENSE
generated
vendored
Normal file
190
vendor/github.com/ibm-messaging/mq-golang/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
© Copyright IBM Corporation 2016, 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.
|
||||
4954
vendor/github.com/ibm-messaging/mq-golang/ibmmq/cmqc_linux.go
generated
vendored
Normal file
4954
vendor/github.com/ibm-messaging/mq-golang/ibmmq/cmqc_linux.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4951
vendor/github.com/ibm-messaging/mq-golang/ibmmq/cmqc_windows.go
generated
vendored
Normal file
4951
vendor/github.com/ibm-messaging/mq-golang/ibmmq/cmqc_windows.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
560
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqi.go
generated
vendored
Normal file
560
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqi.go
generated
vendored
Normal file
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
Package ibmmq provides a wrapper to a subset of the IBM MQ
|
||||
procedural interface (the MQI).
|
||||
|
||||
In this initial implementation not all the MQI verbs are
|
||||
included, but it does have the core operations required to
|
||||
put and get messages and work with topics.
|
||||
|
||||
The verbs are given mixed case names without MQ - Open instead
|
||||
of MQOPEN etc.
|
||||
|
||||
If an MQI call returns MQCC_FAILED or MQCC_WARNING, a custom error
|
||||
type is returned containing the MQCC/MQRC values as
|
||||
a formatted string. Use mqreturn:= err(*ibmmq.MQReturn) to access
|
||||
the particular MQRC or MQCC values.
|
||||
|
||||
The build directives for Windows assume the header and library files have
|
||||
been copied to a temporary location, because the default paths are not
|
||||
acceptable to Go (it does not like spaces or special characters like ~).
|
||||
Note: This problem appears to have been fixed in Go 1.9, and once that
|
||||
is fully available, the directives will be changed to a more reasonable
|
||||
path in this file. For example
|
||||
cgo windows CFLAGS -I"c:/Program Files/IBM/MQ/tools/c/include" -m64
|
||||
|
||||
The build directives for Linux assume the default MQ installation path
|
||||
in /opt/mqm. These would need to be changed in this file if you use a
|
||||
non-default path.
|
||||
*/
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
#cgo !windows CFLAGS: -I/opt/mqm/inc -D_REENTRANT
|
||||
#cgo windows CFLAGS: -I"C:/Program Files/IBM/MQ/Tools/c/include"
|
||||
#cgo !windows LDFLAGS: -L/opt/mqm/lib64 -lmqm_r -Wl,-rpath=/opt/mqm/lib64 -Wl,-rpath=/usr/lib64
|
||||
#cgo windows LDFLAGS: -L "C:/Program Files/IBM/MQ/bin64" -lmqm
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
#include <cmqxc.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
This file contains the C wrappers, calling out to structure-specific
|
||||
functions where necessary.
|
||||
|
||||
Define some basic types to hold the
|
||||
references to MQ objects - hconn, hobj - and
|
||||
a simple way to pass the combination of MQCC/MQRC
|
||||
returned from MQI verbs
|
||||
|
||||
The object name is copied into the structures only
|
||||
for convenience. It's not really needed, but
|
||||
it can sometimes be nice to print which queue an hObj
|
||||
refers to during debug.
|
||||
*/
|
||||
|
||||
/*
|
||||
MQQueueManager contains the connection to the queue manager
|
||||
*/
|
||||
type MQQueueManager struct {
|
||||
hConn C.MQHCONN
|
||||
Name string
|
||||
}
|
||||
|
||||
/*
|
||||
MQObject contains a reference to an open object and the associated
|
||||
queue manager
|
||||
*/
|
||||
type MQObject struct {
|
||||
hObj C.MQHOBJ
|
||||
qMgr *MQQueueManager
|
||||
Name string
|
||||
}
|
||||
|
||||
/*
|
||||
MQReturn holds the MQRC and MQCC values returned from an MQI verb. It
|
||||
implements the Error() function so is returned as the specific error
|
||||
from the verbs. See the sample programs for how to access the
|
||||
MQRC/MQCC values in this returned error.
|
||||
*/
|
||||
type MQReturn struct {
|
||||
MQCC int32
|
||||
MQRC int32
|
||||
verb string
|
||||
}
|
||||
|
||||
func (e *MQReturn) Error() string {
|
||||
return mqstrerror(e.verb, C.MQLONG(e.MQCC), C.MQLONG(e.MQRC))
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a Go string into a fixed-size C char array such as MQCHAR12
|
||||
* Once the string has been copied, it can be immediately freed
|
||||
* Empty strings have first char set to 0 in MQI structures
|
||||
*/
|
||||
func setMQIString(a *C.char, v string, l int) {
|
||||
if len(v) > 0 {
|
||||
p := C.CString(v)
|
||||
C.strncpy(a, p, (C.size_t)(l))
|
||||
C.free(unsafe.Pointer(p))
|
||||
} else {
|
||||
*a = 0
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Conn is the function to connect to a queue manager
|
||||
*/
|
||||
func Conn(goQMgrName string) (MQQueueManager, error) {
|
||||
return Connx(goQMgrName, nil)
|
||||
}
|
||||
|
||||
/*
|
||||
Connx is the extended function to connect to a queue manager.
|
||||
*/
|
||||
func Connx(goQMgrName string, gocno *MQCNO) (MQQueueManager, error) {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
var mqcno C.MQCNO
|
||||
|
||||
if (C.MQENC_NATIVE % 2) == 0 { // May be needed for conversion later
|
||||
endian = binary.LittleEndian
|
||||
} else {
|
||||
endian = binary.BigEndian
|
||||
}
|
||||
|
||||
qMgr := MQQueueManager{}
|
||||
mqQMgrName := unsafe.Pointer(C.CString(goQMgrName))
|
||||
defer C.free(mqQMgrName)
|
||||
|
||||
// Set up a default CNO if not provided.
|
||||
if gocno == nil {
|
||||
// Because Go programs are always threaded, and we cannot
|
||||
// tell on which thread we might get dispatched, allow handles always to
|
||||
// be shareable.
|
||||
gocno = NewMQCNO()
|
||||
gocno.Options = MQCNO_HANDLE_SHARE_NO_BLOCK
|
||||
} else {
|
||||
if (gocno.Options & (MQCNO_HANDLE_SHARE_NO_BLOCK |
|
||||
MQCNO_HANDLE_SHARE_BLOCK)) == 0 {
|
||||
gocno.Options |= MQCNO_HANDLE_SHARE_NO_BLOCK
|
||||
}
|
||||
}
|
||||
copyCNOtoC(&mqcno, gocno)
|
||||
|
||||
C.MQCONNX((*C.MQCHAR)(mqQMgrName), &mqcno, &qMgr.hConn, &mqcc, &mqrc)
|
||||
|
||||
if gocno != nil {
|
||||
copyCNOfromC(&mqcno, gocno)
|
||||
}
|
||||
|
||||
mqreturn := &MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQCONNX",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return qMgr, mqreturn
|
||||
}
|
||||
|
||||
qMgr.Name = goQMgrName
|
||||
|
||||
return qMgr, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Disc is the function to disconnect from the queue manager
|
||||
*/
|
||||
func (x *MQQueueManager) Disc() error {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
|
||||
C.MQDISC(&x.hConn, &mqcc, &mqrc)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQDISC",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return &mqreturn
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
Open an object such as a queue or topic
|
||||
*/
|
||||
func (x *MQQueueManager) Open(good *MQOD, goOpenOptions int32) (MQObject, error) {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
var mqod C.MQOD
|
||||
var mqOpenOptions C.MQLONG
|
||||
|
||||
object := MQObject{
|
||||
Name: good.ObjectName,
|
||||
qMgr: x,
|
||||
}
|
||||
|
||||
copyODtoC(&mqod, good)
|
||||
mqOpenOptions = C.MQLONG(goOpenOptions)
|
||||
|
||||
C.MQOPEN(x.hConn,
|
||||
(C.PMQVOID)(unsafe.Pointer(&mqod)),
|
||||
mqOpenOptions,
|
||||
&object.hObj,
|
||||
&mqcc,
|
||||
&mqrc)
|
||||
|
||||
copyODfromC(&mqod, good)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQOPEN",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return object, &mqreturn
|
||||
}
|
||||
|
||||
// ObjectName may have changed because it's a model queue
|
||||
object.Name = good.ObjectName
|
||||
|
||||
return object, nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Close the object
|
||||
*/
|
||||
func (object *MQObject) Close(goCloseOptions int32) error {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
var mqCloseOptions C.MQLONG
|
||||
|
||||
mqCloseOptions = C.MQLONG(goCloseOptions)
|
||||
|
||||
C.MQCLOSE(object.qMgr.hConn, &object.hObj, mqCloseOptions, &mqcc, &mqrc)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQCLOSE",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return &mqreturn
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Sub is the function to subscribe to a topic
|
||||
*/
|
||||
func (x *MQQueueManager) Sub(gosd *MQSD, qObject *MQObject) (MQObject, error) {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
var mqsd C.MQSD
|
||||
|
||||
subObject := MQObject{
|
||||
Name: gosd.ObjectName,
|
||||
qMgr: x,
|
||||
}
|
||||
|
||||
copySDtoC(&mqsd, gosd)
|
||||
|
||||
C.MQSUB(x.hConn,
|
||||
(C.PMQVOID)(unsafe.Pointer(&mqsd)),
|
||||
&qObject.hObj,
|
||||
&subObject.hObj,
|
||||
&mqcc,
|
||||
&mqrc)
|
||||
|
||||
copySDfromC(&mqsd, gosd)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQSUB",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return subObject, &mqreturn
|
||||
}
|
||||
|
||||
qObject.qMgr = x // Force the correct hConn for managed objects
|
||||
|
||||
return subObject, nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Cmit is the function to commit an in-flight transaction
|
||||
*/
|
||||
func (x *MQQueueManager) Cmit() error {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
|
||||
C.MQCMIT(x.hConn, &mqcc, &mqrc)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQCMIT",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return &mqreturn
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Back is the function to backout an in-flight transaction
|
||||
*/
|
||||
func (x *MQQueueManager) Back() error {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
|
||||
C.MQBACK(x.hConn, &mqcc, &mqrc)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQBACK",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return &mqreturn
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Put a message to a queue or publish to a topic
|
||||
*/
|
||||
func (object MQObject) Put(gomd *MQMD,
|
||||
gopmo *MQPMO, buffer []byte) error {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
var mqmd C.MQMD
|
||||
var mqpmo C.MQPMO
|
||||
var ptr C.PMQVOID
|
||||
|
||||
bufflen := len(buffer)
|
||||
|
||||
copyMDtoC(&mqmd, gomd)
|
||||
copyPMOtoC(&mqpmo, gopmo)
|
||||
|
||||
if bufflen > 0 {
|
||||
ptr = (C.PMQVOID)(unsafe.Pointer(&buffer[0]))
|
||||
} else {
|
||||
ptr = nil
|
||||
}
|
||||
|
||||
C.MQPUT(object.qMgr.hConn, object.hObj, (C.PMQVOID)(unsafe.Pointer(&mqmd)),
|
||||
(C.PMQVOID)(unsafe.Pointer(&mqpmo)),
|
||||
(C.MQLONG)(bufflen),
|
||||
ptr,
|
||||
&mqcc, &mqrc)
|
||||
|
||||
copyMDfromC(&mqmd, gomd)
|
||||
copyPMOfromC(&mqpmo, gopmo)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQPUT",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return &mqreturn
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
Put1 puts a single messsage to a queue or topic. Typically used for one-shot
|
||||
replies where it can be cheaper than multiple Open/Put/Close
|
||||
sequences
|
||||
*/
|
||||
func (x *MQQueueManager) Put1(good *MQOD, gomd *MQMD,
|
||||
gopmo *MQPMO, buffer []byte) error {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
var mqmd C.MQMD
|
||||
var mqpmo C.MQPMO
|
||||
var mqod C.MQOD
|
||||
var ptr C.PMQVOID
|
||||
|
||||
copyODtoC(&mqod, good)
|
||||
copyMDtoC(&mqmd, gomd)
|
||||
copyPMOtoC(&mqpmo, gopmo)
|
||||
|
||||
bufflen := len(buffer)
|
||||
|
||||
if bufflen > 0 {
|
||||
ptr = (C.PMQVOID)(unsafe.Pointer(&buffer[0]))
|
||||
} else {
|
||||
ptr = nil
|
||||
}
|
||||
|
||||
C.MQPUT1(x.hConn, (C.PMQVOID)(unsafe.Pointer(&mqod)),
|
||||
(C.PMQVOID)(unsafe.Pointer(&mqmd)),
|
||||
(C.PMQVOID)(unsafe.Pointer(&mqpmo)),
|
||||
(C.MQLONG)(bufflen),
|
||||
ptr,
|
||||
&mqcc, &mqrc)
|
||||
|
||||
copyODfromC(&mqod, good)
|
||||
copyMDfromC(&mqmd, gomd)
|
||||
copyPMOfromC(&mqpmo, gopmo)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQPUT1",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return &mqreturn
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Get a message from a queue
|
||||
The length of the retrieved message is returned.
|
||||
*/
|
||||
func (object MQObject) Get(gomd *MQMD,
|
||||
gogmo *MQGMO, buffer []byte) (int, error) {
|
||||
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
var mqmd C.MQMD
|
||||
var mqgmo C.MQGMO
|
||||
var datalen C.MQLONG
|
||||
var ptr C.PMQVOID
|
||||
|
||||
bufflen := len(buffer)
|
||||
|
||||
copyMDtoC(&mqmd, gomd)
|
||||
copyGMOtoC(&mqgmo, gogmo)
|
||||
|
||||
if bufflen > 0 {
|
||||
ptr = (C.PMQVOID)(unsafe.Pointer(&buffer[0]))
|
||||
} else {
|
||||
ptr = nil
|
||||
}
|
||||
|
||||
C.MQGET(object.qMgr.hConn, object.hObj, (C.PMQVOID)(unsafe.Pointer(&mqmd)),
|
||||
(C.PMQVOID)(unsafe.Pointer(&mqgmo)),
|
||||
(C.MQLONG)(bufflen),
|
||||
ptr,
|
||||
&datalen,
|
||||
&mqcc, &mqrc)
|
||||
|
||||
godatalen := int(datalen)
|
||||
copyMDfromC(&mqmd, gomd)
|
||||
copyGMOfromC(&mqgmo, gogmo)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQGET",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return 0, &mqreturn
|
||||
}
|
||||
|
||||
return godatalen, nil
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Inq is the function to inquire on an attribute of an object
|
||||
|
||||
Slices are returned containing the integer attributes, and all the
|
||||
strings concatenated into a single buffer - the caller needs to know
|
||||
how long each field in that buffer will be.
|
||||
|
||||
The caller passes in how many integer selectors are expected to be
|
||||
returned, as well as the maximum length of the char buffer to be returned
|
||||
*/
|
||||
func (object MQObject) Inq(goSelectors []int32, intAttrCount int, charAttrLen int) ([]int32,
|
||||
[]byte, error) {
|
||||
var mqrc C.MQLONG
|
||||
var mqcc C.MQLONG
|
||||
var mqCharAttrs C.PMQCHAR
|
||||
var goCharAttrs []byte
|
||||
var goIntAttrs []int32
|
||||
var ptr C.PMQLONG
|
||||
|
||||
if intAttrCount > 0 {
|
||||
goIntAttrs = make([]int32, intAttrCount)
|
||||
ptr = (C.PMQLONG)(unsafe.Pointer(&goIntAttrs[0]))
|
||||
} else {
|
||||
ptr = nil
|
||||
}
|
||||
if charAttrLen > 0 {
|
||||
mqCharAttrs = (C.PMQCHAR)(C.malloc(C.size_t(charAttrLen)))
|
||||
defer C.free(unsafe.Pointer(mqCharAttrs))
|
||||
} else {
|
||||
mqCharAttrs = nil
|
||||
}
|
||||
|
||||
// Pass in the selectors directly
|
||||
C.MQINQ(object.qMgr.hConn, object.hObj,
|
||||
C.MQLONG(len(goSelectors)),
|
||||
C.PMQLONG(unsafe.Pointer(&goSelectors[0])),
|
||||
C.MQLONG(intAttrCount),
|
||||
ptr,
|
||||
C.MQLONG(charAttrLen),
|
||||
mqCharAttrs,
|
||||
&mqcc, &mqrc)
|
||||
|
||||
mqreturn := MQReturn{MQCC: int32(mqcc),
|
||||
MQRC: int32(mqrc),
|
||||
verb: "MQINQ",
|
||||
}
|
||||
|
||||
if mqcc != C.MQCC_OK {
|
||||
return nil, nil, &mqreturn
|
||||
}
|
||||
|
||||
if charAttrLen > 0 {
|
||||
goCharAttrs = C.GoBytes(unsafe.Pointer(mqCharAttrs), C.int(charAttrLen))
|
||||
}
|
||||
|
||||
return goIntAttrs, goCharAttrs, nil
|
||||
}
|
||||
210
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQCD.go
generated
vendored
Normal file
210
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQCD.go
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
#include <cmqxc.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
MQCD is a structure containing the MQ Channel Definition (MQCD)
|
||||
Only fields relevant to a client connection are included in the
|
||||
Go version of this structure.
|
||||
*/
|
||||
type MQCD struct {
|
||||
ChannelName string
|
||||
ConnectionName string
|
||||
DiscInterval int32
|
||||
SecurityExit string
|
||||
SecurityUserData string
|
||||
MaxMsgLength int32
|
||||
HeartbeatInterval int32
|
||||
SSLCipherSpec string
|
||||
SSLPeerName string
|
||||
SSLClientAuth int32
|
||||
KeepAliveInterval int32
|
||||
SharingConversations int32
|
||||
PropertyControl int32
|
||||
ClientChannelWeight int32
|
||||
ConnectionAffinity int32
|
||||
DefReconnect int32
|
||||
CertificateLabel string
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQCD fills in default values for the MQCD structure, based on the
|
||||
MQCD_CLIENT_CONN_DEFAULT
|
||||
*/
|
||||
func NewMQCD() *MQCD {
|
||||
|
||||
cd := new(MQCD)
|
||||
|
||||
cd.ChannelName = ""
|
||||
cd.DiscInterval = 6000
|
||||
cd.SecurityExit = ""
|
||||
cd.SecurityUserData = ""
|
||||
cd.MaxMsgLength = 4194304
|
||||
cd.ConnectionName = ""
|
||||
cd.HeartbeatInterval = 1
|
||||
cd.SSLCipherSpec = ""
|
||||
cd.SSLPeerName = ""
|
||||
cd.SSLClientAuth = int32(C.MQSCA_REQUIRED)
|
||||
cd.KeepAliveInterval = -1
|
||||
cd.SharingConversations = 10
|
||||
cd.PropertyControl = int32(C.MQPROP_COMPATIBILITY)
|
||||
cd.ClientChannelWeight = 0
|
||||
cd.ConnectionAffinity = int32(C.MQCAFTY_PREFERRED)
|
||||
cd.DefReconnect = int32(C.MQRCN_NO)
|
||||
cd.CertificateLabel = ""
|
||||
|
||||
return cd
|
||||
}
|
||||
|
||||
/*
|
||||
It is expected that copyXXtoC and copyXXfromC will be called as
|
||||
matching pairs.
|
||||
Most of the fields in the MQCD structure are not relevant for client
|
||||
channels, but the default settings of such fields may still not be 0
|
||||
or NULL (they are just ignored). The values here are taken from
|
||||
MQ_CLIENT_CONN_DEFAULT structure for consistency.
|
||||
*/
|
||||
func copyCDtoC(mqcd *C.MQCD, gocd *MQCD) {
|
||||
|
||||
setMQIString((*C.char)(&mqcd.ChannelName[0]), gocd.ChannelName, C.MQ_CHANNEL_NAME_LENGTH)
|
||||
mqcd.Version = C.MQCD_VERSION_11 // The version this is written to match
|
||||
mqcd.ChannelType = C.MQCHT_CLNTCONN
|
||||
mqcd.TransportType = C.MQXPT_TCP
|
||||
setMQIString((*C.char)(&mqcd.Desc[0]), "", C.MQ_CHANNEL_DESC_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.QMgrName[0]), "", C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.XmitQName[0]), "", C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.ShortConnectionName[0]), "", C.MQ_SHORT_CONN_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.MCAName[0]), "", C.MQ_MCA_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.ModeName[0]), "", C.MQ_MODE_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.TpName[0]), "", C.MQ_TP_NAME_LENGTH)
|
||||
mqcd.BatchSize = 50
|
||||
mqcd.DiscInterval = 6000
|
||||
mqcd.ShortRetryCount = 10
|
||||
mqcd.ShortRetryInterval = 60
|
||||
mqcd.LongRetryCount = 999999999
|
||||
mqcd.LongRetryInterval = 1200
|
||||
setMQIString((*C.char)(&mqcd.SecurityExit[0]), gocd.SecurityExit, C.MQ_EXIT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.MsgExit[0]), "", C.MQ_EXIT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.SendExit[0]), "", C.MQ_EXIT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.ReceiveExit[0]), "", C.MQ_EXIT_NAME_LENGTH)
|
||||
mqcd.SeqNumberWrap = 999999999
|
||||
mqcd.MaxMsgLength = C.MQLONG(gocd.MaxMsgLength)
|
||||
mqcd.PutAuthority = C.MQPA_DEFAULT
|
||||
mqcd.DataConversion = C.MQCDC_NO_SENDER_CONVERSION
|
||||
setMQIString((*C.char)(&mqcd.SecurityUserData[0]), gocd.SecurityUserData, C.MQ_EXIT_DATA_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.MsgUserData[0]), "", C.MQ_EXIT_DATA_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.SendUserData[0]), "", C.MQ_EXIT_DATA_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.ReceiveUserData[0]), "", C.MQ_EXIT_DATA_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.UserIdentifier[0]), "", C.MQ_USER_ID_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.Password[0]), "", C.MQ_PASSWORD_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.MCAUserIdentifier[0]), "", C.MQ_USER_ID_LENGTH)
|
||||
mqcd.MCAType = C.MQMCAT_PROCESS
|
||||
setMQIString((*C.char)(&mqcd.ConnectionName[0]), gocd.ConnectionName, C.MQ_CONN_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.RemoteUserIdentifier[0]), "", C.MQ_USER_ID_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.RemotePassword[0]), "", C.MQ_PASSWORD_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.MsgRetryExit[0]), "", C.MQ_EXIT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.MsgRetryUserData[0]), "", C.MQ_EXIT_DATA_LENGTH)
|
||||
mqcd.MsgRetryCount = 10
|
||||
mqcd.MsgRetryInterval = 1000
|
||||
mqcd.HeartbeatInterval = 1
|
||||
mqcd.BatchInterval = 0
|
||||
mqcd.NonPersistentMsgSpeed = C.MQNPMS_FAST
|
||||
mqcd.StrucLength = C.MQCD_LENGTH_11
|
||||
mqcd.ExitNameLength = C.MQ_EXIT_NAME_LENGTH
|
||||
mqcd.ExitDataLength = C.MQ_EXIT_DATA_LENGTH
|
||||
mqcd.MsgExitsDefined = 0
|
||||
mqcd.SendExitsDefined = 0
|
||||
mqcd.ReceiveExitsDefined = 0
|
||||
mqcd.MsgExitPtr = C.MQPTR(nil)
|
||||
mqcd.MsgUserDataPtr = C.MQPTR(nil)
|
||||
mqcd.SendExitPtr = C.MQPTR(nil)
|
||||
mqcd.SendUserDataPtr = C.MQPTR(nil)
|
||||
mqcd.ReceiveExitPtr = C.MQPTR(nil)
|
||||
mqcd.ReceiveUserDataPtr = C.MQPTR(nil)
|
||||
mqcd.ClusterPtr = C.MQPTR(nil)
|
||||
mqcd.ClustersDefined = 0
|
||||
mqcd.NetworkPriority = 0
|
||||
mqcd.LongMCAUserIdLength = 0
|
||||
mqcd.LongRemoteUserIdLength = 0
|
||||
mqcd.LongMCAUserIdPtr = C.MQPTR(nil)
|
||||
mqcd.LongRemoteUserIdPtr = C.MQPTR(nil)
|
||||
C.memset((unsafe.Pointer)(&mqcd.MCASecurityId[0]), 0, C.MQ_SECURITY_ID_LENGTH)
|
||||
C.memset((unsafe.Pointer)(&mqcd.RemoteSecurityId[0]), 0, C.MQ_SECURITY_ID_LENGTH)
|
||||
setMQIString((*C.char)(&mqcd.SSLCipherSpec[0]), gocd.SSLCipherSpec, C.MQ_SSL_CIPHER_SPEC_LENGTH)
|
||||
mqcd.SSLPeerNamePtr = C.MQPTR(nil)
|
||||
mqcd.SSLPeerNameLength = 0
|
||||
if gocd.SSLPeerName != "" {
|
||||
mqcd.SSLPeerNamePtr = C.MQPTR(unsafe.Pointer(C.CString(gocd.SSLPeerName)))
|
||||
mqcd.SSLPeerNameLength = C.MQLONG(len(gocd.SSLPeerName))
|
||||
}
|
||||
mqcd.SSLClientAuth = C.MQLONG(gocd.SSLClientAuth)
|
||||
mqcd.KeepAliveInterval = C.MQLONG(gocd.KeepAliveInterval)
|
||||
setMQIString((*C.char)(&mqcd.LocalAddress[0]), "", C.MQ_LOCAL_ADDRESS_LENGTH)
|
||||
mqcd.BatchHeartbeat = 0
|
||||
for i := 0; i < 2; i++ {
|
||||
mqcd.HdrCompList[i] = C.MQCOMPRESS_NOT_AVAILABLE
|
||||
}
|
||||
for i := 0; i < 16; i++ {
|
||||
mqcd.MsgCompList[i] = C.MQCOMPRESS_NOT_AVAILABLE
|
||||
}
|
||||
mqcd.CLWLChannelRank = 0
|
||||
mqcd.CLWLChannelPriority = 0
|
||||
mqcd.CLWLChannelWeight = 50
|
||||
mqcd.ChannelMonitoring = C.MQMON_OFF
|
||||
mqcd.ChannelStatistics = C.MQMON_OFF
|
||||
mqcd.SharingConversations = C.MQLONG(gocd.SharingConversations)
|
||||
mqcd.PropertyControl = C.MQLONG(gocd.PropertyControl)
|
||||
mqcd.MaxInstances = 999999999
|
||||
mqcd.MaxInstancesPerClient = 999999999
|
||||
mqcd.ClientChannelWeight = C.MQLONG(gocd.ClientChannelWeight)
|
||||
mqcd.ConnectionAffinity = C.MQLONG(gocd.ConnectionAffinity)
|
||||
mqcd.BatchDataLimit = 5000
|
||||
mqcd.UseDLQ = C.MQUSEDLQ_YES
|
||||
mqcd.DefReconnect = C.MQLONG(gocd.DefReconnect)
|
||||
setMQIString((*C.char)(&mqcd.CertificateLabel[0]), gocd.CertificateLabel, C.MQ_CERT_LABEL_LENGTH)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
Most of the parameters in the MQCD are input only.
|
||||
Just need to clear up anything that was allocated in the copyCDtoC function
|
||||
*/
|
||||
func copyCDfromC(mqcd *C.MQCD, gocd *MQCD) {
|
||||
|
||||
if mqcd.SSLPeerNamePtr != nil {
|
||||
C.free(unsafe.Pointer(mqcd.SSLPeerNamePtr))
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
193
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQCNO.go
generated
vendored
Normal file
193
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQCNO.go
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
#include <cmqxc.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
/*
|
||||
MQCNO is a structure containing the MQ Connection Options (MQCNO)
|
||||
Note that only a subset of the real structure is exposed in this
|
||||
version.
|
||||
*/
|
||||
type MQCNO struct {
|
||||
Version int32
|
||||
Options int32
|
||||
SecurityParms *MQCSP
|
||||
CCDTUrl string
|
||||
ClientConn *MQCD
|
||||
SSLConfig *MQSCO
|
||||
}
|
||||
|
||||
/*
|
||||
MQCSP is a structure containing the MQ Security Parameters (MQCSP)
|
||||
*/
|
||||
type MQCSP struct {
|
||||
AuthenticationType int32
|
||||
UserId string
|
||||
Password string
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQCNO fills in default values for the MQCNO structure
|
||||
*/
|
||||
func NewMQCNO() *MQCNO {
|
||||
|
||||
cno := new(MQCNO)
|
||||
cno.Version = int32(C.MQCNO_VERSION_1)
|
||||
cno.Options = int32(C.MQCNO_NONE)
|
||||
cno.SecurityParms = nil
|
||||
cno.ClientConn = nil
|
||||
|
||||
return cno
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQCSP fills in default values for the MQCSP structure
|
||||
*/
|
||||
func NewMQCSP() *MQCSP {
|
||||
|
||||
csp := new(MQCSP)
|
||||
csp.AuthenticationType = int32(C.MQCSP_AUTH_NONE)
|
||||
csp.UserId = ""
|
||||
csp.Password = ""
|
||||
|
||||
return csp
|
||||
}
|
||||
|
||||
func copyCNOtoC(mqcno *C.MQCNO, gocno *MQCNO) {
|
||||
var i int
|
||||
var mqcsp C.PMQCSP
|
||||
var mqcd C.PMQCD
|
||||
var mqsco C.PMQSCO
|
||||
|
||||
setMQIString((*C.char)(&mqcno.StrucId[0]), "CNO ", 4)
|
||||
mqcno.Version = C.MQLONG(gocno.Version)
|
||||
mqcno.Options = C.MQLONG(gocno.Options)
|
||||
|
||||
for i = 0; i < C.MQ_CONN_TAG_LENGTH; i++ {
|
||||
mqcno.ConnTag[i] = 0
|
||||
}
|
||||
for i = 0; i < C.MQ_CONNECTION_ID_LENGTH; i++ {
|
||||
mqcno.ConnectionId[i] = 0
|
||||
}
|
||||
|
||||
mqcno.ClientConnOffset = 0
|
||||
if gocno.ClientConn != nil {
|
||||
gocd := gocno.ClientConn
|
||||
mqcd = C.PMQCD(C.malloc(C.MQCD_LENGTH_11))
|
||||
copyCDtoC(mqcd, gocd)
|
||||
mqcno.ClientConnPtr = C.MQPTR(mqcd)
|
||||
if gocno.Version < 2 {
|
||||
mqcno.Version = C.MQCNO_VERSION_2
|
||||
}
|
||||
} else {
|
||||
mqcno.ClientConnPtr = nil
|
||||
}
|
||||
|
||||
mqcno.SSLConfigOffset = 0
|
||||
if gocno.SSLConfig != nil {
|
||||
gosco := gocno.SSLConfig
|
||||
mqsco = C.PMQSCO(C.malloc(C.MQSCO_LENGTH_5))
|
||||
copySCOtoC(mqsco, gosco)
|
||||
mqcno.SSLConfigPtr = C.PMQSCO(mqsco)
|
||||
if gocno.Version < 4 {
|
||||
mqcno.Version = C.MQCNO_VERSION_4
|
||||
}
|
||||
} else {
|
||||
mqcno.SSLConfigPtr = nil
|
||||
}
|
||||
|
||||
mqcno.SecurityParmsOffset = 0
|
||||
if gocno.SecurityParms != nil {
|
||||
gocsp := gocno.SecurityParms
|
||||
|
||||
mqcsp = C.PMQCSP(C.malloc(C.MQCSP_LENGTH_1))
|
||||
setMQIString((*C.char)(&mqcsp.StrucId[0]), "CSP ", 4)
|
||||
mqcsp.Version = C.MQCSP_VERSION_1
|
||||
mqcsp.AuthenticationType = C.MQLONG(gocsp.AuthenticationType)
|
||||
mqcsp.CSPUserIdOffset = 0
|
||||
mqcsp.CSPPasswordOffset = 0
|
||||
|
||||
if gocsp.UserId != "" {
|
||||
mqcsp.AuthenticationType = C.MQLONG(C.MQCSP_AUTH_USER_ID_AND_PWD)
|
||||
mqcsp.CSPUserIdPtr = C.MQPTR(unsafe.Pointer(C.CString(gocsp.UserId)))
|
||||
mqcsp.CSPUserIdLength = C.MQLONG(len(gocsp.UserId))
|
||||
}
|
||||
if gocsp.Password != "" {
|
||||
mqcsp.CSPPasswordPtr = C.MQPTR(unsafe.Pointer(C.CString(gocsp.Password)))
|
||||
mqcsp.CSPPasswordLength = C.MQLONG(len(gocsp.Password))
|
||||
}
|
||||
mqcno.SecurityParmsPtr = C.PMQCSP(mqcsp)
|
||||
if gocno.Version < 5 {
|
||||
mqcno.Version = C.MQCNO_VERSION_5
|
||||
}
|
||||
|
||||
} else {
|
||||
mqcno.SecurityParmsPtr = nil
|
||||
}
|
||||
|
||||
mqcno.CCDTUrlOffset = 0
|
||||
if len(gocno.CCDTUrl) != 0 {
|
||||
mqcno.CCDTUrlPtr = C.PMQCHAR(unsafe.Pointer(C.CString(gocno.CCDTUrl)))
|
||||
mqcno.CCDTUrlLength = C.MQLONG(len(gocno.CCDTUrl))
|
||||
} else {
|
||||
mqcno.CCDTUrlPtr = nil
|
||||
mqcno.CCDTUrlLength = 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func copyCNOfromC(mqcno *C.MQCNO, gocno *MQCNO) {
|
||||
|
||||
if mqcno.SecurityParmsPtr != nil {
|
||||
if mqcno.SecurityParmsPtr.CSPUserIdPtr != nil {
|
||||
C.free(unsafe.Pointer(mqcno.SecurityParmsPtr.CSPUserIdPtr))
|
||||
}
|
||||
// Set memory to 0 for area that held a password
|
||||
if mqcno.SecurityParmsPtr.CSPPasswordPtr != nil {
|
||||
C.memset((unsafe.Pointer)(mqcno.SecurityParmsPtr.CSPPasswordPtr), 0, C.size_t(mqcno.SecurityParmsPtr.CSPPasswordLength))
|
||||
C.free(unsafe.Pointer(mqcno.SecurityParmsPtr.CSPPasswordPtr))
|
||||
}
|
||||
C.free(unsafe.Pointer(mqcno.SecurityParmsPtr))
|
||||
}
|
||||
|
||||
if mqcno.ClientConnPtr != nil {
|
||||
copyCDfromC(C.PMQCD(mqcno.ClientConnPtr), gocno.ClientConn)
|
||||
C.free(unsafe.Pointer(mqcno.ClientConnPtr))
|
||||
}
|
||||
|
||||
if mqcno.SSLConfigPtr != nil {
|
||||
copySCOfromC(C.PMQSCO(mqcno.SSLConfigPtr), gocno.SSLConfig)
|
||||
C.free(unsafe.Pointer(mqcno.SSLConfigPtr))
|
||||
}
|
||||
|
||||
if mqcno.CCDTUrlPtr != nil {
|
||||
C.free(unsafe.Pointer(mqcno.CCDTUrlPtr))
|
||||
}
|
||||
return
|
||||
}
|
||||
122
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQGMO.go
generated
vendored
Normal file
122
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQGMO.go
generated
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
import "bytes"
|
||||
|
||||
/*
|
||||
MQGMO is a structure containing the MQ Get Message Options (MQGMO)
|
||||
*/
|
||||
type MQGMO struct {
|
||||
Version int32
|
||||
Options int32
|
||||
WaitInterval int32
|
||||
Signal1 int32
|
||||
Signal2 int32
|
||||
ResolvedQName string
|
||||
MatchOptions int32
|
||||
GroupStatus rune
|
||||
SegmentStatus rune
|
||||
Segmentation rune
|
||||
Reserved1 rune
|
||||
MsgToken []byte
|
||||
ReturnedLength int32
|
||||
Reserved2 int32
|
||||
MsgHandle C.MQHMSG
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQGMO fills in default values for the MQGMO structure
|
||||
*/
|
||||
func NewMQGMO() *MQGMO {
|
||||
|
||||
gmo := new(MQGMO)
|
||||
gmo.Version = int32(C.MQGMO_VERSION_1)
|
||||
gmo.Options = int32(C.MQGMO_NO_WAIT + C.MQGMO_PROPERTIES_AS_Q_DEF)
|
||||
gmo.WaitInterval = int32(C.MQWI_UNLIMITED)
|
||||
gmo.Signal1 = 0
|
||||
gmo.Signal2 = 0
|
||||
gmo.ResolvedQName = ""
|
||||
gmo.MatchOptions = int32(C.MQMO_MATCH_MSG_ID + C.MQMO_MATCH_CORREL_ID)
|
||||
gmo.GroupStatus = rune(C.MQGS_NOT_IN_GROUP)
|
||||
gmo.SegmentStatus = rune(C.MQSS_NOT_A_SEGMENT)
|
||||
gmo.Segmentation = rune(C.MQSEG_INHIBITED)
|
||||
gmo.Reserved1 = ' '
|
||||
gmo.MsgToken = bytes.Repeat([]byte{0}, C.MQ_MSG_TOKEN_LENGTH)
|
||||
gmo.ReturnedLength = int32(C.MQRL_UNDEFINED)
|
||||
gmo.Reserved2 = 0
|
||||
gmo.MsgHandle = C.MQHM_NONE
|
||||
|
||||
return gmo
|
||||
}
|
||||
|
||||
func copyGMOtoC(mqgmo *C.MQGMO, gogmo *MQGMO) {
|
||||
var i int
|
||||
|
||||
setMQIString((*C.char)(&mqgmo.StrucId[0]), "GMO ", 4)
|
||||
mqgmo.Version = C.MQLONG(gogmo.Version)
|
||||
mqgmo.Options = C.MQLONG(gogmo.Options)
|
||||
mqgmo.WaitInterval = C.MQLONG(gogmo.WaitInterval)
|
||||
mqgmo.Signal1 = C.MQLONG(gogmo.Signal1)
|
||||
mqgmo.Signal2 = C.MQLONG(gogmo.Signal2)
|
||||
setMQIString((*C.char)(&mqgmo.ResolvedQName[0]), gogmo.ResolvedQName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
mqgmo.MatchOptions = C.MQLONG(gogmo.MatchOptions)
|
||||
mqgmo.GroupStatus = C.MQCHAR(gogmo.GroupStatus)
|
||||
mqgmo.SegmentStatus = C.MQCHAR(gogmo.SegmentStatus)
|
||||
mqgmo.Segmentation = C.MQCHAR(gogmo.Segmentation)
|
||||
mqgmo.Reserved1 = C.MQCHAR(gogmo.Reserved1)
|
||||
for i = 0; i < C.MQ_MSG_TOKEN_LENGTH; i++ {
|
||||
mqgmo.MsgToken[i] = C.MQBYTE(gogmo.MsgToken[i])
|
||||
}
|
||||
mqgmo.ReturnedLength = C.MQLONG(gogmo.ReturnedLength)
|
||||
mqgmo.Reserved2 = C.MQLONG(gogmo.Reserved2)
|
||||
mqgmo.MsgHandle = gogmo.MsgHandle
|
||||
return
|
||||
}
|
||||
|
||||
func copyGMOfromC(mqgmo *C.MQGMO, gogmo *MQGMO) {
|
||||
var i int
|
||||
|
||||
gogmo.Version = int32(mqgmo.Version)
|
||||
gogmo.Options = int32(mqgmo.Options)
|
||||
gogmo.WaitInterval = int32(mqgmo.WaitInterval)
|
||||
gogmo.Signal1 = int32(mqgmo.Signal1)
|
||||
gogmo.Signal2 = int32(mqgmo.Signal2)
|
||||
gogmo.ResolvedQName = C.GoStringN((*C.char)(&mqgmo.ResolvedQName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
gogmo.MatchOptions = int32(mqgmo.MatchOptions)
|
||||
gogmo.GroupStatus = rune(mqgmo.GroupStatus)
|
||||
gogmo.SegmentStatus = rune(mqgmo.SegmentStatus)
|
||||
gogmo.Segmentation = rune(mqgmo.Segmentation)
|
||||
gogmo.Reserved1 = rune(mqgmo.Reserved1)
|
||||
for i = 0; i < C.MQ_MSG_TOKEN_LENGTH; i++ {
|
||||
gogmo.MsgToken[i] = (byte)(mqgmo.MsgToken[i])
|
||||
}
|
||||
gogmo.ReturnedLength = int32(mqgmo.ReturnedLength)
|
||||
gogmo.Reserved2 = int32(mqgmo.Reserved2)
|
||||
gogmo.MsgHandle = mqgmo.MsgHandle
|
||||
return
|
||||
}
|
||||
196
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQMD.go
generated
vendored
Normal file
196
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQMD.go
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
)
|
||||
|
||||
/*
|
||||
MQMD is a structure containing the MQ Message Descriptor (MQMD)
|
||||
*/
|
||||
type MQMD struct {
|
||||
Version int32
|
||||
Report int32
|
||||
MsgType int32
|
||||
Expiry int32
|
||||
Feedback int32
|
||||
Encoding int32
|
||||
CodedCharSetId int32
|
||||
Format string
|
||||
Priority int32
|
||||
Persistence int32
|
||||
MsgId []byte
|
||||
CorrelId []byte
|
||||
BackoutCount int32
|
||||
ReplyToQ string
|
||||
ReplyToQMgr string
|
||||
UserIdentifier string
|
||||
AccountingToken []byte
|
||||
ApplIdentityData string
|
||||
PutApplType int32
|
||||
PutApplName string
|
||||
PutDate string
|
||||
PutTime string
|
||||
ApplOriginData string
|
||||
GroupId []byte
|
||||
MsgSeqNumber int32
|
||||
Offset int32
|
||||
MsgFlags int32
|
||||
OriginalLength int32
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQMD fills in default values for the MQMD structure
|
||||
*/
|
||||
func NewMQMD() *MQMD {
|
||||
md := new(MQMD)
|
||||
md.Version = int32(C.MQMD_VERSION_1)
|
||||
md.Report = int32(C.MQRO_NONE)
|
||||
md.MsgType = int32(C.MQMT_DATAGRAM)
|
||||
md.Expiry = int32(C.MQEI_UNLIMITED)
|
||||
md.Feedback = int32(C.MQFB_NONE)
|
||||
md.Encoding = int32(C.MQENC_NATIVE)
|
||||
md.CodedCharSetId = int32(C.MQCCSI_Q_MGR)
|
||||
md.Format = " "
|
||||
md.Priority = int32(C.MQPRI_PRIORITY_AS_Q_DEF)
|
||||
md.Persistence = int32(C.MQPER_PERSISTENCE_AS_Q_DEF)
|
||||
md.MsgId = bytes.Repeat([]byte{0}, C.MQ_MSG_ID_LENGTH)
|
||||
md.CorrelId = bytes.Repeat([]byte{0}, C.MQ_CORREL_ID_LENGTH)
|
||||
md.BackoutCount = 0
|
||||
md.ReplyToQ = ""
|
||||
md.ReplyToQMgr = ""
|
||||
md.UserIdentifier = ""
|
||||
md.AccountingToken = bytes.Repeat([]byte{0}, C.MQ_ACCOUNTING_TOKEN_LENGTH)
|
||||
md.ApplIdentityData = ""
|
||||
md.PutApplType = int32(C.MQAT_NO_CONTEXT)
|
||||
md.PutApplName = ""
|
||||
md.PutDate = ""
|
||||
md.PutTime = ""
|
||||
md.ApplOriginData = ""
|
||||
md.GroupId = bytes.Repeat([]byte{0}, C.MQ_GROUP_ID_LENGTH)
|
||||
md.MsgSeqNumber = 1
|
||||
md.Offset = 0
|
||||
md.MsgFlags = int32(C.MQMF_NONE)
|
||||
md.OriginalLength = int32(C.MQOL_UNDEFINED)
|
||||
|
||||
return md
|
||||
}
|
||||
|
||||
func copyMDtoC(mqmd *C.MQMD, gomd *MQMD) {
|
||||
var i int
|
||||
setMQIString((*C.char)(&mqmd.StrucId[0]), "MD ", 4)
|
||||
mqmd.Version = C.MQLONG(gomd.Version)
|
||||
mqmd.Report = C.MQLONG(gomd.Report)
|
||||
mqmd.MsgType = C.MQLONG(gomd.MsgType)
|
||||
mqmd.Expiry = C.MQLONG(gomd.Expiry)
|
||||
mqmd.Feedback = C.MQLONG(gomd.Feedback)
|
||||
mqmd.Encoding = C.MQLONG(gomd.Encoding)
|
||||
mqmd.CodedCharSetId = C.MQLONG(gomd.CodedCharSetId)
|
||||
setMQIString((*C.char)(&mqmd.Format[0]), gomd.Format, C.MQ_FORMAT_LENGTH)
|
||||
mqmd.Priority = C.MQLONG(gomd.Priority)
|
||||
mqmd.Persistence = C.MQLONG(gomd.Persistence)
|
||||
|
||||
for i = 0; i < C.MQ_MSG_ID_LENGTH; i++ {
|
||||
mqmd.MsgId[i] = C.MQBYTE(gomd.MsgId[i])
|
||||
}
|
||||
for i = 0; i < C.MQ_CORREL_ID_LENGTH; i++ {
|
||||
mqmd.CorrelId[i] = C.MQBYTE(gomd.CorrelId[i])
|
||||
}
|
||||
mqmd.BackoutCount = C.MQLONG(gomd.BackoutCount)
|
||||
|
||||
setMQIString((*C.char)(&mqmd.ReplyToQ[0]), gomd.ReplyToQ, C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqmd.ReplyToQMgr[0]), gomd.ReplyToQMgr, C.MQ_OBJECT_NAME_LENGTH)
|
||||
|
||||
setMQIString((*C.char)(&mqmd.UserIdentifier[0]), gomd.UserIdentifier, C.MQ_USER_ID_LENGTH)
|
||||
for i = 0; i < C.MQ_ACCOUNTING_TOKEN_LENGTH; i++ {
|
||||
mqmd.AccountingToken[i] = C.MQBYTE(gomd.AccountingToken[i])
|
||||
}
|
||||
setMQIString((*C.char)(&mqmd.ApplIdentityData[0]), gomd.ApplIdentityData, C.MQ_APPL_IDENTITY_DATA_LENGTH)
|
||||
mqmd.PutApplType = C.MQLONG(gomd.PutApplType)
|
||||
setMQIString((*C.char)(&mqmd.PutApplName[0]), gomd.PutApplName, C.MQ_PUT_APPL_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqmd.PutDate[0]), gomd.PutDate, C.MQ_PUT_DATE_LENGTH)
|
||||
setMQIString((*C.char)(&mqmd.PutTime[0]), gomd.PutTime, C.MQ_PUT_TIME_LENGTH)
|
||||
setMQIString((*C.char)(&mqmd.ApplOriginData[0]), gomd.ApplOriginData, C.MQ_APPL_ORIGIN_DATA_LENGTH)
|
||||
|
||||
for i = 0; i < C.MQ_GROUP_ID_LENGTH; i++ {
|
||||
mqmd.GroupId[i] = C.MQBYTE(gomd.GroupId[i])
|
||||
}
|
||||
mqmd.MsgSeqNumber = C.MQLONG(gomd.MsgSeqNumber)
|
||||
mqmd.Offset = C.MQLONG(gomd.Offset)
|
||||
mqmd.MsgFlags = C.MQLONG(gomd.MsgFlags)
|
||||
mqmd.OriginalLength = C.MQLONG(gomd.OriginalLength)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func copyMDfromC(mqmd *C.MQMD, gomd *MQMD) {
|
||||
var i int
|
||||
gomd.Version = int32(mqmd.Version)
|
||||
gomd.Report = int32(mqmd.Report)
|
||||
gomd.MsgType = int32(mqmd.MsgType)
|
||||
gomd.Expiry = int32(mqmd.Expiry)
|
||||
gomd.Feedback = int32(mqmd.Feedback)
|
||||
gomd.Encoding = int32(mqmd.Encoding)
|
||||
gomd.CodedCharSetId = int32(mqmd.CodedCharSetId)
|
||||
gomd.Format = C.GoStringN((*C.char)(&mqmd.Format[0]), C.MQ_FORMAT_LENGTH)
|
||||
gomd.Priority = int32(mqmd.Priority)
|
||||
gomd.Persistence = int32(mqmd.Persistence)
|
||||
|
||||
for i = 0; i < C.MQ_MSG_ID_LENGTH; i++ {
|
||||
gomd.MsgId[i] = (byte)(mqmd.MsgId[i])
|
||||
}
|
||||
for i = 0; i < C.MQ_CORREL_ID_LENGTH; i++ {
|
||||
gomd.CorrelId[i] = (byte)(mqmd.CorrelId[i])
|
||||
}
|
||||
gomd.BackoutCount = int32(mqmd.BackoutCount)
|
||||
|
||||
gomd.ReplyToQ = C.GoStringN((*C.char)(&mqmd.ReplyToQ[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
gomd.ReplyToQMgr = C.GoStringN((*C.char)(&mqmd.ReplyToQMgr[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
|
||||
gomd.UserIdentifier = C.GoStringN((*C.char)(&mqmd.UserIdentifier[0]), C.MQ_USER_ID_LENGTH)
|
||||
for i = 0; i < C.MQ_ACCOUNTING_TOKEN_LENGTH; i++ {
|
||||
gomd.AccountingToken[i] = (byte)(mqmd.AccountingToken[i])
|
||||
}
|
||||
gomd.ApplIdentityData = C.GoStringN((*C.char)(&mqmd.ApplIdentityData[0]), C.MQ_APPL_IDENTITY_DATA_LENGTH)
|
||||
gomd.PutApplType = int32(mqmd.PutApplType)
|
||||
gomd.PutApplName = C.GoStringN((*C.char)(&mqmd.PutApplName[0]), C.MQ_PUT_APPL_NAME_LENGTH)
|
||||
gomd.PutDate = C.GoStringN((*C.char)(&mqmd.PutDate[0]), C.MQ_PUT_DATE_LENGTH)
|
||||
gomd.PutTime = C.GoStringN((*C.char)(&mqmd.PutTime[0]), C.MQ_PUT_TIME_LENGTH)
|
||||
gomd.ApplOriginData = C.GoStringN((*C.char)(&mqmd.ApplOriginData[0]), C.MQ_APPL_ORIGIN_DATA_LENGTH)
|
||||
|
||||
for i = 0; i < C.MQ_GROUP_ID_LENGTH; i++ {
|
||||
gomd.GroupId[i] = (byte)(mqmd.GroupId[i])
|
||||
}
|
||||
gomd.MsgSeqNumber = int32(mqmd.MsgSeqNumber)
|
||||
gomd.Offset = int32(mqmd.Offset)
|
||||
gomd.MsgFlags = int32(mqmd.MsgFlags)
|
||||
gomd.OriginalLength = int32(mqmd.OriginalLength)
|
||||
|
||||
return
|
||||
}
|
||||
212
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQOD.go
generated
vendored
Normal file
212
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQOD.go
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
MQOD is a structure containing the MQ Object Descriptor (MQOD)
|
||||
*/
|
||||
type MQOD struct {
|
||||
Version int32
|
||||
ObjectType int32
|
||||
ObjectName string
|
||||
ObjectQMgrName string
|
||||
DynamicQName string
|
||||
AlternateUserId string
|
||||
|
||||
RecsPresent int32
|
||||
KnownDestCount int32
|
||||
UnknownDestCount int32
|
||||
InvalidDestCount int32
|
||||
ObjectRecOffset int32
|
||||
ResponseRecOffset int32
|
||||
|
||||
ObjectRecPtr C.MQPTR
|
||||
ResponseRecPtr C.MQPTR
|
||||
|
||||
AlternateSecurityId []byte
|
||||
ResolvedQName string
|
||||
ResolvedQMgrName string
|
||||
|
||||
ObjectString string
|
||||
SelectionString string
|
||||
ResObjectString string
|
||||
ResolvedType int32
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQOD fills in default values for the MQOD structure
|
||||
*/
|
||||
func NewMQOD() *MQOD {
|
||||
|
||||
od := new(MQOD)
|
||||
od.Version = 1
|
||||
od.ObjectType = C.MQOT_Q
|
||||
od.ObjectName = ""
|
||||
od.ObjectQMgrName = ""
|
||||
od.DynamicQName = "AMQ.*"
|
||||
od.AlternateUserId = ""
|
||||
|
||||
od.RecsPresent = 0
|
||||
od.KnownDestCount = 0
|
||||
od.UnknownDestCount = 0
|
||||
od.InvalidDestCount = 0
|
||||
od.ObjectRecOffset = 0
|
||||
od.ResponseRecOffset = 0
|
||||
|
||||
od.ObjectRecPtr = nil
|
||||
od.ResponseRecPtr = nil
|
||||
|
||||
od.AlternateSecurityId = bytes.Repeat([]byte{0}, C.MQ_SECURITY_ID_LENGTH)
|
||||
od.ResolvedQName = ""
|
||||
od.ResolvedQMgrName = ""
|
||||
|
||||
od.ObjectString = ""
|
||||
od.SelectionString = ""
|
||||
od.ResObjectString = ""
|
||||
od.ResolvedType = C.MQOT_NONE
|
||||
return od
|
||||
}
|
||||
|
||||
/*
|
||||
* It is expected that copyXXtoC and copyXXfromC will be called as
|
||||
* matching pairs. That means that we can handle the MQCHARV type
|
||||
* by allocating storage in the toC function and freeing it in fromC.
|
||||
* If the input string for an MQCHARV type is empty, then we allocate
|
||||
* a fixed length buffer for any potential output.
|
||||
*
|
||||
* In the fromC function, that buffer is freed. Conveniently, we can
|
||||
* free it always, because if we didn't explicitly call malloc(), it was
|
||||
* allocated by C.CString and still needs to be freed.
|
||||
*/
|
||||
func copyODtoC(mqod *C.MQOD, good *MQOD) {
|
||||
var i int
|
||||
const vsbufsize = 10240
|
||||
setMQIString((*C.char)(&mqod.StrucId[0]), "OD ", 4)
|
||||
mqod.Version = C.MQLONG(good.Version)
|
||||
mqod.ObjectType = C.MQLONG(good.ObjectType)
|
||||
setMQIString((*C.char)(&mqod.ObjectName[0]), good.ObjectName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqod.ObjectQMgrName[0]), good.ObjectQMgrName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqod.DynamicQName[0]), good.DynamicQName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqod.AlternateUserId[0]), good.AlternateUserId, C.MQ_USER_ID_LENGTH)
|
||||
|
||||
mqod.RecsPresent = C.MQLONG(good.RecsPresent)
|
||||
mqod.KnownDestCount = C.MQLONG(good.KnownDestCount)
|
||||
mqod.UnknownDestCount = C.MQLONG(good.UnknownDestCount)
|
||||
mqod.InvalidDestCount = C.MQLONG(good.InvalidDestCount)
|
||||
mqod.ObjectRecOffset = C.MQLONG(good.ObjectRecOffset)
|
||||
mqod.ResponseRecOffset = C.MQLONG(good.ResponseRecOffset)
|
||||
|
||||
mqod.ObjectRecPtr = good.ObjectRecPtr
|
||||
mqod.ResponseRecPtr = good.ResponseRecPtr
|
||||
|
||||
for i = 0; i < C.MQ_SECURITY_ID_LENGTH; i++ {
|
||||
mqod.AlternateSecurityId[i] = C.MQBYTE(good.AlternateSecurityId[i])
|
||||
}
|
||||
|
||||
setMQIString((*C.char)(&mqod.ResolvedQName[0]), good.ResolvedQName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqod.ResolvedQMgrName[0]), good.ResolvedQMgrName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
|
||||
mqod.ObjectString.VSLength = (C.MQLONG)(len(good.ObjectString))
|
||||
mqod.ObjectString.VSCCSID = C.MQCCSI_APPL
|
||||
if mqod.ObjectString.VSLength == 0 {
|
||||
mqod.ObjectString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
|
||||
mqod.ObjectString.VSBufSize = vsbufsize
|
||||
} else {
|
||||
mqod.ObjectString.VSPtr = (C.MQPTR)(C.CString(good.ObjectString))
|
||||
}
|
||||
|
||||
mqod.SelectionString.VSLength = (C.MQLONG)(len(good.SelectionString))
|
||||
mqod.SelectionString.VSCCSID = C.MQCCSI_APPL
|
||||
if mqod.SelectionString.VSLength == 0 {
|
||||
mqod.SelectionString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
|
||||
mqod.SelectionString.VSBufSize = vsbufsize
|
||||
} else {
|
||||
mqod.SelectionString.VSPtr = (C.MQPTR)(C.CString(good.SelectionString))
|
||||
}
|
||||
if mqod.SelectionString.VSLength > 0 || mqod.ObjectString.VSLength > 0 {
|
||||
if mqod.Version < C.MQOD_VERSION_4 {
|
||||
mqod.Version = C.MQOD_VERSION_4
|
||||
}
|
||||
}
|
||||
|
||||
mqod.ResObjectString.VSLength = (C.MQLONG)(len(good.ResObjectString))
|
||||
mqod.ResObjectString.VSCCSID = C.MQCCSI_APPL
|
||||
if mqod.ResObjectString.VSLength == 0 {
|
||||
mqod.ResObjectString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
|
||||
mqod.ResObjectString.VSBufSize = vsbufsize
|
||||
} else {
|
||||
mqod.ResObjectString.VSPtr = (C.MQPTR)(C.CString(good.ResObjectString))
|
||||
}
|
||||
|
||||
mqod.ResolvedType = C.MQLONG(good.ResolvedType)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func copyODfromC(mqod *C.MQOD, good *MQOD) {
|
||||
var i int
|
||||
|
||||
good.Version = int32(mqod.Version)
|
||||
good.ObjectType = int32(mqod.ObjectType)
|
||||
good.ObjectName = C.GoStringN((*C.char)(&mqod.ObjectName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
good.ObjectQMgrName = C.GoStringN((*C.char)(&mqod.ObjectQMgrName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
good.DynamicQName = C.GoStringN((*C.char)(&mqod.DynamicQName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
good.AlternateUserId = C.GoStringN((*C.char)(&mqod.AlternateUserId[0]), C.MQ_USER_ID_LENGTH)
|
||||
|
||||
good.RecsPresent = int32(mqod.RecsPresent)
|
||||
good.KnownDestCount = int32(mqod.KnownDestCount)
|
||||
good.UnknownDestCount = int32(mqod.UnknownDestCount)
|
||||
good.InvalidDestCount = int32(mqod.InvalidDestCount)
|
||||
good.ObjectRecOffset = int32(mqod.ObjectRecOffset)
|
||||
good.ResponseRecOffset = int32(mqod.ResponseRecOffset)
|
||||
|
||||
good.ObjectRecPtr = mqod.ObjectRecPtr
|
||||
good.ResponseRecPtr = mqod.ResponseRecPtr
|
||||
|
||||
for i = 0; i < C.MQ_SECURITY_ID_LENGTH; i++ {
|
||||
good.AlternateSecurityId[i] = (byte)(mqod.AlternateSecurityId[i])
|
||||
}
|
||||
|
||||
good.ResolvedQName = C.GoStringN((*C.char)(&mqod.ResolvedQName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
good.ResolvedQMgrName = C.GoStringN((*C.char)(&mqod.ResolvedQMgrName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
|
||||
good.ObjectString = C.GoStringN((*C.char)(mqod.ObjectString.VSPtr), (C.int)(mqod.ObjectString.VSLength))
|
||||
C.free(unsafe.Pointer(mqod.ObjectString.VSPtr))
|
||||
good.SelectionString = C.GoStringN((*C.char)(mqod.SelectionString.VSPtr), (C.int)(mqod.SelectionString.VSLength))
|
||||
C.free(unsafe.Pointer(mqod.SelectionString.VSPtr))
|
||||
good.ResObjectString = C.GoStringN((*C.char)(mqod.ResObjectString.VSPtr), (C.int)(mqod.ResObjectString.VSLength))
|
||||
C.free(unsafe.Pointer(mqod.ResObjectString.VSPtr))
|
||||
good.ResolvedType = int32(mqod.ResolvedType)
|
||||
|
||||
return
|
||||
}
|
||||
143
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQPMO.go
generated
vendored
Normal file
143
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQPMO.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
/*
|
||||
MQPMO is a structure containing the MQ Put MessageOptions (MQPMO)
|
||||
*/
|
||||
type MQPMO struct {
|
||||
Version int32
|
||||
Options int32
|
||||
Timeout int32
|
||||
Context C.MQHOBJ
|
||||
KnownDestCount int32
|
||||
UnknownDestCount int32
|
||||
InvalidDestCount int32
|
||||
ResolvedQName string
|
||||
ResolvedQMgrName string
|
||||
RecsPresent int32
|
||||
PutMsgRecFields int32
|
||||
PutMsgRecOffset int32
|
||||
ResponseRecOffset int32
|
||||
PutMsgRecPtr C.MQPTR
|
||||
ResponseRecPtr C.MQPTR
|
||||
|
||||
OriginalMsgHandle C.MQHMSG
|
||||
NewMsgHandle C.MQHMSG
|
||||
Action int32
|
||||
PubLevel int32
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQPMO fills in default values for the MQPMO structure
|
||||
*/
|
||||
func NewMQPMO() *MQPMO {
|
||||
|
||||
pmo := new(MQPMO)
|
||||
|
||||
pmo.Version = int32(C.MQPMO_VERSION_1)
|
||||
pmo.Options = int32(C.MQPMO_NONE)
|
||||
pmo.Timeout = -1
|
||||
pmo.Context = 0
|
||||
pmo.KnownDestCount = 0
|
||||
pmo.UnknownDestCount = 0
|
||||
pmo.InvalidDestCount = 0
|
||||
pmo.ResolvedQName = ""
|
||||
pmo.ResolvedQMgrName = ""
|
||||
pmo.RecsPresent = 0
|
||||
pmo.PutMsgRecFields = 0
|
||||
pmo.PutMsgRecOffset = 0
|
||||
pmo.ResponseRecOffset = 0
|
||||
pmo.PutMsgRecPtr = nil
|
||||
pmo.ResponseRecPtr = nil
|
||||
|
||||
pmo.OriginalMsgHandle = C.MQHM_NONE
|
||||
pmo.NewMsgHandle = C.MQHM_NONE
|
||||
pmo.Action = int32(C.MQACTP_NEW)
|
||||
pmo.PubLevel = 9
|
||||
|
||||
return pmo
|
||||
}
|
||||
|
||||
func copyPMOtoC(mqpmo *C.MQPMO, gopmo *MQPMO) {
|
||||
|
||||
setMQIString((*C.char)(&mqpmo.StrucId[0]), "PMO ", 4)
|
||||
mqpmo.Version = C.MQLONG(gopmo.Version)
|
||||
|
||||
mqpmo.Options = C.MQLONG(gopmo.Options)
|
||||
mqpmo.Timeout = C.MQLONG(gopmo.Timeout)
|
||||
mqpmo.Context = gopmo.Context
|
||||
mqpmo.KnownDestCount = C.MQLONG(gopmo.KnownDestCount)
|
||||
mqpmo.UnknownDestCount = C.MQLONG(gopmo.UnknownDestCount)
|
||||
mqpmo.InvalidDestCount = C.MQLONG(gopmo.InvalidDestCount)
|
||||
|
||||
setMQIString((*C.char)(&mqpmo.ResolvedQName[0]), gopmo.ResolvedQName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqpmo.ResolvedQMgrName[0]), gopmo.ResolvedQMgrName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
|
||||
mqpmo.RecsPresent = C.MQLONG(gopmo.RecsPresent)
|
||||
mqpmo.PutMsgRecFields = C.MQLONG(gopmo.PutMsgRecFields)
|
||||
mqpmo.PutMsgRecOffset = C.MQLONG(gopmo.PutMsgRecOffset)
|
||||
mqpmo.ResponseRecOffset = C.MQLONG(gopmo.ResponseRecOffset)
|
||||
mqpmo.PutMsgRecPtr = gopmo.PutMsgRecPtr
|
||||
mqpmo.ResponseRecPtr = gopmo.ResponseRecPtr
|
||||
|
||||
mqpmo.OriginalMsgHandle = gopmo.OriginalMsgHandle
|
||||
mqpmo.NewMsgHandle = gopmo.NewMsgHandle
|
||||
mqpmo.Action = C.MQLONG(gopmo.Action)
|
||||
mqpmo.PubLevel = C.MQLONG(gopmo.PubLevel)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func copyPMOfromC(mqpmo *C.MQPMO, gopmo *MQPMO) {
|
||||
|
||||
gopmo.Version = int32(mqpmo.Version)
|
||||
|
||||
gopmo.Options = int32(mqpmo.Options)
|
||||
gopmo.Timeout = int32(mqpmo.Timeout)
|
||||
gopmo.Context = mqpmo.Context
|
||||
gopmo.KnownDestCount = int32(mqpmo.KnownDestCount)
|
||||
gopmo.UnknownDestCount = int32(mqpmo.UnknownDestCount)
|
||||
gopmo.InvalidDestCount = int32(mqpmo.InvalidDestCount)
|
||||
|
||||
gopmo.ResolvedQName = C.GoStringN((*C.char)(&mqpmo.ResolvedQName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
gopmo.ResolvedQMgrName = C.GoStringN((*C.char)(&mqpmo.ResolvedQMgrName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
|
||||
gopmo.RecsPresent = int32(mqpmo.RecsPresent)
|
||||
gopmo.PutMsgRecFields = int32(mqpmo.PutMsgRecFields)
|
||||
gopmo.PutMsgRecOffset = int32(mqpmo.PutMsgRecOffset)
|
||||
gopmo.ResponseRecOffset = int32(mqpmo.ResponseRecOffset)
|
||||
gopmo.PutMsgRecPtr = mqpmo.PutMsgRecPtr
|
||||
gopmo.ResponseRecPtr = mqpmo.ResponseRecPtr
|
||||
|
||||
gopmo.OriginalMsgHandle = mqpmo.OriginalMsgHandle
|
||||
gopmo.NewMsgHandle = mqpmo.NewMsgHandle
|
||||
gopmo.Action = int32(mqpmo.Action)
|
||||
gopmo.PubLevel = int32(mqpmo.PubLevel)
|
||||
return
|
||||
}
|
||||
100
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQSCO.go
generated
vendored
Normal file
100
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQSCO.go
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
#include <cmqxc.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
/*
|
||||
MQSCO is a structure containing the MQ SSL/TLS Configuration (MQSCO)
|
||||
options.
|
||||
*/
|
||||
type MQSCO struct {
|
||||
KeyRepository string
|
||||
CryptoHardware string
|
||||
KeyResetCount int32
|
||||
FipsRequired bool
|
||||
EncryptionPolicySuiteB [4]int32
|
||||
CertificateValPolicy int32
|
||||
CertificateLabel string
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQSCO fills in default values for the MQSCO structure
|
||||
*/
|
||||
func NewMQSCO() *MQSCO {
|
||||
|
||||
sco := new(MQSCO)
|
||||
|
||||
sco.KeyRepository = ""
|
||||
sco.CryptoHardware = ""
|
||||
sco.KeyResetCount = int32(C.MQSCO_RESET_COUNT_DEFAULT)
|
||||
sco.FipsRequired = false
|
||||
sco.EncryptionPolicySuiteB[0] = int32(C.MQ_SUITE_B_NONE)
|
||||
for i := 1; i < 4; i++ {
|
||||
sco.EncryptionPolicySuiteB[i] = int32(C.MQ_SUITE_B_NOT_AVAILABLE)
|
||||
}
|
||||
sco.CertificateValPolicy = int32(C.MQ_CERT_VAL_POLICY_DEFAULT)
|
||||
sco.CertificateLabel = ""
|
||||
|
||||
return sco
|
||||
}
|
||||
|
||||
/*
|
||||
It is expected that copyXXtoC and copyXXfromC will be called as
|
||||
matching pairs.
|
||||
*/
|
||||
func copySCOtoC(mqsco *C.MQSCO, gosco *MQSCO) {
|
||||
|
||||
setMQIString((*C.char)(&mqsco.StrucId[0]), "SCO ", 4)
|
||||
mqsco.Version = C.MQSCO_VERSION_5
|
||||
setMQIString((*C.char)(&mqsco.KeyRepository[0]), gosco.KeyRepository, C.MQ_SSL_KEY_REPOSITORY_LENGTH)
|
||||
setMQIString((*C.char)(&mqsco.CryptoHardware[0]), gosco.CryptoHardware, C.MQ_SSL_CRYPTO_HARDWARE_LENGTH)
|
||||
mqsco.AuthInfoRecCount = 0
|
||||
mqsco.AuthInfoRecOffset = 0
|
||||
mqsco.AuthInfoRecPtr = nil
|
||||
mqsco.KeyResetCount = C.MQLONG(gosco.KeyResetCount)
|
||||
if gosco.FipsRequired {
|
||||
mqsco.FipsRequired = C.MQSSL_FIPS_YES
|
||||
} else {
|
||||
mqsco.FipsRequired = C.MQSSL_FIPS_NO
|
||||
}
|
||||
for i := 0; i < 4; i++ {
|
||||
mqsco.EncryptionPolicySuiteB[i] = C.MQLONG(gosco.EncryptionPolicySuiteB[i])
|
||||
}
|
||||
mqsco.CertificateValPolicy = C.MQLONG(gosco.CertificateValPolicy)
|
||||
setMQIString((*C.char)(&mqsco.CertificateLabel[0]), gosco.CertificateLabel, C.MQ_CERT_LABEL_LENGTH)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
All of the parameters in the MQSCO are input only.
|
||||
*/
|
||||
func copySCOfromC(mqsco *C.MQSCO, gosco *MQSCO) {
|
||||
|
||||
return
|
||||
}
|
||||
216
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQSD.go
generated
vendored
Normal file
216
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiMQSD.go
generated
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
MQSD is a structure containing the MQ Subscription Descriptor (MQSD)
|
||||
*/
|
||||
type MQSD struct {
|
||||
Version int32
|
||||
Options int32
|
||||
|
||||
ObjectName string
|
||||
AlternateUserId string
|
||||
AlternateSecurityId []byte
|
||||
SubExpiry int32
|
||||
ObjectString string
|
||||
SubName string
|
||||
SubUserData string
|
||||
SubCorrelId []byte
|
||||
|
||||
PubPriority int32
|
||||
PubAccountingToken []byte
|
||||
|
||||
PubApplIdentityData string
|
||||
|
||||
SelectionString string
|
||||
SubLevel int32
|
||||
ResObjectString string
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQSD fills in default values for the MQSD structure
|
||||
*/
|
||||
func NewMQSD() *MQSD {
|
||||
|
||||
sd := new(MQSD)
|
||||
|
||||
sd.Version = int32(C.MQSD_VERSION_1)
|
||||
sd.Options = 0
|
||||
|
||||
sd.ObjectName = ""
|
||||
sd.AlternateUserId = ""
|
||||
sd.AlternateSecurityId = bytes.Repeat([]byte{0}, C.MQ_SECURITY_ID_LENGTH)
|
||||
sd.SubExpiry = int32(C.MQEI_UNLIMITED)
|
||||
sd.ObjectString = ""
|
||||
sd.SubName = ""
|
||||
sd.SubUserData = ""
|
||||
sd.SubCorrelId = bytes.Repeat([]byte{0}, C.MQ_CORREL_ID_LENGTH)
|
||||
|
||||
sd.PubPriority = int32(C.MQPRI_PRIORITY_AS_PUBLISHED)
|
||||
sd.PubAccountingToken = bytes.Repeat([]byte{0}, C.MQ_ACCOUNTING_TOKEN_LENGTH)
|
||||
|
||||
sd.PubApplIdentityData = ""
|
||||
|
||||
sd.SelectionString = ""
|
||||
sd.SubLevel = 1
|
||||
sd.ResObjectString = ""
|
||||
|
||||
return sd
|
||||
}
|
||||
|
||||
/*
|
||||
It is expected that copyXXtoC and copyXXfromC will be called as
|
||||
matching pairs. That means that we can handle the MQCHARV type
|
||||
by allocating storage in the toC function and freeing it in fromC.
|
||||
If the input string for an MQCHARV type is empty, then we allocate
|
||||
a fixed length buffer for any potential output.
|
||||
|
||||
In the fromC function, that buffer is freed. Conveniently, we can
|
||||
free it always, because if we didn't explicitly call malloc(), it was
|
||||
allocated by C.CString and still needs to be freed.
|
||||
*/
|
||||
func copySDtoC(mqsd *C.MQSD, gosd *MQSD) {
|
||||
var i int
|
||||
const vsbufsize = 10240
|
||||
|
||||
setMQIString((*C.char)(&mqsd.StrucId[0]), "SD ", 4)
|
||||
mqsd.Version = C.MQLONG(gosd.Version)
|
||||
mqsd.Options = C.MQLONG(gosd.Options)
|
||||
|
||||
setMQIString((*C.char)(&mqsd.ObjectName[0]), gosd.ObjectName, C.MQ_OBJECT_NAME_LENGTH)
|
||||
setMQIString((*C.char)(&mqsd.AlternateUserId[0]), gosd.AlternateUserId, C.MQ_USER_ID_LENGTH)
|
||||
for i = 0; i < C.MQ_SECURITY_ID_LENGTH; i++ {
|
||||
mqsd.AlternateSecurityId[i] = C.MQBYTE(gosd.AlternateSecurityId[i])
|
||||
}
|
||||
mqsd.SubExpiry = C.MQLONG(gosd.SubExpiry)
|
||||
|
||||
mqsd.ObjectString.VSLength = (C.MQLONG)(len(gosd.ObjectString))
|
||||
mqsd.ObjectString.VSCCSID = C.MQCCSI_APPL
|
||||
if mqsd.ObjectString.VSLength == 0 {
|
||||
mqsd.ObjectString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
|
||||
mqsd.ObjectString.VSBufSize = vsbufsize
|
||||
} else {
|
||||
mqsd.ObjectString.VSPtr = (C.MQPTR)(C.CString(gosd.ObjectString))
|
||||
}
|
||||
|
||||
mqsd.SubName.VSLength = (C.MQLONG)(len(gosd.SubName))
|
||||
mqsd.SubName.VSCCSID = C.MQCCSI_APPL
|
||||
if mqsd.SubName.VSLength == 0 {
|
||||
mqsd.SubName.VSPtr = C.MQPTR(C.malloc(vsbufsize))
|
||||
mqsd.SubName.VSBufSize = vsbufsize
|
||||
} else {
|
||||
mqsd.SubName.VSPtr = (C.MQPTR)(C.CString(gosd.SubName))
|
||||
}
|
||||
|
||||
mqsd.SubUserData.VSLength = (C.MQLONG)(len(gosd.SubUserData))
|
||||
mqsd.SubUserData.VSCCSID = C.MQCCSI_APPL
|
||||
if mqsd.SubUserData.VSLength == 0 {
|
||||
mqsd.SubUserData.VSPtr = C.MQPTR(C.malloc(vsbufsize))
|
||||
mqsd.SubUserData.VSBufSize = vsbufsize
|
||||
} else {
|
||||
mqsd.SubUserData.VSPtr = (C.MQPTR)(C.CString(gosd.SubUserData))
|
||||
}
|
||||
|
||||
for i = 0; i < C.MQ_CORREL_ID_LENGTH; i++ {
|
||||
mqsd.SubCorrelId[i] = C.MQBYTE(gosd.SubCorrelId[i])
|
||||
}
|
||||
|
||||
mqsd.PubPriority = C.MQLONG(gosd.PubPriority)
|
||||
for i = 0; i < C.MQ_ACCOUNTING_TOKEN_LENGTH; i++ {
|
||||
mqsd.PubAccountingToken[i] = C.MQBYTE(gosd.PubAccountingToken[i])
|
||||
}
|
||||
|
||||
setMQIString((*C.char)(&mqsd.PubApplIdentityData[0]), gosd.PubApplIdentityData, C.MQ_APPL_IDENTITY_DATA_LENGTH)
|
||||
|
||||
mqsd.SelectionString.VSLength = (C.MQLONG)(len(gosd.SelectionString))
|
||||
mqsd.SelectionString.VSCCSID = C.MQCCSI_APPL
|
||||
if mqsd.SelectionString.VSLength == 0 {
|
||||
mqsd.SelectionString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
|
||||
mqsd.SelectionString.VSBufSize = vsbufsize
|
||||
} else {
|
||||
mqsd.SelectionString.VSPtr = (C.MQPTR)(C.CString(gosd.SelectionString))
|
||||
}
|
||||
|
||||
mqsd.SubLevel = C.MQLONG(gosd.SubLevel)
|
||||
|
||||
mqsd.ResObjectString.VSLength = (C.MQLONG)(len(gosd.ResObjectString))
|
||||
mqsd.ResObjectString.VSCCSID = C.MQCCSI_APPL
|
||||
if mqsd.ResObjectString.VSLength == 0 {
|
||||
mqsd.ResObjectString.VSPtr = C.MQPTR(C.malloc(vsbufsize))
|
||||
mqsd.ResObjectString.VSBufSize = vsbufsize
|
||||
} else {
|
||||
mqsd.ResObjectString.VSPtr = (C.MQPTR)(C.CString(gosd.ResObjectString))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func copySDfromC(mqsd *C.MQSD, gosd *MQSD) {
|
||||
var i int
|
||||
gosd.Version = int32(mqsd.Version)
|
||||
gosd.Options = int32(mqsd.Options)
|
||||
|
||||
gosd.ObjectName = C.GoStringN((*C.char)(&mqsd.ObjectName[0]), C.MQ_OBJECT_NAME_LENGTH)
|
||||
gosd.AlternateUserId = C.GoStringN((*C.char)(&mqsd.AlternateUserId[0]), C.MQ_USER_ID_LENGTH)
|
||||
for i := 0; i < C.MQ_SECURITY_ID_LENGTH; i++ {
|
||||
gosd.AlternateSecurityId[i] = (byte)(mqsd.AlternateSecurityId[i])
|
||||
}
|
||||
gosd.SubExpiry = int32(mqsd.SubExpiry)
|
||||
|
||||
gosd.ObjectString = C.GoStringN((*C.char)(mqsd.ObjectString.VSPtr), (C.int)(mqsd.ObjectString.VSLength))
|
||||
C.free(unsafe.Pointer(mqsd.ObjectString.VSPtr))
|
||||
gosd.SubName = C.GoStringN((*C.char)(mqsd.SubName.VSPtr), (C.int)(mqsd.SubName.VSLength))
|
||||
C.free(unsafe.Pointer(mqsd.SubName.VSPtr))
|
||||
gosd.SubUserData = C.GoStringN((*C.char)(mqsd.SubUserData.VSPtr), (C.int)(mqsd.SubUserData.VSLength))
|
||||
C.free(unsafe.Pointer(mqsd.SubUserData.VSPtr))
|
||||
|
||||
for i = 0; i < C.MQ_CORREL_ID_LENGTH; i++ {
|
||||
gosd.SubCorrelId[i] = (byte)(mqsd.SubCorrelId[i])
|
||||
}
|
||||
|
||||
gosd.PubPriority = int32(mqsd.PubPriority)
|
||||
for i = 0; i < C.MQ_ACCOUNTING_TOKEN_LENGTH; i++ {
|
||||
gosd.PubAccountingToken[i] = (byte)(mqsd.PubAccountingToken[i])
|
||||
}
|
||||
|
||||
gosd.PubApplIdentityData = C.GoStringN((*C.char)(&mqsd.PubApplIdentityData[0]), C.MQ_APPL_IDENTITY_DATA_LENGTH)
|
||||
|
||||
gosd.SelectionString = C.GoStringN((*C.char)(mqsd.SelectionString.VSPtr), (C.int)(mqsd.SelectionString.VSLength))
|
||||
C.free(unsafe.Pointer(mqsd.SelectionString.VSPtr))
|
||||
|
||||
gosd.SubLevel = int32(mqsd.SubLevel)
|
||||
|
||||
gosd.ResObjectString = C.GoStringN((*C.char)(mqsd.ResObjectString.VSPtr), (C.int)(mqsd.ResObjectString.VSLength))
|
||||
C.free(unsafe.Pointer(mqsd.ResObjectString.VSPtr))
|
||||
return
|
||||
}
|
||||
267
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiPCF.go
generated
vendored
Normal file
267
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqiPCF.go
generated
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <cmqc.h>
|
||||
#include <cmqcfc.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/*
|
||||
MQCFH is a structure containing the MQ PCF Header fields
|
||||
*/
|
||||
type MQCFH struct {
|
||||
Type int32
|
||||
StrucLength int32
|
||||
Version int32
|
||||
Command int32
|
||||
MsgSeqNumber int32
|
||||
Control int32
|
||||
CompCode int32
|
||||
Reason int32
|
||||
ParameterCount int32
|
||||
}
|
||||
|
||||
var endian binary.ByteOrder
|
||||
|
||||
/*
|
||||
PCFParameter is a structure containing the data associated with
|
||||
various types of PCF element. Use the Type field to decide which
|
||||
of the data fields is relevant.
|
||||
*/
|
||||
type PCFParameter struct {
|
||||
Type int32
|
||||
Parameter int32
|
||||
Int64Value []int64 // Always store as 64; cast to 32 when needed
|
||||
String []string
|
||||
CodedCharSetId int32
|
||||
ParameterCount int32
|
||||
GroupList []*PCFParameter
|
||||
strucLength int32 // Do not need to expose these
|
||||
stringLength int32 // lengths
|
||||
}
|
||||
|
||||
/*
|
||||
NewMQCFH returns a PCF Command Header structure with correct initialisation
|
||||
*/
|
||||
func NewMQCFH() *MQCFH {
|
||||
cfh := new(MQCFH)
|
||||
cfh.Type = C.MQCFT_COMMAND
|
||||
cfh.StrucLength = C.MQCFH_STRUC_LENGTH
|
||||
cfh.Version = C.MQCFH_VERSION_1
|
||||
cfh.Command = C.MQCMD_NONE
|
||||
cfh.MsgSeqNumber = 1
|
||||
cfh.Control = C.MQCFC_LAST
|
||||
cfh.CompCode = C.MQCC_OK
|
||||
cfh.Reason = C.MQRC_NONE
|
||||
cfh.ParameterCount = 0
|
||||
|
||||
if (C.MQENC_NATIVE % 2) == 0 {
|
||||
endian = binary.LittleEndian
|
||||
} else {
|
||||
endian = binary.BigEndian
|
||||
}
|
||||
|
||||
return cfh
|
||||
}
|
||||
|
||||
/*
|
||||
Bytes serialises an MQCFH structure as if it were the corresponding C structure
|
||||
*/
|
||||
func (cfh *MQCFH) Bytes() []byte {
|
||||
|
||||
buf := make([]byte, cfh.StrucLength)
|
||||
offset := 0
|
||||
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.Type))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.StrucLength))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.Version))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.Command))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.MsgSeqNumber))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.Control))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.CompCode))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.Reason))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(cfh.ParameterCount))
|
||||
offset += 4
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
/*
|
||||
Bytes serialises a PCFParameter into the C structure
|
||||
corresponding to its type
|
||||
*/
|
||||
func (p *PCFParameter) Bytes() []byte {
|
||||
var buf []byte
|
||||
|
||||
switch p.Type {
|
||||
case C.MQCFT_INTEGER:
|
||||
buf = make([]byte, C.MQCFIN_STRUC_LENGTH)
|
||||
offset := 0
|
||||
|
||||
endian.PutUint32(buf[offset:], uint32(p.Type))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(len(buf)))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(p.Parameter))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(p.Int64Value[0]))
|
||||
offset += 4
|
||||
|
||||
case C.MQCFT_STRING:
|
||||
buf = make([]byte, C.MQCFST_STRUC_LENGTH_FIXED+roundTo4(int32(len(p.String[0]))))
|
||||
offset := 0
|
||||
endian.PutUint32(buf[offset:], uint32(p.Type))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(len(buf)))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(p.Parameter))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(C.MQCCSI_DEFAULT))
|
||||
offset += 4
|
||||
endian.PutUint32(buf[offset:], uint32(len(p.String[0])))
|
||||
offset += 4
|
||||
copy(buf[offset:], []byte(p.String[0]))
|
||||
}
|
||||
return buf
|
||||
}
|
||||
|
||||
/*
|
||||
ReadPCFHeader extracts the MQCFH from an MQ message
|
||||
*/
|
||||
func ReadPCFHeader(buf []byte) (*MQCFH, int) {
|
||||
cfh := new(MQCFH)
|
||||
fullLen := len(buf)
|
||||
p := bytes.NewBuffer(buf)
|
||||
|
||||
binary.Read(p, endian, &cfh.Type)
|
||||
binary.Read(p, endian, &cfh.StrucLength)
|
||||
binary.Read(p, endian, &cfh.Version)
|
||||
binary.Read(p, endian, &cfh.Command)
|
||||
binary.Read(p, endian, &cfh.MsgSeqNumber)
|
||||
binary.Read(p, endian, &cfh.Control)
|
||||
binary.Read(p, endian, &cfh.CompCode)
|
||||
binary.Read(p, endian, &cfh.Reason)
|
||||
binary.Read(p, endian, &cfh.ParameterCount)
|
||||
|
||||
bytesRead := fullLen - p.Len()
|
||||
return cfh, bytesRead
|
||||
}
|
||||
|
||||
/*
|
||||
ReadPCFParameter extracts the next PCF parameter element from an
|
||||
MQ message.
|
||||
*/
|
||||
func ReadPCFParameter(buf []byte) (*PCFParameter, int) {
|
||||
var i32 int32
|
||||
var i64 int64
|
||||
var mqlong int32
|
||||
var count int32
|
||||
|
||||
pcfParm := new(PCFParameter)
|
||||
fullLen := len(buf)
|
||||
p := bytes.NewBuffer(buf)
|
||||
|
||||
binary.Read(p, endian, &pcfParm.Type)
|
||||
binary.Read(p, endian, &pcfParm.strucLength)
|
||||
|
||||
switch pcfParm.Type {
|
||||
// There are more PCF element types but the samples only
|
||||
// needed a subset
|
||||
case C.MQCFT_INTEGER:
|
||||
binary.Read(p, endian, &pcfParm.Parameter)
|
||||
binary.Read(p, endian, &i32)
|
||||
pcfParm.Int64Value = append(pcfParm.Int64Value, int64(i32))
|
||||
|
||||
case C.MQCFT_INTEGER_LIST:
|
||||
binary.Read(p, endian, &pcfParm.Parameter)
|
||||
binary.Read(p, endian, &count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
binary.Read(p, endian, &i32)
|
||||
pcfParm.Int64Value = append(pcfParm.Int64Value, int64(i32))
|
||||
}
|
||||
|
||||
case C.MQCFT_INTEGER64:
|
||||
binary.Read(p, endian, &pcfParm.Parameter)
|
||||
binary.Read(p, endian, &mqlong) // Used for alignment
|
||||
binary.Read(p, endian, &i64)
|
||||
pcfParm.Int64Value = append(pcfParm.Int64Value, i64)
|
||||
|
||||
case C.MQCFT_INTEGER64_LIST:
|
||||
binary.Read(p, endian, &pcfParm.Parameter)
|
||||
binary.Read(p, endian, &count)
|
||||
for i := 0; i < int(count); i++ {
|
||||
binary.Read(p, endian, &i64)
|
||||
pcfParm.Int64Value = append(pcfParm.Int64Value, i64)
|
||||
}
|
||||
|
||||
case C.MQCFT_STRING:
|
||||
offset := int32(C.MQCFST_STRUC_LENGTH_FIXED)
|
||||
binary.Read(p, endian, &pcfParm.Parameter)
|
||||
binary.Read(p, endian, &pcfParm.CodedCharSetId)
|
||||
binary.Read(p, endian, &pcfParm.stringLength)
|
||||
s := string(buf[offset : pcfParm.stringLength+offset])
|
||||
pcfParm.String = append(pcfParm.String, s)
|
||||
p.Next(int(pcfParm.strucLength - offset))
|
||||
|
||||
case C.MQCFT_STRING_LIST:
|
||||
binary.Read(p, endian, &pcfParm.Parameter)
|
||||
binary.Read(p, endian, &pcfParm.CodedCharSetId)
|
||||
binary.Read(p, endian, &count)
|
||||
binary.Read(p, endian, &pcfParm.stringLength)
|
||||
for i := 0; i < int(count); i++ {
|
||||
offset := C.MQCFSL_STRUC_LENGTH_FIXED + i*int(pcfParm.stringLength)
|
||||
s := string(buf[offset : int(pcfParm.stringLength)+offset])
|
||||
pcfParm.String = append(pcfParm.String, s)
|
||||
}
|
||||
p.Next(int(pcfParm.strucLength - C.MQCFSL_STRUC_LENGTH_FIXED))
|
||||
|
||||
case C.MQCFT_GROUP:
|
||||
binary.Read(p, endian, &pcfParm.Parameter)
|
||||
binary.Read(p, endian, &pcfParm.ParameterCount)
|
||||
default:
|
||||
fmt.Println("mqiPCF.go: Unknown PCF type ", pcfParm.Type)
|
||||
// Skip the remains of this structure, assuming it really is
|
||||
// PCF and we just don't know how to process the element type
|
||||
p.Next(int(pcfParm.strucLength - 8))
|
||||
}
|
||||
|
||||
bytesRead := fullLen - p.Len()
|
||||
return pcfParm, bytesRead
|
||||
}
|
||||
|
||||
func roundTo4(u int32) int32 {
|
||||
return ((u) + ((4 - ((u) % 4)) % 4))
|
||||
}
|
||||
98
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqistr.go
generated
vendored
Normal file
98
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqistr.go
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
package ibmmq
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cmqc.h>
|
||||
#include <cmqstrc.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
/*
|
||||
Convert MQCC/MQRC values into readable text using
|
||||
the functions introduced in cmqstrc.h in MQ V8004
|
||||
*/
|
||||
func mqstrerror(verb string, mqcc C.MQLONG, mqrc C.MQLONG) string {
|
||||
return fmt.Sprintf("%s: MQCC = %s [%d] MQRC = %s [%d]", verb,
|
||||
C.GoString(C.MQCC_STR(mqcc)), mqcc,
|
||||
C.GoString(C.MQRC_STR(mqrc)), mqrc)
|
||||
}
|
||||
|
||||
/*
|
||||
MQItoString returns a string representation of the MQI #define. Only a few of the
|
||||
sets of constants are decoded here; see cmqstrc.h for a full set. Some of the
|
||||
sets are aggregated, so that "RC" will return something from either the MQRC
|
||||
or MQRCCF sets. These sets are related and do not overlap values.
|
||||
*/
|
||||
func MQItoString(class string, value int) string {
|
||||
s := ""
|
||||
v := C.MQLONG(value)
|
||||
switch class {
|
||||
case "BACF":
|
||||
s = C.GoString(C.MQBACF_STR(v))
|
||||
|
||||
case "CA":
|
||||
s = C.GoString(C.MQCA_STR(v))
|
||||
if s == "" {
|
||||
s = C.GoString(C.MQCACF_STR(v))
|
||||
}
|
||||
if s == "" {
|
||||
s = C.GoString(C.MQCACH_STR(v))
|
||||
}
|
||||
if s == "" {
|
||||
s = C.GoString(C.MQCAMO_STR(v))
|
||||
}
|
||||
|
||||
case "CC":
|
||||
s = C.GoString(C.MQCC_STR(v))
|
||||
case "CMD":
|
||||
s = C.GoString(C.MQCMD_STR(v))
|
||||
|
||||
case "IA":
|
||||
s = C.GoString(C.MQIA_STR(v))
|
||||
if s == "" {
|
||||
s = C.GoString(C.MQIACF_STR(v))
|
||||
}
|
||||
if s == "" {
|
||||
s = C.GoString(C.MQIACH_STR(v))
|
||||
}
|
||||
if s == "" {
|
||||
s = C.GoString(C.MQIAMO_STR(v))
|
||||
}
|
||||
if s == "" {
|
||||
s = C.GoString(C.MQIAMO64_STR(v))
|
||||
}
|
||||
|
||||
case "OT":
|
||||
s = C.GoString(C.MQOT_STR(v))
|
||||
|
||||
case "RC":
|
||||
s = C.GoString(C.MQRC_STR(v))
|
||||
if s == "" {
|
||||
s = C.GoString(C.MQRCCF_STR(v))
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
746
vendor/github.com/ibm-messaging/mq-golang/mqmetric/discover.go
generated
vendored
Normal file
746
vendor/github.com/ibm-messaging/mq-golang/mqmetric/discover.go
generated
vendored
Normal file
@@ -0,0 +1,746 @@
|
||||
/*
|
||||
Package mqmetric contains a set of routines common to several
|
||||
commands used to export MQ metrics to different backend
|
||||
storage mechanisms including Prometheus and InfluxDB.
|
||||
*/
|
||||
package mqmetric
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016, 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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
Functions in this file discover the data available from a queue manager
|
||||
via the MQ V9 pub/sub monitoring feature. Each metric (element) is
|
||||
found by discovering the types of metric, and the types are found by first
|
||||
discovering the classes. Sample program amqsrua is shipped with MQ V9 to
|
||||
give a good demonstration of the process, which is followed here.
|
||||
*/
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/ibm-messaging/mq-golang/ibmmq"
|
||||
)
|
||||
|
||||
// MonElement describes the real metric element generated by MQ
|
||||
type MonElement struct {
|
||||
Parent *MonType
|
||||
Description string // An English phrase describing the element
|
||||
MetricName string // Reformatted description suitable as label
|
||||
Datatype int32
|
||||
Values map[string]int64
|
||||
}
|
||||
|
||||
// MonType describes the "types" of data generated by MQ. Each class generates
|
||||
// one or more type of data such as OPENCLOSE (from STATMQI class) or
|
||||
// LOG (from DISK class)
|
||||
type MonType struct {
|
||||
Parent *MonClass
|
||||
Name string
|
||||
Description string
|
||||
ObjectTopic string // topic for actual data responses
|
||||
elementTopic string // discovery of elements
|
||||
Elements map[int]*MonElement
|
||||
subHobj map[string]ibmmq.MQObject
|
||||
}
|
||||
|
||||
// MonClass described the "classes" of data generated by MQ, such as DISK and CPU
|
||||
type MonClass struct {
|
||||
Parent *AllMetrics
|
||||
Name string
|
||||
Description string
|
||||
typesTopic string
|
||||
flags int
|
||||
Types map[int]*MonType
|
||||
}
|
||||
|
||||
// The AllMetrics structure is the top of the tree, holding the set of classes.
|
||||
type AllMetrics struct {
|
||||
Classes map[int]*MonClass
|
||||
}
|
||||
|
||||
// QMgrMapKey can never be a real object name and is therefore useful in
|
||||
// maps that may contain only this single entry
|
||||
const QMgrMapKey = "@self"
|
||||
|
||||
// Metrics is the global variable for the tree of data
|
||||
var Metrics AllMetrics
|
||||
|
||||
var qList []string
|
||||
|
||||
/*
|
||||
DiscoverAndSubscribe does all the work of finding the
|
||||
different resources available from a queue manager and
|
||||
issuing the MQSUB calls to collect the data
|
||||
*/
|
||||
func DiscoverAndSubscribe(queueList string, checkQueueList bool, metaPrefix string) error {
|
||||
var err error
|
||||
// What metrics can the queue manager provide?
|
||||
if err == nil {
|
||||
err = discoverStats(metaPrefix)
|
||||
}
|
||||
|
||||
// Which queues have we been asked to monitor? Expand wildcards
|
||||
// to explicit names so that subscriptions work.
|
||||
if err == nil {
|
||||
if checkQueueList {
|
||||
discoverQueues(queueList)
|
||||
} else {
|
||||
qList = strings.Split(queueList, ",")
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to all of the various topics
|
||||
if err == nil {
|
||||
createSubscriptions()
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func discoverClasses(metaPrefix string) error {
|
||||
var data []byte
|
||||
var sub ibmmq.MQObject
|
||||
var err error
|
||||
var rootTopic string
|
||||
|
||||
// Have to know the starting point for the topic that tells about classes
|
||||
if metaPrefix == "" {
|
||||
rootTopic = "$SYS/MQ/INFO/QMGR/" + qMgr.Name + "/Monitor/METADATA/CLASSES"
|
||||
} else {
|
||||
rootTopic = metaPrefix + "/INFO/QMGR/" + qMgr.Name + "/Monitor/METADATA/CLASSES"
|
||||
}
|
||||
sub, err = subscribe(rootTopic)
|
||||
if err == nil {
|
||||
data, err = getMessage(true)
|
||||
sub.Close(0)
|
||||
|
||||
elemList, _ := parsePCFResponse(data)
|
||||
|
||||
for i := 0; i < len(elemList); i++ {
|
||||
if elemList[i].Type != ibmmq.MQCFT_GROUP {
|
||||
continue
|
||||
}
|
||||
group := elemList[i]
|
||||
cl := new(MonClass)
|
||||
classIndex := 0
|
||||
cl.Types = make(map[int]*MonType)
|
||||
cl.Parent = &Metrics
|
||||
|
||||
for j := 0; j < len(group.GroupList); j++ {
|
||||
elem := group.GroupList[j]
|
||||
switch elem.Parameter {
|
||||
case ibmmq.MQIAMO_MONITOR_CLASS:
|
||||
classIndex = int(elem.Int64Value[0])
|
||||
case ibmmq.MQIAMO_MONITOR_FLAGS:
|
||||
cl.flags = int(elem.Int64Value[0])
|
||||
case ibmmq.MQCAMO_MONITOR_CLASS:
|
||||
cl.Name = elem.String[0]
|
||||
case ibmmq.MQCAMO_MONITOR_DESC:
|
||||
cl.Description = elem.String[0]
|
||||
case ibmmq.MQCA_TOPIC_STRING:
|
||||
cl.typesTopic = elem.String[0]
|
||||
default:
|
||||
return fmt.Errorf("Unknown parameter %d in class discovery", elem.Parameter)
|
||||
}
|
||||
}
|
||||
Metrics.Classes[classIndex] = cl
|
||||
}
|
||||
}
|
||||
|
||||
subsOpened = true
|
||||
return err
|
||||
}
|
||||
|
||||
func discoverTypes(cl *MonClass) error {
|
||||
var data []byte
|
||||
var sub ibmmq.MQObject
|
||||
var err error
|
||||
|
||||
sub, err = subscribe(cl.typesTopic)
|
||||
if err == nil {
|
||||
data, err = getMessage(true)
|
||||
sub.Close(0)
|
||||
|
||||
elemList, _ := parsePCFResponse(data)
|
||||
|
||||
for i := 0; i < len(elemList); i++ {
|
||||
if elemList[i].Type != ibmmq.MQCFT_GROUP {
|
||||
continue
|
||||
}
|
||||
|
||||
group := elemList[i]
|
||||
ty := new(MonType)
|
||||
ty.Elements = make(map[int]*MonElement)
|
||||
ty.subHobj = make(map[string]ibmmq.MQObject)
|
||||
|
||||
typeIndex := 0
|
||||
ty.Parent = cl
|
||||
|
||||
for j := 0; j < len(group.GroupList); j++ {
|
||||
elem := group.GroupList[j]
|
||||
switch elem.Parameter {
|
||||
|
||||
case ibmmq.MQIAMO_MONITOR_TYPE:
|
||||
typeIndex = int(elem.Int64Value[0])
|
||||
case ibmmq.MQCAMO_MONITOR_TYPE:
|
||||
ty.Name = elem.String[0]
|
||||
case ibmmq.MQCAMO_MONITOR_DESC:
|
||||
ty.Description = elem.String[0]
|
||||
case ibmmq.MQCA_TOPIC_STRING:
|
||||
ty.elementTopic = elem.String[0]
|
||||
default:
|
||||
return fmt.Errorf("Unknown parameter %d in type discovery", elem.Parameter)
|
||||
}
|
||||
}
|
||||
cl.Types[typeIndex] = ty
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func discoverElements(ty *MonType) error {
|
||||
var err error
|
||||
var data []byte
|
||||
var sub ibmmq.MQObject
|
||||
var elem *MonElement
|
||||
|
||||
sub, err = subscribe(ty.elementTopic)
|
||||
if err == nil {
|
||||
data, err = getMessage(true)
|
||||
sub.Close(0)
|
||||
|
||||
elemList, _ := parsePCFResponse(data)
|
||||
|
||||
for i := 0; i < len(elemList); i++ {
|
||||
|
||||
if elemList[i].Type == ibmmq.MQCFT_STRING && elemList[i].Parameter == ibmmq.MQCA_TOPIC_STRING {
|
||||
ty.ObjectTopic = elemList[i].String[0]
|
||||
continue
|
||||
}
|
||||
|
||||
if elemList[i].Type != ibmmq.MQCFT_GROUP {
|
||||
continue
|
||||
}
|
||||
|
||||
group := elemList[i]
|
||||
|
||||
elem = new(MonElement)
|
||||
elementIndex := 0
|
||||
elem.Parent = ty
|
||||
elem.Values = make(map[string]int64)
|
||||
|
||||
for j := 0; j < len(group.GroupList); j++ {
|
||||
e := group.GroupList[j]
|
||||
switch e.Parameter {
|
||||
|
||||
case ibmmq.MQIAMO_MONITOR_ELEMENT:
|
||||
elementIndex = int(e.Int64Value[0])
|
||||
case ibmmq.MQIAMO_MONITOR_DATATYPE:
|
||||
elem.Datatype = int32(e.Int64Value[0])
|
||||
case ibmmq.MQCAMO_MONITOR_DESC:
|
||||
elem.Description = e.String[0]
|
||||
default:
|
||||
return fmt.Errorf("Unknown parameter %d in type discovery", e.Parameter)
|
||||
}
|
||||
}
|
||||
|
||||
elem.MetricName = formatDescription(elem)
|
||||
ty.Elements[elementIndex] = elem
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
Discover the complete set of available statistics in the queue manager
|
||||
by working through the classes, types and individual elements.
|
||||
|
||||
Then discover the list of individual queues we have been asked for.
|
||||
*/
|
||||
func discoverStats(metaPrefix string) error {
|
||||
var err error
|
||||
|
||||
// Start with an empty set of information about the available stats
|
||||
Metrics.Classes = make(map[int]*MonClass)
|
||||
|
||||
// Then get the list of CLASSES
|
||||
err = discoverClasses(metaPrefix)
|
||||
|
||||
// For each CLASS, discover the TYPEs of data available
|
||||
if err == nil {
|
||||
for _, cl := range Metrics.Classes {
|
||||
err = discoverTypes(cl)
|
||||
// And for each CLASS, discover the actual statistics elements
|
||||
if err == nil {
|
||||
for _, ty := range cl.Types {
|
||||
err = discoverElements(ty)
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
discoverQueues lists the queues that match all of the configured
|
||||
patterns.
|
||||
|
||||
The patterns must match the MQ rule - asterisk on the end of the
|
||||
string only.
|
||||
|
||||
If a bad pattern is used, or no queues exist that match the pattern
|
||||
then an error is reported but we continue processing other patterns.
|
||||
|
||||
An alternative would be to list ALL the queues (though that could be a
|
||||
long list, and we would really have to worry about TRUNCATED message retrieval),
|
||||
and then use a more general regexp match. Something for a later update
|
||||
perhaps.
|
||||
*/
|
||||
func discoverQueues(monitoredQueues string) error {
|
||||
var err error
|
||||
var elem *ibmmq.PCFParameter
|
||||
var datalen int
|
||||
|
||||
if monitoredQueues == "" {
|
||||
return err
|
||||
}
|
||||
|
||||
queues := strings.Split(monitoredQueues, ",")
|
||||
for i := 0; i < len(queues) && err == nil; i++ {
|
||||
var buf []byte
|
||||
|
||||
pattern := queues[i]
|
||||
|
||||
if strings.Count(pattern, "*") > 1 ||
|
||||
(strings.Count(pattern, "*") == 1 && !strings.HasSuffix(pattern, "*")) {
|
||||
return fmt.Errorf("Queue pattern '%s' is not valid", pattern)
|
||||
}
|
||||
|
||||
putmqmd := ibmmq.NewMQMD()
|
||||
pmo := ibmmq.NewMQPMO()
|
||||
|
||||
pmo.Options = ibmmq.MQPMO_NO_SYNCPOINT
|
||||
pmo.Options |= ibmmq.MQPMO_NEW_MSG_ID
|
||||
pmo.Options |= ibmmq.MQPMO_NEW_CORREL_ID
|
||||
pmo.Options |= ibmmq.MQPMO_FAIL_IF_QUIESCING
|
||||
|
||||
putmqmd.Format = "MQADMIN"
|
||||
putmqmd.ReplyToQ = replyQObj.Name
|
||||
putmqmd.MsgType = ibmmq.MQMT_REQUEST
|
||||
putmqmd.Report = ibmmq.MQRO_PASS_DISCARD_AND_EXPIRY
|
||||
|
||||
cfh := ibmmq.NewMQCFH()
|
||||
|
||||
// Can allow all the other fields to default
|
||||
cfh.Command = ibmmq.MQCMD_INQUIRE_Q_NAMES
|
||||
|
||||
// Add the parameters one at a time into a buffer
|
||||
pcfparm := new(ibmmq.PCFParameter)
|
||||
pcfparm.Type = ibmmq.MQCFT_STRING
|
||||
pcfparm.Parameter = ibmmq.MQCA_Q_NAME
|
||||
pcfparm.String = []string{pattern}
|
||||
cfh.ParameterCount++
|
||||
buf = append(buf, pcfparm.Bytes()...)
|
||||
|
||||
pcfparm = new(ibmmq.PCFParameter)
|
||||
pcfparm.Type = ibmmq.MQCFT_INTEGER
|
||||
pcfparm.Parameter = ibmmq.MQIA_Q_TYPE
|
||||
pcfparm.Int64Value = []int64{int64(ibmmq.MQQT_LOCAL)}
|
||||
cfh.ParameterCount++
|
||||
buf = append(buf, pcfparm.Bytes()...)
|
||||
|
||||
// Once we know the total number of parameters, put the
|
||||
// CFH header on the front of the buffer.
|
||||
buf = append(cfh.Bytes(), buf...)
|
||||
|
||||
// And put the command to the queue
|
||||
err = cmdQObj.Put(putmqmd, pmo, buf)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Now get the response
|
||||
getmqmd := ibmmq.NewMQMD()
|
||||
gmo := ibmmq.NewMQGMO()
|
||||
gmo.Options = ibmmq.MQGMO_NO_SYNCPOINT
|
||||
gmo.Options |= ibmmq.MQGMO_FAIL_IF_QUIESCING
|
||||
gmo.Options |= ibmmq.MQGMO_WAIT
|
||||
gmo.Options |= ibmmq.MQGMO_CONVERT
|
||||
gmo.WaitInterval = 30 * 1000
|
||||
|
||||
// Ought to add a loop here in case we get truncated data
|
||||
buf = make([]byte, 32768)
|
||||
|
||||
datalen, err = replyQObj.Get(getmqmd, gmo, buf)
|
||||
if err == nil {
|
||||
cfh, offset := ibmmq.ReadPCFHeader(buf)
|
||||
if cfh.CompCode != ibmmq.MQCC_OK {
|
||||
return fmt.Errorf("PCF command failed with CC %d RC %d", cfh.CompCode, cfh.Reason)
|
||||
} else {
|
||||
parmAvail := true
|
||||
bytesRead := 0
|
||||
for parmAvail && cfh.CompCode != ibmmq.MQCC_FAILED {
|
||||
elem, bytesRead = ibmmq.ReadPCFParameter(buf[offset:])
|
||||
offset += bytesRead
|
||||
// Have we now reached the end of the message
|
||||
if offset >= datalen {
|
||||
parmAvail = false
|
||||
}
|
||||
|
||||
switch elem.Parameter {
|
||||
case ibmmq.MQCACF_Q_NAMES:
|
||||
if len(elem.String) == 0 {
|
||||
return fmt.Errorf("No queues matching '%s' exist", pattern)
|
||||
}
|
||||
for i := 0; i < len(elem.String); i++ {
|
||||
qList = append(qList, strings.TrimSpace(elem.String[i]))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
Now that we know which topics can return data, need to
|
||||
create all the subscriptions.
|
||||
*/
|
||||
func createSubscriptions() error {
|
||||
var err error
|
||||
var sub ibmmq.MQObject
|
||||
|
||||
for _, cl := range Metrics.Classes {
|
||||
for _, ty := range cl.Types {
|
||||
|
||||
if strings.Contains(ty.ObjectTopic, "%s") {
|
||||
for i := 0; i < len(qList); i++ {
|
||||
topic := fmt.Sprintf(ty.ObjectTopic, qList[i])
|
||||
sub, err = subscribe(topic)
|
||||
ty.subHobj[qList[i]] = sub
|
||||
}
|
||||
} else {
|
||||
sub, err = subscribe(ty.ObjectTopic)
|
||||
ty.subHobj[QMgrMapKey] = sub
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error subscribing to %s: %v", ty.ObjectTopic, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
ProcessPublications has to read all of the messages since the last scrape
|
||||
and update the values for every relevant gauge.
|
||||
|
||||
Because the generation of the messages by the qmgr, and being told to
|
||||
read them by the main loop, may not have identical frequencies, there may be
|
||||
cases where multiple pieces of data have to be collated for the same
|
||||
gauge. Conversely, there may be times when this is called but there
|
||||
are no metrics to update.
|
||||
*/
|
||||
func ProcessPublications() error {
|
||||
var err error
|
||||
var data []byte
|
||||
|
||||
var qName string
|
||||
var classidx int
|
||||
var typeidx int
|
||||
var elementidx int
|
||||
var value int64
|
||||
|
||||
// Keep reading all available messages until queue is empty. Don't
|
||||
// do a GET-WAIT; just immediate removals.
|
||||
cnt := 0
|
||||
for err == nil {
|
||||
data, err = getMessage(false)
|
||||
|
||||
// Most common error will be MQRC_NO_MESSAGE_AVAILABLE
|
||||
// which will end the loop.
|
||||
if err == nil {
|
||||
cnt++
|
||||
elemList, _ := parsePCFResponse(data)
|
||||
|
||||
// A typical publication contains some fixed
|
||||
// headers (qmgrName, objectName, class, type etc)
|
||||
// followed by a list of index/values.
|
||||
|
||||
// This map contains those element indexes and values from each message
|
||||
values := make(map[int]int64)
|
||||
|
||||
qName = ""
|
||||
|
||||
for i := 0; i < len(elemList); i++ {
|
||||
switch elemList[i].Parameter {
|
||||
case ibmmq.MQCA_Q_MGR_NAME:
|
||||
_ = strings.TrimSpace(elemList[i].String[0])
|
||||
case ibmmq.MQCA_Q_NAME:
|
||||
qName = strings.TrimSpace(elemList[i].String[0])
|
||||
case ibmmq.MQCA_TOPIC_NAME:
|
||||
qName = strings.TrimSpace(elemList[i].String[0])
|
||||
case ibmmq.MQIACF_OBJECT_TYPE:
|
||||
// Will need to use this as part of the object key and
|
||||
// labelling if/when MQ starts to produce stats for other types
|
||||
// such as a topic. But for now we can ignore it.
|
||||
_ = ibmmq.MQItoString("OT", int(elemList[i].Int64Value[0]))
|
||||
case ibmmq.MQIAMO_MONITOR_CLASS:
|
||||
classidx = int(elemList[i].Int64Value[0])
|
||||
case ibmmq.MQIAMO_MONITOR_TYPE:
|
||||
typeidx = int(elemList[i].Int64Value[0])
|
||||
case ibmmq.MQIAMO64_MONITOR_INTERVAL:
|
||||
_ = elemList[i].Int64Value[0]
|
||||
case ibmmq.MQIAMO_MONITOR_FLAGS:
|
||||
_ = int(elemList[i].Int64Value[0])
|
||||
default:
|
||||
value = elemList[i].Int64Value[0]
|
||||
elementidx = int(elemList[i].Parameter)
|
||||
values[elementidx] = value
|
||||
}
|
||||
}
|
||||
|
||||
// Now have all the values in this particular message
|
||||
// Have to incorporate them into any that already exist.
|
||||
//
|
||||
// Each element contains a map holding all the objects
|
||||
// touched by these messages. The map is referenced by
|
||||
// object name if it's a queue; for qmgr-level stats, the
|
||||
// map only needs to contain a single entry which I've
|
||||
// chosen to reference by "@self" which can never be a
|
||||
// real queue name.
|
||||
//
|
||||
// We have to know whether to need to add the values
|
||||
// contained from multiple publications that might
|
||||
// have arrived in the scrape interval
|
||||
// for the same resource, or whether we should just
|
||||
// overwrite with the latest. Although there are
|
||||
// several monitor Datatypes, all of them apart from
|
||||
// explicitly labelled "DELTA" are ones we should just
|
||||
// use the latest value.
|
||||
for key, newValue := range values {
|
||||
if elem, ok := Metrics.Classes[classidx].Types[typeidx].Elements[key]; ok {
|
||||
objectName := qName
|
||||
if objectName == "" {
|
||||
objectName = QMgrMapKey
|
||||
}
|
||||
|
||||
if oldValue, ok := elem.Values[objectName]; ok {
|
||||
if elem.Datatype == ibmmq.MQIAMO_MONITOR_DELTA {
|
||||
value = oldValue + newValue
|
||||
} else {
|
||||
value = newValue
|
||||
}
|
||||
} else {
|
||||
value = newValue
|
||||
}
|
||||
elem.Values[objectName] = value
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// err != nil
|
||||
mqreturn := err.(*ibmmq.MQReturn)
|
||||
|
||||
if mqreturn.MQCC == ibmmq.MQCC_FAILED && mqreturn.MQRC != ibmmq.MQRC_NO_MSG_AVAILABLE {
|
||||
return mqreturn
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
Parse a PCF response message, returning the
|
||||
elements. If an element represents a PCF group, that element
|
||||
has the pieces of the group attached to itself. While
|
||||
it is theoretically possible for groups to contain groups, MQ never
|
||||
does that, so the code here does not need to recurse through multiple
|
||||
levels.
|
||||
|
||||
Returns TRUE if this is the last response in a
|
||||
set, based on the MQCFH.Control value.
|
||||
*/
|
||||
func parsePCFResponse(buf []byte) ([]*ibmmq.PCFParameter, bool) {
|
||||
var elem *ibmmq.PCFParameter
|
||||
var elemList []*ibmmq.PCFParameter
|
||||
var bytesRead int
|
||||
|
||||
rc := false
|
||||
|
||||
// First get the MQCFH structure. This also returns
|
||||
// the number of bytes read so we know where to start
|
||||
// looking for the next element
|
||||
cfh, offset := ibmmq.ReadPCFHeader(buf)
|
||||
|
||||
// If the command succeeded, loop through the remainder of the
|
||||
// message to decode each parameter.
|
||||
for i := 0; i < int(cfh.ParameterCount); i++ {
|
||||
// We don't know how long the parameter is, so we just
|
||||
// pass in "from here to the end" and let the parser
|
||||
// tell us how far it got.
|
||||
elem, bytesRead = ibmmq.ReadPCFParameter(buf[offset:])
|
||||
offset += bytesRead
|
||||
// Have we now reached the end of the message
|
||||
elemList = append(elemList, elem)
|
||||
if elem.Type == ibmmq.MQCFT_GROUP {
|
||||
groupElem := elem
|
||||
for j := 0; j < int(groupElem.ParameterCount); j++ {
|
||||
elem, bytesRead = ibmmq.ReadPCFParameter(buf[offset:])
|
||||
offset += bytesRead
|
||||
groupElem.GroupList = append(groupElem.GroupList, elem)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if cfh.Control == ibmmq.MQCFC_LAST {
|
||||
rc = true
|
||||
}
|
||||
return elemList, rc
|
||||
}
|
||||
|
||||
/*
|
||||
Need to turn the "friendly" name of each element into something
|
||||
that is suitable for metric names.
|
||||
|
||||
Should also have consistency of units (always use seconds,
|
||||
bytes etc), and organisation of the elements of the name (units last)
|
||||
|
||||
While we can't change the MQ-generated descriptions for its statistics,
|
||||
we can reformat most of them heuristically here.
|
||||
*/
|
||||
func formatDescription(elem *MonElement) string {
|
||||
s := elem.Description
|
||||
s = strings.Replace(s, " ", "_", -1)
|
||||
s = strings.Replace(s, "/", "_", -1)
|
||||
s = strings.Replace(s, "-", "_", -1)
|
||||
|
||||
/* Make sure we don't have multiple underscores */
|
||||
multiunder := regexp.MustCompile("__*")
|
||||
s = multiunder.ReplaceAllLiteralString(s, "_")
|
||||
|
||||
/* make it all lowercase. Not essential, but looks better */
|
||||
s = strings.ToLower(s)
|
||||
|
||||
/* Remove all cases of bytes, seconds, count or percentage (we add them back in later) */
|
||||
s = strings.Replace(s, "_count", "", -1)
|
||||
s = strings.Replace(s, "_bytes", "", -1)
|
||||
s = strings.Replace(s, "_byte", "", -1)
|
||||
s = strings.Replace(s, "_seconds", "", -1)
|
||||
s = strings.Replace(s, "_second", "", -1)
|
||||
s = strings.Replace(s, "_percentage", "", -1)
|
||||
|
||||
// Switch round a couple of specific names
|
||||
s = strings.Replace(s, "messages_expired", "expired_messages", -1)
|
||||
|
||||
// Add the unit at end
|
||||
switch elem.Datatype {
|
||||
case ibmmq.MQIAMO_MONITOR_PERCENT, ibmmq.MQIAMO_MONITOR_HUNDREDTHS:
|
||||
s = s + "_percentage"
|
||||
case ibmmq.MQIAMO_MONITOR_MB, ibmmq.MQIAMO_MONITOR_GB:
|
||||
s = s + "_bytes"
|
||||
case ibmmq.MQIAMO_MONITOR_MICROSEC:
|
||||
s = s + "_seconds"
|
||||
default:
|
||||
if strings.Contains(s, "_total") {
|
||||
/* If we specify it is a total in description put that at the end */
|
||||
s = strings.Replace(s, "_total", "", -1)
|
||||
s = s + "_total"
|
||||
} else if strings.Contains(s, "log_") {
|
||||
/* Weird case where the log datatype is not MB or GB but should be bytes */
|
||||
s = s + "_bytes"
|
||||
} else {
|
||||
s = s + "_count"
|
||||
}
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
/*
|
||||
ReadPatterns is called during the initial configuration step to read a file
|
||||
containing object name patterns if they are not explicitly given
|
||||
on the command line.
|
||||
*/
|
||||
func ReadPatterns(f string) (string, error) {
|
||||
var s string
|
||||
|
||||
file, err := os.Open(f)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error Opening file %s: %v", f, err)
|
||||
}
|
||||
defer file.Close()
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
if s != "" {
|
||||
s += ","
|
||||
}
|
||||
s += scanner.Text()
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
return "", fmt.Errorf("Error Reading from %s: %v", f, err)
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
/*
|
||||
Normalise converts the value returned from MQ into the correct units
|
||||
such as converting MB to bytes.
|
||||
*/
|
||||
func Normalise(elem *MonElement, key string, value int64) float64 {
|
||||
f := float64(value)
|
||||
// I've seen negative numbers which are nonsense,
|
||||
// possibly 32-bit overflow or uninitialised values
|
||||
// in the qmgr. So force data to something sensible
|
||||
// just in case those were due to a bug.
|
||||
if f < 0 {
|
||||
f = 0
|
||||
}
|
||||
|
||||
// Convert suitable metrics to base units
|
||||
if elem.Datatype == ibmmq.MQIAMO_MONITOR_PERCENT ||
|
||||
elem.Datatype == ibmmq.MQIAMO_MONITOR_HUNDREDTHS {
|
||||
f = f / 100
|
||||
} else if elem.Datatype == ibmmq.MQIAMO_MONITOR_MB {
|
||||
f = f * 1024 * 1024
|
||||
} else if elem.Datatype == ibmmq.MQIAMO_MONITOR_GB {
|
||||
f = f * 1024 * 1024 * 1024
|
||||
} else if elem.Datatype ==
|
||||
ibmmq.MQIAMO_MONITOR_MICROSEC {
|
||||
f = f / 1000000
|
||||
}
|
||||
|
||||
return f
|
||||
}
|
||||
224
vendor/github.com/ibm-messaging/mq-golang/mqmetric/mqif.go
generated
vendored
Normal file
224
vendor/github.com/ibm-messaging/mq-golang/mqmetric/mqif.go
generated
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
package mqmetric
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2016
|
||||
|
||||
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
|
||||
|
||||
Contributors:
|
||||
Mark Taylor - Initial Contribution
|
||||
*/
|
||||
|
||||
/*
|
||||
This file holds most of the calls to the MQI, so we
|
||||
don't need to repeat common setups eg of MQMD or MQSD structures.
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ibm-messaging/mq-golang/ibmmq"
|
||||
)
|
||||
|
||||
var (
|
||||
qMgr ibmmq.MQQueueManager
|
||||
cmdQObj ibmmq.MQObject
|
||||
replyQObj ibmmq.MQObject
|
||||
statsQObj ibmmq.MQObject
|
||||
getBuffer = make([]byte, 32768)
|
||||
|
||||
qmgrConnected = false
|
||||
queuesOpened = false
|
||||
statsQueuesOpened = false
|
||||
subsOpened = false
|
||||
)
|
||||
|
||||
type ConnectionConfig struct {
|
||||
ClientMode bool
|
||||
UserId string
|
||||
Password string
|
||||
}
|
||||
|
||||
/*
|
||||
InitConnection connects to the queue manager, and then
|
||||
opens both the command queue and a dynamic reply queue
|
||||
to be used for all responses including the publications
|
||||
*/
|
||||
func InitConnection(qMgrName string, replyQ string, cc *ConnectionConfig) error {
|
||||
return InitConnectionStats(qMgrName, replyQ, "", cc)
|
||||
}
|
||||
|
||||
/*
|
||||
InitConnectionStats is the same as InitConnection with the addition
|
||||
of a call to open the queue manager statistics queue.
|
||||
*/
|
||||
func InitConnectionStats(qMgrName string, replyQ string, statsQ string, cc *ConnectionConfig) error {
|
||||
var err error
|
||||
gocno := ibmmq.NewMQCNO()
|
||||
gocsp := ibmmq.NewMQCSP()
|
||||
|
||||
if cc.ClientMode {
|
||||
gocno.Options = ibmmq.MQCNO_CLIENT_BINDING
|
||||
} else {
|
||||
gocno.Options = ibmmq.MQCNO_LOCAL_BINDING
|
||||
}
|
||||
gocno.Options |= ibmmq.MQCNO_HANDLE_SHARE_BLOCK
|
||||
|
||||
if cc.Password != "" {
|
||||
gocsp.Password = cc.Password
|
||||
}
|
||||
if cc.UserId != "" {
|
||||
gocsp.UserId = cc.UserId
|
||||
gocno.SecurityParms = gocsp
|
||||
}
|
||||
|
||||
qMgr, err = ibmmq.Connx(qMgrName, gocno)
|
||||
if err == nil {
|
||||
qmgrConnected = true
|
||||
}
|
||||
|
||||
// MQOPEN of the COMMAND QUEUE
|
||||
if err == nil {
|
||||
mqod := ibmmq.NewMQOD()
|
||||
|
||||
openOptions := ibmmq.MQOO_OUTPUT | ibmmq.MQOO_FAIL_IF_QUIESCING
|
||||
|
||||
mqod.ObjectType = ibmmq.MQOT_Q
|
||||
mqod.ObjectName = "SYSTEM.ADMIN.COMMAND.QUEUE"
|
||||
|
||||
cmdQObj, err = qMgr.Open(mqod, openOptions)
|
||||
|
||||
}
|
||||
|
||||
// MQOPEN of the statistics queue
|
||||
if err == nil && statsQ != "" {
|
||||
mqod := ibmmq.NewMQOD()
|
||||
openOptions := ibmmq.MQOO_INPUT_AS_Q_DEF | ibmmq.MQOO_FAIL_IF_QUIESCING
|
||||
mqod.ObjectType = ibmmq.MQOT_Q
|
||||
mqod.ObjectName = statsQ
|
||||
statsQObj, err = qMgr.Open(mqod, openOptions)
|
||||
if err == nil {
|
||||
statsQueuesOpened = true
|
||||
}
|
||||
}
|
||||
|
||||
// MQOPEN of a reply queue
|
||||
if err == nil {
|
||||
mqod := ibmmq.NewMQOD()
|
||||
openOptions := ibmmq.MQOO_INPUT_AS_Q_DEF | ibmmq.MQOO_FAIL_IF_QUIESCING
|
||||
mqod.ObjectType = ibmmq.MQOT_Q
|
||||
mqod.ObjectName = replyQ
|
||||
replyQObj, err = qMgr.Open(mqod, openOptions)
|
||||
if err == nil {
|
||||
queuesOpened = true
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Cannot access queue manager. Error: %v", err)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
/*
|
||||
EndConnection tidies up by closing the queues and disconnecting.
|
||||
*/
|
||||
func EndConnection() {
|
||||
|
||||
// MQCLOSE all subscriptions
|
||||
if subsOpened {
|
||||
for _, cl := range Metrics.Classes {
|
||||
for _, ty := range cl.Types {
|
||||
for _, hObj := range ty.subHobj {
|
||||
hObj.Close(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MQCLOSE the queues
|
||||
if queuesOpened {
|
||||
cmdQObj.Close(0)
|
||||
replyQObj.Close(0)
|
||||
}
|
||||
|
||||
if statsQueuesOpened {
|
||||
statsQObj.Close(0)
|
||||
}
|
||||
|
||||
// MQDISC regardless of other errors
|
||||
if qmgrConnected {
|
||||
qMgr.Disc()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
getMessage returns a message from the replyQ. The only
|
||||
parameter to the function says whether this should block
|
||||
for 30 seconds or return immediately if there is no message
|
||||
available. When working with the command queue, blocking is
|
||||
required; when getting publications, non-blocking is better.
|
||||
|
||||
A 32K buffer was created at the top of this file, and should always
|
||||
be big enough for what we are expecting.
|
||||
*/
|
||||
func getMessage(wait bool) ([]byte, error) {
|
||||
return getMessageWithHObj(wait, replyQObj)
|
||||
}
|
||||
|
||||
func getMessageWithHObj(wait bool, hObj ibmmq.MQObject) ([]byte, error) {
|
||||
var err error
|
||||
var datalen int
|
||||
|
||||
getmqmd := ibmmq.NewMQMD()
|
||||
gmo := ibmmq.NewMQGMO()
|
||||
gmo.Options = ibmmq.MQGMO_NO_SYNCPOINT
|
||||
gmo.Options |= ibmmq.MQGMO_FAIL_IF_QUIESCING
|
||||
gmo.Options |= ibmmq.MQGMO_CONVERT
|
||||
|
||||
gmo.MatchOptions = ibmmq.MQMO_NONE
|
||||
|
||||
if wait {
|
||||
gmo.Options |= ibmmq.MQGMO_WAIT
|
||||
gmo.WaitInterval = 30 * 1000
|
||||
}
|
||||
|
||||
datalen, err = replyQObj.Get(getmqmd, gmo, getBuffer)
|
||||
|
||||
return getBuffer[0:datalen], err
|
||||
}
|
||||
|
||||
/*
|
||||
subscribe to the nominated topic. The previously-opened
|
||||
replyQ is used for publications; we do not use a managed queue here,
|
||||
so that everything can be read from one queue. The object handle for the
|
||||
subscription is returned so we can close it when it's no longer needed.
|
||||
*/
|
||||
func subscribe(topic string) (ibmmq.MQObject, error) {
|
||||
var err error
|
||||
|
||||
mqsd := ibmmq.NewMQSD()
|
||||
mqsd.Options = ibmmq.MQSO_CREATE
|
||||
mqsd.Options |= ibmmq.MQSO_NON_DURABLE
|
||||
mqsd.Options |= ibmmq.MQSO_FAIL_IF_QUIESCING
|
||||
|
||||
mqsd.ObjectString = topic
|
||||
|
||||
subObj, err := qMgr.Sub(mqsd, &replyQObj)
|
||||
if err != nil {
|
||||
return subObj, fmt.Errorf("Error subscribing to topic '%s': %v", topic, err)
|
||||
}
|
||||
|
||||
return subObj, err
|
||||
}
|
||||
Reference in New Issue
Block a user