New: MQ Channel Connection Inspector v1.1.0

Capitalware Inc. would like to announce the official release of MQ Channel Connection Inspector (MQCCI) v1.1.0. This is a FREE upgrade for ALL licensed users of MQCCI. MQCCI is a solution that allows a company to track and/or audit what information a client application or remote queue manager is exchanging with the local queue manager when a connection is made. MQCCI is comprised of an MQ Channel Security Exit. A channel security exit is ONLY invoked/called by the queue manager’s MCA (Message Channel Agent) for MQCONN/X and MQDISC API calls (so it is very light-weight).

For more information about MQ Channel Connection Inspector go to:
https://www.capitalware.com/mqcci_overview.html

Changes for MQ Channel Connection Inspector v1.1.0:

    Server-side:

  • Fixed an issue with tracking QMgr to QMgr channels
  • Added support for IncludeTag keyword
  • Added support for IncludeDurationTime keyword
  • Tuned the code that is called on entry
  • Tuned the logging code

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Channel Connection Inspector, Unix, Windows Comments Off on New: MQ Channel Connection Inspector v1.1.0

New: MQ Channel Connection Inspector for z/OS v1.1.0

Capitalware Inc. would like to announce the official release of MQ Channel Connection Inspector for z/OS (z/MQCCI) v1.1.0. This is a FREE upgrade for ALL licensed users of z/MQCCI. z/MQCCI is a solution that allows a company to track and/or audit what information a client application or remote queue manager is exchanging with the local queue manager when a connection is made. z/MQCCI is comprised of an MQ Channel Security Exit. A channel security exit is ONLY invoked/called by the queue manager’s MCA (Message Channel Agent) for MQCONN/X and MQDISC API calls (so it is very light-weight).

For more information about MQ Channel Connection Inspector for z/OS go to:
https://www.capitalware.com/mqcci_zos_overview.html

Changes for MQ Channel Connection Inspector for z/OS v1.1.0:

    Server-side:

  • Fixed an issue with tracking QMgr to QMgr channels
  • Added support for IncludeTag keyword
  • Added support for IncludeDurationTime keyword
  • Tuned the code that is called on entry
  • Tuned the logging code

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, IBM MQ, MQ Channel Connection Inspector, z/OS Comments Off on New: MQ Channel Connection Inspector for z/OS v1.1.0

New: MQ Authenticate User Security Exit v3.4.0

Capitalware Inc. would like to announce the official release of MQ Authenticate User Security Exit v3.4.0. This is a FREE upgrade for ALL licensed users of MQ Authenticate User Security Exit. MQ Authenticate User Security Exit is a solution that allows a company to fully authenticate a user who is accessing an IBM MQ resource. It authenticates the user’s UserID and Password (and possibly Domain Name) against the server’s native OS system, LDAP server, Microsoft’s Active Directory, Quest Authentication Services, Centrify’s DirectControl or an encrypted MQAUSX FBA file.

For more information about MQ Authenticate User Security Exit go to:
https://www.capitalware.com/mqausx_overview.html

Changes for MQ Authenticate User Security Exit v3.4.0:

    Server-side:

  • Added code to check the length of the incoming UserId & Password in the MQCSP structure
  • Tuned the code that is called on entry
  • Tuned the logging code

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Authenticate User Security Exit, Unix, Windows Comments Off on New: MQ Authenticate User Security Exit v3.4.0

New: MQ Authenticate User Security Exit for z/OS v3.4.0

New: MQ Authenticate User Security Exit for z/OS v3.4.0

Capitalware Inc. would like to announce the official release of MQ Authenticate User Security Exit for z/OS v3.4.0. This is a FREE upgrade for ALL licensed users of MQ Authenticate User Security Exit for z/OS. MQ Authenticate User Security Exit for z/OS is a solution that allows a company to fully authenticate a user who is accessing an IBM MQ for z/OS resource. It authenticates the user’s UserID and Password against the native z/OS system or an encrypted MQAUSX FBA file.

For more information about MQ Authenticate User Security Exit for z/OS go to:
https://www.capitalware.com/mqausx_zos_overview.html

