Initial delivery of metrics code (#81)
* Initial delivery of metrics code * Fix build issues * Fix build issue with go vet
This commit is contained in:
committed by
Rob Parker
parent
e251839639
commit
a4b9a9abaf
4
vendor/github.com/ibm-messaging/mq-golang/.github/ISSUE_TEMPLATE.md
generated
vendored
Executable file
4
vendor/github.com/ibm-messaging/mq-golang/.github/ISSUE_TEMPLATE.md
generated
vendored
Executable file
@@ -0,0 +1,4 @@
|
||||
Please include the following information in your ticket.
|
||||
|
||||
- Version information for MQ, mq-golang, Go compiler
|
||||
- A small code sample that demonstrates the issue.
|
||||
22
vendor/github.com/ibm-messaging/mq-golang/.github/PULL_REQUEST_TEMPLATE.md
generated
vendored
Executable file
22
vendor/github.com/ibm-messaging/mq-golang/.github/PULL_REQUEST_TEMPLATE.md
generated
vendored
Executable file
@@ -0,0 +1,22 @@
|
||||
Please ensure all items are complete before opening.
|
||||
|
||||
- [ ] Tick to sign-off your agreement to the [IBM Contributor License Agreement](https://github.com/ibm-messaging/mq-golang/CLA.md)
|
||||
- [ ] You have added tests for any code changes
|
||||
- [ ] You have updated the [CHANGES.md](https://github.com/ibm-messaging/mq-golang/CHANGES.md)
|
||||
- [ ] You have completed the PR template below:
|
||||
|
||||
## What
|
||||
|
||||
What was changed
|
||||
|
||||
## How
|
||||
|
||||
How the change was implemented or reasoning behind it
|
||||
|
||||
## Testing
|
||||
|
||||
How to test your changes work, not required for documentation changes.
|
||||
|
||||
## Issues
|
||||
|
||||
Links to the github issue(s) (if present) that this pull request is resolving.
|
||||
97
vendor/github.com/ibm-messaging/mq-golang/CHANGELOG.md
generated
vendored
Normal file
97
vendor/github.com/ibm-messaging/mq-golang/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
# Changelog
|
||||
|
||||
## May 2018
|
||||
|
||||
* Corrected package imports
|
||||
* Formatted go code with `go fmt`
|
||||
* Rearranged this file
|
||||
* Removed logging from golang package `mqmetric`
|
||||
* Moved samples to a separate repository
|
||||
* Added build scripts for `ibmmq` and `mqmetric` packages and `ibmmq` samples
|
||||
* Added unit tests for `ibmmq` and `mqmetric` packages
|
||||
|
||||
## March 2018 - v1.0.0
|
||||
|
||||
* Added V9.0.5 constant definitions
|
||||
* Changed #cgo directives for Windows now the compiler supports standard path names
|
||||
* Added mechanism to set MQ userid and password for Prometheus monitor
|
||||
* Released v1.0.0 of this repository for use with golang dependency management tools
|
||||
|
||||
## October 2017
|
||||
|
||||
* Added V9.0.4 constant definitions - now generated from original MQ source code
|
||||
* Added MQSC script to show how to redefine event queues for pub/sub
|
||||
* Prometheus collector has new parameter to override the first component of the metric name
|
||||
* Prometheus collector can now process channel-level statistics
|
||||
|
||||
## 18 May 2017
|
||||
|
||||
* Added the V9.0.3 constant definitions.
|
||||
* Reinstated 64-bit structure "length" fields in cmqc.go after fixing a bug in the base product C source code generator.
|
||||
|
||||
## 25 Mar 2017
|
||||
|
||||
* Added the metaPrefix option to the Prometheus monitor. This allows selection of non-default resources such as the MQ Bridge for Salesforce included in MQ 9.0.2.
|
||||
|
||||
## 15 Feb 2017
|
||||
|
||||
* API BREAKING CHANGE: The MQI verbs have been changed to return a single error indicator instead of two separate values. See mqitest.go for examples of how MQRC/MQCC codes can now be tested and extracted. This change makes the MQI implementation a bit more natural for Go environments.
|
||||
|
||||
## 10 Jan 2017
|
||||
|
||||
* Added support for the MQCD and MQSCO structures to allow programmable client connectivity, without requiring a CCDT. See the clientconn sample program for an example of using the MQCD.
|
||||
* Moved sample programs into subdirectory
|
||||
|
||||
## 14 Dec 2016
|
||||
|
||||
* Minor updates to this README for formatting
|
||||
* Removed xxx_CURRENT_LENGTH definitions from cmqc
|
||||
|
||||
## 07 Nov 2016
|
||||
|
||||
* Added a collector that prints metrics in a simple JSON format. See the [README](cmd/mq_json/README.md) for more details.
|
||||
* Fixed bug where freespace metrics were showing as non-integer bytes, not percentages
|
||||
|
||||
## 17 Oct 2016
|
||||
|
||||
* Added some Windows support. An example batch file is included in the mq_influx directory; changes would be needed to the MQSC script to call it. The other monitor programs can be supported with similar modifications.
|
||||
* Added a "getting started" section to this README.
|
||||
|
||||
## 23 Aug 2016
|
||||
|
||||
* Added a collector for Amazon AWS CloudWatch monitoring. See the [README](cmd/mq_aws/README.md) for more details.
|
||||
|
||||
## 12 Aug 2016
|
||||
|
||||
* Added a OpenTSDB monitor. See the [README](cmd/mq_opentsdb/README.md) for more details.
|
||||
* Added a Collectd monitor. See the [README](cmd/mq_coll/README.md) for more details.
|
||||
* Added MQI MQCNO/MQCSP structures to support client connections and password authentication with MQCONNX.
|
||||
* Allow client-mode connections from the monitor programs
|
||||
* Added Grafana dashboards for the different monitors to show how to query them
|
||||
* Changed database password mechanism so that "exec" maintains the PID for MQ services
|
||||
|
||||
## 04 Aug 2016
|
||||
|
||||
* Added a monitor command for exporting MQ data to InfluxDB. See the [README](cmd/mq_influx/README.md) for more details
|
||||
* Restructured the monitoring code to put common material in the mqmetric package, called from the Influx and Prometheus monitors.
|
||||
|
||||
## 25 Jul 2016
|
||||
|
||||
* Added functions to handle basic PCF creation and parsing
|
||||
* Added a monitor command for exporting MQ V9 queue manager data to Prometheus. See the [README](cmd/mq_prometheus/README.md) for more details
|
||||
|
||||
## 18 Jul 2016
|
||||
|
||||
* Changed structures so that most applications will not need to use cgo to imbed the MQ C headers
|
||||
* Go programs will now use int32 where C programs use MQLONG
|
||||
* Use of message handles, distribution lists require cgo for now
|
||||
* Package ibmmq now includes the numeric #defines as a Go file, cmqc.go, for easier use
|
||||
* Removed "src/" prefix from tree in github repo
|
||||
* Removed need for buffer length parm on Put/Put1
|
||||
* Updated comments
|
||||
* Added MQINQ
|
||||
* Added MQItoString function for some maps of values to constant names
|
||||
|
||||
## 08 Jul 2016
|
||||
|
||||
* Initial release
|
||||
32
vendor/github.com/ibm-messaging/mq-golang/CLA.md
generated
vendored
Normal file
32
vendor/github.com/ibm-messaging/mq-golang/CLA.md
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
IBM Contributor License Agreement
|
||||
=================================
|
||||
|
||||
Version 1.0.0 January 14, 2014
|
||||
|
||||
In order for You (as defined below) to make intellectual property Contributions (as defined below) now or in the future to IBM GitHub repositories,
|
||||
You must agree to this Contributor License Agreement ("CLA").
|
||||
|
||||
Please read this CLA carefully before accepting its terms. By accepting the CLA, You are agreeing to be bound by its terms.
|
||||
If You submit a Pull Request against an IBM repository on GitHub You must include in the Pull Request a statement of Your acceptance of this CLA.
|
||||
|
||||
As used in this CLA:
|
||||
(i) "You" (or "Your") shall mean the entity that is making this Agreement with IBM;
|
||||
(ii)"Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is submitted by You to IBM for inclusion in,
|
||||
or documentation of, any of the IBM GitHub repositories;
|
||||
(iii) "Submit" (or "Submitted") means any form of communication sent to IBM (e.g. the content You post in a GitHub Issue or submit as part of a GitHub Pull Request).
|
||||
|
||||
This agreement applies to all Contributions You Submit.
|
||||
|
||||
This CLA, and the license(s) associated with the particular IBM GitHub repositories You are contributing to, provides a license to Your Contributions to IBM and downstream consumers,
|
||||
but You still own Your Contributions, and except for the licenses provided for in this CLA, You reserve all right, title and interest in Your Contributions.
|
||||
|
||||
IBM requires that each Contribution You Submit now or in the future comply with the following four commitments.
|
||||
|
||||
1) You will only Submit Contributions where You have authored 100% of the content.
|
||||
2) You will only Submit Contributions to which You have the necessary rights. This means that if You are employed You have received the necessary permissions from Your employer to make the
|
||||
Contributions.
|
||||
3) Whatever content You Contribute will be provided under the license(s) associated with the particular IBM GitHub repository You are contributing to.
|
||||
4) You understand and agree that IBM GitHub repositories and Your contributions are public, and that a record of the contribution (including all personal information You submit with it)
|
||||
is maintained indefinitely and may be redistributed consistent with the license(s) involved.
|
||||
You will promptly notify the Eclipse Foundation if You become aware of any facts or circumstances that would make these commitments inaccurate in any way.
|
||||
To do so, please create an Issue in the appropriate GitHub repository.
|
||||
49
vendor/github.com/ibm-messaging/mq-golang/Dockerfile-build-packages
generated
vendored
Normal file
49
vendor/github.com/ibm-messaging/mq-golang/Dockerfile-build-packages
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
# © Copyright IBM Corporation 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.
|
||||
|
||||
ARG BASE_IMAGE=mq-sdk:9.0.5.0-x86_64-ubuntu-16.04
|
||||
|
||||
FROM $BASE_IMAGE
|
||||
|
||||
ENV GO_VERSION=1.10
|
||||
|
||||
# Install the Go compiler and Git
|
||||
RUN export DEBIAN_FRONTEND=noninteractive \
|
||||
&& bash -c 'source /etc/os-release; \
|
||||
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_CODENAME} main restricted" > /etc/apt/sources.list; \
|
||||
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_CODENAME}-updates main restricted" >> /etc/apt/sources.list; \
|
||||
echo "deb http://archive.ubuntu.com/ubuntu/ ${UBUNTU_CODENAME}-backports main restricted universe" >> /etc/apt/sources.list;' \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends golang-${GO_VERSION} git ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENV PATH="${PATH}:/usr/lib/go-${GO_VERSION}/bin:/go/bin" \
|
||||
CGO_CFLAGS="-I/opt/mqm/inc/" \
|
||||
CGO_LDFLAGS_ALLOW="-Wl,-rpath.*" \
|
||||
GOPATH="/go" \
|
||||
OUTPUT_DIR="${OUTPUT_DIR}"
|
||||
|
||||
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" "$GOPATH/pkg" \
|
||||
&& chmod -R 777 "$GOPATH" \
|
||||
&& mkdir -p "$GOPATH/src/github.com/ibm-messaging/mq-golang"
|
||||
|
||||
WORKDIR $GOPATH/src/github.com/ibm-messaging/mq-golang
|
||||
|
||||
COPY ./ibmmq ibmmq
|
||||
COPY ./mqmetric mqmetric
|
||||
|
||||
RUN go build ./ibmmq \
|
||||
&& go test ./ibmmq \
|
||||
&& go build ./mqmetric \
|
||||
&& go test ./mqmetric
|
||||
26
vendor/github.com/ibm-messaging/mq-golang/Dockerfile-build-samples
generated
vendored
Normal file
26
vendor/github.com/ibm-messaging/mq-golang/Dockerfile-build-samples
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# © Copyright IBM Corporation 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.
|
||||
|
||||
ARG BASE_IMAGE=mq-golang-build:9.0.5.0-x86_64-ubuntu-16.04
|
||||
|
||||
FROM $BASE_IMAGE
|
||||
|
||||
RUN mkdir -p "$GOPATH/src/github.com/ibm-messaging/mq-golang/samples"
|
||||
WORKDIR $GOPATH/src/github.com/ibm-messaging/mq-golang/samples
|
||||
|
||||
COPY ./samples/clientconn clientconn
|
||||
COPY ./samples/mqitest mqitest
|
||||
|
||||
RUN go install ./clientconn \
|
||||
&& go install ./mqitest
|
||||
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.
|
||||
79
vendor/github.com/ibm-messaging/mq-golang/Makefile
generated
vendored
Normal file
79
vendor/github.com/ibm-messaging/mq-golang/Makefile
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
# © Copyright IBM Corporation 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.
|
||||
|
||||
###############################################################################
|
||||
# Conditional variables - you can override the values of these variables from
|
||||
# the command line
|
||||
###############################################################################
|
||||
# BASE_IMAGE is the MQ SDK base image to use
|
||||
BASE_IMAGE ?= mq-sdk:9.0.5.0-x86_64-ubuntu-16.04
|
||||
# GO_IMAGE is the GOLANG image to use for building samples
|
||||
GO_IMAGE ?= golang:1.10
|
||||
# DOCKER is the Docker command to run
|
||||
DOCKER ?= docker
|
||||
# BUILD_IMAGE is the name of the image that will be produced while building packages
|
||||
BUILD_IMAGE ?= mq-golang-build:9.0.5.0-x86_64-ubuntu-16.04
|
||||
# SAMPLE_BUILD_IMAGE is the name of the image that will be produced while building samples
|
||||
SAMPLE_BUILD_IMAGE ?= mq-sample-build:9.0.5.0-x86_64-ubuntu-16.04
|
||||
|
||||
###############################################################################
|
||||
# Other variables
|
||||
###############################################################################
|
||||
|
||||
ifneq (,$(findstring Microsoft,$(shell uname -r)))
|
||||
PLATFORM=WINDOWS
|
||||
else
|
||||
PLATFORM=UNIX
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
# Build targets
|
||||
###############################################################################
|
||||
|
||||
# Build all packages when on unix
|
||||
.PHONY: all
|
||||
ifeq ("$(PLATFORM)", "WINDOWS")
|
||||
all: unsupported-message
|
||||
else
|
||||
all: build-packages-unix build-samples-unix
|
||||
endif
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(DOCKER) rmi -f $(BUILD_IMAGE)
|
||||
$(DOCKER) rmi -f $(SAMPLE_BUILD_IMAGE)
|
||||
|
||||
.PHONY: build-packages-unix
|
||||
build-packages-unix:
|
||||
$(info $(SPACER)$(shell printf $(TITLE)"Building packages in build container"$(END)))
|
||||
$(call docker-build,$(BUILD_IMAGE),Dockerfile-build-packages,$(BASE_IMAGE))
|
||||
|
||||
.PHONY: build-samples-unix
|
||||
build-samples-unix: build-packages-unix
|
||||
$(info $(SPACER)$(shell printf $(TITLE)"Building samples in build container"$(END)))
|
||||
$(call docker-build,$(SAMPLE_BUILD_IMAGE),Dockerfile-build-samples,$(BUILD_IMAGE))
|
||||
|
||||
.PHONY: unsupported-message
|
||||
unsupported-message:
|
||||
$(info $(SPACER)$(shell printf $(TITLE)"This makefile can only be ran on UNIX platforms"$(END)))
|
||||
|
||||
define docker-build
|
||||
# Build the image first to compile the package/samples
|
||||
$(DOCKER) build -t $1 \
|
||||
-f $2 \
|
||||
--build-arg BASE_IMAGE=$3 \
|
||||
.
|
||||
endef
|
||||
|
||||
include formatting.mk
|
||||
117
vendor/github.com/ibm-messaging/mq-golang/README.md
generated
vendored
Executable file
117
vendor/github.com/ibm-messaging/mq-golang/README.md
generated
vendored
Executable file
@@ -0,0 +1,117 @@
|
||||
# mq-golang
|
||||
|
||||
This repository demonstrates how you can call IBM MQ from applications written in the Go language.
|
||||
|
||||
> **NOTICE**: Please ensure that you use a dependency management tool such as [dep](https://github.com/golang/dep) or [Glide](http://glide.sh/), and add a specific version dependency. The current content has been marked as version 1.0.0, and a new version with breaking changes will be released soon. By using a dependency manager, you can continue to use the old version if you want to.
|
||||
|
||||
This repository previously contained sample programs that exported MQ statistics to some monitoring packages. These have now been moved to a new [GitHub repository called mq-metric-samples](https://github.com/ibm-messaging/mq-metric-samples).
|
||||
|
||||
A minimum level of MQ V9 is required to build these packages.
|
||||
The monitoring data published by the queue manager is not available before that version; the interface also assumes availability of MQI structures from that level of MQ.
|
||||
|
||||
## Health Warning
|
||||
|
||||
This package is provided as-is with no guarantees of support or updates. There are also no guarantees of compatibility with any future versions of the package; the API is subject to change based on any feedback.
|
||||
|
||||
## MQI Description
|
||||
|
||||
The ibmmq directory contains a Go package, exposing an MQI-like interface.
|
||||
|
||||
The intention is to give an API that is more natural for Go programmers than the common procedural MQI. For example, fixed length string arrays from the C API such as MQCHAR48 are represented by the native Go string type. Conversion between these types is handled within the ibmmq package itself, removing the need for Go programmers to know about it.
|
||||
|
||||
A short program in the mqitest directory gives an example of using this interface, to put and get messages and to subscribe to a topic.
|
||||
|
||||
Feedback on the utility of this package, thoughts about whether it should be changed or extended are welcomed.
|
||||
|
||||
## Using the package
|
||||
|
||||
To use code in this repository, you will need to be able to build Go applications, and have a copy of MQ installed to build against. It uses cgo to access the MQI C structures and definitions. It assumes that MQ has been installed in the default location on a Linux platform (`/opt/mqm`) but you can easily change the cgo directives in the source files if necessary.
|
||||
|
||||
Some Windows capability is also included. This has been tested with Go 1.10 compiler, which now permits standard Windows paths (eg including spaces) so the CGO directives can point at the normal MQ install path.
|
||||
|
||||
## Getting started
|
||||
|
||||
If you are unfamiliar with Go, the following steps can help create a working environment with source code in a suitable tree. Initial setup tends to be platform-specific, but subsequent steps are independent of the platform.
|
||||
|
||||
### Linux
|
||||
|
||||
* Install the Go runtime and compiler. On Linux, the packaging may vary but a typical directory for the code is `/usr/lib/golang`.
|
||||
|
||||
* Create a working directory. For example, ```mkdir $HOME/gowork```
|
||||
|
||||
* Set environment variables. Based on the previous lines,
|
||||
|
||||
```export GOROOT=/usr/lib/golang```
|
||||
|
||||
```export GOPATH=$HOME/gowork```
|
||||
|
||||
* If using a version of Go from after 2017, you must set environment variables to permit some compile/link flags. This is due to a security fix in the compiler.
|
||||
|
||||
```export CGO_LDFLAGS_ALLOW="-Wl,-rpath.*"```
|
||||
|
||||
* Install the git client
|
||||
|
||||
### Windows
|
||||
|
||||
* Install the Go runtime and compiler. On Windows, the common directory is `c:\Go`
|
||||
* Ensure you have a gcc-based compiler, for example from the Cygwin distribution. I use the mingw variation, to ensure compiled code can be used on systems without Cygwin installed
|
||||
* Create a working directory. For example, ```mkdir c:\Gowork```
|
||||
* Set environment variables. Based on the previous lines,
|
||||
|
||||
```set GOROOT=c:\Go```
|
||||
|
||||
```set GOPATH=c:\Gowork```
|
||||
|
||||
```set CC=x86_64-w64-mingw32-gcc.exe```
|
||||
|
||||
* The `CGO_LDFLAGS_ALLOW` variable is not needed on Windows
|
||||
* Install the git client
|
||||
* Make sure the MQ include files and libraries are in a path that does not include spaces or other special characters, as discussed above.
|
||||
|
||||
### Common
|
||||
|
||||
* Make sure your PATH includes routes to the Go compiler (`$GOROOT/bin`), the Git client, and the C compiler.
|
||||
* Change directory to the workspace you created earlier. (`cd $GOPATH`)
|
||||
* Use git to get a copy of the MQ components into a new directory in the workspace.
|
||||
|
||||
```git clone https://github.com/ibm-messaging/mq-golang.git src/github.com/ibm-messaging/mq-golang```
|
||||
|
||||
* Compile the `ibmmq` component:
|
||||
|
||||
```go install ./src/github.com/ibm-messaging/mq-golang/ibmmq```
|
||||
|
||||
* Compile the `mqmetric` component:
|
||||
|
||||
```go install ./src/github.com/ibm-messaging/mq-golang/mqmetric```
|
||||
|
||||
* Follow the instructions in the [mq-metric-samples repository](https://github.com/ibm-messaging/mq-metric-samples) to compile the sample programs you are interested in.
|
||||
|
||||
At this point, you should have a compiled copy of the code in `$GOPATH/bin`.
|
||||
|
||||
## Limitations
|
||||
|
||||
Not all of the MQI verbs are available through the `ibmmq` package. This
|
||||
implementation concentrates on the core API calls needed to put and get messages.
|
||||
Currently unavailable verbs include:
|
||||
|
||||
* MQSET
|
||||
* All of the message property manipulators
|
||||
* MQCB
|
||||
|
||||
There are also no structure handlers for message headers such as MQRFH2 or MQDLH.
|
||||
|
||||
## History
|
||||
|
||||
See [CHANGELOG](CHANGELOG.md) in this directory.
|
||||
|
||||
## Issues and Contributions
|
||||
|
||||
For feedback and issues relating specifically to this package, please use the [GitHub issue tracker](https://github.com/ibm-messaging/mq-golang/issues).
|
||||
|
||||
Contributions to this package can be accepted under the terms of the IBM Contributor License Agreement,
|
||||
found in the [CLA file](CLA.md) of this repository. When submitting a pull request, you must include a statement stating
|
||||
you accept the terms in the CLA.
|
||||
|
||||
## Copyright
|
||||
|
||||
© Copyright IBM Corporation 2016, 2018
|
||||
17
vendor/github.com/ibm-messaging/mq-golang/formatting.mk
generated
vendored
Normal file
17
vendor/github.com/ibm-messaging/mq-golang/formatting.mk
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
GREEN="\033[32m"
|
||||
RED="\033[31m"
|
||||
BLUE="\033[34m"
|
||||
PURPLE="\033[35m"
|
||||
AQUA="\033[36m"
|
||||
|
||||
END="\033[0m"
|
||||
|
||||
UNDERLINE="\033[4m"
|
||||
BOLD="\033[1m"
|
||||
|
||||
TITLE=$(BLUE)$(BOLD)$(UNDERLINE)
|
||||
|
||||
define SPACER
|
||||
|
||||
|
||||
endef
|
||||
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
Executable file
4951
vendor/github.com/ibm-messaging/mq-golang/ibmmq/cmqc_windows.go
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
291
vendor/github.com/ibm-messaging/mq-golang/ibmmq/ibmmq_test.go
generated
vendored
Normal file
291
vendor/github.com/ibm-messaging/mq-golang/ibmmq/ibmmq_test.go
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 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.
|
||||
*/
|
||||
package ibmmq
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Tests for mqistr.go
|
||||
func TestMqstrerror(t *testing.T) {
|
||||
output := mqstrerror("test", 0, 0)
|
||||
expected := "test: MQCC = MQCC_OK [0] MQRC = MQRC_NONE [0]"
|
||||
if output != expected {
|
||||
t.Logf("Gave 0, 0. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = mqstrerror("test", 1, 2393)
|
||||
expected = "test: MQCC = MQCC_WARNING [1] MQRC = MQRC_SSL_INITIALIZATION_ERROR [2393]"
|
||||
if output != expected {
|
||||
t.Logf("Gave 1, 2393. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = mqstrerror("test", 2, 2035)
|
||||
expected = "test: MQCC = MQCC_FAILED [2] MQRC = MQRC_NOT_AUTHORIZED [2035]"
|
||||
if output != expected {
|
||||
t.Logf("Gave 2, 2035. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestMQItoString(t *testing.T) {
|
||||
output := MQItoString("BACF", 7019)
|
||||
expected := "MQBACF_ALTERNATE_SECURITYID"
|
||||
if output != expected {
|
||||
t.Logf("Gave BACF, 7019. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("CA", 2030)
|
||||
expected = "MQCA_CLUSTER_NAMELIST"
|
||||
if output != expected {
|
||||
t.Logf("Gave CA, 2030. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("CA", 3134)
|
||||
expected = "MQCACF_ACTIVITY_DESC"
|
||||
if output != expected {
|
||||
t.Logf("Gave CA, 3134. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("CA", 3529)
|
||||
expected = "MQCACH_CHANNEL_START_DATE"
|
||||
if output != expected {
|
||||
t.Logf("Gave CA, 3529. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("CA", 2708)
|
||||
expected = "MQCAMO_END_TIME"
|
||||
if output != expected {
|
||||
t.Logf("Gave CA, 2708. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("CC", -1)
|
||||
expected = "MQCC_UNKNOWN"
|
||||
if output != expected {
|
||||
t.Logf("Gave CC, -1. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("CMD", 208)
|
||||
expected = "MQCMD_CHANGE_PROT_POLICY"
|
||||
if output != expected {
|
||||
t.Logf("Gave CMD, 208. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("IA", 102)
|
||||
expected = "MQIA_ADOPTNEWMCA_CHECK"
|
||||
if output != expected {
|
||||
t.Logf("Gave IA, 102. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("IA", 1019)
|
||||
expected = "MQIACF_AUTH_INFO_ATTRS"
|
||||
if output != expected {
|
||||
t.Logf("Gave IA, 1019. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("IA", 1584)
|
||||
expected = "MQIACH_ADAPS_MAX"
|
||||
if output != expected {
|
||||
t.Logf("Gave IA, 1584. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("IA", 770)
|
||||
expected = "MQIAMO_CBS_FAILED"
|
||||
if output != expected {
|
||||
t.Logf("Gave IA, 770. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("IA", 745)
|
||||
expected = "MQIAMO64_BROWSE_BYTES"
|
||||
if output != expected {
|
||||
t.Logf("Gave IA, 745. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("OT", 1008)
|
||||
expected = "MQOT_SERVER_CHANNEL"
|
||||
if output != expected {
|
||||
t.Logf("Gave OT, 1008. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("RC", 2277)
|
||||
expected = "MQRC_CD_ERROR"
|
||||
if output != expected {
|
||||
t.Logf("Gave RC, 2277. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("RC", 3049)
|
||||
expected = "MQRCCF_CCSID_ERROR"
|
||||
if output != expected {
|
||||
t.Logf("Gave RC, 3049. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("BADVALUE", 0)
|
||||
expected = ""
|
||||
if output != expected {
|
||||
t.Logf("Gave BADVALUE, 0. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
output = MQItoString("IA", 0123123123123)
|
||||
expected = ""
|
||||
if output != expected {
|
||||
t.Logf("Gave IA, 0123123123123. Expected: %s, Got: %s", expected, output)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
// Tests for mqiPCF.go
|
||||
func TestReadPCFHeader(t *testing.T) {
|
||||
testHeader := NewMQCFH()
|
||||
returned, offset := ReadPCFHeader(testHeader.Bytes())
|
||||
if returned.Type != testHeader.Type {
|
||||
t.Logf("Returned 'Type' does not match Initial: Expected: %d Got: %d", testHeader.Type, returned.Type)
|
||||
t.Fail()
|
||||
}
|
||||
if returned.StrucLength != testHeader.StrucLength {
|
||||
t.Logf("Returned 'StrucLength' does not match Initial: Expected: %d Got: %d", testHeader.StrucLength, returned.StrucLength)
|
||||
t.Fail()
|
||||
}
|
||||
if returned.Version != testHeader.Version {
|
||||
t.Logf("Returned 'Version' does not match Initial: Expected: %d Got: %d", testHeader.Version, returned.Version)
|
||||
t.Fail()
|
||||
}
|
||||
if returned.Command != testHeader.Command {
|
||||
t.Logf("Returned 'Command' does not match Initial: Expected: %d Got: %d", testHeader.Command, returned.Command)
|
||||
t.Fail()
|
||||
}
|
||||
if returned.MsgSeqNumber != testHeader.MsgSeqNumber {
|
||||
t.Logf("Returned 'MsgSeqNumber' does not match Initial: Expected: %d Got: %d", testHeader.MsgSeqNumber, returned.MsgSeqNumber)
|
||||
t.Fail()
|
||||
}
|
||||
if returned.Control != testHeader.Control {
|
||||
t.Logf("Returned 'Control' does not match Initial: Expected: %d Got: %d", testHeader.Control, returned.Control)
|
||||
t.Fail()
|
||||
}
|
||||
if returned.CompCode != testHeader.CompCode {
|
||||
t.Logf("Returned 'CompCode' does not match Initial: Expected: %d Got: %d", testHeader.CompCode, returned.CompCode)
|
||||
t.Fail()
|
||||
}
|
||||
if returned.Reason != testHeader.Reason {
|
||||
t.Logf("Returned 'Reason' does not match Initial: Expected: %d Got: %d", testHeader.Reason, returned.Reason)
|
||||
t.Fail()
|
||||
}
|
||||
if returned.ParameterCount != testHeader.ParameterCount {
|
||||
t.Logf("Returned 'ParameterCount' does not match Initial: Expected: %d Got: %d", testHeader.ParameterCount, returned.ParameterCount)
|
||||
t.Fail()
|
||||
}
|
||||
if offset != 36 {
|
||||
t.Logf("Expected offset to be 36 but was %d", offset)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadPCFParameter(t *testing.T) {
|
||||
start := PCFParameter{
|
||||
Parameter: MQCACF_APPL_NAME,
|
||||
Int64Value: []int64{100},
|
||||
String: []string{"HELLOTEST"},
|
||||
ParameterCount: 1,
|
||||
}
|
||||
|
||||
t.Log("-MQCFT_INTEGER-")
|
||||
start.Type = MQCFT_INTEGER
|
||||
back, _ := ReadPCFParameter(start.Bytes())
|
||||
verifyParam(t, &start, back)
|
||||
|
||||
t.Log("-MQCFT_STRING-")
|
||||
start.Type = MQCFT_STRING
|
||||
back, _ = ReadPCFParameter(start.Bytes())
|
||||
verifyParam(t, &start, back)
|
||||
|
||||
// The rest of the types are not implemented in the Bytes()
|
||||
// function so cannot be tested.
|
||||
}
|
||||
|
||||
func verifyParam(t *testing.T, given, returned *PCFParameter) {
|
||||
t.Log("Testing Type")
|
||||
if given.Type != returned.Type {
|
||||
t.Logf("Returned 'Type' does not match Initial: Expected: %d Got: %d", given.Type, returned.Type)
|
||||
t.Fail()
|
||||
}
|
||||
t.Log("Testing Parameter")
|
||||
if given.Parameter != returned.Parameter {
|
||||
t.Logf("Returned 'Parameter' does not match Initial: Expected: %d Got: %d", given.Parameter, returned.Parameter)
|
||||
t.Fail()
|
||||
}
|
||||
if given.Type == MQCFT_INTEGER || given.Type == MQCFT_INTEGER64 || given.Type == MQCFT_INTEGER_LIST || given.Type == MQCFT_INTEGER64_LIST {
|
||||
t.Log("Testing Length")
|
||||
if len(given.Int64Value) != len(returned.Int64Value) {
|
||||
t.Logf("Length of Returned 'Int64Value' does not match Initial: Expected: %d Got: %d", len(given.Int64Value), len(returned.Int64Value))
|
||||
t.Fail()
|
||||
} else if given.Int64Value[0] != returned.Int64Value[0] {
|
||||
t.Logf("Returned parameter 'Int64Value' did not match. Expected: %d, Got: %d", given.Int64Value[0], returned.Int64Value[0])
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
if given.Type == MQCFT_STRING || given.Type == MQCFT_STRING_LIST {
|
||||
if len(given.String) != len(returned.String) {
|
||||
t.Logf("Length of Returned 'String' does not match Initial: Expected: %d Got: %d", len(given.String), len(returned.String))
|
||||
t.Fail()
|
||||
} else if given.String[0] != returned.String[0] {
|
||||
t.Logf("Returned parameter 'String' did not match. Expected: %s, Got: %s", given.String[0], returned.String[0])
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
if given.Type == MQCFT_GROUP {
|
||||
if given.ParameterCount != returned.ParameterCount {
|
||||
t.Logf("Returned 'ParameterCount' does not match Initial: Expected: %d Got: %d", given.ParameterCount, returned.ParameterCount)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
if len(given.GroupList) != len(returned.GroupList) {
|
||||
t.Logf("Length of Returned 'GroupList' does not match Initial: Expected: %d Got: %d", len(given.GroupList), len(returned.GroupList))
|
||||
t.Fail()
|
||||
} // Should be nil
|
||||
}
|
||||
|
||||
func TestRoundTo4(t *testing.T) {
|
||||
start := []int32{12, 13, 14, 15, 16, 17}
|
||||
expected := []int32{12, 16, 16, 16, 16, 20}
|
||||
|
||||
for i, e := range start {
|
||||
back := roundTo4(e)
|
||||
if back != expected[i] {
|
||||
t.Logf("Passed: %d. Expected: %d. Got: %d", e, expected[i], back)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
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
Executable file
98
vendor/github.com/ibm-messaging/mq-golang/ibmmq/mqistr.go
generated
vendored
Executable 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
|
||||
}
|
||||
747
vendor/github.com/ibm-messaging/mq-golang/mqmetric/discover.go
generated
vendored
Executable file
747
vendor/github.com/ibm-messaging/mq-golang/mqmetric/discover.go
generated
vendored
Executable file
@@ -0,0 +1,747 @@
|
||||
/*
|
||||
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"
|
||||
"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 = formatDescriptionElem(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() {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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 formatDescriptionElem(elem *MonElement) string {
|
||||
s := formatDescription(elem.Description)
|
||||
|
||||
unit := ""
|
||||
switch elem.Datatype {
|
||||
case ibmmq.MQIAMO_MONITOR_MICROSEC:
|
||||
// Although the qmgr captures in us, we convert when
|
||||
// pushing out to the backend, so this label needs to match
|
||||
unit = "_seconds"
|
||||
}
|
||||
s += unit
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
func formatDescription(baseName string) string {
|
||||
s := baseName
|
||||
s = strings.Replace(s, " ", "_", -1)
|
||||
s = strings.Replace(s, "/", "_", -1)
|
||||
s = strings.Replace(s, "-", "_", -1)
|
||||
|
||||
/* common pattern is "xxx - yyy" leading to 3 ugly adjacent underscores */
|
||||
s = strings.Replace(s, "___", "_", -1)
|
||||
s = strings.Replace(s, "__", "_", -1)
|
||||
|
||||
/* make it all lowercase. Not essential, but looks better */
|
||||
s = strings.ToLower(s)
|
||||
|
||||
// Do not use _count
|
||||
s = strings.Replace(s, "_count", "", -1)
|
||||
|
||||
// Switch round a couple of specific names
|
||||
s = strings.Replace(s, "bytes_written", "written_bytes", -1)
|
||||
s = strings.Replace(s, "bytes_max", "max_bytes", -1)
|
||||
s = strings.Replace(s, "bytes_in_use", "in_use_bytes", -1)
|
||||
s = strings.Replace(s, "messages_expired", "expired_messages", -1)
|
||||
|
||||
if strings.HasSuffix(s, "free_space") {
|
||||
s = s + "_percentage"
|
||||
s = strings.Replace(s, "__", "_", -1)
|
||||
}
|
||||
|
||||
// Make "byte", "file" and "message" units plural
|
||||
if strings.HasSuffix(s, "byte") ||
|
||||
strings.HasSuffix(s, "message") ||
|
||||
strings.HasSuffix(s, "file") {
|
||||
s = s + "s"
|
||||
}
|
||||
|
||||
// Move % to the end
|
||||
if strings.Contains(s, "_percentage_") {
|
||||
s = strings.Replace(s, "_percentage_", "_", -1)
|
||||
s += "_percentage"
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
237
vendor/github.com/ibm-messaging/mq-golang/mqmetric/mqif.go
generated
vendored
Normal file
237
vendor/github.com/ibm-messaging/mq-golang/mqmetric/mqif.go
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
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
|
||||
var mqreturn *ibmmq.MQReturn
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
mqreturn = err.(*ibmmq.MQReturn)
|
||||
|
||||
if mqreturn.MQRC == ibmmq.MQRC_Q_MGR_NOT_AVAILABLE ||
|
||||
mqreturn.MQRC == ibmmq.MQRC_Q_MGR_NAME_ERROR ||
|
||||
mqreturn.MQRC == ibmmq.MQRC_Q_MGR_QUIESCING {
|
||||
return nil, fmt.Errorf("Queue Manager error: %v", err)
|
||||
}
|
||||
if mqreturn.MQCC == ibmmq.MQCC_FAILED && mqreturn.MQRC != ibmmq.MQRC_NO_MSG_AVAILABLE {
|
||||
return nil, fmt.Errorf("Get message error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
175
vendor/github.com/ibm-messaging/mq-golang/mqmetric/mqmetric_test.go
generated
vendored
Normal file
175
vendor/github.com/ibm-messaging/mq-golang/mqmetric/mqmetric_test.go
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
© Copyright IBM Corporation 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.
|
||||
*/
|
||||
package mqmetric
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/ibm-messaging/mq-golang/ibmmq"
|
||||
)
|
||||
|
||||
func TestNormalise(t *testing.T) {
|
||||
var expected float64
|
||||
test := MonElement{}
|
||||
value := int64(1000000)
|
||||
|
||||
test.Datatype = ibmmq.MQIAMO_MONITOR_PERCENT
|
||||
expected = 10000
|
||||
returned := Normalise(&test, "", value)
|
||||
if returned != expected {
|
||||
t.Logf("Gave %s, %d. Expected: %f, Got: %f", "ibmmq.MQIAMO_MONITOR_PERCENT", value, expected, returned)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
test.Datatype = ibmmq.MQIAMO_MONITOR_HUNDREDTHS
|
||||
expected = 10000
|
||||
returned = Normalise(&test, "", value)
|
||||
if returned != expected {
|
||||
t.Logf("Gave %s, %d. Expected: %f, Got: %f", "ibmmq.MQIAMO_MONITOR_HUNDREDTHS", value, expected, returned)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
test.Datatype = ibmmq.MQIAMO_MONITOR_MB
|
||||
expected = 1048576000000
|
||||
returned = Normalise(&test, "", value)
|
||||
if returned != expected {
|
||||
t.Logf("Gave %s, %d. Expected: %f, Got: %f", "ibmmq.MQIAMO_MONITOR_MB", value, expected, returned)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
test.Datatype = ibmmq.MQIAMO_MONITOR_GB
|
||||
expected = 1073741824000000
|
||||
returned = Normalise(&test, "", value)
|
||||
if returned != expected {
|
||||
t.Logf("Gave %s, %d. Expected: %f, Got: %f", "ibmmq.MQIAMO_MONITOR_GB", value, expected, returned)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
test.Datatype = ibmmq.MQIAMO_MONITOR_MICROSEC
|
||||
expected = 1
|
||||
returned = Normalise(&test, "", value)
|
||||
if returned != expected {
|
||||
t.Logf("Gave %s, %d. Expected: %f, Got: %f", "ibmmq.MQIAMO_MONITOR_GB", value, expected, returned)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadPatterns(t *testing.T) {
|
||||
const filename = "testFile"
|
||||
//Create dummy test file
|
||||
testData := []byte("test1=yes\ntest2=no\n")
|
||||
err := ioutil.WriteFile(filename, testData, 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not create test file - %v", err)
|
||||
}
|
||||
defer os.Remove(filename)
|
||||
|
||||
expected := "test1=yes,test2=no"
|
||||
back, err := ReadPatterns(filename)
|
||||
if err != nil {
|
||||
t.Logf("Got error while running ReadPatterns - %v", err)
|
||||
t.Fail()
|
||||
} else if back != expected {
|
||||
t.Logf("File was not parsed correctly. Expected: %s. Got: %s", expected, back)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
func TestFormatDescription(t *testing.T) {
|
||||
give := [...]string{"hello", "no space", "no/slash", "no-dash", "single___underscore", "single__underscore", "ALLLOWER", "no_count", "this_bytes_written_switch", "this_bytes_max_switch", "this_bytes_in_use_switch", "this messages_expired_switch", "add_free_space", "suffix_byte", "suffix_message", "suffix_file", "this_percentage_move"}
|
||||
expected := [...]string{"hello", "no_space", "no_slash", "no_dash", "single_underscore", "single_underscore", "alllower", "no", "this_written_bytes_switch", "this_max_bytes_switch", "this_in_use_bytes_switch", "this_expired_messages_switch", "add_free_space_percentage", "suffix_bytes", "suffix_messages", "suffix_files", "this_move_percentage"}
|
||||
|
||||
for i, e := range give {
|
||||
back := formatDescription(e)
|
||||
if back != expected[i] {
|
||||
t.Logf("Gave %s. Expected: %s, Got: %s", e, expected[i], back)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
func TestFormatDescriptionElem(t *testing.T) {
|
||||
test := MonElement{}
|
||||
test.Description = "THIS-should__be/formatted_count"
|
||||
expected := "this_should_be_formatted"
|
||||
|
||||
back := formatDescriptionElem(&test)
|
||||
if back != expected {
|
||||
t.Logf("Gave %s. Expected: %s, Got: %s", test.Description, expected, back)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
test.Datatype = ibmmq.MQIAMO_MONITOR_MICROSEC
|
||||
expected = "this_should_be_formatted_seconds"
|
||||
back = formatDescriptionElem(&test)
|
||||
if back != expected {
|
||||
t.Logf("Gave %s. Expected: %s, Got: %s", test.Description, expected, back)
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
func TestParsePCFResponse(t *testing.T) {
|
||||
cfh := ibmmq.NewMQCFH()
|
||||
cfh.Type = ibmmq.MQCFT_RESPONSE
|
||||
headerbytes := cfh.Bytes()
|
||||
|
||||
params, last := parsePCFResponse(headerbytes)
|
||||
if len(params) != 0 && !last {
|
||||
t.Logf("Gave just a header. Expected: 0, false , Got: %d, %t", len(params), last)
|
||||
t.Fail()
|
||||
}
|
||||
|
||||
cfh.ParameterCount = 1
|
||||
parm := ibmmq.PCFParameter{
|
||||
Type: ibmmq.MQCFT_STRING, // String
|
||||
Parameter: ibmmq.MQCACF_APPL_NAME,
|
||||
String: []string{"HELLOTEST"},
|
||||
ParameterCount: 1,
|
||||
}
|
||||
headerbytes = cfh.Bytes()
|
||||
parmbytes := parm.Bytes()
|
||||
messagebytes := append(headerbytes, parmbytes...)
|
||||
|
||||
params, last = parsePCFResponse(messagebytes)
|
||||
if len(params) != 1 && !last {
|
||||
t.Logf("Gave header and parameter. Expected: 1, false , Got: %d, %t", len(params), last)
|
||||
t.Fail()
|
||||
} else {
|
||||
elem := params[0]
|
||||
if elem.Type != parm.Type {
|
||||
t.Logf("Returned parameter 'Type' did not match. Expected: %d, Got: %d", parm.Type, elem.Type)
|
||||
t.Fail()
|
||||
}
|
||||
if elem.Parameter != parm.Parameter {
|
||||
t.Logf("Returned parameter 'Parameter' did not match. Expected: %d, Got: %d", parm.Parameter, elem.Parameter)
|
||||
t.Fail()
|
||||
}
|
||||
if len(elem.String) != len(parm.String) {
|
||||
t.Logf("Length of Returned parameter 'String' did not match. Expected: %d, Got: %d", len(parm.String), len(elem.String))
|
||||
t.Fail()
|
||||
} else if elem.String[0] != parm.String[0] {
|
||||
t.Logf("Returned parameter 'String' did not match. Expected: %s, Got: %s", parm.String[0], elem.String[0])
|
||||
t.Fail()
|
||||
}
|
||||
if len(elem.Int64Value) != 0 {
|
||||
t.Logf("Returned parameter 'Int64Value' was not empty, length=%d", len(elem.Int64Value))
|
||||
t.Fail()
|
||||
}
|
||||
if len(elem.GroupList) != 0 {
|
||||
t.Logf("Returned parameter 'GroupList' was not empty, length=%d", len(elem.GroupList))
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
}
|
||||
118
vendor/github.com/ibm-messaging/mq-golang/samples/clientconn/clientconn.go
generated
vendored
Normal file
118
vendor/github.com/ibm-messaging/mq-golang/samples/clientconn/clientconn.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
This is a short sample to show how to connect to a remote
|
||||
queue manager in a Go program without requiring external
|
||||
client configuration such as a CCDT. Only the basic
|
||||
parameters are needed here - channel name and connection information -
|
||||
along with the queue manager name.
|
||||
|
||||
For example, run as
|
||||
clientconn QMGR1 "SYSTEM.DEF.SVRCONN" "myhost.example.com(1414)"
|
||||
|
||||
If the MQSAMP_USER_ID environment variable is set, then a userid/password
|
||||
flow is also made to authenticate to the queue manager.
|
||||
|
||||
There is no attempt in this sample to configure advanced security features
|
||||
such TLS.
|
||||
|
||||
If an error occurs, the error is reported.
|
||||
*/
|
||||
package main
|
||||
|
||||
/*
|
||||
Copyright (c) IBM Corporation 2017
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/ibm-messaging/mq-golang/ibmmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var qMgrName string
|
||||
var err error
|
||||
var qMgr ibmmq.MQQueueManager
|
||||
var rc int
|
||||
|
||||
if len(os.Args) != 4 {
|
||||
fmt.Println("clientconn <qmgrname> <channelname> <conname>")
|
||||
fmt.Println("")
|
||||
fmt.Println("For example")
|
||||
fmt.Println(" clientconn QMGR1 \"SYSTEM.DEF.SVRCONN\" \"myhost.example.com(1414)\"")
|
||||
fmt.Println("All parameters are required.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Which queue manager do we want to connect to
|
||||
qMgrName = os.Args[1]
|
||||
|
||||
// Allocate the MQCNO and MQCD structures needed for the
|
||||
// MQCONNX call.
|
||||
cno := ibmmq.NewMQCNO()
|
||||
cd := ibmmq.NewMQCD()
|
||||
|
||||
// Fill in the required fields in the
|
||||
// MQCD channel definition structure
|
||||
cd.ChannelName = os.Args[2]
|
||||
cd.ConnectionName = os.Args[3]
|
||||
|
||||
// Reference the CD structure from the CNO
|
||||
// and indicate that we want to use the client
|
||||
// connection method.
|
||||
cno.ClientConn = cd
|
||||
cno.Options = ibmmq.MQCNO_CLIENT_BINDING
|
||||
|
||||
// Also fill in the userid and password if the MQSAMP_USER_ID
|
||||
// environment variable is set. This is the same as the C
|
||||
// sample programs such as amqsput.
|
||||
userId := os.Getenv("MQSAMP_USER_ID")
|
||||
if userId != "" {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
csp := ibmmq.NewMQCSP()
|
||||
csp.AuthenticationType = ibmmq.MQCSP_AUTH_USER_ID_AND_PWD
|
||||
csp.UserId = userId
|
||||
|
||||
fmt.Printf("Enter password for qmgr %s: \n", qMgrName)
|
||||
scanner.Scan()
|
||||
csp.Password = scanner.Text()
|
||||
|
||||
// And make the CNO refer to the CSP structure
|
||||
cno.SecurityParms = csp
|
||||
}
|
||||
|
||||
// And connect. Wait a short time before
|
||||
// disconnecting.
|
||||
qMgr, err = ibmmq.Connx(qMgrName, cno)
|
||||
if err == nil {
|
||||
fmt.Printf("Connection to %s succeeded.\n", qMgrName)
|
||||
d, _ := time.ParseDuration("5s")
|
||||
time.Sleep(d)
|
||||
qMgr.Disc()
|
||||
rc = 0
|
||||
} else {
|
||||
fmt.Printf("Connection to %s failed.\n", qMgrName)
|
||||
fmt.Println(err)
|
||||
rc = int(err.(*ibmmq.MQReturn).MQCC)
|
||||
}
|
||||
|
||||
fmt.Println("Done.")
|
||||
os.Exit(rc)
|
||||
|
||||
}
|
||||
275
vendor/github.com/ibm-messaging/mq-golang/samples/mqitest/mqitest.go
generated
vendored
Normal file
275
vendor/github.com/ibm-messaging/mq-golang/samples/mqitest/mqitest.go
generated
vendored
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
This is a short sample to show how to call IBM MQ from
|
||||
a Go program.
|
||||
|
||||
The flow is to connect to a queue manager,
|
||||
open the queue named on the command line,
|
||||
put a message and then get it back.
|
||||
The queue is closed.
|
||||
|
||||
The program then subscribes to the topic corresponding
|
||||
to collecting activity trace for itself - this requires MQ V9.
|
||||
|
||||
Finally, it closes the subscription and target queue, and
|
||||
disconnects.
|
||||
|
||||
If an error occurs at any stage, the error is reported and
|
||||
subsequent steps skipped.
|
||||
*/
|
||||
package main
|
||||
|
||||
/*
|
||||
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
|
||||
*/
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/ibm-messaging/mq-golang/ibmmq"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
var openOptions int32
|
||||
|
||||
var qMgrObject ibmmq.MQObject
|
||||
var qObject ibmmq.MQObject
|
||||
var managedQObject ibmmq.MQObject
|
||||
var subObject ibmmq.MQObject
|
||||
|
||||
var qMgrName string
|
||||
|
||||
if len(os.Args) != 3 {
|
||||
fmt.Println("mqitest <qname> <qmgrname>")
|
||||
fmt.Println(" Both parms required")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
qMgrName = os.Args[2]
|
||||
connected := false
|
||||
qMgr, err := ibmmq.Conn(qMgrName)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
connected = true
|
||||
fmt.Println("Connected to queue manager ", qMgrName)
|
||||
}
|
||||
|
||||
// MQOPEN of the queue named on command line
|
||||
if err == nil {
|
||||
mqod := ibmmq.NewMQOD()
|
||||
|
||||
openOptions = ibmmq.MQOO_OUTPUT + ibmmq.MQOO_FAIL_IF_QUIESCING
|
||||
openOptions |= ibmmq.MQOO_INPUT_AS_Q_DEF
|
||||
|
||||
mqod.ObjectType = ibmmq.MQOT_Q
|
||||
mqod.ObjectName = os.Args[1]
|
||||
|
||||
qObject, err = qMgr.Open(mqod, openOptions)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println("Opened queue", qObject.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// MQPUT a message
|
||||
// Create the standard MQI structures MQMD, MQPMO and
|
||||
// set the values.
|
||||
// The message is always sent as bytes, so has to be converted
|
||||
// before the MQPUT.
|
||||
if err == nil {
|
||||
putmqmd := ibmmq.NewMQMD()
|
||||
pmo := ibmmq.NewMQPMO()
|
||||
|
||||
pmo.Options = ibmmq.MQPMO_SYNCPOINT | ibmmq.MQPMO_NEW_MSG_ID | ibmmq.MQPMO_NEW_CORREL_ID
|
||||
|
||||
putmqmd.Format = "MQSTR"
|
||||
msgData := "Hello from Go"
|
||||
buffer := []byte(msgData)
|
||||
|
||||
err = qObject.Put(putmqmd, pmo, buffer)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println("Put message to", qObject.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// The message was put in syncpoint so it needs
|
||||
// to be committed.
|
||||
if err == nil {
|
||||
err = qMgr.Cmit()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
// MQGET all messages on the queue. Wait 3 seconds for any more
|
||||
// to arrive.
|
||||
if err == nil {
|
||||
msgAvail := true
|
||||
|
||||
for msgAvail == true {
|
||||
var datalen int
|
||||
|
||||
getmqmd := ibmmq.NewMQMD()
|
||||
gmo := ibmmq.NewMQGMO()
|
||||
gmo.Options = ibmmq.MQGMO_NO_SYNCPOINT | ibmmq.MQGMO_FAIL_IF_QUIESCING
|
||||
gmo.Options |= ibmmq.MQGMO_WAIT
|
||||
gmo.WaitInterval = 3000
|
||||
buffer := make([]byte, 32768)
|
||||
|
||||
datalen, err = qObject.Get(getmqmd, gmo, buffer)
|
||||
|
||||
if err != nil {
|
||||
msgAvail = false
|
||||
fmt.Println(err)
|
||||
mqret := err.(*ibmmq.MQReturn)
|
||||
if mqret.MQRC == ibmmq.MQRC_NO_MSG_AVAILABLE {
|
||||
// not a real error so reset err
|
||||
err = nil
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Got message of length %d: ", datalen)
|
||||
fmt.Println(strings.TrimSpace(string(buffer[:datalen])))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MQCLOSE the queue
|
||||
if err == nil {
|
||||
err = qObject.Close(0)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println("Closed queue")
|
||||
}
|
||||
}
|
||||
|
||||
// This section demonstrates subscribing to a topic
|
||||
// where the topic string is set to collect activity trace
|
||||
// from this program - it needs MQ V9 for publications to
|
||||
// automatically be generated on this topic.
|
||||
if err == nil {
|
||||
mqsd := ibmmq.NewMQSD()
|
||||
mqsd.Options = ibmmq.MQSO_CREATE
|
||||
mqsd.Options |= ibmmq.MQSO_NON_DURABLE
|
||||
mqsd.Options |= ibmmq.MQSO_FAIL_IF_QUIESCING
|
||||
mqsd.Options |= ibmmq.MQSO_MANAGED
|
||||
mqsd.ObjectString = "$SYS/MQ/INFO/QMGR/" + qMgrName + "/ActivityTrace/ApplName/mqitest"
|
||||
|
||||
subObject, err = qMgr.Sub(mqsd, &managedQObject)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Println("Subscribed to topic ", mqsd.ObjectString)
|
||||
}
|
||||
}
|
||||
|
||||
// Loop on the managed queue created by the MQSUB call until there
|
||||
// are no more messages. Because these are going to be PCF-format
|
||||
// events, they cannot be simply printed so here I'm just
|
||||
// printing the format of the message to show that something has
|
||||
// been retrieved.
|
||||
if err == nil {
|
||||
msgAvail := true
|
||||
|
||||
for msgAvail == true {
|
||||
var datalen int
|
||||
|
||||
getmqmd := ibmmq.NewMQMD()
|
||||
gmo := ibmmq.NewMQGMO()
|
||||
gmo.Options = ibmmq.MQGMO_NO_SYNCPOINT | ibmmq.MQGMO_FAIL_IF_QUIESCING
|
||||
gmo.Options |= ibmmq.MQGMO_WAIT
|
||||
gmo.WaitInterval = 3000
|
||||
buffer := make([]byte, 32768)
|
||||
|
||||
datalen, err = managedQObject.Get(getmqmd, gmo, buffer)
|
||||
|
||||
if err != nil {
|
||||
msgAvail = false
|
||||
fmt.Println(err)
|
||||
mqret := err.(*ibmmq.MQReturn)
|
||||
if mqret.MQRC == ibmmq.MQRC_NO_MSG_AVAILABLE {
|
||||
// not a real error so reset err, but
|
||||
// end retrieval loop
|
||||
err = nil
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Got message of length %d. Format = %s\n", datalen, getmqmd.Format)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MQCLOSE the subscription, ignoring errors.
|
||||
if err == nil {
|
||||
subObject.Close(0)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
mqod := ibmmq.NewMQOD()
|
||||
openOptions = ibmmq.MQOO_INQUIRE + ibmmq.MQOO_FAIL_IF_QUIESCING
|
||||
|
||||
mqod.ObjectType = ibmmq.MQOT_Q_MGR
|
||||
mqod.ObjectName = ""
|
||||
|
||||
qMgrObject, err = qMgr.Open(mqod, openOptions)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
fmt.Printf("Opened QMgr for MQINQ\n")
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
selectors := []int32{ibmmq.MQCA_Q_MGR_NAME,
|
||||
ibmmq.MQCA_DEAD_LETTER_Q_NAME,
|
||||
ibmmq.MQIA_MSG_MARK_BROWSE_INTERVAL}
|
||||
|
||||
intAttrs, charAttrs, err := qMgrObject.Inq(selectors, 2, 160)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
returnedName := string(charAttrs[0:48])
|
||||
fmt.Printf("MQINQ returned +%v %s \n",
|
||||
intAttrs, string(charAttrs))
|
||||
fmt.Printf(" '%s'\n", returnedName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MQDISC regardless of other errors
|
||||
if connected {
|
||||
err = qMgr.Disc()
|
||||
fmt.Println("Disconnected from queue manager ", qMgrName)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
os.Exit(0)
|
||||
} else {
|
||||
mqret := err.(*ibmmq.MQReturn)
|
||||
os.Exit((int)(mqret.MQCC))
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user