Skip to content

Commit

Permalink
Better config checks
Browse files Browse the repository at this point in the history
  • Loading branch information
ibmmqmet committed Jan 12, 2019
1 parent f9bbbef commit 72cbde8
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 9 deletions.
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,11 @@ export CGO_LDFLAGS_ALLOW="-Wl,-rpath.*"
### 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
* Ensure you have a gcc-based compiler, for example from the Cygwin distribution.
I recommend you use the mingw variation, to ensure compiled code can be used on systems without Cygwin installed.
The default `gcc` compiler from Cygwin does not work because it tries to build a
Cygwin-enabled executable but the MQ libraries do not work in that model;
the `mingw` versions build Windows-native programs.
* Create a working directory. For example, `mkdir c:\Gowork`
* Set environment variables. Based on the previous lines,

Expand All @@ -99,11 +103,21 @@ set CC=x86_64-w64-mingw32-gcc.exe
`git clone https://github.com/ibm-messaging/mq-golang.git src/github.com/ibm-messaging/mq-golang`

* If you have not installed MQ libraries into the default location, then set environment variables
for the C compiler to recognise those directories. For example,
for the C compiler to recognise those directories. You may get messages from the compiler
saying that the default MQ directories cannot be found, but those warnings can be ignored.
The exact values for these environment variables will vary by platform, but follow the
corresponding CFLAGS/LDFLAGS values in `mqi.go`

For example,

```
export CGO_CFLAGS="-I/my/mq/dir/inc"
export CGO_LDFLAGS="-I/my/mq/dir/lib64"
export MQ_INSTALLATION_PATH=/my/mq/dir # This will also be set from the setmqenv command
export CGO_CFLAGS="-I$MQ_INSTALLATION_PATH/inc"
export CGO_LDFLAGS="-L$MQ_INSTALLATION_PATH/lib64 -Wl,rpath=$MQ_INSTALLATION_PATH/lib64"
or on Darwin
export CGO_LDFLAGS="-L$MQ_INSTALLATION_PATH/lib64 -Wl,rpath,$MQ_INSTALLATION_PATH/lib64"
```

* Compile the `ibmmq` component:
Expand Down Expand Up @@ -144,4 +158,4 @@ in the CLA.

## Copyright

