MQ

MQ

Join this online group to communicate across IBM product users and experts by sharing advice and best practices with peers and staying up to date regarding product enhancements.

 View Only
Expand all | Collapse all

C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

  • 1.  C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Wed September 06, 2023 02:29 AM

    Hello dear MQ people,

    I was unable to find classes for c# which allow me to read embedded headers from messages, such as MQRFH, MQRFH2, MQDEAD, MQIIH.

    If anyone could point me to a source/documentation, if it exists.

    Kind regards,

    Sebastian



    ------------------------------
    Sebastian Wilk
    ------------------------------


  • 2.  RE: C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Thu September 07, 2023 02:23 PM

    I'm not sure why, but to my knowledge, IBM never implemented the classes of MQCIH, MQIIH, MQDLH, etc. classes in .NET. If you switch to Java then you can make use of them.



    ------------------------------
    Roger Lacroix
    CTO
    Capitalware Inc.
    London ON Canada
    https://capitalware.com
    ------------------------------



  • 3.  RE: C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Tue September 12, 2023 03:09 AM

    That's the thing, we cannot switch unless we build a new application, the existing one is using .NET.

    Thank you for the repsonse.

    Regards



    ------------------------------
    Sebastian Wilk
    ------------------------------



  • 4.  RE: C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Tue September 12, 2023 03:58 AM

    Did you already have a look into the discussion from 2021?

    https://community.ibm.com/community/user/integration/discussion/adding-mqrfh2-headers-to-mqmessage-in-c



    ------------------------------
    Matthias Jungbauer
    ------------------------------



  • 5.  RE: C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Tue September 12, 2023 07:05 PM

    That's the thing, we cannot switch unless we build a new application, the existing one is using .NET.

    Years ago, before IBM decided to create classes in Java for the embedded structures, I had to create my own for MQ Visual Edit.  Since I've converted my code to now use IBM's classes for embedded structures, I thought I would try and convert them to C#. Then I thought, that's dumb - just use ChatGPT. So here is my old Java code converted to C# by ChatGPT.  Note: I do NOT warrant it nor have I tested it. I leave it for you to play around with.

    using System;
    using System.Collections;
    using System.IO;
    using IBM.WMQ; // Assuming you have the IBM MQ .NET library installed

    namespace CapitalWare.MQ.Hdrs
    {
        public class MQRFH2 : MQMessage
        {
            private string _strucID = "RFH ";
            private int _version = MQC.MQRFH_VERSION_2;
            private int _strucLength = MQC.MQRFH_STRUC_LENGTH_FIXED_2;
            private int _encoding = MQC.MQENC_NATIVE;
            private int _CCSID = MQC.MQCCSI_INHERIT;
            private string _format = MQC.MQFMT_STRING;
            private int _flags = 0;
            private string _nameValueData;
            private byte[] _data = new byte[0];
            private int _nameValueCCSID = 1208;
            private byte[] _mcd;
            private byte[] _jms;
            private byte[] _usr;
            private ArrayList _allFolders;

            public MQRFH2(MQMessage msg) : base()
            {
                msg.Seek(0);
                int totalMsgLength = msg.MessageLength;
                int hdrOffset;

                _strucID = msg.ReadString(4);
                _version = msg.ReadInt32();
                _strucLength = msg.ReadInt32();
                _encoding = msg.ReadInt32();
                _CCSID = msg.ReadInt32();
                _format = msg.ReadString(8);
                _flags = msg.ReadInt32();
                _nameValueCCSID = msg.ReadInt32();

                _allFolders = new ArrayList();

                if (_strucLength > 36) // min. header size
                {
                    FindAllFolders(msg);
                }

                hdrOffset = msg.DataOffset;

                if (hdrOffset < totalMsgLength)
                {
                    int dataLen = totalMsgLength - hdrOffset;
                    _data = new byte[dataLen];
                    msg.ReadFully(_data);
                }
                else
                {
                    _data = new byte[0];
                }
            }

            private void FindAllFolders(MQMessage msg)
            {
                bool moreFolders = true;
                int hdrOffset;
                int folderLen;

                while (moreFolders)
                {
                    folderLen = msg.ReadInt32();
                    byte[] b = new byte[folderLen];
                    msg.ReadFully(b);

                    if (b.Length >= 5)
                    {
                        string l1 = (b[1] + "").ToLower();
                        string l2 = (b[2] + "").ToLower();
                        string l3 = (b[3] + "").ToLower();

                        if ((b[0] == '<') && ("m".Equals(l1)) && ("c".Equals(l2)) && ("d".Equals(l3)) && (b[4] == '>'))
                            _mcd = b;
                        else if ((b[0] == '<') && ("j".Equals(l1)) && ("m".Equals(l2)) && ("s".Equals(l3)) && (b[4] == '>'))
                            _jms = b;
                        else if ((b[0] == '<') && ("u".Equals(l1)) && ("s".Equals(l2)) && ("r".Equals(l3)) && (b[4] == '>'))
                            _usr = b;
                        else
                            _allFolders.Add(b);
                    }
                    else
                        _allFolders.Add(b);

                    hdrOffset = msg.DataOffset;

                    if (hdrOffset >= _strucLength)
                    {
                        moreFolders = false;
                    }
                }
            }

            public MQMessage GetMsg(string qName)
            {
                int x = 0, structLen = 0;
                int mcdLen, jmsLen, usrLen;
                string tempMcdFolder = "";
                string tempJmsFolder = "";
                string tempUsrFolder = "";

                // clear message contents
                ClearMessage();

                // Handle MCD Folder
                if (_mcd == null)
                    tempMcdFolder = "<mcd><Msd>jms_text</Msd></mcd> ";
                else
                    tempMcdFolder = System.Text.Encoding.ASCII.GetString(_mcd);

                mcdLen = tempMcdFolder.Length;

                // Handle JMS Folder
                if (_jms == null)
                    tempJmsFolder = "<jms><Dst>queue:///" + qName + "</Dst><Pri>0</Pri></jms>";
                else
                    tempJmsFolder = System.Text.Encoding.ASCII.GetString(_jms);

                x = (tempJmsFolder.Length + 3) / 4;
                jmsLen = x * 4;
                tempJmsFolder = StringUtils.PadRight(tempJmsFolder, " ", jmsLen);

                // Handle USR Folder
                if (_usr == null)
                {
                    tempUsrFolder = "";
                    usrLen = 0;
                }
                else
                {
                    tempUsrFolder = System.Text.Encoding.ASCII.GetString(_usr);
                    x = (tempUsrFolder.Length + 3) / 4;
                    usrLen = x * 4;
                    tempUsrFolder = StringUtils.PadRight(tempUsrFolder, " ", usrLen);
                }

                // Calculate total header length
                structLen = MQC.MQRFH_STRUC_LENGTH_FIXED_2 + 4 + mcdLen + 4 + jmsLen;

                if (_usr != null)
                {
                    structLen += 4 + tempUsrFolder.Length;
                }

                WriteString("RFH "); // 'RFH '
                WriteInt(MQC.MQRFH_VERSION_2);
                WriteInt(structLen);
                WriteInt(_encoding);
                WriteInt(_CCSID);
                WriteString(_format);
                WriteInt(_flags);
                WriteInt(_nameValueCCSID);

                WriteInt(mcdLen);
                WriteString(tempMcdFolder);

                WriteInt(tempJmsFolder.Length);
                WriteString(tempJmsFolder);

                if (_usr != null)
                {
                    WriteInt(tempUsrFolder.Length);
                    WriteString(tempUsrFolder);
                }

                Write(_data);

                // MQMD header
                MessageId = MQC.MQMI_NONE;
                CorrelationId = MQC.MQCI_NONE;
                Format = MQC.MQFMT_RF_HEADER_2;

                return this;
            }

            public ArrayList GetAllFolders()
            {
                return _allFolders;
            }

            public int GetCCSID()
            {
                return _CCSID;
            }

            public byte[] GetData()
            {
                return _data;
            }

            public int GetEncoding()
            {
                return _encoding;
            }

            public int GetFlags()
            {
                return _flags;
            }

            public string GetFormat()
            {
                return _format;
            }

            public string GetNameValueData()
            {
                return _nameValueData;
            }

            public int GetNameValueCCSID()
            {
                return _nameValueCCSID;
            }

            public string GetStrucID()
            {
                return _strucID;
            }

            public int GetStrucLength()
            {
                return _strucLength;
            }

            public int GetVersion()
            {
                return _version;
            }

            public void SetAllFolders(ArrayList allFolders)
            {
                _allFolders = allFolders;
            }

            public void SetCCSID(int i)
            {
                _CCSID = i;
            }

            public void SetData(byte[] data)
            {
                _data = data;
            }

            public void SetEncoding(int i)
            {
                _encoding = i;
            }

            public void SetFlags(int i)
            {
                _flags = i;
            }

            public void SetFormat(string s)
            {
                _format = s;
            }

            public void SetNameValueData(string nameValueData)
            {
                _nameValueData = nameValueData;
            }

            public void SetNameValueCCSID(int nameValueCCSID)
            {
                _nameValueCCSID = nameValueCCSID;
            }
        }
    }

    Note: MQRFH2 is the hardest embedded structure to create. If this works for you, then I can get ChatGPT to convert the other 4 embedded structures: MQDLH, MQCIH, MQIIH & MQXQH classes too.

    later

    Roger



    ------------------------------
    Roger Lacroix
    CTO
    Capitalware Inc.
    London ON Canada
    https://capitalware.com
    ------------------------------



  • 6.  RE: C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Wed September 13, 2023 04:28 AM

    Hey Roger,

    thank you for the code! I implemented a solution already, but I'll have a look at your code and play around with it!

    Cheers



    ------------------------------
    Sebastian Wilk
    ------------------------------



  • 7.  RE: C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Thu January 02, 2025 02:39 PM

    Hi Sebastian,

    i am having the same issues. I need an implementation for writing various properties in the usr folder and setting the RFH2 Header accordingly.

    Could you Provide an excerpt of the header-implementation in this forum or could you be so kind to contact me via: markus.gerstner@oekb.at

    best regards

    Markus



    ------------------------------
    Markus Gerstner
    ------------------------------



  • 8.  RE: C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Fri January 03, 2025 08:45 AM

    You do NOT need any RFH2 parsing or manipulation to set properties. Use the various setProperty methods instead. It ends up with the same result.



    ------------------------------
    Mark Taylor
    Winchester
    ------------------------------



  • 9.  RE: C# classes to browse embedded Header from MQ Message such as MQRFH, MQDEAD etc

    Posted Fri January 03, 2025 03:34 PM

    Hi Mark,

    Thank you for clarification.

    Indeed with the help of Roger's code-example i managed to create a working solution.

    Many Thanks to you both.

    i appreciate this help alot.

    kind regards markus



    ------------------------------
    Markus Gerstner
    ------------------------------