ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ API Support » PCF call to get queue name from AS400 machine

Post new topic  Reply to topic Goto page 1, 2  Next
 PCF call to get queue name from AS400 machine « View previous topic :: View next topic » 
Author Message
souciance
PostPosted: Wed Feb 26, 2020 9:50 am    Post subject: PCF call to get queue name from AS400 machine Reply with quote

Disciple

Joined: 29 Jun 2010
Posts: 169

Hello,

Our scenario is as follows. We have a dotnet core application that uses the IBM MQ dotnet client apis. It issues PCF commands using PCFMessageAgent and PCFMessage to get list of queues with queue depth greater than zero.

The dotnet app runs on a windows machine.

When issuing this call against an MQ queue manager installed on a windows machine we get the queue name and everything works fine.

When issuing this call against an MQ queue manager that is installed on an AS400 with codepage 37 the queue names we get back are just jibberish like ?????@@@ . We have tried different ways to convert the queue name but nothing has worked.

Does anyone know what command to issue for MQ to convert the queue name to UTF8 or ASCII?

Thanks
Back to top
View user's profile Send private message
Vitor
PostPosted: Wed Feb 26, 2020 1:26 pm    Post subject: Re: PCF call to get queue name from AS400 machine Reply with quote

Grand High Poobah

Joined: 11 Nov 2005
Posts: 26093
Location: Texas, USA

souciance wrote:
When issuing this call against an MQ queue manager that is installed on an AS400 with codepage 37 the queue names we get back are just jibberish like ?????@@@ .


Codepage 37 is an EBCDIC page.

souciance wrote:
We have tried different ways to convert the queue name but nothing has worked.


Name 3.

souciance wrote:
Does anyone know what command to issue for MQ to convert the queue name to UTF8 or ASCII?


I'd expect a get with convert to do it, hence my question about what you've tried. EBCDIC -> ASCII isn't exactly an unusual conversion of payload.
_________________
Honesty is the best policy.
Insanity is the best defence.
Back to top
View user's profile Send private message
souciance
PostPosted: Wed Feb 26, 2020 1:51 pm    Post subject: Re: PCF call to get queue name from AS400 machine Reply with quote

Disciple

Joined: 29 Jun 2010
Posts: 169

Vitor wrote:
souciance wrote:
When issuing this call against an MQ queue manager that is installed on an AS400 with codepage 37 the queue names we get back are just jibberish like ?????@@@ .


Codepage 37 is an EBCDIC page.

souciance wrote:
We have tried different ways to convert the queue name but nothing has worked.


Name 3.

souciance wrote:
Does anyone know what command to issue for MQ to convert the queue name to UTF8 or ASCII?


I'd expect a get with convert to do it, hence my question about what you've tried. EBCDIC -> ASCII isn't exactly an unusual conversion of payload.


We are not trying to convert the payload. We are issuing PCF calls to get a list of queue names with a certain depth. It is the names that look gibberish when sending requests to AS400 queue managers. We are not looking to look at the payload.
Back to top
View user's profile Send private message
PaulClarke
PostPosted: Wed Feb 26, 2020 2:09 pm    Post subject: Reply with quote

Grand Master

Joined: 17 Nov 2005
Posts: 1002
Location: New Zealand

Can you share what call you are using to get the command server response on your Windows machine ?

I think was Vitor was suggesting is that you use the MQGMO_CONVERT option on the MQGET and if that does not work what reason code do you get ?
_________________
Paul Clarke
MQGem Software
www.mqgem.com
Back to top
View user's profile Send private message Visit poster's website
hughson
PostPosted: Wed Feb 26, 2020 2:25 pm    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1914
Location: Bay of Plenty, New Zealand

Could you show your code? Assume you are using getParameterValue? Is there an exception thrown that might provide some reason for the failure to convert the string data?

Cheers,
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
souciance
PostPosted: Thu Feb 27, 2020 12:50 am    Post subject: Reply with quote