Changes for MQ Authenticate User Security Exit for z/OS v3.4.0:

    Server-side:

  • Added code to check the length of the incoming UserId & Password in the MQCSP structure
  • Tuned the code that is called on entry
  • Tuned the logging code

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, IBM MQ, MQ Authenticate User Security Exit, z/OS Comments Off on New: MQ Authenticate User Security Exit for z/OS v3.4.0

New: MQ Auditor v3.1.0

Capitalware Inc. would like to announce the official release of MQ Auditor v3.1.0. This is a FREE upgrade for ALL licensed users of MQ Auditor. MQ Auditor is a solution that allows a company to audit/track all MQ API calls performed by MQ applications that are connected to a queue manager.

For more information about MQ Auditor go to:
https://www.capitalware.com/mqa_overview.html

    Changes for MQ Auditor v3.1.0:

  • Added code to make sure AuditPath and AuditArchivePath have a trailing slash.
  • Updated code so that when ArchiveCleanup is Yes, only ‘*.csv’ files are deleted.
  • Added code to allocate ResObjectString on MQOPEN if application did not provide it.
  • Erase ExitUserArea field on on exiting.
  • Added code to append trailing slash for ExitPath if it is missing.
  • Added code to append trailing slash for AuditPath if it is missing.
  • Added code to append trailing slash for AuditArchivePath if it is missing.
  • Fixed issue with UserIDFormatting
  • Tuned the logging code

Regards,
Roger Lacroix
Capitalware Inc.

Capitalware, IBM i (OS/400), IBM MQ, Linux, MQ Auditor, Unix, Windows Comments Off on New: MQ Auditor v3.1.0

WebSphere MQ V5.3 for HP NonStop Server End of Service Date

The end of service date for WebSphere MQ V5.3 for HP NonStop Server is April 30, 2020. The official announcement can be found here:
https://www.ibm.com/support/docview.wss?uid=ibm10957081

Regards,
Roger Lacroix
Capitalware Inc.

HPE NonStop, IBM MQ Comments Off on WebSphere MQ V5.3 for HP NonStop Server End of Service Date

New Raspberry Pi 4 Model B Released

Raspberry Pi Foundation has just released a new Raspberry Pi 4 Model B.
https://www.raspberrypi.org/blog/raspberry-pi-4-on-sale-now-from-35/

Everything is bigger, faster & better.

    Specifications:

  • A 1.5GHz quad-core 64-bit ARM Cortex-A72 CPU (~3× performance)
  • 1GB, 2GB, or 4GB of LPDDR4 SDRAM
  • Full-throughput Gigabit Ethernet
  • Dual-band 802.11ac wireless networking
  • Bluetooth 5.0
  • Two USB 3.0 and two USB 2.0 ports
  • Dual monitor support, at resolutions up to 4K
  • VideoCore VI graphics, supporting OpenGL ES 3.x
  • 4Kp60 hardware decode of HEVC video

Regards,
Roger Lacroix
Capitalware Inc.

Education, Linux, Open Source, Operating Systems, Programming, Raspberry Pi Comments Off on New Raspberry Pi 4 Model B Released

Updates to MessageSelector Class

In the blog posting, Java MQ Code to Retrieve Messages from a Queue Based on a Filter, I posted code for a Java MessageSelector class.

I have updated the setFilter method to catch any invalid values that may be passed to the MessageSelector class on the setFilter call.

You can download the source code for the test driver program called MQTest12MS from here which includes the MessageSelector class. If you just want the MessageSelector class, you can download from here.

Note: I have updated the original blog posting with the updated code.

Regards,
Roger Lacroix
Capitalware Inc.

IBM i (OS/400), IBM MQ, Java, Linux, macOS (Mac OS X), Programming, Unix, Windows Comments Off on Updates to MessageSelector Class

Java MQ Code to Retrieve Messages from a Queue Based on a Filter

There is a misconception regarding MQ/JMS message based filtering. Some people think that the IBM MQ queue manager does something special for JMS applications that is not done for plain Java or C/C++/C#/COBOL applications. It is just NOT true. Note: For C/C++/C#/COBOL applications, they can use the SelectionString from MQOD structure to perform message selection.

