Visibility of QMgr’s Server in MO71

The MO71 product allows you to administer queue managers that are both local and remote to the machine where it runs. When remote, you can connect in via mode, or in client mode. Since WebSphere MQ V7.1 was released, queue managers could be configured as multi-instance, and client connections could be made with a comma-separated list of hostnames (and ports) in the CONNAME field.

This comma-separated CONNAME has been available to use in MO71’s direct client configuration since that time. You can also make MO71 client connections using a CCDT if you prefer.

When using a comma-separated list of hostnames, it is useful to know which of the hostnames you actually managed to connect to, perhaps so you can have a quick view of which machine is currently the primary in order to log into the machine directly, or because you have a preferential Primary and Backup machine and you need to know when the Backup is in use.

MO71 Client configuration

MO71 Client configuration for Multi-instance queue manager

MO71 showing multi-instance annotation

MO71 showing multi-instance annotation

When configuring the list of hostnames in MO71’s client connection dialog, you can now optionally add a string to be displayed when that hostname is the one successfully connected to. You don’t have to include the string for each hostname. You may prefer to only have the annotation on the screen when the Backup server is in use and so would omit the string for the primary hostname and add it to the secondary hostname.

Here are a few examples

Connection Name : win9.mqgem.com(1701) “Primary”, win12.mqgem.com(1701) “Secondary”
Connection Name : win9.mqgem.com(1701), win12.mqgem.com(1701) “**Backup**”

Note that you must configure the client channel directly for this annotation to work. You cannot, for example, use a channel defined in the Client Channel Definition Table (CCDT).


Comma-separated CONNAME has been in MO71 for a while, but the recent 9.0.2 release added the ability to see which of the instances is in use.

Can you see your QMgr for the trees?

When you have a lot of queue managers to manage, if you’re not careful it can get to point where you can’t see the wood for the trees. Where’s that queue manager I’m after/need to make a change to/have just been phoned about?

MO71 is capable of managing hundreds of queue managers, but you don’t have to spend your time scrolling down a very long list of queue managers looking for the one you want. There are several ways that MO71 allows you to organize your queue managers.

MO71 Main Window - Grouped QMgrs

MO71 Main Window showing Grouped QMgrs

Grouping

The main window of MO71 shows all your queue managers, and to arrange that otherwise long list, you can organize your queue managers into groups. A group name is set in the location dialog, along with the queue manager name and connection details (see the screenshot below).

Import and Set Group name

Set the Group name during import

You can also choose a group name when you import queue managers from the local machine, or from a CCDT, allowing your newly imported queue managers to be immediately placed in an appropriate group.

Network Names

MO71 Network View

MO71 Network View with one network selected

In addition to putting a queue manager in a group, you can also put each queue manager into one, or many, networks. Networks are other groupings of queue managers and can be anything you like, but some examples include by platform; by environment, for example, Devt, Test, QA, Production; or by application group. Clearly these would all overlap, you could have a Windows queue manager in the QA environment for the Sales application group. Adding that queue manager to all three networks then allows you to filter your queue manager list by any or all of these. As you’ll see in a moment, you can search by these network names, but they are also used for choosing which queue managers are shown in the network display.

MO71 Location Dialog

MO71 Location Dialog showing a group name and multiple network names.

Searching for queue managers

MO71 Main Window Search

MO71 Main Window with the Search bar

There are a number of places in MO71 where you can search for queue managers in the list. First there is the main window. If the search bar is not visible at the top of the list, enable it from the View menu. In this search bar you can reduce the queue managers shown temporarily by typing in a search string which can be part of the queue manager name, the queue manager location, the group name, the network name or the client connection name.

MO71 will remember your last 20 searches, so after you’ve used them once you’ll be able to select them from the drop-down list.

The other place this is useful is on a multi-queue manager list dialog. Again, typing your search string temporarily reduces the queue managers shown, and you can use buttons to easily add those shown to the dialog with one click.

MO71 Multi-QMgr queue list dialog

MO71 Multi-QMgr queue list dialog with search string

