Running the Trigger Monitor as a SERVICE

There was a recent update to MO71 that allowed multiple SERVICE objects to be edited at once.

The example used in the screenshot was of the trigger monitor being run as a service, and is straight out of Knowledge Center (with the exception of a more meaningful object name).

It uses the provided amqsstop program as recommended too. The parameters that amqsstop expects are provided in the STOPARG which include the +MQ_SERVER_PID+ which is a token representing the process id of the process started by the STARTCMD and STARTARG arguments.

I was playing around with this SERVICE object a little more today and discovered that the STOP SERVICE command doesn’t work. This post covers what I discovered and how to fix it.

You’ll note from the screen shot that I’m running a 64-bit Windows queue manager – you can tell that from the path of the amqsstop program which is in the bin64 directory. However, I used the runmqtrm program from the bin directory. This is no doubt a migratory aid for those users that had scripts etc starting the trigger monitor from that location prior to the Windows queue manager becoming a 64-bit entity.

Having started my trigger monitor with the above definition, I can see it’s status using the DISPLAY SVSTATUS command.

AMQ8632: Display service status details.
   SERVICE(TRIGGER.MONITOR)                STATUS(RUNNING)
   PID(3384)                               SERVTYPE(SERVER)
   STARTDA(2017-06-17)                     STARTTI(11.40.55)
   CONTROL(QMGR)                           STARTCMD(C:\mqm8004\bin/runmqtrm)
   STARTARG(-m MQG1 -q ACCOUNTS.INITQ)     STOPCMD(C:\mqm8004\bin64/amqsstop)
   STOPARG(-m MQG1 -p 3384)             
   DESCR(Trigger Monitor Service Auto Started with QMgr)
   STDOUT( )                               STDERR( )

Part of this display is the process ID of the trigger monitor, and you can also see that the replaceable insert +MQ_PROCESS_ID+ in the STOPARG attribute has been replaced with the same PID.

When you issue the MQ command STOP SERVICE(TRIGGER.MONITOR) it issues a PCF Inquire Connections command with a WHERE clause asking for all those connections where the PID is 3384. You can see in the MQ trace that the answer which comes back is MQRCCF_NONE_FOUND.

Now I know the trigger monitor is running so I find it myself in a DISPLAY CONN command and I see this:-

AMQ8276: Display Connection details.
   CONN(876C445920002201)                
   EXTCONN(414D51434D5147312020202020202020)
   TYPE(*)                               
   PID(4604)                               TID(1) 
   APPLDESC(WebSphere MQ Trigger Monitor)
   APPLTAG(:\mqm8004\bin64\runmqtrm.exe)   APPLTYPE(SYSTEM)
   ASTATE(NONE)                            CHANNEL( )
   CLIENTID( )                             CONNAME( )
   CONNOPTS(MQCNO_SHARED_BINDING)          USERID(MUSR_MQADMIN)
   UOWLOG( )                               UOWSTDA(2017-06-17)
   UOWSTTI(11.40.55)                       UOWLOGDA( )
   UOWLOGTI( )                             URTYPE(QMGR)
   EXTURID(XA_FORMATID[] XA_GTRID[] XA_BQUAL[])
   QMURID(0.20482)                         UOWSTATE(ACTIVE)

So there are two interesting things in this output. Firstly the PID is different. Secondly, it’s the bin64 version of runmqtrm. There’s no sign of the bin version of runmqtrm with PID(3384) anywhere in DISPLAY CONN. So I guess it didn’t make a connection to the queue manager.

Next thing to check out is the processes that the Windows OS thinks are running. I look for and find both PID(3384) and PID(4604).

runmqtrm processes

Two processes running called runmqtrm

So it seems that the runmqtrm in the bin directory is not a copy of the one in the bin64 directory, but something else that starts the bin64 version of runmqtrm. This means that amqsstop doesn’t work because it is trying to find the first process which never connected to the queue manager.