Sometimes when you quickly read a paragraph, you may miss the subtle nuances of the paragraph. See the first paragraph of the Message selectors in JMS in the Knowledge Center. It says:

Messages can contain application-defined property values. An application can use message selectors to have a JMS provider filter messages.

It doesn’t say the queue manager will filter the messages but rather, it says “JMS provider”. The JMS provider, aka the JMS client library, will perform the filtering of the messages.

So, I decided to create a simple POJO (Plain Old Java Object) class which can be used as a simple message selector with your POJO MQ application. There is nothing complicated about the code. It browses the messages on the queue, checks the message property for a matching value. If found then the message is removed from the queue and returned to the application, otherwise it continues to the next message. This is done until all messages have been checked (RC of 2033 – MQRC_NO_MSG_AVAILABLE).

I could have just as easily created it in C but I decided to do it in Java because I have seen people want a message selector in POJO.

You can download the source code for the test driver program called MQTest12MS from here which includes the MessageSelector class. If you just want the MessageSelector class, you can download from here.

Here is a snippet of the MQTest12MS that shows you how to use the MessageSelector class.

ms = new MessageSelector(qMgr);
ms.openQueue(inputQName);
ms.setFilter("SomeNum", MessageSelector.Conditions.GREATER_THAN_EQUAL, 123);

while (true)
{
   receiveMsg = ms.getMessage(startAtBeginning);

   // got the message, now go and do something with it.

   // set flag to continue rather than restart at the beginning.
   startAtBeginning = false;
}
ms.closeQueue();

Here is the MessageSelector class.

import java.io.IOException;

import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;

/**
 * Class Name
 *  MessageSelector
 *
 * Description
 *  This java class will retrieve messages from a queue based on a filter.
 *
 * @author Roger Lacroix
 * @version 1.0.0
 * @license Apache 2 License
 */
public class MessageSelector
{
   public enum Conditions
   {
      EQUAL, NOT_EQUAL, LESS_THAN, LESS_THAN_EQUAL, GREATER_THAN, GREATER_THAN_EQUAL;
   }
   
   private MQQueueManager  qMgr = null;
   private MQQueue         inQ = null;
   private String          filterName = null;
   private Conditions      filterCondition;
   private Object          filterValue = null;

   /**
    * The constructor
    * @param qMgr - must have a valid/active connection to the queue manager 
    */
   public MessageSelector(MQQueueManager qMgr)
   {
      super();
      this.qMgr = qMgr;
   }
   
   /**
    * Open the queue for both browsing and destructive gets.
    * @param qName
    * @throws MQException
    */
   public void openQueue(String qName) throws MQException
   {
      inQ = qMgr.accessQueue(qName, CMQC.MQOO_INQUIRE + CMQC.MQOO_BROWSE + CMQC.MQOO_FAIL_IF_QUIESCING + CMQC.MQOO_INPUT_SHARED);
   }
   
   /**
    * Close the queue.
    * @throws MQException
    */
   public void closeQueue() throws MQException 
   {
      if (inQ != null)
         inQ.close();
   }
   
   /**
    * Set the filter name, condition and value. 
    * @param name
    * @param condition
    * @param value
    * @throws IllegalArgumentException
    */
   public void setFilter(String name, Conditions condition, Object value) throws IllegalArgumentException
   {
      if (name == null)
         throw new IllegalArgumentException("Filter name cannot be null.");
      else if ("".equals(name))
         throw new IllegalArgumentException("Filter name cannot be blank.");
      else if (value == null)
         throw new IllegalArgumentException("Filter value cannot be null.");
      
      if ( (value instanceof String) || (value instanceof Boolean) ||
           (value instanceof Byte)   || (value instanceof Byte[])  )
       {
          if ( (Conditions.EQUAL != condition) && (Conditions.NOT_EQUAL != condition) )
          {
             throw new IllegalArgumentException("Filter condition can only be EQUAL or NOT_EQUAL.");
          }
       }
       else if ( (value instanceof Integer) || (value instanceof Long) ||
                 (value instanceof Double)  || (value instanceof Float) )
       {
          if ( (Conditions.EQUAL != condition) && (Conditions.NOT_EQUAL != condition) &&
               (Conditions.LESS_THAN != condition) && (Conditions.LESS_THAN_EQUAL != condition) &&
               (Conditions.GREATER_THAN != condition) && (Conditions.GREATER_THAN_EQUAL != condition) )
          {
             throw new IllegalArgumentException("Filter condition must be one of the following: EQUAL, NOT_EQUAL, LESS_THAN, LESS_THAN_EQUAL, GREATER_THAN, GREATER_THAN_EQUAL.");
          }
       }
       else
       {
          throw new IllegalArgumentException("Unknown Object type for Filter value.");
       }

      /**
       * Pass the checks, save the values
       */
      this.filterName = name;
      this.filterCondition = condition;
      this.filterValue = value;
   }