If you have a search string present in the main window when you open a list dialog, it’s search bar is initially populated with the same search string.

In both these locations you can explicitly search a specific field by qualifying your search string, for example adding “<net>” to indicate you only want to search network names.

Location Dialog Field Qualifier Qualifier Shortform
Queue Manager name qm m
Queue Manager Location loc l
Group Name grp g
Network Names net n
Client Connection Name conn c

When you use one of these qualifiers it should be specified between < and > characters.

So, don’t struggle with scrolling long lists of queue manager names, get your queue managers organised into groups and networks.


Most of these features have been in MO71 for a while, but the recent 9.0.1 release added the search bar to the multi-queue manager list dialog

Only run MQSC script on intended Queue Manager

Correct QMgr?IBM MQ is a robust product and queue managers can run without problems for months, or even years at a time. In fact, often when problems do occur they are the result of human error, and one example of such as error can be running an MQSC script against an unintended queue manager.

I think we have all pushed an MQSC file into the wrong queue manager. 😦

So, the question was asked, how can I ensure that I only run my MQSC script against the queue manager it was intended for?

This is something that MQSCX can help you with. There are a few ways you can do this.

Check that you are connected to the correct queue manager

One way to protect against running an MQSC script against the wrong queue manager is to start the script with a quick test to see which queue manager it is currently connected to and to exit the script immediately if it is found to be administering the wrong one.

if ( _qmgr != "QM1" )
  print "Wrong queue manager! Script expects to be used on QM1"
  leave
endif

_qmgr is an MQSCX system variable that tells you which queue manager you are administering. There are also some others that might be helpful when coding up checks at the start of a script, _connqmgr tells you which queue manager you are connected to, and will be different from _qmgr if you are using a via connection. _client tells you if you are connected as a client. You can see these in action in the DISPLAY DQM for Distributed blog post.

You could also make the check broader and have it query some attribute of the queue manager to determine if it was an appropriate queue manager to run the script against. For example, looking for the word “(Test)” in the queue manager description. This means a script couldn’t accidentally be run against one of your production queue managers. Using this simple technique, each script can be limited to a class of queue managers; Production, Test, Devt and so on.

DISPLAY QMGR DESCR
if (!findstr("(Test)",DESCR))
  print "Queue Manager",_qmgr,"does not appear to be a test QMgr"
  print "Queue Manager",_qmgr,"DESCR(",:n:DESCR,:n:")"
  leave
endif

Have the script connect to the appropriate queue manager

As an alternative, rather than having the script check that the human running it has used the correct queue manager, the script could make the connection itself.

=conn qm(QM1)
if (_lastrc)
  leave
endif
ALTER QMGR ...
DEFINE CHANNEL ...

A script with commands for different queue managers

Having made a script that connects to the correct queue manager before running the commands against it, it is not difficult to make the next step where you can have a script that issues commands on multiple queue managers – has a section for each queue manager prefixed by an =conn command.

=conn qm(QM1)
ALTER QMGR ...
ALTER CHANNEL ...
 
=conn qm(QM2)
ALTER QMGR ...
ALTER QLOCAL ...
 
=conn qm(Q3)
ALTER QLOCAL ...

This is only scratching the surface of what MQSCX can do, but it can certainly make administration of your IBM MQ queue managers less error prone.


If you’re not a current MQSCX licence holder, and you’d like to try out MQSCX, please email support@mqgem.com to request a trial licence.


I was prompted to write this post as a result of this list-server question.

DISPLAY DQM for Distributed

If you’re familiar with the IBM MQ for z/OS product, you may have issued the DISPLAY DQM command which gives you the following output:

CSQX830I M901 CSQXRDQM Channel initiator active
CSQX831I M901 CSQXRDQM 8 adapter subtasks started, 8 requested 
CSQX832I M901 CSQXRDQM 5 dispatchers started, 5 requested
CSQX833I M901 CSQXRDQM 0 SSL server subtasks started, 0 requested
CSQX840I M901 CSQXRDQM 5 channels current, maximum 200 
CSQX841I M901 CSQXRDQM 4 channels active, maximum 200, including 0 paused 
CSQX842I M901 CSQXRDQM 0 channels starting, 1 stopped, 0 retrying
CSQX836I M901 CSQXRDQM Maximum channels - TCP/IP 200, LU 6.2 200 
CSQX845I M901 CSQXRDQM TCP/IP system name is TCPIP 
CSQX846I M901 CSQXRDQM TCP/IP listener INDISP=QMGR started, for port 1591 address *
CSQX849I M901 CSQXRDQM LU 6.2 listener INDISP=QMGR not started 

There is no equivalent command for a distributed queue manager, however, you can get most of the same information from various other commands. So we have created an MQSCX script to create an equivalent set of output for a distributed queue manager.

Clearly some of the information simply doesn’t apply to distributed queue managers; for example the number of adapter, dispatcher and SSL Server subtasks. Also the TCP/IP system name doesn’t really have an equivalent on a distributed platform – or at least certainly not one that can be retrieved from the command server. The equivalents of DISPLAY QMGR MAXCHL ACTCHL TCPCHL LU62CHL is to look in the queue manager’s qm.ini file for MaxChannels and MaxActiveChannels on distributed, which is something that cannot work unless you are running the script local to the queue manager.

So the script issues the various commands required to get the information and then prints out a set of equivalent looking lines to give you a similar output:

MQG1 Channel initiator active
MQG1 14 channels current, maximum 400
MQG1 12 channels active, maximum 400, including 0 paused
MQG1 0 channels starting, 1 stopped, 1 retrying
MQG1 TCP/IP listener TCP.LSTR started, for port 1701 address *
MQG1 LU6.2 listener not started

It starts by checking whether the Channel initiator is active, which for most people will be since it gets started automatically by the queue manager these days.

DISPLAY QMSTATUS CHINIT
if (CHINIT = "RUNNING")
  print _qmgr,'Channel initiator active'
endif

Then it looks in the qm.ini file (but only if you’re not connected by a client or via connection). MQSCX can read environment variables just as if they were user variables, so it can make use of the MQ environment variable MQ_DATA_PATH which is setup by setmqenv. The _client system variable is new in MQSCX V9.0.0.

if (!(_client | (_connqmgr != _qmgr)))
  @filename = @MQ_DATA_PATH+"/qmgrs/"+_qmgr+"/qm.ini"
  @hf = fopen(@filename,"r")
  if (@hf)
    while (fgets(@hf,@line) >= 0)

For each line in the qm.ini file it will check for MaxChannels and MaxActiveChannels.

if (findstri(@line, "MaxChannels") > 0)
  @offset = findstr(@line, "=")
  if (@offset > 0)
    @MaxChannelsStr = substr(@line,@offset+1,strlen(@line)-@offset)
    @MaxChannels = eval(@MaxChannelsStr)
  endif
endif

A simple foreach loop allows the script to total up the number of different channel states currently on show. This then allows the various channel status lines in the output to be printed.

Finally the script has another simple foreach loop for listeners which also makes use of the new _numEach system variable to detect if the loop has never been called.

foreach(DISPLAY LSSTATUS(*) ALL WHERE(TRPTYPE EQ TCP))
  print _qmgr, 'TCP/IP listener', LISTENER ,'started, for port', PORT, 'address', IPADDR
endfor
if (_numEach = 0)
  print _qmgr, 'TCP/IP listener not started'
endif

The complete function is available to download in our Example Scripts bundle.


If you’re not a current licence holder, and you’d like to try out MQSCX, please email support@mqgem.com to request a trial licence.

Import queue managers from a CCDT

Import CCDT Menu

The menu to import queue managers

In a recent update to MO71 V8.0.4 a new feature was added to allow you to import queue manager location information from a Client Channel Definition Table (CCDT) file. You can drive this from the File menu, which then brings up a dialog.

Import CCDT

Import CCDT Dialog – choose your queue managers

The dialog will start by looking for the CCDT in the default location, but you can change this by navigating to the CCDT file you wish to use before clicking on Read CCDT.