The fix to get your Trigger Monitor Service definition to work again with a STOP SERVICE command is to use the bin64 version of runmqtrm directly in the STARTCMD and avoid this double hop which leaves you with two processes running unnecessarily.

DEFINE SERVICE(TRIGGER.MONITOR) +
       SERVTYPE(SERVER) CONTROL(QMGR) +
       DESCR('Trigger Monitor Service Auto Started with QMgr') +
       STARTCMD('+MQ_INSTALL_PATH+bin64\runmqtrm') +
       STARTARG('-m +QMNAME+ -q ACCOUNTS.INITQ') +
       STOPCMD('+MQ_INSTALL_PATH+bin64\amqsstop') +
       STOPARG('-m +QMNAME+ -p +MQ_SERVER_PID+')

You don’t have the same problem on Unixes, because there aren’t the two bin directories on those platforms. So this is very specific to Windows.

Really it’s a shame that there isn’t a replaceable insert something like +MQ_BIN_DIR_PATH+ so that these platform differences would be completely removed from the SERVICE object definition. But I suppose you could make one yourself and put it into the service.env file.


IBM Certified SpecialistIBM Champion 2017 Cloud

Morag Hughson
IBM Champion 2017 – Cloud
IBM Certified System Administrator – MQ V8.0
Find her on: LinkedIn: http://uk.linkedin.com/in/moraghughson Twitter: https://twitter.com/MoragHughson SlideShare: http://www.slideshare.net/moraghughson developerWorks: https://www.ibm.com/developerworks/community/profiles/html/profileView.do?userid=110000EQPN

MQGem Products: Minor Updates

MQGem products licences are time based, allowing you to use the latest version of the product without needing to buy a new licence. One of the advantages of this is described as follows in the manual:-

Features are available sooner
Using this model it is not necessary for us to collect a large group of features together to ‘justify’ a new release of the product. Instead a new release can be made available whenever a new feature is added which is regarded as sufficiently useful since all current users will be able to migrate to the new version at no cost to themselves.

This allows us to do even very small minor updates to the products from time to time. These minor updates are notified to you in a couple of ways. At the end of each month, any minor updates will be included in the News section of our MQGem Monthly newsletter.

In addition to this, minor updates will be tweeted using each product’s hashtag on the day of the upload.

You can see all the minor updates so far using each of the following links. Even if you’re not a twitter user, these posts are all public for you to view. Below each link is an example tweet. Whenever possible, these tweets will include a screenshot to demonstrate the new update.

MO71 Minor Updates

MQSCX Minor Updates

MQEdit Minor Updates

Remember, if you have a minor change you’d like to see to one of our products, please tell us about it. Small updates don’t have to wait for a whole new version!


If you don’t have a licence and would like to try out any of our products then send an email to support@mqgem.com stating which product you’d like to try and a 1-month trial licence will be sent to you.

What’s in Command Levels 90x

MQ90x StairsIBM MQ released Long Term Support release V9.0.0 back in June 2016 which had a Command Level of 900. The subsequent Continuous Delivery releases, V9.0.1, V9.0.2 and V9.0.3 have each introduced their own Command Levels, 901, 902 and 903 respectively.

This post captures the changes that are available in each of those Command Levels.

Release Command Level Features protected by Command Level – details below
V9.0.0.0 900 AMS Protection Policy enhancement – Confidentiality Policy
LDAP Authorization on Windows
V9.0.1 901 No changes protected by Command Level
V9.0.2 902 Log management features
V9.0.3 903 No changes protected by Command Level

AMS Protection Policy enhancement – Confidentiality Policy

With the introduction of Confidentiality Policies in Command Level 900, there is a new attribute on the Set Policy command. A confidentiality policy has no signature algorithm, but does have a encryption algorithm. The Key Reuse feature is applicable to this type of policy. Jon Rumsey has a great write-up of this IBM MQ V9 feature on the MQDev blog, MQ V9 Fast encrypted messages with MQ – Introducing AMS Confidentiality Policies.

AMS Policy

New Attribute MQSC name
See SET POLICY
Look for KC 9000 indicator
PCF constant and values
See Set Policy
Look for KC 9000 indicator
Key Reuse

