3

I have MQ client code that can browse an Alias Queue to get the Alias Queue's base object name (i.e. the name of the Local Queue which the Alias Queue points to). However, the code only works when the MQ client connects to an MQ Manager running on the same host as the client code but NOT when the client code connects to an MQ Manager on a remote host.

Client Code:

MQEnvironment.hostname = "192.168.1.3";
MQEnvironment.port = "1415";
MQEnvironment.channel = "ADMIN.SVRCONN";

MQQueueManager mqQueueManager = new MQQueueManager(null);

int openOptions = CMQC.MQOO_BROWSE;// + CMQC.MQOO_RESOLVE_LOCAL_Q;

MQQueue mqQueue = mqQueueManager.accessQueue("AN.ALIAS.QUEUE.NAME", openOptions);

String resolvedName = mqQueue.getResolvedQName();

// resolvedName is null when the MQ Manager is on a remote host 
System.out.println("Resolved Queue Name: " + resolvedName);

When the resolved queue name of the Alias Queue is null, the MQ Manager's error logs shows the following single entry:

AMQ9208: Error on receive from host devlaptop (192.168.1.5).

EXPLANATION:
An error occurred receiving data from devlaptop (192.168.1.5) over TCP/IP.
This may be due to a communications failure.
ACTION:
The return code from the TCP/IP (recv) call was 10054 (X'2746'). Record these
values and tell the systems administrator. 

Should it be possible for client code to get a remote MQ Manager's Alias Queue's base object name? And if so, how? Am I missing remote permissions somewhere? Or are my client code openOptions wrong?

NOTE: The Alias Queue or any other queues in the Queue Managers are NOT clustered.

Going Bananas
  • 2,265
  • 3
  • 43
  • 83

2 Answers2

3

What you are seeing at the server is the client shutting down without closing the connection. TCP closes it and the QMgr emits the error you see in the QMgr logs. If the client were receiving an error you would see it returned to the client.

The question doesn't specify whether the alias you are trying to open is clustered or not. If it is clustered then we expect the resolved name to be blank as per the docs. In this case, the OPEN resolves to a transmission queue but the application is not told which one. In the returned handle the application sees, the resolved queue and QMgr name are left blank.

This is covered in the section on Name Resolution in the Knowledge Center. Refer to the table row with Blank queue manager in Column 1 and Alias queue with CLUSTER attribute in Column 2.

T.Rob
  • 31,522
  • 9
  • 59
  • 103
  • @T, as you explained, the client shutting down without closing the connection must be because I am killing the app and therefore not giving the app a chance to run `mqQueue.close();` and `mqManager.close();`. With regards to the Alias queue itself, I can confirm that it is NOT clustered in any way. – Going Bananas Jan 17 '17 at 17:24
  • In that case, please update the question with the values being used to populate the QMgr and queue name for the `OPEN`. – T.Rob Jan 18 '17 at 03:48
  • @JoshMc, the target of the alias queue is a local queue which is not clustered either. There are no clustered queues at all within these queue managers. – Going Bananas Jan 18 '17 at 10:04
  • @T.Rob, by "values" do you mean the open options being passed to the client's `MQQueueManager` on create and the client's `MQQueue` when trying to get access to it? If so, then for the queue manager the options passed are currently `null` and the options passed to the alias queue are `CMQC.MQOO_BROWSE` - see inline code in the question. – Going Bananas Jan 18 '17 at 10:10
  • It isn't clear from the post what is meant by "a remote MQ Manager's Alias Queue's base object name." If the QMgr is the one to which the client is connected, by definition it isn't remote. In that case there should be no difference in how name resolution works for bindings mode versus client mode connections. That there is suggests the queue is remote in the MQ sense of that word, meaning "not on the QMgr to which the app connects," hence why I asked about clustering. Glad you got it working but the stated conditions seem mutually exclusive so it's unclear what the actual issue was. – T.Rob Jan 18 '17 at 23:13
2

I was able to get the Alias queue's base object queue name using the following code:

    int openOptions = CMQC.MQOO_INQUIRE;

    MQQueue mqQueue = mqQueueManager.accessQueue("AN.ALIAS.QUEUE.NAME", openOptions);
    int[] selectors = new int[1];
    int[] intAttrs = new int[1];
    byte[] charAttrs = new byte[64];
    selectors[0] = CMQC.MQCA_BASE_OBJECT_NAME;
    mqQueue.inquire(selectors, intAttrs, charAttrs);

    logger.trace("baseObjectName:{}", new String(charAttrs).trim());

I would welcome any comments on this solution or an alternative simpler solution if one exists?

Going Bananas
  • 2,265
  • 3
  • 43
  • 83