MQSCX version 9.0.1 is released

MQGem Software is pleased to announce that a new version of MQSCX, our command line extended MQSC tool for IBM MQ, is now available.

This is a mini-release, specifically to release the first of the below features. But then we added a couple more things at the same time!

Issue RESET QSTATS as an MQSC command

Sparked by a conversation on MQSeries.net we were intrigued when one user asked us whether it would be possible to provide RESET QSTATS as an MQSC command on the distributed platforms using MQSCX. Turns out it is possible!

Support certlabl on connect

The =conn command provides for a number of client channel configuration attributes, and now certlabl is among them.

The Any Key

Press Any Key?

Provide a simple way of getting user key input

This version introduces the getkey() function which will return the next key pressed by the user. This can be useful to, for example, navigate your way through a script menu, or to exit from a while loop in a script at the user’s command.


The new version can be downloaded from the MQSCX Download Page. Any current licensed users of MQSCX can run the new version on their existing licence. If you don’t have a licence and would like to try out MQSCX then send a note to support@mqgem.com and a 1-month trial licence will be sent to you.

Advertisements

Creating a CCDT for any version

You may have read an earlier post where we described being able to determine what version of CCDT you had in your hand.

CCDT Version

How often have you had a CCDT file in your hand and wondered what version it was and whether you can give it to some of your known back-level client machines to use.

MQSCX can help you determine this. Open up your CCDT using the mqscx -n mode and then you can quite simply display the version number of all your client channels therein.

What you may not have realised from that post however, was that not only can MQSCX help to investigate what version number your CCDT is made for, it can also make a CCDT for the correct version as well. If you have back-level clients, it can be a real pain having to keep a queue manager of the same level around just to be able to create a CCDT that it will understand. Well, you can ditch that queue manager and use MQSCX instead. It’s really easy to do as well.

To use MQSCX to work with a CCDT, you need to use the -n parameter. This will then look for the CCDT file in the location specified by the MQCHLLIB and MQCHLTAB environment variables unless you provide the -t parameter to give it a specific file name. If one doesn’t exist, it will make a new one for you, and if one does exist it will read it and allow you to update it. In order to control the version of CCDT you are creating, you should additionally use the -V parameter which allows you to specify the version the CCDT file should be written as.

Here’s an example, run the MQSCX program like this:

mqscx -n -t C:\MQGem\CCDT\MQGEM.TAB -V7.0

And then you can use it to make DISPLAY, ALTER and DELETE commands.

MQSCX Extended MQSC Program – Version 8.0.0

CCDT commands directed to file ‘C:\MQGem\CCDT\MQGEM.TAB’

Licenced to Paul Clarke

Licence Location: Head Office

[12:02:10] DISPLAY CHANNEL(*) CONNAME VERSION

_________________________________________________

CHANNEL(MQG1.SVRCONN) CHLTYPE(CLNTCONN)

CONNAME(win12.mqgem.com(1602)) VERSION(8.0)

_________________________________________________

CHANNEL(MQG2.SVRCONN) CHLTYPE(CLNTCONN)

CONNAME(aix5.mqgem.com(4231)) VERSION(8.0)

_________________________________________________

CHANNEL(MQG3.SVRCONN) CHLTYPE(CLNTCONN)

CONNAME(mvs1.mqgem.com(1255)) VERSION(8.0)

_________________________________________________

Total display responses – Received:3

>

As you can see, at the moment all the channels in this CCDT are at V8.0 which means my V7.0 client won’t be able to read them. I need to make a change to each record to ensure MQSCX will write it out at version V7.0 as I have indicated on my start command. Helpfully, I can do that in one single command:-

ALTER CHANNEL(*)

This makes no actual change to the attributes of the channel definition, but does ‘touch’ each record to ensure that it gets the new version. Displaying the records again as above will show that the version number for each channel mentioned by the ALTER command (in this example all of them), now indicates it is at version V7.0, just what my back-level client application needs.

Exiting MQSCX and re-running it will show you that this earlier version of the CCDT has indeed been hardened.

Note that if you had been using some attributes introduced in later versions than V7.0, this information would be lost when altering the channel definition to be an earlier version.


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

MQSCX Bootstrap file