   /**
    * Retrieve the next matching message from the queue.
    * @param reset - Start over from the beginning of the queue.
    * @return
    * @throws MQException
    * @throws IOException
    */
   public MQMessage getMessage(boolean reset) throws MQException, IOException
   {
      MQGetMessageOptions gmo = new MQGetMessageOptions();
      if (reset)
         gmo.options = CMQC.MQGMO_BROWSE_FIRST + CMQC.MQGMO_NO_WAIT + CMQC.MQGMO_FAIL_IF_QUIESCING;
      else
         gmo.options = CMQC.MQGMO_BROWSE_NEXT + CMQC.MQGMO_NO_WAIT + CMQC.MQGMO_FAIL_IF_QUIESCING;
      MQMessage getMsg = null;

      while (true)
      {
         getMsg = new MQMessage();

         inQ.get(getMsg, gmo);

         if (performConditionalTest(getMsg))
         {
            deleteMessage();
            break;
         }

         gmo.options = CMQC.MQGMO_BROWSE_NEXT + CMQC.MQGMO_NO_WAIT + CMQC.MQGMO_FAIL_IF_QUIESCING;
      }
      
      return getMsg;
   }
   
   /**
    * Handle the conditional testing of the value.
    * @param getMsg
    * @return true/false
    */
   private boolean performConditionalTest(MQMessage getMsg)
   {
      boolean flag = false;

      try
      {
         if (filterValue instanceof String)
         {
            String value = getMsg.getStringProperty(filterName);
            if (value != null) 
            {
               if ( (Conditions.EQUAL == filterCondition) && (((String)filterValue).equals(value)) )
                  flag = true;
               else if ( (Conditions.NOT_EQUAL == filterCondition) && (!(((String)filterValue).equals(value))) )
                  flag = true;
            }
         }
         else if (filterValue instanceof Integer)
         {
            int value = getMsg.getIntProperty(filterName);
            
            if ( (Conditions.EQUAL == filterCondition) && (value == (Integer)filterValue) ) 
               flag = true;
            else if ( (Conditions.NOT_EQUAL == filterCondition) && (value != (Integer)filterValue) ) 
               flag = true;
            else if ( (Conditions.LESS_THAN == filterCondition) && (value < (Integer)filterValue) ) 
               flag = true;
            else if ( (Conditions.LESS_THAN_EQUAL == filterCondition) && (value <= (Integer)filterValue) ) 
               flag = true;
            else if ( (Conditions.GREATER_THAN == filterCondition) && (value > (Integer)filterValue) ) 
               flag = true;
            else if ( (Conditions.GREATER_THAN_EQUAL == filterCondition) && (value >= (Integer)filterValue) ) 
               flag = true;
         }
         else if (filterValue instanceof Long)
         {
            long value = getMsg.getLongProperty(filterName);
            
            if ( (Conditions.EQUAL == filterCondition) && (value == (Long)filterValue) ) 
               flag = true;
            else if ( (Conditions.NOT_EQUAL == filterCondition) && (value != (Long)filterValue) ) 
               flag = true;
            else if ( (Conditions.LESS_THAN == filterCondition) && (value < (Long)filterValue) ) 
               flag = true;
            else if ( (Conditions.LESS_THAN_EQUAL == filterCondition) && (value <= (Long)filterValue) ) 
               flag = true;
            else if ( (Conditions.GREATER_THAN == filterCondition) && (value > (Long)filterValue) ) 
               flag = true;
            else if ( (Conditions.GREATER_THAN_EQUAL == filterCondition) && (value >= (Long)filterValue) ) 
               flag = true;
         }
         else if (filterValue instanceof Double)
         {
            double value = getMsg.getDoubleProperty(filterName);
            
            if ( (Conditions.EQUAL == filterCondition) && (value == (Double)filterValue) ) 
               flag = true;
            else if ( (Conditions.NOT_EQUAL == filterCondition) && (value != (Double)filterValue) ) 
               flag = true;
            else if ( (Conditions.LESS_THAN == filterCondition) && (value < (Double)filterValue) ) 
               flag = true;
            else if ( (Conditions.LESS_THAN_EQUAL == filterCondition) && (value <= (Double)filterValue) ) 
               flag = true;
            else if ( (Conditions.GREATER_THAN == filterCondition) && (value > (Double)filterValue) ) 
               flag = true;
            else if ( (Conditions.GREATER_THAN_EQUAL == filterCondition) && (value >= (Double)filterValue) ) 
               flag = true;
         }
         else if (filterValue instanceof Float)
         {
            float value = getMsg.getFloatProperty(filterName);

            if ( (Conditions.EQUAL == filterCondition) && (value == (Float)filterValue) ) 
               flag = true;
            else if ( (Conditions.NOT_EQUAL == filterCondition) && (value != (Float)filterValue) ) 
               flag = true;
            else if ( (Conditions.LESS_THAN == filterCondition) && (value < (Float)filterValue) ) 
               flag = true;
            else if ( (Conditions.LESS_THAN_EQUAL == filterCondition) && (value <= (Float)filterValue) ) 
               flag = true;
            else if ( (Conditions.GREATER_THAN == filterCondition) && (value > (Float)filterValue) ) 
               flag = true;
            else if ( (Conditions.GREATER_THAN_EQUAL == filterCondition) && (value >= (Float)filterValue) ) 
               flag = true;
         }
         else if (filterValue instanceof Boolean)
         {
            Boolean value = getMsg.getBooleanProperty(filterName);
            if ( (value != null) && ((Boolean)filterValue == value) ) 
               flag = true;
         }
         else if (filterValue instanceof Byte)
         {
            byte value = getMsg.getByteProperty(filterName);
            if ((Byte)filterValue == value)  
               flag = true;
         }
         else if (filterValue instanceof Byte[])
         {
            byte[] value = getMsg.getBytesProperty(filterName);
            if ( (value != null) && (java.util.Arrays.equals((byte[])filterValue, value)) ) 
               flag = true;
         }
      }
      catch (Exception e)
      {}

      return flag;
   }
   
