The transaction start monitoring event of an IIB flow with a MQ Input node produces a base64 encoded byte array of the MQ message. Now I would like to write a Java program that reconstructs this byte array so I can read the headers and body.
The base64 MQ messages looks like this:
TUQgIAIAAAAAAAAACAAAAP////8AAAAAEQEAALgEAABNUUhSRjIgIAQAAAABAAAAQU1RIENFTUJSQSAgICAgIKVV+Fslx7YCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENFTUJSQSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhbmllbCAgICAgIBYBBRUAAADiboF1+wHSKOpNUf3pAwAAAAAAAAAAAAALICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICALAAAAMC45XGNvbW1vblxqZGtcYmluXGphdmF3LmV4ZTIwMTgxMTI1MTQzNjEyNDcgICAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAA/////1JGSCAAAAACAAAAvAAAAREAAAS4TVFTVFIgICAAAAAAAAAEuAAAACA8bWNkPjxNc2Q+am1zX3RleHQ8L01zZD48L21jZD4gIAAAAEg8am1zPjxEc3Q+cXVldWU6Ly8vTU9OSTwvRHN0PjxUbXM+MTU0MzE1NjU3MjQ1NjwvVG1zPjxEbHY+MjwvRGx2Pjwvam1zPiAAAAAkPHVzcj48VGhlS2V5PlRoZVZhbHVlPC9UaGVLZXk+PC91c3I+PGZvbz5iYXI8L2Zvbz4=
I made following tests to parse this in Java:
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import javax.xml.bind.DatatypeConverter;
import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Test;
import com.ibm.mq.headers.CCSID;
import com.ibm.mq.headers.MQHeaderList;
import com.ibm.mq.headers.MQMD;
import com.ibm.mq.headers.MQRFH2;
public class MqMsgTest {
@Test
public void allGood() throws Exception {
String msgBase64 = IOUtils.toString(getClass().getResourceAsStream("/mq-msg.base64"), "UTF-8");
byte[] msgBytes = DatatypeConverter.parseBase64Binary(msgBase64);
DataInputStream msgStream = new DataInputStream(new ByteArrayInputStream(msgBytes));
MQMD mqmd = new MQMD(msgStream);
Assert.assertEquals("MQHRF2 ", mqmd.getFormat());
Assert.assertEquals("daniel ", mqmd.getUserIdentifier());
MQRFH2 mqrfh2 = new MQRFH2(msgStream);
Assert.assertEquals("TheValue", mqrfh2.getStringFieldValue("usr", "TheKey"));
String body = IOUtils.toString(msgStream, CCSID.getCodepage(mqrfh2.nextCharacterSet()));
Assert.assertEquals("<foo>bar</foo>", body);
}
@Test
public void doesNotWork() throws Exception {
String msgBase64 = IOUtils.toString(getClass().getResourceAsStream("/mq-msg.base64"), "UTF-8");
byte[] msgBytes = DatatypeConverter.parseBase64Binary(msgBase64);
DataInputStream msgStream = new DataInputStream(new ByteArrayInputStream(msgBytes));
MQHeaderList headers = new MQHeaderList(msgStream, true);
Assert.assertEquals(2, headers.size());
}
}
The allGood()
test parses the headers and body nicely. But it would fail if the message would not contain a RFH2 header. The doesNotWork()
test should parse the headers in a generic way, but it does not work.
How can I parse the base64 encoded MQ message in a flexible way so I have access to the headers and the body?