0

I'm reading messages from IBM WMQ in C#. I need to read the message Id. Currently when attempting to read it, it's not readable.

enter image description here

I think it may be because the messages contain RFH2 headers and I need to handle them before consuming the messages however I'm not sure how to exactly do this?

C# code:

try
{
    MQMessage queueMessage;
    MQGetMessageOptions queueGetMessageOptions;
    string message = string.Empty;
    queueMessage = new MQMessage();
    queueMessage.Format = MQC.MQFMT_STRING;
    queueGetMessageOptions = new MQGetMessageOptions { WaitInterval = _appSettings.MqProperties.WaitIntervalMs };
    queueGetMessageOptions.Options |= MQC.MQGMO_WAIT;
    queueGetMessageOptions.Options |= MQC.MQGMO_SYNCPOINT;
    queue.Get(queueMessage, queueGetMessageOptions);

    if (queueMessage.Format.CompareTo(MQC.MQFMT_STRING) == 0)
    {
        if (queueMessage.MessageLength > 0)
        {
            message = queueMessage.ReadString(queueMessage.MessageLength);
            _logger.LogInfo(LogStatus.InProgress, $"Message: {message}.");
            _logger.LogInfo(LogStatus.InProgress, $"Message ID length: {queueMessage.MessageId.Length}.MessageId: {Encoding.UTF8.GetString(queueMessage.MessageId, 0, queueMessage.MessageId.Length)}");
            _logger.LogInfo(LogStatus.InProgress, $"Message ID length: {queueMessage.MessageId.Length}.MessageId: {Encoding.ASCII.GetString(queueMessage.MessageId, 0, queueMessage.MessageId.Length)}");
            _logger.LogInfo(LogStatus.InProgress, $"Message ID length: {queueMessage.MessageId.Length}.MessageId: {Encoding.Default.GetString(queueMessage.MessageId, 0, queueMessage.MessageId.Length)}");
            _logger.LogInfo(LogStatus.InProgress, $"Message ID length: {queueMessage.MessageId.Length}.MessageId: {Encoding.Unicode.GetString(queueMessage.MessageId, 0, queueMessage.MessageId.Length)}");
            _logger.LogInfo(LogStatus.InProgress, $"Message ID length: {queueMessage.MessageId.Length}.MessageId: {Encoding.Latin1.GetString(queueMessage.MessageId, 0, queueMessage.MessageId.Length)}");
            _logger.LogInfo(LogStatus.InProgress, $"Message ID length: {queueMessage.MessageId.Length}.MessageId: {Encoding.UTF32.GetString(queueMessage.MessageId, 0, queueMessage.MessageId.Length)}");
            _logger.LogInfo(LogStatus.InProgress, $"Message ID length: {queueMessage.MessageId.Length}.MessageId: {Encoding.BigEndianUnicode.GetString(queueMessage.MessageId, 0, queueMessage.MessageId.Length)}");

            await _messageConsumer.ConsumeMessage(message, Encoding.UTF8.GetString(queueMessage.MessageId, 0, queueMessage.MessageId.Length));
        }
        else
        {
            _logger.LogInfo(LogStatus.InProgress, $"INVALID MESSAGE. Message Length {queueMessage.MessageLength}");
        }
    }
    else
    {
        _logger.LogInfo(LogStatus.InProgress, $"UNRECOGNISED MESSAGE FORMAT");
    }
}
catch (MQException mqex)
{
    if (mqex.Reason == MQC.MQRC_NO_MSG_AVAILABLE)
    {
        _logConstants.InitializeCorrelationIdAndKeysForEachRun();
        _logConstants.InitializeLoggerKeys(null, null);
        _logger.LogInfo(LogStatus.InProgress, $"{mqex.ReasonCode} {mqex.Message} CurrentDepth: {queue.CurrentDepth}. MaximumDepth {queue.MaximumDepth}");
    }
    else if (mqex.Reason == MQC.MQRC_Q_MGR_STOPPING)
    {
        _logger.LogError(
            LogErrors.ErrorWhileConsumingMsgFromIBMMQ,
            LogStatus.Failed,
            "IBM MQ Consumer Error",
            $" Error in Consuming the message from MQ. Making the thread sleep for one minute");

        await Task.Delay(60000, cancellationToken);
    }
    else
    {
        _logger.LogError(
            LogErrors.ErrorWhileConsumingMsgFromIBMMQ,
            LogStatus.Failed,
            "IBM MQ Consumer Error",
            $" Error in Consuming the Message from MQ {mqex.Reason} {mqex.Message} {mqex.StackTrace}");

        await Task.Delay(60000, cancellationToken);
        queueManager = null;
        queue = null;
    }
}

Update:

Following the comments on here, I tried the following:

_logger.LogInfo(LogStatus.InProgress, $"Message ID length: {queueMessage.MessageId.Length}.MessageId: {queueMessage.MessageId.ByteArrayToString}");

public static string ByteArrayToString(this byte[] ba)
{
    return BitConverter.ToString(ba).Replace("-", "");
}

However that outputs:

Message ID length: 24.MessageId: System.Func`1[System.String]
Bhav
  • 1,957
  • 7
  • 33
  • 66
  • 2
    This looks like a normal IBM MQ MessageId to me. The 24 bytes contain non-printable characters. You should hex-encode the MessageId before printing it. – Daniel Steinmann Jul 08 '22 at 09:31
  • 1
    "I need to read the message Id. Currently when attempting to read it, it's not readable." MessageId is an array of 24 bytes long, contaning hex characters. You have to convert them to hex string. Sample code here on how to convert. https://stackoverflow.com/questions/311165/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-and-vice-versa – Shashi Jul 08 '22 at 09:31
  • @Shashi I've updated the op with my attempt and current output. – Bhav Jul 11 '22 at 13:12
  • @DanielSteinmann I've updated the op and the new output. – Bhav Jul 11 '22 at 13:21
  • I am not well versed with this style of programming in .NET. But simply calling ByteArrayToString(message.MessageId) should return a hex string. – Shashi Jul 12 '22 at 04:29
  • 1
    I am also not fluent with .NET. Looks like you see a small part of a stack trace. I would use directly the [Convert.ToHexString](https://learn.microsoft.com/en-us/dotnet/api/system.convert.tohexstring) function. – Daniel Steinmann Jul 12 '22 at 06:47
  • @DanielSteinmann Thanks. That worked. Please can you post an answer. – Bhav Jul 12 '22 at 08:45

1 Answers1

2

This looks like a normal IBM MQ MessageId. The 24 bytes contain non-printable characters. You should Convert.ToHexString the MessageId before printing it:

string messageIdHex = Convert.ToHexString(queueMessage.MessageId);
// Now you can print this hex-encoded IBM MQ Message ID
Daniel Steinmann
  • 2,119
  • 2
  • 15
  • 25