   /**
    * Delete the message that the cursor is pointing to. 
    */
   private void deleteMessage()
   {
      MQMessage deleteMsg = new MQMessage();
      MQGetMessageOptions gmo = new MQGetMessageOptions();
      gmo.options = CMQC.MQGMO_MSG_UNDER_CURSOR + CMQC.MQGMO_NO_WAIT + CMQC.MQGMO_FAIL_IF_QUIESCING + CMQC.MQGMO_ACCEPT_TRUNCATED_MSG;

      /** 
       * don't need it - because we already have the message
       * just delete it.
       */
      try
      {
         inQ.get(deleteMsg, gmo, 1);  // only get 1 byte - who cares right!!  
      }
      catch (MQException e)
      {}
   }
}

Regards,
Roger Lacroix
Capitalware Inc.

IBM i (OS/400), IBM MQ, Java, Linux, macOS (Mac OS X), Programming, Unix, Windows 5 Comments

IBM MQ Fix Pack 9.0.0.7 Released

IBM has just released Fix Pack 9.0.0.7 for IBM MQ V9.0 LTS
https://www.ibm.com/support/docview.wss?uid=ibm10887223

Regards,
Roger Lacroix
Capitalware Inc.

Fix Packs for MQ, IBM i (OS/400), IBM MQ, Linux, Unix, Windows Comments Off on IBM MQ Fix Pack 9.0.0.7 Released