MQSCX BootstrapMQGem recently delivered a new version of MQSCX that supports the new IBM MQ V9 release. As well as support for the new command level, there were a number of other features in this new version of MQSCX. One of those new features was a bootstrap file. This is a well known named MQSCX script file that is always imported when you start up MQSCX. It can be a handy place to put any frequently used functions.

The bootstrap file can either have your frequently used functions included in it directly, or the bootstrap file can have =import file statements in it (or both). For example:-

*********************************************************************
* Load these useful functions at start up                           *
*********************************************************************
=import file(C:\MQGem\MQScripts\Utility.mqx)

Then when you start the program you’ll see:-

MQSCX Extended MQSC Program – Version 9.0.0

Licenced to Paul Clarke

Connected to ‘MQG1’

[10:50:13] =import file(C:\MQGem\MQScripts\Utility.mqx)

MQG1>

and all your utility functions will be available.

The bootstrap file could also be used to print a banner out to remind users of something each time they start up the MQSCX program. For example:-

print '*************************************************'
print '*                                               *'
print '*  MQGem Software systems must only be used by  *'
print '*               MQGem employees                 *'
print '*                                               *'
print '*************************************************'

Then when you start the program you’ll see:-

MQSCX Extended MQSC Program – Version 9.0.0

Licenced to Paul Clarke

Connected to ‘MQG1’

*************************************************

* *

* MQGem Software systems must only be used by *

* MQGem employees *

* *

*************************************************

MQG1>

Of course the bootstrap file could also be used to run a command, or a number of commands every time the program is started up. Anything you can do in a normal MQSCX script file (or interactively) you can put into the bootstrap file. Here’s one example, but of course I’m sure you can think of plenty of others.

*********************************************************************
* Always check queue manager up-time                                *
*********************************************************************
DISPLAY QMSTATUS STARTDA STARTTI

Then when you start the program you’ll see:-

MQSCX Extended MQSC Program – Version 9.0.0

Licenced to Paul Clarke

Connected to ‘MQG1’

[11:09:54] DISPLAY QMSTATUS STARTDA STARTTI

QMNAME(MQG1) STATUS(RUNNING) STARTDA(2016-08-05) STARTTI(20.58.00)

MQG1>

I’m sure there are lots of other things you could do with the bootstrap file. Let us know in the comments if you have any other ideas.


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.

Be sure of your CCDT Version

CCDT VersionWe all know that you can’t use a CCDT file with a client that is older than the CCDT version. For example, a version 6 client can’t understand what the channel definitions in a V8 produced CCDT mean.

How often have you had a CCDT file in your hand and wondered what version it was and whether you can give it to some of your known back-level client machines to use.

MQSCX can help you determine this. Open up your CCDT using the mqscx -n mode and then you can quite simply display the version number of all your client channels therein.

DISPLAY CHANNEL(*) VERSION

CHANNEL(MQGEM.SVRCONN)            CHLTYPE(CLNTCONN)   VERSION(8.0)
CHANNEL(MQGEM.SVRCONN.SSL)        CHLTYPE(CLNTCONN)   VERSION(9.0)
CHANNEL(MQGEM.SVRCONN.ADMIN)      CHLTYPE(CLNTCONN)   VERSION(7.0)

Alternatively, you might like to write a little script that could iterate through all the channels in the table and tell you the minimum and maximum versions in use within that CCDT.

if (_ccdtmode)
  @minVer = 999999999
  @maxVer = 0
  foreach (DISPLAY CHANNEL(*) VERSION)
    if (VERSION < @minVer)
      @minVer = VERSION
    endif
    if (VERSION > @maxVer)
      @maxVer = VERSION
    endif
  endfor
  if (_numEach)
    print "Channel version in",_ccdt
    print "Minimum:",@minVer,"Maximum:",@maxVer
  else
    print "No channels found in",_ccdt
  endif
else
  print "Run this script with MQSCX in CCDT mode"
endif

Running this against a multi-version CCDT might produce output such as:-

Channel version in C:\MQGem\CCDT\MQGEM101.TAB
Minimum: 7.00 Maximum: 9.00

foreachThis type of CCDT analysis is possible due to the recent addition of the foreach construct to the CCDT processing in MQSCX.

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.

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!