Java/PCF Program to Create an IBM MQ SVRCONN Channel

A couple of weeks ago, I posted a Java/PCF Program to Create an IBM MQ Queue. So, today I thought I would create a Java/PCF program to create an IBM MQ SVRCONN channel

If you are used to creating an IBM MQ channel using runmqsc command then the following simple Java/PCF program will create a IBM MQ channel based on the following runmqsc command:

DEFINE CHL('ABC.CHL') MAXMSGL(10485760) SCYEXIT('C:\Capitalware\MQCCI\mqcci(CCI)') SCYDATA('mqcci.ini')

Note: For the channel security exit, I used Capitalware’s MQ Channel Connection Inspector (MQCCI) product. 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 queue manager when a connection is made.

You can download the source code from here.

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

import com.ibm.mq.MQException;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.CMQC;
import com.ibm.mq.constants.MQConstants;
import com.ibm.mq.headers.MQDataException;
import com.ibm.mq.headers.pcf.PCFException;
import com.ibm.mq.headers.pcf.PCFMessage;
import com.ibm.mq.headers.pcf.PCFMessageAgent;

/**
 * Program Name
 *  MQCreateChannel01
 *
 * Description
 *  This java class issues a PCF "create channel" request message that will create a SVRCONN channel 
 *  specifying max message length & channel security exit.  
 *  For the channel security exit, I used Capitalware's MQ Channel Connection Inspector (MQCCI) product.
 *  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 queue manager when a connection is made. 
 *  
 *  This PCF code is equivalent to issuing the runmqsc command of:
 *     DEFINE CHL('ABC.CHL') MAXMSGL(10485760) SCYEXIT('C:\Capitalware\MQCCI\mqcci(CCI)') SCYDATA('mqcci.ini')
 *
 * Sample Command Line Parameters
 *  -m MQA1 -z TEST.CHL -h 127.0.0.1 -p 1414 -c TEST.CHL -u UserID -x Password
 *
 * @author Roger Lacroix
 */
public class MQCreateChannel01
{
   private static final SimpleDateFormat  LOGGER_TIMESTAMP = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");

   private Hashtable<String,String> params;
   private Hashtable<String,Object> mqht;

   public MQCreateChannel01()
   {
      super();
      params = new Hashtable<String,String>();
      mqht = new Hashtable<String,Object>();
   }

   /**
    * Make sure the required parameters are present.
    * @return true/false
    */
   private boolean allParamsPresent()
   {
      boolean b = params.containsKey("-h") && params.containsKey("-p") &&
                  params.containsKey("-c") && params.containsKey("-m") &&
                  params.containsKey("-z") &&
                  params.containsKey("-u") && params.containsKey("-x");
      if (b)
      {
         try
         {
            Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            b = false;
         }
      }

      return b;
   }

   /**
    * Extract the command-line parameters and initialize the MQ HashTable.
    * @param args
    * @throws IllegalArgumentException
    */
   private void init(String[] args) throws IllegalArgumentException
   {
      int port = 1414;
      if (args.length > 0 && (args.length % 2) == 0)
      {
         for (int i = 0; i < args.length; i += 2)
         {
            params.put(args[i], args[i + 1]);
         }
      }
      else
      {
         throw new IllegalArgumentException();
      }

      if (allParamsPresent())
      {
         try
         {
            port = Integer.parseInt((String) params.get("-p"));
         }
         catch (NumberFormatException e)
         {
            port = 1414;
         }
         
         mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c"));
         mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h"));
         mqht.put(CMQC.PORT_PROPERTY, new Integer(port));
         mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u"));
         mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x"));

         // I don't want to see MQ exceptions at the console.
         MQException.log = null;
      }
      else
      {
         throw new IllegalArgumentException();
      }
   }
   