KEYREUSE

  • DISABLED
  • UNLIMITED
  • 1 – 9999999

MQIA_KEY_REUSE_COUNT (267)

  • MQKEY_REUSE_DISABLED (0)
  • MQKEY_REUSE_UNLIMITED (-1)
  • 1 – 9999999

LDAP Authorization on Windows

Introduced in Command Level 801 on Unix, this feature extended the V8.0.0 Connection Authentication feature which checked your user ID and password, to allow LDAP authorization as well. The fields now available on Windows are the same as those noted in the earlier post for Command Level 801, and are not repeated here.

Log management

With the introduction of Automatic management of linear log extents, and Automatic writing of media images, in Command Level 902, there are new attributes on the queue manager object, queue manager status, and one on queue objects. Mark Whitlock has written about this in an MQDev Blog Post: Logger enhancements for MQ v9.0.2.

Queue Manager Object

New Attribute MQSC name
See ALTER QMGR
Look for KC 902 indicator
PCF constant and values
See Change Queue Manager
Look for KC 902 indicator
Image Schedule

IMGSCHED

  • AUTO
  • MANUAL

MQIA_MEDIA_IMAGE_SCHEDULING (268)

  • MQMEDIMGSCHED_AUTO (1)
  • MQMEDIMGSCHED_MANUAL (0)
Image Interval

IMGINTVL

  • 1 – 999 999 999
  • OFF

MQIA_MEDIA_IMAGE_INTERVAL (269)

  • 1 – 999 999 999
  • MQMEDIMGINTVL_OFF (0)
Image Log Length

IMGLOGLN

  • 1 – 999 999 999
  • OFF

MQIA_MEDIA_IMAGE_LOG_LENGTH (270)

  • 1 – 999 999 999
  • MQMEDIMGLOGLN_OFF (0)
Image Recover Object

IMGRCOVO

  • NO
  • YES

MQIA_MEDIA_IMAGE_RECOVER_OBJ (271)

  • MQIMGRCOV_NO (0)
  • MQIMGRCOV_YES (1)
Image Recover Queue

IMGRCOVQ

  • NO
  • YES

MQIA_MEDIA_IMAGE_RECOVER_Q (272)

  • MQIMGRCOV_NO (0)
  • MQIMGRCOV_YES (1)

Queue Manager Status

New Attribute MQSC name
See DISPLAY QMSTATUS
Look for KC 902 indicator
PCF constant and values
See Inquire Queue Manager Status
Look for KC 902 indicator
Archive Log Extent Name

ARCHLOG

MQCACF_ARCHIVE_LOG_EXTENT_NAME (3208)

  • String of length MQ_LOG_EXTENT_NAME_LENGTH (24)
Archive Log Size

ARCHSZ

MQIACF_ARCHIVE_LOG_SIZE (1416)

Media Log Size

MEDIASZ

MQIACF_MEDIA_LOG_SIZE (1417)

Restart Log Size

RECSZ

MQIACF_RESTART_LOG_SIZE (1418)

Reusable Log Size

REUSESZ

MQIACF_REUSABLE_LOG_SIZE (1419)

Archive Log In Use

LOGINUSE

MQIACF_LOG_IN_USE (1420)

Archive Log Utilization

LOGUTIL

MQIACF_LOG_UTILIZATION (1421)

Reset QMgr command

Updated attribute MQSC name
See RESET QMGR
Look for KC 902 indicator
PCF constant and values
See Reset Queue Manager
Look for KC 902 indicator
Action

TYPE

  • REDUCELOG
  • ARCHLOG

MQIACF_ACTION (1086)

  • MQACT_REDUCE_LOG (10)
  • MQACT_ARCHIVE_LOG (11)
Archived Log

ARCHIVED

MQCACF_ARCHIVE_LOG_EXTENT_NAME (3208)

  • String of length MQ_LOG_EXTENT_NAME_LENGTH (24)
Log Reduction

