JMS BytesMessage for sending multiple documents - jms

I have a requirement for a batch job that should send out emails.However I have to break it out in such a fashion that I need to handover the email details to another system via messaging which will then read the messages placed and send out emails leisurely.
My emails have attachments.How do I achieve this? There could be multiple attachments for a given email.
I read about bytes message but how do I use it for multiple attachments for a given email message?
Any thoughts about this?

You could send one JMS message containing email details (from, to list, subject, text), and after that send attachments as JMS bytes message, each attachment message with the same custom identifier.
Sender side
// create JMS Bytes message with mail content
// MailData class should implement java.io.Serializable)
MailData mailData = new MailData();
// emailID could be GUID or anything else that would uniquely identify mail
mailData.setEmailID(emailID);
mailData.setFrom(from);
mailData.setToList(toList);
mailData.setSubject(subject);
mailData.setText(text);
BytesMessage msg = session.createBytesMessage();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(mailData);
out.close();
bos.close();
msg.writeBytes(bos.toByteArray());
producer.send(msg);
// for the sake of simplicity, object attachment contains attachment name, MIME type
// and value as byte array
for(Attachment att : attachmentList) {
BytesMessage msgAtt = session.createBytesMessage();
// emailID
msgAtt.setStringProperty("emailId", emailID);
msgAtt.setStringProperty("fileName", att.getAttachmentName());
msgAtt.setStringProperty("mimeType", att.getMimeType());
// set bytes message payload to attachment content
msgAtt.writeBytes(att.getValue());
producer.send(msgAtt);
}
Receiver side
BytesMessage bytesMessage = (BytesMessage) message;
byte[] bytes = new byte[(int) bytesMessage.getBodyLength()];
bytesMessage.readBytes(bytes);
ByteArrayInputStream bis = new ByteArrayInputStream(bytesMessage);
ObjectInputStream in = new ObjectInputStream(bis);
MailData mailData = (MailData) in.readObject();
in.close();
bis.close();
// get data from queue with the same emailID
MessageConsumer consumer = session.createConsumer(queue, "emailID='"
+ mailData.getEmailID() + "'");
connection.start();
Message attMsg = null;
while((attMsg = consumer.receiveNoWait()) != null) {
String fileName = attMsg.getStringProperty("fileName");
String mimeType = att.getStringProperty("mimeType");
BytesMessage bytesMessage = (BytesMessage) attMsg;
byte[] attachmentValue = new byte[(int) bytesMessage.getBodyLength()];
bytesMessage.readBytes(attachmentValue);
}

Related

MQHeaderList size is 0, but reading a specific MQRFH2 works