   /**
    * Handle connecting to the queue manager, issuing PCF command then 
    * disconnect from the queue manager. 
    */
   private void doPCF()
   {
      String qMgrName = (String) params.get("-m");
      String chlName    = (String) params.get("-z");

      MQQueueManager qMgr = null;
      PCFMessageAgent agent = null;
      PCFMessage   request = null;
      
      try
      {
         qMgr = new MQQueueManager(qMgrName, mqht);
         logger("successfully connected to "+ qMgrName);

         agent = new PCFMessageAgent(qMgr);
         logger("successfully created agent");
      
         // https://www.ibm.com/docs/en/ibm-mq/latest?topic=formats-change-copy-create-channel
         
         request = new PCFMessage(MQConstants.MQCMD_CREATE_CHANNEL);

         // Specify the channel name to be created.
         request.addParameter(MQConstants.MQCACH_CHANNEL_NAME, chlName);
         
         // Add parameter to set channel type to be a SVRCONN channel
         request.addParameter(MQConstants.MQIACH_CHANNEL_TYPE, MQConstants.MQCHT_SVRCONN);
         
         // Add parameter to set the max message length to be 10MB
         request.addParameter(MQConstants.MQIACH_MAX_MSG_LENGTH, 10 * 1024 * 1024);
         
         // Add parameter to set the channel security exit name
         request.addParameter(MQConstants.MQCACH_SEC_EXIT_NAME, "C:\\Capitalware\\MQCCI\\mqcci(CCI)");
         
         // Add parameter to set the data parameter for channel security exit
         request.addParameter(MQConstants.MQCACH_SEC_EXIT_USER_DATA, "mqcci.ini");

         agent.send(request);
         
         logger("successfully created channel: " + chlName);
      }
      catch (PCFException pcfe) 
      {
         if (pcfe.reasonCode == MQConstants.MQRCCF_OBJECT_ALREADY_EXISTS) 
            logger("Error: The channel '" + chlName+ "' already exists on the queue manager '" + qMgrName + "'.");
         else
            logger("CC=" +pcfe.completionCode +  " [" + MQConstants.lookupCompCode(pcfe.completionCode) + "] : RC=" + pcfe.reasonCode + " ["+MQConstants.lookupReasonCode(pcfe.reasonCode)+"]");
      }
      catch (MQException e)
      {
         logger("CC=" +e.completionCode +  " [" + MQConstants.lookupCompCode(e.completionCode) + "] : RC=" + e.reasonCode + " ["+MQConstants.lookupReasonCode(e.reasonCode)+"]");
      }
      catch (IOException e)
      {
         logger("IOException:" +e.getLocalizedMessage());
      }
      catch (MQDataException e)
      {
         logger("MQDataException:" +e.getLocalizedMessage());
      }
      catch (Exception e)
      {
         logger("Exception:" +e.getLocalizedMessage());
      }
      finally
      {
         try
         {
            if (agent != null)
            {
               agent.disconnect();
               logger("disconnected from agent");
            }
         }
         catch (MQDataException e)
         {
            logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }

         try
         {
            if (qMgr != null)
            {
               qMgr.disconnect();
               logger("disconnected from "+ qMgrName);
            }
         }
         catch (MQException e)
         {
            logger("CC=" +e.completionCode + " : RC=" + e.reasonCode);
         }
      }
   }

   /**
    * A simple logger method
    * @param data
    */
   public static void logger(String data)
   {
      String className = Thread.currentThread().getStackTrace()[2].getClassName();

      // Remove the package info.
      if ( (className != null) && (className.lastIndexOf('.') != -1) )
         className = className.substring(className.lastIndexOf('.')+1);

      System.out.println(LOGGER_TIMESTAMP.format(new Date())+" "+className+": "+Thread.currentThread().getStackTrace()[2].getMethodName()+": "+data);
   }

   public static void main(String[] args)
   {
      MQCreateChannel01 mqcq = new MQCreateChannel01();
      
      try
      {
         mqcq.init(args);
         mqcq.doPCF();
      }
      catch (IllegalArgumentException e)
      {
         logger("Usage: java MQCreateChannel01 -m QueueManagerName -z Channel_Name -h host -p port -c channel -u UserID -x Password");
         System.exit(1);
      }

      System.exit(0);
   }
}

Regards,
Roger Lacroix
Capitalware Inc.

This entry was posted in HPE NonStop, IBM i (OS/400), IBM MQ, IBM MQ Appliance, Java, Linux, macOS (Mac OS X), Open Source, PCF, Programming, Raspberry Pi, Unix, Windows, z/OS.

Comments are closed.