REDUCE

  • AUTO
  • ONE
  • MAX

MQIACF_LOG_REDUCTION (1422)

  • MQLR_AUTO (-1)
  • MQLR_ONE (1)
  • MQLR_MAX (-2)

Queue Local and Queue Model

New Attribute MQSC name
See DEFINE queues
Look for KC 902 indicator
PCF constant and values
See Change, Copy, and Create Queue
Look for KC 902 indicator
Image Recover Queue

IMGRCOVQ

  • NO
  • YES
  • QMGR

MQIA_MEDIA_IMAGE_RECOVER_Q (272)

  • MQIMGRCOV_NO (0)
  • MQIMGRCOV_YES (1)
  • MQIMGRCOV_AS_Q_MGR (2)

You can get the equivalent information for earlier Command Levels from these posts.

Running User Commands in MO71

MO71 User Commands

The User Commands menu on a queue manager in MO71

Do you have a number of commands, or scripts, or batch jobs that you regularly use against your queue managers? How would like to be able to invoke them from the queue manager menu in MO71? In the latest version of MO71 just released, you can do just that. This might be useful when setting up MO71 for your operations team to use (see Delivering an MO71 Bundle to your MQ team) to pre-configure MO71 with the various scripts they should be using for tasks outside MO71.

MO71 User Command strmqm

A User Command that will invoke strmqm for the queue manager

Of course, not all user commands you might want to run would apply to all queue managers in your MO71 configuration, so when setting up User Commands in MO71 you can say which queue managers they apply to. For example, if your queue manager is local to MO71 you can use commands such as strmqm, but for remote queue manager’s you’ll need some sort of remote script to achieve the same. The easiest way to categorize your queue managers is to put them into various “networks” (MO71’s way of categorizing them – see Can you see your QMgr for the trees?). You could imagine a network called “Local” and another called “Remote” which you can then use to determine whether the User Command that runs strmqm can be used. You can make one User command definition which applies to all queue managers in the “Local” network and use the %q substitution character to pass the queue manager name through to the command.

Here you’ve seen an example of a substitution character allowing you to pull information from the location to build up the command. Other substitutions that pull information from the location details are as follows. If there are other things that might be useful to use from the location details as substitutions in User Commands, let us know.

Insert Meaning
%c Location CLNTCONN connection name
%g Location Group Name
%l Location Name
%q Queue Manager Name

If you need to use any environment variables, for example MQ_DATA_PATH or MQ_INSTALLATION_PATH, these can also be used in substitutions in your User Commands with the following syntax:-

%[MQ_DATA_PATH]
MO71 User Command SSH

A User Command to launch an SSH session to the machine the queue manager is on

For “Remote” queue managers you might want to have quick access to a telnet/putty/ssh session to the machine the queue manager is running on. The session you use might vary based on the platform of the machine. For example, for your z/OS queue managers you might want to start a 3270 session. So there’s another possible network, you could also categorize your queue managers by platform. You can use the %c substitution character to pass the connection name (without port number) through to the command.

These User Commands can run anything you can imagine doing in a script. These might be quite simple wrapper scripts or quite complex scripts. You could use it to run an MQSCX script that generates a report with a known file name, and then open the script with something like notepad to view the results.

mqscx -x -f -C "=import file(C:\MQGem\MQReport.mqx) parms(%1)"
notepad C:\MQGem\Output\MQReport_%1_%2_%3_%4.txt

The User Command would then run the command file:

C:\MQGem\runReport.cmd %q %y %m %d

When generating files, it is common to use dates and times in the file names. The other inserts available as substitutions in User Commands are those you can use to generate dates and time, as follows.

Insert Meaning
%d Day of the month e.g. 16
%D Day of the month e.g. Mon, Tue, Wed
%H Current time hours
%m Current Month e.g. Jan, Feb, Mar
%M Current time minutes
%S Current time seconds
%t Current time in HH.MM.SS format
%y Four digit year