I am wring custom java code to read messages from Websphere MQ (version 8) and read all the headers from the MQ message.
When I use the MQHeaderList to parse all the headers the list size is 0:
MQMessage message = new MQMessage();
queue.get(message, getOptions);
DataInput in = new DataInputStream (new ByteArrayInputStream (b));
MQHeaderList headersfoundlist = null;
headersfoundlist = new MQHeaderList (in);
System.out.println("headersfoundlist size: " + headersfoundlist.size());
However, I read only a specific MQRFH2 it works
MQMessage message = new MQMessage();
queue.get(message, getOptions);
DataInput in = new DataInputStream (new ByteArrayInputStream (b));
MQRFH2 rfh2 = new MQRFH2(in);
Element usrfolder = rfh2.getFolder("usr", false);
System.out.println("usr folder" + usrfolder);
How can I parse all the headers of the MQ Message?
DataInput in = new DataInputStream (new ByteArrayInputStream (b));
What's that about? Not sure why you want to do that.
It should just be:
MQMessage message = new MQMessage();
queue.get(message, getOptions);
MQHeaderList headersfoundlist = new MQHeaderList(message);
System.out.println("headersfoundlist size: " + headersfoundlist.size());
Read more here.
Update:
#anshu's comment about it not working, well, I've always found MQHeaderList class to be very buggy. Hence, that is why I don't use it.
Also, 99.99% messages in MQ will only ever have 1 embedded MQ header (i.e. MQRFH2). Note: A JMS message == MQRFH2 message. The only case where you will find 2 embedded MQ headers are for messages on the Dead Letter Queue.
i.e.
{MQDLH}{MQRFH2}{message payload}
Is there a real need for your application to process multiple embedded MQ headers? Is your application putting/getting JMS messages (aka MQRFH2 messages)?
If so then you should do something like the following:
queue.get(receiveMsg, gmo);
if (CMQC.MQFMT_RF_HEADER_2.equals(receiveMsg.format))
{
receiveMsg.seek(0);
MQRFH2 rfh2 = new MQRFH2(receiveMsg);
int strucLen = rfh2.getStrucLength();
int encoding = rfh2.getEncoding();
int CCSID = rfh2.getCodedCharSetId();
String format= rfh2.getFormat();
int flags = rfh2.getFlags();
int nameValueCCSID = rfh2.getNameValueCCSID();
String[] folderStrings = rfh2.getFolderStrings();
for (String folder : folderStrings)
System.out.println.logger("Folder: "+folder);
if (CMQC.MQFMT_STRING.equals(format))
{
String msgStr = receiveMsg.readStringOfByteLength(receiveMsg.getDataLength());
System.out.println.logger("Data: "+msgStr);
}
else if (CMQC.MQFMT_NONE.equals(format))
{
byte[] b = new byte[receiveMsg.getDataLength()];
receiveMsg.readFully(b);
System.out.println.logger("Data: "+new String(b));
}
}
else if ( (CMQC.MQFMT_STRING.equals(receiveMsg.format)) ||
(CMQC.MQFMT_NONE.equals(receiveMsg.format)) )
{
Enumeration<String> props = receiveMsg.getPropertyNames("%");
if (props != null)
{
System.out.println.logger("Named Properties:");
while (props.hasMoreElements())
{
String propName = props.nextElement();
Object o = receiveMsg.getObjectProperty(propName);
System.out.println.logger(" Name="+propName+" : Value="+o);
}
}
if (CMQC.MQFMT_STRING.equals(receiveMsg.format))
{
String msgStr = receiveMsg.readStringOfByteLength(receiveMsg.getMessageLength());
System.out.println.logger("Data: "+msgStr);
}
else
{
byte[] b = new byte[receiveMsg.getMessageLength()];
receiveMsg.readFully(b);
System.out.println.logger("Data: "+new String(b));
}
}
else
{
byte[] b = new byte[receiveMsg.getMessageLength()];
receiveMsg.readFully(b);
System.out.println.logger("Data: "+new String(b));
}
I found the mistake in my code. I have a few more steps before reading the headers. It was moving the cursor in message buffer to the end.
I added message.setDataOffset(0); before reading headers and it worked.

How to include and send image in whats app message using chat api

My requirement is to send image as a whats app message, how can i achieve it, below is my code and i'm using chat api.
message = message.Replace("#", "\n");
message = "https://upload.wikimedia.org/wikipedia/ru/3/33/NatureCover2001.jpg";
string param = "phone=91" + phonenumber + "&body=" + message + "&filename=cover.jpg";
byte[] buffer = System.Text.Encoding.ASCII.GetBytes(param);
HttpWebRequest WebReq = (HttpWebRequest)WebRequest.Create("https://eu9.chat-api.com/instance7102/message?token=i8ra4a0zlfxwh90b");
WebReq.Method = "POST";
WebReq.ContentType = "application/x-www-form-urlencoded";
WebReq.ContentLength = buffer.Length;
Stream PostData = WebReq.GetRequestStream();
PostData.Write(buffer, 0, buffer.Length);
PostData.Close();
HttpWebResponse WebResp = (HttpWebResponse)WebReq.GetResponse();
Stream Answer = WebResp.GetResponseStream();
StreamReader _Answer = new StreamReader(Answer);
string response = _Answer.ReadToEnd();
return response;

Spring Framework, get incoming emails with attachments using IMAP

Using this link, I could not figure out how to get incoming emails with attachments. For example, the mail foo#bar.com receives a letter to which the baz.csv file is attached. How to read the contents of a file?Thank you.
Using java mail platform, you can get attachments of an email:
Multipart multipart = (Multipart) message.getContent();
List<byte[]> attachments = new ArrayList<>();
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = multipart.getBodyPart(i);
if (Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()) && bodyPart.getFileName()!=null) {
InputStream is = bodyPart.getInputStream();
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int bytesRead;
while ((bytesRead = is.read(buf)) != -1) {
os.write(buf, 0, bytesRead);
}
os.close();
attachments.add(os.toByteArray());
}
}
message is an object of type javax.mail.Message.
Now, you have a list of byte[] that each one is one of your mail attachment. You can convert byte[] to File easily.