Disciple

Joined: 29 Jun 2010
Posts: 169

Hello,

Here is part of our code. Below is to create a queue manager.
Code:
QueueManager qm = new QueueManager(name, hostNport, "1414", channel);
                Queue qu = new Queue();
                qu._QueueManager = qm;
                MQEnvironment.Hostname = hostNport;
                MQEnvironment.Port = Int32.Parse(port);
                MQEnvironment.Channel = channel; 


Here is the main code to connect to a queue and get the queue name.

Code:

PCFMessage RequestMessage = new PCFMessage(MQC.MQCMD_INQUIRE_Q);
                RequestMessage.AddParameter(MQC.MQCA_Q_NAME, "*");
                MQGetMessageOptions msgopt = new MQGetMessageOptions();
                PCFMessage[] pcfResponse = MessageAgent.Send(RequestMessage);

                for (int i = 0; i < pcfResponse.Length; i++)
                {
                    Queue mqQueue = new Queue();
                    mqQueue._Type = pcfResponse[i].GetIntParameterValue(MQC.MQIA_Q_TYPE);
                    if (mqQueue._Type == 1)
                    {
                     
                        mqQueue._QueueName = pcfResponse[i].GetStringParameterValue(MQC.MQCA_Q_NAME).Trim();
                        mqQueue._QueueDepth = pcfResponse[i].GetIntParameterValue(MQC.MQIA_CURRENT_Q_DEPTH);


The problem is that the value of the QueueName is just jibberish. I think we need a way to tell MQ to convert the CCSID when sending the response back to us.
Back to top
View user's profile Send private message
RogerLacroix
PostPosted: Thu Feb 27, 2020 1:11 pm    Post subject: Reply with quote

Jedi Knight

Joined: 15 May 2001
Posts: 3252
Location: London, ON Canada

souciance wrote:
Code:
Queue mqQueue = new Queue();
mqQueue._Type = pcfResponse[i].GetIntParameterValue(MQC.MQIA_Q_TYPE);
if (mqQueue._Type == 1)
{
    mqQueue._QueueName = pcfResponse[i].GetStringParameterValue(MQC.MQCA_Q_NAME).Trim();
    mqQueue._QueueDepth = pcfResponse[i].GetIntParameterValue(MQC.MQIA_CURRENT_Q_DEPTH);

What is the "Queue" class? Is "_QueueName" of type String or MQQueue? Because I see for "_QueueManager" it appears of type QueueManager.

If it is of type MQQueue then that would explain the gibberish.

Regards,
Roger Lacroix
Capitalware Inc.
_________________
Capitalware: Transforming tomorrow into today.
Connected to MQ!
Twitter
Back to top
View user's profile Send private message Visit poster's website
hughson
PostPosted: Thu Feb 27, 2020 2:28 pm    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1914
Location: Bay of Plenty, New Zealand

souciance wrote:
Code:

PCFMessage RequestMessage = new PCFMessage(MQC.MQCMD_INQUIRE_Q);
                RequestMessage.AddParameter(MQC.MQCA_Q_NAME, "*");
                MQGetMessageOptions msgopt = new MQGetMessageOptions();
                PCFMessage[] pcfResponse = MessageAgent.Send(RequestMessage);

                for (int i = 0; i < pcfResponse.Length; i++)
                {
                    Queue mqQueue = new Queue();
                    mqQueue._Type = pcfResponse[i].GetIntParameterValue(MQC.MQIA_Q_TYPE);
                    if (mqQueue._Type == 1)
                    {
                     
                        mqQueue._QueueName = pcfResponse[i].GetStringParameterValue(MQC.MQCA_Q_NAME).Trim();
                        mqQueue._QueueDepth = pcfResponse[i].GetIntParameterValue(MQC.MQIA_CURRENT_Q_DEPTH);


What do you see if you just print out the value from pcfResponse[i].GetStringParameterValue(MQC.MQCA_Q_NAME) before assigning it to mqQueue._QueueName?

Cheers,
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
souciance
PostPosted: Wed Mar 04, 2020 4:31 am    Post subject: Reply with quote

Disciple

Joined: 29 Jun 2010
Posts: 169

hughson wrote:
souciance wrote:
Code:

PCFMessage RequestMessage = new PCFMessage(MQC.MQCMD_INQUIRE_Q);
                RequestMessage.AddParameter(MQC.MQCA_Q_NAME, "*");
                MQGetMessageOptions msgopt = new MQGetMessageOptions();
                PCFMessage[] pcfResponse = MessageAgent.Send(RequestMessage);

                for (int i = 0; i < pcfResponse.Length; i++)
                {
                    Queue mqQueue = new Queue();
                    mqQueue._Type = pcfResponse[i].GetIntParameterValue(MQC.MQIA_Q_TYPE);
                    if (mqQueue._Type == 1)
                    {
                     
                        mqQueue._QueueName = pcfResponse[i].GetStringParameterValue(MQC.MQCA_Q_NAME).Trim();
                        mqQueue._QueueDepth = pcfResponse[i].GetIntParameterValue(MQC.MQIA_CURRENT_Q_DEPTH);


What do you see if you just print out the value from pcfResponse[i].GetStringParameterValue(MQC.MQCA_Q_NAME) before assigning it to mqQueue._QueueName?

Cheers,
Morag


Hello again, sorry for the delay. Been a bit sick.

But here is the main gist of the code:

Code:
  MQEnvironment.Hostname = hostNport;
            MQEnvironment.Port = port;
            MQEnvironment.Channel = channel;
           
            PCFMessageAgent MessageAgent = new PCFMessageAgent(name);
            PCFMessage reqeuestMessage = new PCFMessage(MQC.MQCMD_INQUIRE_Q);
           reqeuestMessage.AddParameter(MQC.MQCA_Q_NAME, "*");
            reqeuestMessage.AddParameter(MQC.MQIA_Q_TYPE, MQC.MQQT_LOCAL);
            reqeuestMessage.AddParameter(MQC.MQIACF_Q_ATTRS,
                              new int[] { MQC.MQCA_Q_NAME,
                                          MQC.MQIA_Q_TYPE,
                                          MQC.MQIA_CURRENT_Q_DEPTH });

            PCFMessage[] pcfResponse = MessageAgent.Send(reqeuestMessage);
            for (int i = 0; i < pcfResponse.Length; i++)
            {
               
                string QueueName = pcfResponse[i].GetStringParameterValue(MQC.MQCA_Q_NAME);
                int QueueDepth = pcfResponse[i].GetIntParameterValue(MQC.MQIA_CURRENT_Q_DEPTH);
                Console.WriteLine($"Queue  {QueueName} found with depth {QueueDepth}");
            }


Here is the output:
Queue ??????K???????K??????????K?????@@@@@@@@@@@@@@@@@ found with depth 2
Queue ??????K???????K????????K?????@@@@@@@@@@@@@@@@@@@ found with depth 0
Queue ??????K??????K?????K?????@@@@@@@@@@@@@@@@@@@@@@@ found with depth 0
Queue ??????K????K??????K?????@@@@@@@@@@@@@@@@@@@@@@@@ found with depth 1
Queue ??????K???????K??????????K?????@@@@@@@@@@@@@@@@@ found with depth 0
Queue ??????K???????K?????K?????@@@@@@@@@@@@@@@@@@@@@@ found with depth 0
Queue ??????K??????K??????????K?????@@@@@@@@@@@@@@@@@@ found with depth 0
Queue ??????K???????K??????????K?????@@@@@@@@@@@@@@@@@ found with depth 1
Queue ??????K?????????K?????@@@@@@@@@@@@@@@@@@@@@@@@@@ found with depth 2
Queue ??????K?????K????K???????@@@@@@@@@@@@@@@@@@@@@@@ found with depth 0
Queue ??????K?????K????K??????@@@@@@@@@@@@@@@@@@@@@@@@ found with dept

How can we get the actual queue names? The queue manager on the ISeries has codepage 37.
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Wed Mar 04, 2020 6:58 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20696
Location: LI,NY

What CCSID did you assign to the PCFMessageAgent ? Try and assign it CCSID 1208 and see if it makes a difference.
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
hughson
PostPosted: Wed Mar 04, 2020 12:21 pm    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1914
Location: Bay of Plenty, New Zealand

fjb_saper wrote:
What CCSID did you assign to the PCFMessageAgent ?


We can see from the provided code that it has not been explicitly set, which would mean it would default to MQCCSI_Q_MGR which is supposed to pick up the CCSID of the client locale.

fjb_saper wrote:
Try and assign it CCSID 1208 and see if it makes a difference.


In case you don't know how to do this, I think you need:-

Code:
MessageAgent.setCharacterSet(1208)


Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
tczielke
PostPosted: Wed Mar 04, 2020 12:52 pm    Post subject: Reply with quote

Guardian

Joined: 08 Jul 2010
Posts: 939
Location: Illinois, USA

I can run similar logic on a proprietary Java MQ monitor that is running on Linux x86 and executing PCF commands against a z/OS queue manager with a CCSID of 37, and this works fine with getting the queue names back in ASCII without having to explicitly set any CCSID in the code. Below is a snippet. In my snippet, this.agent is a PCFMessageAgent.

Have you opened a PMR with IBM for help here?

Code:

        private void processQDepthGtX(MQAlerts mqAlerts) {
           boolean goodResult = false;
          
           while (!goodResult && this.qMgr != null)
           {
              try {
                 PCFMessage pcfCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_Q_STATUS);
                 pcfCmd.addParameter(MQConstants.MQCA_Q_NAME, "*");
                 pcfCmd.addParameter(MQConstants.MQIACF_Q_STATUS_ATTRS, new int [] {MQConstants.MQCA_Q_NAME,MQConstants.MQIA_CURRENT_Q_DEPTH});
                 PCFMessage[] pcfResponse = this.agent.send(pcfCmd);
                 for (int i=0; i < pcfResponse.length; i++)
                 {
                    Object obj = pcfResponse[i].getParameterValue(MQConstants.MQCA_Q_NAME);
                    if (obj != null && obj instanceof String)
                    {
                       String qName = (String) obj;
                       Pattern pattern = Pattern.compile(mqAlerts.objMask);
                       Matcher matcher = pattern.matcher(qName);
                       if (matcher.matches())
                       {
                          obj = pcfResponse[i].getParameterValue(MQConstants.MQIA_CURRENT_Q_DEPTH);
                          if (obj != null && obj instanceof Integer)
                          {
                             int qDepth = ((Integer)obj).intValue();
                             if (qDepth > mqAlerts.qDpthGTX)
                             {
                                MQActiveAlerts mqActiveAlerts = this.mqaaht.get("QDGTX-" + mqAlerts.alertId + "-" + qName);
                                if (mqActiveAlerts == null)
                                {
                                   mqActiveAlerts = new MQActiveAlerts();
                                   mqActiveAlerts.key = "QDGTX-" + mqAlerts.alertId + "-" + qName;
                                   mqActiveAlerts.alertName = "Queue Depth Greater Than " + mqAlerts.qDpthGTX;
                                   mqActiveAlerts.alertType = "QDGTX";
                                   mqActiveAlerts.objName = qName;
                                   mqActiveAlerts.startTimeMillis = System.currentTimeMillis();
                                   mqActiveAlerts.lastTouchTimeMillis = mqActiveAlerts.startTimeMillis;
                                   mqActiveAlerts.delay = mqAlerts.delay;
                                   mqActiveAlerts.ntfyIntv = mqAlerts.ntfyIntv;
                                   mqActiveAlerts.ntfyGpId = mqAlerts.ntfyGpId;
                                   if (mqActiveAlerts.ntfyGpId != 0)
                                          this.buildEmailList(mqActiveAlerts);
                                   this.mqaaht.put("QDGTX-" + mqAlerts.alertId + "-" + qName, mqActiveAlerts);
                                }
                                else
                                {
                                   mqActiveAlerts.lastTouchTimeMillis = System.currentTimeMillis();
                                   mqActiveAlerts.delay = mqAlerts.delay;
                                   mqActiveAlerts.ntfyIntv = mqAlerts.ntfyIntv;
                                   mqActiveAlerts.ntfyGpId = mqAlerts.ntfyGpId;
                                }
                                this.processActiveAlerts(mqActiveAlerts);
                             }
                          }
                       }
                    }
                 }
                
                 goodResult = true;
              } catch (Exception ex) {
                 try { Thread.sleep(MQMonitor.connDelay); } catch (Exception ex2) { }
                 try {this.agent.disconnect();} catch (Exception ex2) {};
                 try {this.qMgr.disconnect();} catch (Exception ex2) {};
                 this.connectMQ();
              }
           }
        }

_________________
Working with MQ since 2010.
Back to top
View user's profile Send private message
souciance
PostPosted: Wed Mar 04, 2020 1:36 pm    Post subject: Reply with quote

Disciple

Joined: 29 Jun 2010
Posts: 169

hughson wrote:
fjb_saper wrote:
What CCSID did you assign to the PCFMessageAgent ?


We can see from the provided code that it has not been explicitly set, which would mean it would default to MQCCSI_Q_MGR which is supposed to pick up the CCSID of the client locale.

fjb_saper wrote:
Try and assign it CCSID 1208 and see if it makes a difference.


In case you don't know how to do this, I think you need:-

Code:
MessageAgent.setCharacterSet(1208)


Cheers
Morag

Thanks for the hint but that method only seems to be available in the java version. There seems to be way to set the character set in the dotnet api, which given that it is 2020 seems somewhat strange.
Back to top
View user's profile Send private message
souciance
PostPosted: Wed Mar 04, 2020 1:40 pm    Post subject: Reply with quote

Disciple

Joined: 29 Jun 2010
Posts: 169

tczielke wrote:
I can run similar logic on a proprietary Java MQ monitor that is running on Linux x86 and executing PCF commands against a z/OS queue manager with a CCSID of 37, and this works fine with getting the queue names back in ASCII without having to explicitly set any CCSID in the code. Below is a snippet. In my snippet, this.agent is a PCFMessageAgent.

Have you opened a PMR with IBM for help here?

Code:

        private void processQDepthGtX(MQAlerts mqAlerts) {
           boolean goodResult = false;
          
           while (!goodResult && this.qMgr != null)
           {
              try {
                 PCFMessage pcfCmd = new PCFMessage(MQConstants.MQCMD_INQUIRE_Q_STATUS);
                 pcfCmd.addParameter(MQConstants.MQCA_Q_NAME, "*");
                 pcfCmd.addParameter(MQConstants.MQIACF_Q_STATUS_ATTRS, new int [] {MQConstants.MQCA_Q_NAME,MQConstants.MQIA_CURRENT_Q_DEPTH});
                 PCFMessage[] pcfResponse = this.agent.send(pcfCmd);
                 for (int i=0; i < pcfResponse.length; i++)
                 {
                    Object obj = pcfResponse[i].getParameterValue(MQConstants.MQCA_Q_NAME);
                    if (obj != null && obj instanceof String)
                    {
                       String qName = (String) obj;
                       Pattern pattern = Pattern.compile(mqAlerts.objMask);
                       Matcher matcher = pattern.matcher(qName);
                       if (matcher.matches())
                       {
                          obj = pcfResponse[i].getParameterValue(MQConstants.MQIA_CURRENT_Q_DEPTH);
                          if (obj != null && obj instanceof Integer)
                          {
                             int qDepth = ((Integer)obj).intValue();
                             if (qDepth > mqAlerts.qDpthGTX)
                             {
                                MQActiveAlerts mqActiveAlerts = this.mqaaht.get("QDGTX-" + mqAlerts.alertId + "-" + qName);
                                if (mqActiveAlerts == null)
                                {
                                   mqActiveAlerts = new MQActiveAlerts();
                                   mqActiveAlerts.key = "QDGTX-" + mqAlerts.alertId + "-" + qName;
                                   mqActiveAlerts.alertName = "Queue Depth Greater Than " + mqAlerts.qDpthGTX;
                                   mqActiveAlerts.alertType = "QDGTX";
                                   mqActiveAlerts.objName = qName;
                                   mqActiveAlerts.startTimeMillis = System.currentTimeMillis();
                                   mqActiveAlerts.lastTouchTimeMillis = mqActiveAlerts.startTimeMillis;
                                   mqActiveAlerts.delay = mqAlerts.delay;
                                   mqActiveAlerts.ntfyIntv = mqAlerts.ntfyIntv;
                                   mqActiveAlerts.ntfyGpId = mqAlerts.ntfyGpId;
                                   if (mqActiveAlerts.ntfyGpId != 0)
                                          this.buildEmailList(mqActiveAlerts);
                                   this.mqaaht.put("QDGTX-" + mqAlerts.alertId + "-" + qName, mqActiveAlerts);
                                }
                                else
                                {
                                   mqActiveAlerts.lastTouchTimeMillis = System.currentTimeMillis();
                                   mqActiveAlerts.delay = mqAlerts.delay;
                                   mqActiveAlerts.ntfyIntv = mqAlerts.ntfyIntv;
                                   mqActiveAlerts.ntfyGpId = mqAlerts.ntfyGpId;
                                }
                                this.processActiveAlerts(mqActiveAlerts);
                             }
                          }
                       }
                    }
                 }
                
                 goodResult = true;
              } catch (Exception ex) {
                 try { Thread.sleep(MQMonitor.connDelay); } catch (Exception ex2) { }
                 try {this.agent.disconnect();} catch (Exception ex2) {};
                 try {this.qMgr.disconnect();} catch (Exception ex2) {};
                 this.connectMQ();
              }
           }
        }


Yup we tried with the Java API and that works fine and it converts without having to set the character set. Unfortunately it doesn't seem like IBM has put the same methods available in the .net api. We were hoping to run a console dotnet core app for some basic admin stuff and not have to revert to java.
Back to top
View user's profile Send private message
tczielke
PostPosted: Wed Mar 04, 2020 2:40 pm    Post subject: Reply with quote

Guardian

Joined: 08 Jul 2010
Posts: 939
Location: Illinois, USA

My apologies. Your code snippet looked so much like Java PCF that I lost track that you were doing this in .NET. I haven't worked with .NET, but I would think the GetStringParameterValue would be responsible for parsing the MQCFST record that actually contains the queue name string and recognizing that the CCSID inside that MQCFST record is one that needs to be converted from EBCDIC to ASCII. So it sounds like a PMR to me, if it is not doing that.

CORRECTION: A PCF application that will take a raw PCF message and parse it (I have a C PCF program that does this) will do a GET with a convert and then the queue manager goes through and converts all the individual PCF records (like MQCFST) accordingly before handing the message to the application. I have a C PCF program that I run on Linux x86 and it can take PCF messages from z/OS and the MQCFST records (strings) are converted properly because of the GET with the convert.
_________________
Working with MQ since 2010.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » IBM MQ API Support » PCF call to get queue name from AS400 machine
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.