You can also start other programs directly from MO71, and pass in the queue manager name as a parameter where required. For GUI applications make sure the User Command is defined with Hidden set to No or the GUI won’t be visible. If you are an MQSCX user as well as an MO71 user, you may prefer to use MQSCX rather than the MQSC window in MO71 for command line operations. You can create a user command to start an MQSCX session up for the queue manager through a User Command.

The flexibility of running any command scripts means you can do a lot with this, but if you think of other inserts or requirements on this feature, please drop us a line, or leave a comment below to let us know.


The new version can be downloaded from the MO71 Download Page. Any current licensed users of MO71 can run the new version on their existing licence. 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.

Scripts using foreach on the CCDT

foreachThere are different types of users who use MQSCX. Some like the interactive experience, with tab auto-complete of commands, keywords and objects names. Others like the ability to create and edit CCDT files suitable for any required version of IBM MQ. Others again like the powerful control language which makes writing scripts to interrogate your queue manager a breeze.

Freaking awesome, Paul! I wrote several reporting scripts for a customer a couple of months back. They declined to purchase MQSCX so I was forced to do much of the logic in the script, giving me I have a good basis for comparison of both approaches. The differential in lines of code, complexity and amount of additional billable time I spent would have paid for a site license for several years. The ROI is now more than doubled, possibly even 5x what it was.

User comment on MQSCX – see more at What our customers say

Sometimes those different use cases come together. The control language has a for loop concept where you can easily iterate over all the queue manager objects that are returned by the command server as the answer to an MQSC command, with a script something like this:-

@total = 0
foreach(DISPLAY QLOCAL(*) WHERE(CURDEPTH GT 0))
  @total = @total + CURDEPTH
endfor
print 'Total CURDEPTH =',@total

You can also write scripts that operate, not on queue manager objects, but on the contents of a CCDT file.

With the latest version of MQSCX, you can use the foreach construct on the items in your CCDT file in just same way as above. Here’s a small example:-

@ssl = 0;
foreach(DISPLAY CHANNEL(*) SSLCIPH)
  if (SSLCIPH)
    @ssl = @ssl + 1
  endif
endfor
print 'Found',@ssl,'SSL Channels out of',_numEach

Now with MQSCX V9.0.0 you can use the powerful control language to analyse and manipulate your CCDT files. Another example of using the foreach construct on a CCDT file can be see in Be sure of your CCDT Version


If you are a current MQSCX licence holder, you can simply download the new version of MQSCX and start using it. 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.

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.

Adding up

When answering this question I offered a suggestion that you could total the number of connections coming over a set of SVRCONN channels by using the following single line in MQSCX.

@total=0;foreach(DISPLAY CHSTATUS(*) CURSHCNV);@total=@total+CURSHCNV;endfor;print @total

This totaled all the CURSHCNV values for all the channels whose status was displayed.

It occurred to me that there are many other examples of commands where you might want to total up some integer attribute from a set of objects or status records.

  • DISPLAY QLOCAL(SYSTEM.ADMIN.*.EVENT) CURDEPTH
    How many event messages you have
  • DISPLAY CHSTATUS(*) WHERE(RQMNAME EQ MQG2) MSGS
    How many messages have been sent to queue manager MQG2
  • DISPLAY TPSTATUS(‘#’) TYPE(SUB) NUMMSGS
    How many messages have been sent to susbcribers
  • DISPLAY QLOCAL(*) OPPROCS
    How many putting applications are around

Instead of repeating the single line each time with changes to reflect the different command, it might be handy to have a little function that you could just throw a command at and it would do the totaling up for you. For example, you could do something like this:-

func totals(Command,Attribute)
  @total = 0
  foreach(@Command + ' ' + @Attribute)
    @total = @total + eval(@Attribute)
  endfor
  print 'Total of',@Attribute,'for all',@Command,'is',@total
endfunc

And then call it and get the result like so:-

totals("DISPLAY QLOCAL(Q*)","CURDEPTH")

Total of CURDEPTH for all DISPLAY QLOCAL(Q*) is 8

MQSCX functions are just so handy!