© Copyright IBM Corporation 2016, 2018
© Copyright IBM Corporation 2016, 2019
4 changes: 2 additions & 2 deletions ibmmq/mqi.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ package ibmmq
/*
#cgo !windows CFLAGS: -I/opt/mqm/inc -D_REENTRANT
#cgo windows CFLAGS: -I"C:/Program Files/IBM/MQ/Tools/c/include"
#cgo !windows,!darwin LDFLAGS: -L/opt/mqm/lib64 -lmqm_r -Wl,-rpath=/opt/mqm/lib64 -Wl,-rpath=/usr/lib64
#cgo darwin LDFLAGS: -L/opt/mqm/lib64 -lmqm_r -Wl,-rpath,/opt/mqm/lib64 -Wl,-rpath=/usr/lib64
#cgo !windows,!darwin LDFLAGS: -L/opt/mqm/lib64 -lmqm_r -Wl,-rpath,/opt/mqm/lib64 -Wl,-rpath,/usr/lib64
#cgo darwin 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>
Expand Down
51 changes: 50 additions & 1 deletion mqmetric/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ var Metrics AllMetrics

var qList []string
var locale string
var discoveryDone = false

func GetDiscoveredQueues() []string {
return qList
Expand All @@ -105,12 +106,60 @@ func SetLocale(l string) {
}

/*
DiscoverAndSubscribe does all the work of finding the
* Check any important parameters - this must be called after DiscoverAndSubscribe
* to maintain compatibility of the package's APIs. It also needs the qList to have been
* populated first which is also done in DiscoverAndSubscribe.
* Returns: an MQ CompCode, error string. CompCode can be MQCC_OK, WARNING or ERROR.
*/
func VerifyConfig() (int32, error) {
var err error
var v map[int32]interface{}
var compCode = ibmmq.MQCC_OK
if !discoveryDone {
err = fmt.Errorf("Error: Need to call DiscoverAndSubscribe first")
compCode = ibmmq.MQCC_FAILED
}

if err == nil {
selectors := []int32{ibmmq.MQIA_MAX_Q_DEPTH, ibmmq.MQIA_DEFINITION_TYPE}
v, err = replyQObj.InqMap(selectors)
if err == nil {
maxQDepth := v[ibmmq.MQIA_MAX_Q_DEPTH].(int32)
// Function has tuning based on number of queues to be monitored
// Current published resource topics are approx 95 for qmgr
// ... and 35 per queue
// Make recommended minimum qdepth 60 / 10 * total per interval to allow one minute of data
// as MQ publications are at 10 second interval by default (and no public tuning)
// and monitor collection interval is one minute
recommendedDepth := (100 + len(qList)*50) * 6
if maxQDepth < int32(recommendedDepth) {
err = fmt.Errorf("Warning: Maximum queue depth on %s may be too low. Current value = %d", replyQBaseName, maxQDepth)
compCode = ibmmq.MQCC_WARNING
}

// Make sure this reply queue that has been opened is not a predefined queue, so it
// has come from a model definition. The base replyQ is opened twice for different reasons.
// A LOCAL queue would end up with mixed sets of replies/publications
defType := v[ibmmq.MQIA_DEFINITION_TYPE].(int32)
if defType == ibmmq.MQQDT_PREDEFINED {
err = fmt.Errorf("Error: ReplyQ parameter %s must refer to a MODEL queue,", replyQBaseName)
compCode = ibmmq.MQCC_FAILED
}
}
}
return compCode, err
}

/*
DiscoverAndSubscribe does 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

discoveryDone = true

// What metrics can the queue manager provide?
if err == nil {
err = discoverStats(metaPrefix)
Expand Down
3 changes: 3 additions & 0 deletions mqmetric/mqif.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ var (
qMgr ibmmq.MQQueueManager
cmdQObj ibmmq.MQObject
replyQObj ibmmq.MQObject
replyQBaseName string
statusReplyQObj ibmmq.MQObject
getBuffer = make([]byte, 32768)
platform int32
Expand Down Expand Up @@ -133,9 +134,11 @@ func InitConnection(qMgrName string, replyQ string, cc *ConnectionConfig) error
if err == nil {
mqod := ibmmq.NewMQOD()
openOptions := ibmmq.MQOO_INPUT_AS_Q_DEF | ibmmq.MQOO_FAIL_IF_QUIESCING
openOptions |= ibmmq.MQOO_INQUIRE
mqod.ObjectType = ibmmq.MQOT_Q
mqod.ObjectName = replyQ
replyQObj, err = qMgr.Open(mqod, openOptions)
replyQBaseName = replyQ
if err == nil {
queuesOpened = true
}
Expand Down
6 changes: 5 additions & 1 deletion samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,16 @@ aspect.
Apart from the `amqsconn.go` program, the other samples are designed to either connect
to a local queue manager (on the same machine) or for the client configuration to be
provided externally such as by the MQSERVER environment variable or the
MQ Client Channel Definition Table (CCDT) file.
MQ Client Channel Definition Table (CCDT) file. The MQ_CONNECT_TYPE environment
variable can be used to force client connections to be made, even if you have
installed the full server product; that variable is not needed if you have
only installed the MQ client libraries.

For example

```
export MQSERVER="SYSTEM.DEF.SVRCONN/TCP/localhost(1414)"
export MQ_CONNECT_TYPE=CLIENT
go run amqsput.go DEV.QUEUE.1 QM1
```

Expand Down

0 comments on commit 72cbde8

Please sign in to comment.