The list below will show all the queue managers that were found in the CCDT. If any of the found queue managers are already locations in MO71, the CCDT entry will have a ‘no entry’ symbol beside it showing it cannot be added again. You can click on any others to indicate you wish to import them and the red cross will change to a green tick. Once you have selected all the ones you want, click on Import, and you’re done.

And of course, just as with imported local queue managers, you can edit the imported ones after the locations are created to change the location labels and any other settings.


The new version can be downloaded from the MO71 Download Page. If you don’t have a licence and would like to try out MO71 then send an email to support@mqgem.com and a 1-month trial licence will be sent to you.

MQSCX feature – String Replace

MQSCX String ReplaceWhen building a report, or outputting information to the screen about your IBM MQ Queue Manager, you may wish to manipulate strings, as is shown in a new example script, mqauthlist.mqsx, available in our Example Scripts bundle. This script builds an array of temporary dynamic queues to exclude from the report later. Some string manipulation is done on the names to make the search easier using the strreplace() function of MQSCX to replace underscores with dots. Here’s how:-

** Query the queue manager for the current temporary dynamic queues
delvar(@tempqlist)
@x = 0
foreach(DISPLAY QLOCAL(*) WHERE(DEFTYPE EQ TEMPDYN))

   if( !_cmdok )
      print "Error querying TempDyn queues for queue manager", _qmgr
      continue
   endif

   @x = @x + 1
   ** In order for the search to work properly,
   ** we need to uppercase the queue names
   ** and substitute underscores with periods.
   @tempqlist[@x] = strreplace(upper(QUEUE), "_", ".")
endfor

Of course there are many uses you might find for using the strreplace() function, especially if you want to work with MQ object names that follow a Naming Convention, then you might find yourself wanting to replace the characters TEST with the characters PROD when working with different environments for Test and Production.


The best way to understand scripts is of course to have a go with them yourself. There are various examples in the download, so why not try them out yourself. If you are not currently an MQSCX licence holder, you may email support@mqgem.com to request a trial licence.

MQSCX feature – write to a file

MQSCX File AccessWhen writing an MQSCX script you can print out details to the screen, or open a file and write your output to the file instead. This can be very useful for generating a report about something, as is shown in a new example script, mqauthlist.mqsx, available in our Example Scripts bundle. This script writes a report to file. Here’s how:-

** Open file and write header
@filename = "mqauthlist_" + date(_time, "_y_mm_d") + ".txt"

@hf = fopen(@filename, "w")
if( @hf = -1 )
   print "Error opening file", @filename, "ErrorNo=", _errno
   leave
endif

fprint @hf,"MQ Report for", @env, "on", date(_time, "mmm dd, y"), _nl
fprint @hf, "**-------------------------------------------------**"
fprint @hf, "** Queue Manager", :10:_qmgr, "                       **"
fprint @hf, "**-------------------------------------------------**"

** Close the file
fclose(@hf)
print "Created file <@filename>"

There are a few system variables also demonstrated in the above snippet that are useful in this, and other situations.

When opening a file, and any other interactions with the system, the errno is always useful to be able to get hold of. In MQSCX you can do so through the _errno system variable. You might also find it useful to use the _errnostr system variable which will provide a string interpretation of the errno. So you might print your error opening the file out like this:-

@hf = fopen(@filename,"w")
if ( @hf = -1 )
    print "Can not open file '<@filename>' errno:<_errno> <_errnostr>"
    leave
endif

Another system variable shown is _nl which simply writes a new line to the screen or file (depending on whether you use print or fprint).

Also demonstrated is the system variable _qmgr which is an easy way to access the name of the queue manager the script is currently connected to. Similar to _cmdlevel and _platform (which were covered in MQSCX feature – CommandLevel and Platform) they give you quick access to attributes you could also get through issuing a command.

Writing reports based on interrogations of your queue manager by issuing commands in an MQSCX script opens up a world of possibilities for what you are able to do.


The best way to understand scripts is of course to have a go with them yourself. There are various examples in the download, so why not try them out yourself. If you are not currently an MQSCX licence holder, you may email support@mqgem.com to request a trial licence.