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.

Advertisements

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!

MaxChannels vs DIS QMSTATUS CONNS

I got asked this question on twitter the other day, so I thought it would make an interesting blog post.

Let’s look at each piece of the question.

DISPLAY QMSTATUS CONNS

You can use the DISPLAY QMSTATUS command to see how many connections there are currently made into the queue manager. This is a count of the number of applications (or some queue manager processes too) that have made an MQCONN(X) to the queue manager. It is also the same number of responses you should see returned by DISPLAY CONN(*) – if you don’t want to count them, find an MQ admin tool that counts them for you. These connections might be local or client connections – both contribute to the total.

To see the local ones use command:-

DISPLAY CONN(*) ALL WHERE(CHANNEL EQ ' ')

To see the remote ones use command:-

DISPLAY CONN(*) ALL WHERE(CHANNEL NE ' ')

Client Connections and MaxChannels

So having ruled out the local connections what should you think if the number of connections coming in over a channel is more than MaxChannels? As the question asks, “Shouldn’t that be failing?”

The other thing to remember here is that, since MQ V7, one SVRCONN channel can relay several client MQCONNs over to the queue manager.

To see this take a look at the DISPLAY CHSTATUS command. There is a status attribute CURSHCNV that shows the number currently being shared over that one SVRCONN instance.

To see the number of running channels, use the command:-

DISPLAY CHSTATUS(*) CURSHCNV

The number of responses will show you how many running channel instances there are – which is the number to compare against MaxChannels. If you add up the total of all the numbers shown in CURSHCNV, this total will be less than (or equal to) the above number of channel based connections shown when you used the DISPLAY CONN command. Both queue manager channels and client channels contribute to that total.

HINT: If you want an easy way to total up all the numbers shown in CURSHCNV, try out MQSCX with this single line:-

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

Or you could make a little import file to print out all the various numbers:-

=echo cmds(NO)
=echo resp(NO)
print 'Show all the connections into queue manager',_connqmgr
print _sep

DISPLAY QMSTATUS CONNS
print 'Total connections ',CONNS

DISPLAY CONN(*) ALL WHERE(CHANNEL EQ ' ')
print 'Local connections ',_matches

DISPLAY CONN(*) ALL WHERE(CHANNEL NE ' ')
print 'Remote connections',_matches

@total = 0
@svrcn = 0
foreach(DISPLAY CHSTATUS(*) CURSHCNV CHLTYPE)
  if (CHLTYPE = "SVRCONN")
    @svrcn = @svrcn + 1
  endif
  @total = @total + CURSHCNV
endfor
print 'Total Channel instances ',_matches
print 'QMgr Channel instances  ',_matches - @svrcn
print 'Client Channel instances',@svrcn
print 'Client connections',@total
=echo cmds(YES)
=echo resp(YES)

UPDATE: This script evolved further with the release of MQSCX V9.0.0 and the use of functions – see more in MQSCX Functions.


IBM Certified SpecialistIBM Champion 2016 Middleware

Morag Hughson
IBM Champion 2016 – Middleware
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

Translate from setmqaut to SET AUTHREC

IBM MQ on the distributed platforms have commands to grant authorities to groups and users, in order to allow them access to use resources on a queue manager. There are actually three command interfaces to do this.

  • setmqaut
    This was historically the first command interface. It is a control command, issued from the command line by a user who is a member of the mqm group.
  • Set Authority Record
    Next the PCF flavour of the command was implemented allowing the MQ Explorer (and other remotely connected tools such as MO71) to be able to issue these commands.
  • SET AUTHREC
    Finally, and most recently, the MQSC flavour of the command was implemented, allowing authority commands to co-exist in scripts along with object definitions.

When using a queue manager on the MQ Appliance, there is no setmqaut command. You are expected to either use a GUI with the PCF commands, or the MQSC scripting language and a SET AUTHREC command. In general the queue manager on the MQ Appliance is just like any other queue manager, and you may well be following some instructions to set up something on your appliance queue manager, but those instructions only provide examples with the setmqaut command.

This post is going to help you translate from an example setmqaut command to a SET AUTHREC command.

Here’s a couple of example commands that cover all the main switches you might see on a setmqaut command (although not all the values).

setmqaut -m QM1 -t qmgr -g mqgadm +connect

setmqaut -m QM1 -t queue -n WORK.Q -p mqgusr -all +put +get

Sometimes it’s easier to see this sort of thing diagrammatically. So first I show a picture and then below is a table to step through each switch.

setmqaut mapped to SET AUTHREC

setmqaut mapped to SET AUTHREC

Here’s a table to map from setmqaut to an MQSC SET AUTHREC.

setmqaut SET AUTHREC Notes
setmqaut SET AUTHREC Instead of using the setmqaut command, you’re going to use the SET AUTHREC command.
-m QM1 runmqsc QM1 MQSC commands are directed to the queue manager your MQSC issuing tool, such as runmqsc is connected to, so it’s not part of the SET AUTHREC command, instead it’s the direction to runmqsc to tell it which queue manager to connect to.
-t queue OBJTYPE(QUEUE) The -t switch becomes the OBJTYPE parameter and it’s value could be exactly the same, except for cases when setmqaut uses shortened forms. For example -t q is the same as -t queue. If you know your IBM MQ object names from other MQSC commands, then you’ll have no trouble figuring out which one is which.
-n WORK.Q PROFILE(WORK.Q) The -n switch becomes the PROFILE parameter. It’s called a profile rather than an object name since it could have wildcards in it. The value that went with the -n goes inside the brackets. One thing to remember though, MQSC will upper case anything that you don’t put inside quotes, so if your profile name is not upper case, add quotes around it. In the case of -t qmgr, there will be no -n switch, and you can omit the PROFILE parameter.
-g mqgadm GROUP(‘mqgadm’) The -g switch becomes the GROUP parameter and the value goes inside the brackets. Remember to use quotes.
-p mqgusr PRINCIPAL(‘mqgusr’) The -p switch becomes the PRINCIPAL parameter and the value goes inside the brackets. Remember to use quotes.
-all AUTHRMV(ALL) Any authority switches with a ‘-‘ sign are being removed. These should go in the comma-separated list in the AUTHRMV parameter. It is often seen that -all is used because adding a few authorities, in order to remove everything before adding new ones so you know where you are. Normally you wouldn’t combine AUTHRMV and AUTHADD parameters, but the use of ALL is one of the cases where it is allowed.
+put +get AUTHADD(PUT,GET) Any authority switches with a ‘+’ sign are being added. These should go in the comma-separated list in the AUTHADD parameter. The authority switches are spelled the same in both setmqaut and SET AUTHREC, just remove the ‘+’ (or ‘-‘) prefix.

If you come across a setmqaut command that you can’t translate into a SET AUTHREC with the above instructions, add it in the comments, and I’ll help you out. It’ll also improve this blog post for others.


IBM Certified SpecialistIBM Champion 2016 Middleware

Morag Hughson
IBM Champion 2016 – Middleware
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