Get ClusterName of MQ Queue using Java

折月煮酒 提交于 2019-12-22 18:17:21

问题


I'm building a java application that connects to a MQQueueManager and extracts information about queues. I'm able to get data like QueueType, MaximumMessageLength and more. However, I also want the name of the cluster the queue might be in. There is no function that comes with the MQQueue that gives me this information. After searching the internet I found several things pointing in this direction, but no examples.

A part of my function that gives me the MaximumDepth is:

    queueManager = makeConnection(host, portNo, qMgr, channelName);
    queue = queueManager.accessQueue(queueName, CMQC.MQOO_INQUIRE);
    maxQueueDepth = queue.getMaximumDepth();

(makeConnection is not shown here, it is the function that makes the actual connection to the QueueManager; I also left out the try/catch/finally for less clutter)

How do I get ClusterName and perhaps other data, that doesn't have a function like queue.getMaximumDepth()?


回答1:


There are two ways to get information about a queue.

The API Inquire call gets operational status of a queue. This includes things like the name the MQOpen call resolved to or the depth if the queue is local. Much of the q.inquire functionality has been superseded with getter and setter functions on the queue. If you are not using the v8.0 client with the latest functionality, you are highly advised to upgrade. It can access all versions of QMgr.

The following code is from Getting and setting attribute values in WebSphere MQ classes for Java

// inquire on a queue
final static int MQIA_DEF_PRIORITY = 6;
final static int MQCA_Q_DESC = 2013;
final static int MQ_Q_DESC_LENGTH = 64;

int[] selectors  = new int[2];
int[] intAttrs   = new int[1];
byte[] charAttrs = new byte[MQ_Q_DESC_LENGTH]

selectors[0] = MQIA_DEF_PRIORITY;
selectors[1] = MQCA_Q_DESC;

queue.inquire(selectors,intAttrs,charAttrs);

System.out.println("Default Priority = " + intAttrs[0]);
System.out.println("Description : " + new String(charAttrs,0));

For things that are not part of the API Inquire call, a PCF command is needed. Programmable Command Format, commonly abbreviated as PCF, is a message format used to pass messages to the command queue and for reading messages from the command queue, event queues and others.

To use a PCF command the calling application must be authorized with +put on SYSTEM.ADMIN.COMMAND.QUEUE and for +dsp on the object being inquired upon.

IBM provides sample code.
On Windows, please see: %MQ_FILE_PATH%\Tools\pcf\samples
In UNIX flavors, please see: /opt/mqm/samp/pcf/samples
The locations may vary depending on where MQ was installed.

Please see: Handling PCF messages with IBM MQ classes for Java. The following snippet is from the PCF_DisplayActiveLocalQueues.java sample program.

  public static void DisplayActiveLocalQueues(PCF_CommonMethods pcfCM) throws PCFException,
      MQDataException, IOException {
    // Create the PCF message type for the inquire.
    PCFMessage pcfCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_Q);

    // Add the inquire rules.
    // Queue name = wildcard.
    pcfCmd.addParameter(MQConstants.MQCA_Q_NAME, "*");

    // Queue type = LOCAL.
    pcfCmd.addParameter(MQConstants.MQIA_Q_TYPE, MQConstants.MQQT_LOCAL);

    // Queue depth filter = "WHERE depth > 0".
    pcfCmd.addFilterParameter(MQConstants.MQIA_CURRENT_Q_DEPTH, MQConstants.MQCFOP_GREATER, 0);

    // Execute the command. The returned object is an array of PCF messages.
    PCFMessage[] pcfResponse = pcfCM.agent.send(pcfCmd);

    // For each returned message, extract the message from the array and display the
    // required information.
    System.out.println("+-----+------------------------------------------------+-----+");
    System.out.println("|Index|                    Queue Name                  |Depth|");
    System.out.println("+-----+------------------------------------------------+-----+");

    for (int index = 0; index < pcfResponse.length; index++) {
      PCFMessage response = pcfResponse[index];

      System.out.println("|"
          + (index + pcfCM.padding).substring(0, 5)
          + "|"
          + (response.getParameterValue(MQConstants.MQCA_Q_NAME) + pcfCM.padding).substring(0, 48)
          + "|"
          + (response.getParameterValue(MQConstants.MQIA_CURRENT_Q_DEPTH) + pcfCM.padding)
              .substring(0, 5) + "|");
    }

    System.out.println("+-----+------------------------------------------------+-----+");
    return;
  }
}



回答2:


After more research I finally found what I was looking for. This example of IBM: Getting and setting attribute values in WebSphere MQ classes helped me to set up the inquiry.

The necessary values I found in this list: Constant Field Values.

I also needed to expand the openOptionsArg of accessQueue(), else cluster queues cannot be inquired.

Final result: (without makeConnection())

public class QueueManagerServices {

final static int MQOO_INQUIRE_TOTAL = CMQC.MQOO_FAIL_IF_QUIESCING | CMQC.MQOO_INPUT_SHARED | CMQC.MQOO_INQUIRE;

MQQueueManager queueManager = null;
String cluster = null;
MQQueue queue = null;

public String getcluster(String host, int portNo, String qMgr, String channelName){

 try{
  queueManager = makeConnection(host, portNo, qMgr, channelName);
  queue = queueManager.accessQueue(queueName, MQOO_INQUIRE_TOTAL);

  int MQCA_CLUSTER_NAME = 2029;
  int MQ_CLUSTER_NAME_LENGTH = 48;

  int[] selectors = new int[1];
  int[] intAttrs = new int[1];
  byte[] charAttrs = new byte[MQ_CLUSTER_NAME_LENGTH];

  selectors[0] = MQCA_CLUSTER_NAME;

  queue.inquire(selectors, intAttrs, charAttrs);

  cluster = new String (charAttrs);

  } catch (MQException e) {
      System.out.println(e);
  } finally {
      if (queue != null){
        queue.close();
      }
      if (queueManager != null){
        queueManager.disconnect();
      }
  }
  return cluster;
  }
 }


来源:https://stackoverflow.com/questions/33922650/get-clustername-of-mq-queue-using-java

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!