Not able to construct httpmessage for push notification in windows phone 7

I am trying to construct the httpmessage for sending push notification(toast type), but it doesn't recognize methods in the below code. I have this code in Class Library.
Add method in sendNotificationRequest.Headers.Add("X-NotificationClass", "2");
Content Length in sendNotificationRequest.ContentLength = notificationMessage.Length;
GetRequestStream in Stream requestStream = sendNotificationRequest.GetRequestStream()
GetResponse in HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(channel.ChannelUri.ToString());
sendNotificationRequest.Method = "POST";
//Indicate that you'll send toast notifications!
sendNotificationRequest.ContentType = "text/xml";
sendNotificationRequest.Headers = new WebHeaderCollection();
sendNotificationRequest.Headers.Add("X-NotificationClass", "2");
if (string.IsNullOrEmpty(txtMessage.Text)) return;
//Create xml envelope
string data = "X-WindowsPhone-Target: toast\r\n\r\n" +
"<?xml version='1.0' encoding='utf-8'?>" +
"<wp:Notification xmlns:wp='WPNotification'>" +
"<wp:Toast>" +
"<wp:Text1>{0}</wp:Text1>" +
"</wp:Toast>" +
"</wp:Notification>";
//Wrap custom data into envelope
string message = string.Format(data, txtMessage.Text);
byte[] notificationMessage = Encoding.Default.GetBytes(message);
// Set Content Length
sendNotificationRequest.ContentLength = notificationMessage.Length;
//Push data to stream
using (Stream requestStream = sendNotificationRequest.GetRequestStream())
{
requestStream.Write(notificationMessage, 0, notificationMessage.Length);
}
//Get reponse for message sending
HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
string notificationStatus = response.Headers["X-NotificationStatus"];
string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];
Got it worked after moving the code to WCF project.

MQMessage deos not send whole message

I am fairly new to MQMessage broker. In my project, I want to send an xml message. Every thing is ok but when message get larger than 500 bytes, My code send broken message to the Queue. what I am doing is
//queueManager has been initialized in the class constructor and connected to a channel.
public MQResponse WriteMsg(string QueueName, string strInputMsg)
{
MQResponse response = new MQResponse();
try
{
queue = queueManager.AccessQueue(QueueName,
MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING );
queueMessage = new MQMessage();
queueMessage.DataOffset = 0;
//queueMessage.MessageLength = 2000000;
queueMessage.ResizeBuffer(6 * strInputMsg.Length);
queueMessage.WriteString(strInputMsg);
queueMessage.Format = MQC.MQFMT_STRING;
queuePutMessageOptions = new MQPutMessageOptions();
queue.Put(queueMessage, queuePutMessageOptions);
response.Message = "Message sent to the queue successfully";
response.Status=MQResponseStatus.WriteSuccessful;
}
catch (MQException MQexp)
{
response.Message = "Exception: " + MQexp.Message;
response.Status=MQResponseStatus.WriteFail;
response.CatchedException=MQexp;
}
catch (Exception exp)
{
response.Message = "Exception: " + exp.Message;
response.Status=MQResponseStatus.WriteFail;
response.CatchedException=exp;
}
return response;
}
I guess queueMessage should be initialized correctly so that we able to send whole message.
First of all how did you determine that the message is broken? Did you try to receive the sent message and compared with the original message or you viewed the message using MQExplorer or some other means. MQExplorer by default displays first 1000 bytes of the message. To view more you need to change the Max data bytes displayed setting in Window/Preferences/Messages panel.
WebSphere MQ can handle messages of size as large as 100 MB.
Regarding your code snippet above: The few lines of code is enough to build and send a message.
queueMessage = new MQMessage();
queueMessage.Format = MQC.MQFMT_STRING;
queueMessage.WriteString(strInputMsg);
queuePutMessageOptions = new MQPutMessageOptions();
queue.Put(queueMessage, queuePutMessageOptions);

Resources