I am using .net client to post mesages to MQ server which is hosted on Unix. It is added some control character before the messages. Like below
**^CD**<request>
The Queue connection is through SSL Table channel connection.
The code i am using is
MQQueueManager queueManager = new MQQueueManager ;
int openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_BIND_NOT_FIXED + MQC.MQOO_FAIL_IF_QUIESCING;
MQQueue Queue = queueManager.AccessQueue("TestQueue", openOptions);
MQMessage queueMessage = new MQMessage();
queueMessage.WriteUTF("<request>");
MQPutMessageOptions MessageOptions = new MQPutMessageOptions();
Queue.Put(queueMessage, MessageOptions);
please let me know what cause this special chars
From IBM's own doco on WriteUTF:
This method takes an ActiveX string and writes it into the message data buffer at the current position in UTF format. The data written consists of a 2-byte length followed by the character data. DataOffset is incremented by the length of the string if the method succeeds.
If you don't want that length, consider using WriteString instead (follow that doco link above and just go up a couple of lines in the navigation pane)..
Related
Regarding: “Sending response back to the out/reply queue.”
There is a requirement to send the response back to a different queue (reply queue).
While sending the response, we have to use the correlation and message id from the request message and pass it to the reply queue as header. I suspect the format of correlation/message id is wrong.
While reading the message, the correlation id and message id format are as below:
MessageId = “ID:616365323063633033343361313165646139306638346264”
CorrelationId = “ID:36626161303030305f322020202020202020202020202020”
While sending the back to out/reply queue, we are passing these ids as below:
ITextMessage txtReplyMessage = sessionOut.CreateTextMessage();
txtReplyMessage.JMSMessageID = “616365323063633033343361313165646139306638346264”;
txtReplyMessage.JMSCorrelationID = “36626161303030305f322020202020202020202020202020”;
txtReplyMessage.Text = sentMessage.Contents;
txtReplyMessage.JMSDeliveryMode = DeliveryMode.NonPersistent;
txtReplyMessage.JMSPriority = sentMessage.Priority;
messagePoducerOut.Send(txtReplyMessage);
Please note:
With the XMS.NET library, we need to pass the correlation and message id in string format as per shown above
With MQ API’s (which we were using earlier) passing the correlation and message ids we use to send in bytes format like below:
MQMessage queueMessage = new MQMessage();
string[] parms = document.name.Split('-');
queueMessage.MessageId = StringToByte(parms[1]);
queueMessage.CorrelationId = StringToByte(parms[2]);
queueMessage.CharacterSet = 1208;
queueMessage.Encoding = MQC.MQENC_NATIVE;
queueMessage.Persistence = 0; // Do not persist the replay message.
queueMessage.Format = "MQSTR ";
queueMessage.WriteString(document.contents);
queueOut.Put(queueMessage);
queueManagerOut.Commit();
Please help to troubleshoot the problem.
Troubleshooting is a bit difficult because you haven’t clearly specified the trouble (is there an exception, or is the message just not be correlated successfully?).
In your code you have missed to add the “ID:” prefix. However, to address the requirements, you should not need to bother too much about what is in this field, because you simply need to copy one value to the other:
txtReplyMessage.JMSCorrelationID = txtRequestMessage.JMSMessageID
A bit unclear what the issue is. Are you able to run the provided examples in the MQ tools/examples? This approach uses tmp queues(AMQ.*) as JMSReplyTo
Start the "server" application first.
Request/Response Client: "SimpleRequestor"
Request/Response Server: "SimpleRequestorServer"
You can find the exmaples at the default install location(win):
"C:\Program Files\IBM\MQ\tools\dotnet\samples\cs\xms\simple\wmq"
The "SimpleMessageSelector" will show how to use the selector pattern.
Note the format on the selector: "JMSCorrelationID = '00010203040506070809'"
IBM MQ SELECTOR
I have recently started working with IBM MQ (v7.5) and currently working on a bridge like service for 2 way data transfer between MQ & another REST service I have.
By using standard APIs I am able to read and write messages without any issue.
But the problem I am facing came when I started setting up MQRFH2 header to my messages. I must be doing some mistake while writing data with header because every time I am getting "End of file exception ('MQMessage.seek()')." error while reading those messages.
This is my code snippet while putting the message into MQ:
//Constructing message
MQMessage sendmsg = new MQMessage();
sendmsg.characterSet = 1208;
sendmsg.format = MQC.MQFMT_STRING;
sendmsg.feedback = MQC.MQFB_NONE;
sendmsg.messageType = MQC.MQMT_DATAGRAM;
sendmsg.replyToQueueName = outputBackupQueueName;
sendmsg.replyToQueueManagerName = queueManager;
//Constructing header
MQRFH2 rfh2 = new MQRFH2();
rfh2.setEncoding(MQConstants.MQENC_NATIVE);
rfh2.setCodedCharSetId(MQConstants.MQCCSI_INHERIT);
rfh2.setFormat(MQConstants.MQFMT_STRING);
rfh2.setNameValueCCSID(1208);
//adding message to header
rfh2.write(sendmsg);
//payload is the actual data which we want to send
byte[] messageBytes = payload.getBytes("UTF-8");
sendmsg.write(messageBytes);
//putting message to MQ
MQPutMessageOptions outputMsgOpt = new MQPutMessageOptions();
outputMsgOpt.options = MQConstants.MQPMO_FAIL_IF_QUIESCING |
MQConstants.MQPMO_DEFAULT_CONTEXT |
MQConstants.MQPMO_SYNCPOINT;
outputQueue.put(sendmsg, outputMsgOpt);
queueManager.commit();
And this is how I am trying to retrieve it later:
MQMessage incomingMessage = new MQMessage();
byte[] incomingMessageId = incomingMessage.messageId;
MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQGMO_FAIL_IF_QUIESCING |
MQConstants.MQGMO_CONVERT |
MQConstants.MQGMO_SYNCPOINT |
MQConstants.MQGMO_LOGICAL_ORDER |
MQConstants.MQGMO_ALL_MSGS_AVAILABLE |
MQConstants.MQGMO_WAIT;
inputQueue.get(incomingMessage, gmo);
MQRFH2 myRfh2 = new MQRFH2(incomingMessage); //this statement throws error with headers
Complete error message is:
com.ibm.mq.headers.MQDataException: MQJE001: Completion Code '2', Reason '2195'.
at com.ibm.mq.headers.MQDataException.getMQDataException(MQDataException.java:317)
at com.ibm.mq.headers.internal.Header.read(Header.java:620)
at com.ibm.mq.headers.MQRFH2.<init>(MQRFH2.java:113)
at com.simility.util.MQRfh2HeaderHelper.getMsgByteArray(MQRfh2HeaderHelper.java:16)
at com.simility.mq.SimilityMQBridge.main(SimilityMQBridge.java:182)
Caused by: com.ibm.mq.headers.MQDataException: MQJE001: Completion Code '2', Reason '6114'.
at com.ibm.mq.headers.MQDataException.getMQDataException(MQDataException.java:314)
at com.ibm.mq.headers.MQRFH2.read(MQRFH2.java:184)
at com.ibm.mq.headers.internal.Header.read(Header.java:639)
at com.ibm.mq.headers.internal.Header.read(Header.java:617)
... 3 more
Caused by: java.io.EOFException: MQJE086: End of file exception ('MQMessage.seek()').
at com.ibm.mq.MQMessage.seek(MQMessage.java:716)
at com.ibm.mq.headers.internal.store.MQMessageStore.readFrom(MQMessageStore.java:274)
at com.ibm.mq.headers.internal.Header.read(Header.java:661)
at com.ibm.mq.headers.MQRFH2.read(MQRFH2.java:181)
Another thing I verified is message length by "TotalMessageLength", and that matches between reading and writing the messages, but still the failure happens.
Can anyone please help me out or point me in right direction related to adding and retrieving messages with RFH2 header ?
Another thing I verified is message length by "TotalMessageLength",
and that matches between reading and writing the messages, but still
the failure happens.
Does the method "getMessageLength()" of MQMessage return the data length of the payload?
Why don't you try (in the sender):
byte[] messageBytes = payload.getBytes();
If your data is not the same codepage or encoding then let MQ do the work rather than you doing getBytes("UTF-8").
i.e. Set the Encoding and CCSID to what the data is.
rfh2.setEncoding(???);
rfh2.setCodedCharSetId(???);
I am reading large files using the following code and sending the file content over a TCP connection buffer by buffer. At the end of each send the TCP channel adds a CRLF character. I don't want this to appear in the results unless I add it.
final int BUFFER_SIZE = 65536;
long bytesToSkip = 0;
byte[] buffer = new byte[BUFFER_SIZE];
try (RandomAccessFile rand = new RandomAccessFile(new File(requestModel.getFilePath()), "r");
) {
rand.seek(bytesToSkip);
while ((read = rand.read(buffer)) != -1) {
MessageBuilder mb = MessageBuilder.withPayload(buffer).setHeaderIfAbsent(IpHeaders.CONNECTION_ID, connectionId);
outMsgChannel.send(mb.build())
buffer = new byte[BUFFER_SIZE];
}
}
catch(Exceptions ..............
Sample output where new line is added. (Both the buffers are huge. I have mentioned only the lines causing problems at the end of each buffer)
Buffer One contained
A quick brown fox jumps over the lazy dog
A quick brown fox jumps over
the lazy dog
A quick brown fox jumps over the
Buffer Two Contains
lazy dog
If there is no unwanted CRLF then I will not get the issue of single line splitting in to two in output.. I want to have new lines only where the file has.
See the documentation.
TCP is a streaming protocol; this means that some structure has to be provided to data transported over TCP, so the receiver can demarcate the data into discrete messages. Connection factories are configured to use (de)serializers to convert between the message payload and the bits that are sent over TCP. This is accomplished by providing a deserializer and serializer for inbound and outbound messages respectively. A number of standard (de)serializers are provided.
The ByteArrayCrlfSerializer, converts a byte array to a stream of bytes followed by carriage return and linefeed characters (\r\n). This is the default (de)serializer and can be used with telnet as a client, for example.
...
You need some way to know when the message is complete - the underlying network might packetize your message so it is received in chunks.
The ByteArrayRawSerializer adds no characters to the message; it might satisfy your needs. When used on the reading side, it uses the socket EOF to indicate the message is complete.
I have a mail reader class which sets the FetchProfile and later does a msg.getContent.
I want to do both reading of header and content in one call, basically download the full mail in one call. Because I have observed msg.getcontent makes a call to the server to get the body/content , if we can download the full mail in one call, a call to the server can be saved.
Is this possible?
The code is similar to this
inbox.open(Folder.READ_ONLY);
/* Get the messages which is unread in the Inbox */
Message messages[] = inbox.search(new FlagTerm(
new Flags(Flag.SEEN), false));
/* Use a suitable FetchProfile */
FetchProfile fp = new FetchProfile();
fp.add(FetchProfile.Item.ENVELOPE);
fp.add(FetchProfile.Item.CONTENT_INFO);
inbox.fetch(messages, fp);
for (int i = 0; i < messages.length; i++) {
System.out.println("MESSAGE #" + (i + 1) + ":");
Message message = messages[i];
**String content = message.getContent();**
System.out.println("Content : " + content);
}
Appreciate any help.
Thanks and Regards
Raaghu.K
If you want the entire message in one call, and don't need to use any of the features of the IMAP protocol, you have two choices:
Use POP3 instead of IMAP.
Use the Message.writeTo method to write the message content to a file or byte array and process it from there, e.g., using the MimeMessage constructor that takes an InputStream. (This makes a local copy of the entire message.)
I am using IBM Websphere MQ. I have the queue manager and queue name. Now, I want to check whether the queue has any messages in it?
I did not work on this before. Pleas help
Please let me know if you need further information!
Thanks
The below code is .NET / amqmdnet - but you might try and convert this in the meantime until a Java dev sees your post.
To see if there is a message on the queue, without actually taking it off the queue, use MQC.MQOO_BROWSE on the Queue and IBM.WMQ.MQC.MQGMO_BROWSE_FIRST as the option
You'll get MQRC_NO_MSG_AVAILABLE if the queue is empty.
MQMessage queueMessage = new MQMessage();
MQQueueManager queueManager = new MQQueueManager(qmName, channelName, connName);
MQQueuequeue = queueManager.AccessQueue(qName,
MQC.MQOO_BROWSE + MQC.MQOO_FAIL_IF_QUIESCING);
MQGetMessageOptions opt = new MQGetMessageOptions();
opt.Options = IBM.WMQ.MQC.MQGMO_BROWSE_FIRST;
queueMessage.CorrelationId = IBM.WMQ.MQC.MQMI_NONE;
queueMessage.MessageId = IBM.WMQ.MQC.MQMI_NONE;
queue.Get(queueMessage, opt);
String sMessage = queueMessage.ReadString(queueMessage.DataLength);
To peek the next message use IBM.WMQ.MQC.MQGMO_BROWSE_NEXT;
To actually read the message OFF the queue, use MQC.MQOO_INPUT_SHARED on the AccessQueue.
The answer didn't show how to check for MQRC_NO_MSG_AVAILABLE. Here is my solution. If there are better ones please let me know.
try
{
queue.Get(queueMessage, opt);
String sMessage = queueMessage.ReadString(queueMessage.DataLength);
}
catch (MQException err)
{
if (err.ReasonCode.CompareTo(MQC.MQRC_NO_MSG_AVAILABLE) == 0)
return true;
}
For Windows machine
It depends on where your queue manager is.
You could use MQUtilities - ih03 pack - which has rfhUtil.exe (Local Qm) and rfhUtilC.exe (for remote qm)
For Local QM , it is straight forward you need to place appropriate values and hit browse, it will show you Queue Depth.
For Remote QM, Place /TCP/(PortNo) for queue manager name and queue for queue name. Hit browse and you will get to know the queue depth.
For Unix/Ubuntu/Linux versions - There is a product called MQVisualEdit which is similar to this one.