I have a Jmeter script which follows the following steps
1. registers user
2. Reads email using Mail Reader Sampler which has following script
StringBuilder aggregateResult = new StringBuilder()
prev.getSubResults().each {
aggregateResult.append(it.getResponseDataAsString())
it.getSubResults().each {
aggregateResult.append(it.getResponseDataAsString())
it.getSubResults().each {
aggregateResult.append(it.getResponseDataAsString())
}
}
}
prev.setResponseData(aggregateResult.toString().getBytes())
Then extracts a particular link based on regexp.
As of now, it reads either the latest email or all the unread emails in the server.
Can someone please help me to modify the above script to read the message based on the user email created at step 1? Emails are created like test+1#gmail.com, test+2#gmail.com and so on.
Unfortunately it is not something you can do with Mail Reader Sampler, if you need to get mail(s) only for this or that sender email address you can use JavaMail API which provides filtering using i.e. FromStringTerm class from JSR223 Sampler
Example code:
import javax.mail.Multipart
Properties properties = new Properties()
properties.put('mail.imap.host', 'your mail server host') // i.e. imap.gmail.com
properties.put('mail.imap.port', your mail server port) // i.e. 993
properties.setProperty('mail.imap.socketFactory.class', 'javax.net.ssl.SSLSocketFactory')
properties.setProperty('mail.imap.socketFactory.fallback', 'false')
properties.setProperty('mail.imap.socketFactory.port', 'your_mail_server_port') // i.e. 993
def session = javax.mail.Session.getDefaultInstance(properties)
def store = session.getStore('imap')
store.connect('your username (usually email address)', 'your_password')
def inbox = store.getFolder('INBOX')
inbox.open(javax.mail.Folder.READ_ONLY)
def onlyFromGivenUser = inbox.search(new javax.mail.search.FromStringTerm('your_sender_address')) // i.e. test+1#gmail.com
onlyFromGivenUser.each { message ->
if (message.getContent() instanceof Multipart) {
StringBuilder content = new StringBuilder()
def multipart = (Multipart) message.getContent()
multipart.eachWithIndex { Multipart entry, int i ->
def part = entry.getBodyPart(i)
if (part.isMimeType('text/plain')) {
content.append(part.getContent().toString())
}
}
SampleResult.setResponseData(content.toString(), 'UTF-8')
} else {
SampleResult.setResponseData(message.getContent().toString(), 'UTF-8')
}
}
More information:
Apache Groovy - Why and How You Should Use It
Filter emails by domain using javamail
Not sure if you ever managed, I stepped away from javax.mail.Multipart and have implemented the below code in a JSR223 sampler inside a While Controller, this worked for me.
import javax.mail.Message
import javax.mail.search.RecipientStringTerm
Properties properties = new Properties();
properties.put('mail.imap.host', 'your mail server host') // i.e. imap.gmail.com
properties.put('mail.imap.port', your mail server port) // i.e. 993
properties.setProperty('mail.imap.socketFactory.class', 'javax.net.ssl.SSLSocketFactory')
properties.setProperty('mail.imap.socketFactory.fallback', 'false')
properties.setProperty('mail.imap.socketFactory.port', 'your_mail_server_port') // i.e. 993
def session = javax.mail.Session.getDefaultInstance(properties)
def store = session.getStore('imap')
store.connect('your username (usually email address)', 'your_password')
def inbox = store.getFolder('INBOX');
inbox.open(javax.mail.Folder.READ_ONLY);
def onlyToGivenUser = inbox.search(new RecipientStringTerm(Message.RecipientType.TO,'your_recipient_address')); // i.e. test+1#gmail.com
try {
onlyToGivenUser.each { message ->
ByteArrayOutputStream emailRaw = new ByteArrayOutputStream();
message.writeTo(emailRaw);
SampleResult.setResponseData(emailRaw.toString(), 'UTF-8');
}
} catch (Exception ex) {
log.warn("Something went wrong", ex);
OUT.println("Something went wrong", ex);
throw ex;
}
You probably need additional conditions and not only use the recipients address, in my case the recipient is unique for each iteration
Related
I'm reading messages from an Outlook webmail and getting a list of Messages('javax.mail.Message'). Now I want to forward these Messages to another email address using a java program.
private void sendTestMail(String from, String subject, String sentDate, Object object, Message message)
throws EmailException, Exception {
MultiPartEmail email = new MultiPartEmail();
email.setHostName(forwardHost);
email.addTo(mailRecipients(to));
email.setFrom(emailFrom);
email.setSubject(subject);
email.setMsg("Testing email by sahil.");
EmailAttachment attachment = new EmailAttachment();
attachment.setPath("c:\\sahil\\test.jpg");
attachment.setDisposition(EmailAttachment.ATTACHMENT);
attachment.setDescription("Picture_of_John");
attachment.setName("John.jpg");
email.attach(attachment);
MimeMultipart multiPart = getMimeMultipart(message);
email.addPart(multiPart);
email.send();
}
If I comment below two lines in above code then it works fine.
MimeMultipart multiPart = getMimeMultipart(message);
email.addPart(multiPart);
But with these two line I'm getting exception.
2020-04-20 15:41:44,271 ERROR com.st.ict.ols.service.impl.ReplyToMessageServiceImpl [main] Inner Exception occurred while processing individual message. Error stacktrace is[org.apache.commons.mail.EmailException: Sending the email to the following server failed : smtpapp1.sgp.st.com:25
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1421)
at org.apache.commons.mail.Email.send(Email.java:1448)
at com.st.ict.ols.service.impl.ReplyToMessageServiceImpl.sendTestMail(ReplyToMessageServiceImpl.java:342)
at com.st.ict.ols.service.impl.ReplyToMessageServiceImpl.processMessage(ReplyToMessageServiceImpl.java:167)
at com.st.ict.ols.service.impl.MessageServiceImpl.processMessage(MessageServiceImpl.java:22)
at com.st.ict.ols.OlsMailSenderApplication.run(OlsMailSenderApplication.java:36)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:732)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:716)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:703)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:304)
at com.st.ict.ols.OlsMailSenderApplication.main(OlsMailSenderApplication.java:27)
Caused by: javax.mail.MessagingException: IOException while sending message;
nested exception is:
java.io.IOException: Exception writing Multipart
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1308)
at javax.mail.Transport.send0(Transport.java:255)
at javax.mail.Transport.send(Transport.java:124)
at org.apache.commons.mail.Email.sendMimeMessage(Email.java:1411)
... 10 more
Caused by: java.io.IOException: Exception writing Multipart
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:83)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:884)
at javax.activation.DataHandler.writeTo(DataHandler.java:317)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1652)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:961)
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:553)
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:81)
at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:884)
at javax.activation.DataHandler.writeTo(DataHandler.java:317)
at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1652)
at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1850)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1259)
... 13 more
Caused by: javax.mail.MessagingException: Empty multipart: multipart/mixed;
boundary="----=_Part_1_1176580790.1587377502798"
at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:548)
at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:81)
... 24 more
Code I've written to retrieve MimeMultipart from JavaMailApi's Message object to set in apache common's org.apache.commons.mail.MultiPartEmail Object using attach function.
public MimeMultipart getMimeMultipart(Message message) throws Exception {
Object content = message.getContent();
if (content instanceof String)
return null;
if (content instanceof MimeMultipart) {
MimeMultipart multiPartResult = new MimeMultipart();
MimeMultipart multiPart = (MimeMultipart) content;
List<BodyPart> result = new ArrayList<>();
for (int i = 0; i < multiPart.getCount(); i++) {
BodyPart bodyPart = (BodyPart) multiPart.getBodyPart(i);
result.addAll(getMimeMultipart(bodyPart));
}
for(BodyPart part:result) {
multiPart.addBodyPart(part);
}
return multiPartResult;
}
return null;
}
private List<BodyPart> getMimeMultipart(BodyPart part) throws Exception{
List<BodyPart> result = new ArrayList<>();
Object content = part.getContent();
if (content instanceof InputStream || content instanceof String) {
if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition()) || StringUtils.isNotBlank(part.getFileName())) {
result.add(part);
}
return result;
}
if (content instanceof MimeMultipart) {
MimeMultipart multipart = (MimeMultipart) content;
for (int i = 0; i < multipart.getCount(); i++) {
BodyPart bodyPart = (BodyPart) multipart.getBodyPart(i);
result.addAll(getMimeMultipart(bodyPart));
}
}
return result;
}
I was able to forward email excluding attachments but facing issues forwarding with attachments/inline images.
Please help me with this issue.
I'm able to forward the complete message as an attachment, how to forward the message as it is.
MultiPartEmail email = new MultiPartEmail();
MimeMultipart mp = new MimeMultipart();
MimeBodyPart fmbp = new MimeBodyPart();
fmbp.setContent(message, "message/rfc822");
fmbp.setDisposition(Part.INLINE);
mp.addBodyPart(fmbp);
email.setContent(mp);
or if I use code
MimeMultipart mp = (MimeMultipart) message.getContent();
email.setContent(mp, message.getContentType());
I'm getting forwarded email like this
screenshot of forwarded encoded mail
Here the situation is reading mail from one mail server and sending the same message to another email id, within same application.
To achieve this, I used Java Mail API for both reading and sending.
Make sure to update the properties if you're using different host for both steps.
private void sendMailJavax(Message oldMessage) {
try {
// creating a new message using the older message
MimeMessage message = new MimeMessage((MimeMessage)oldMessage);
// updating properties as per sender Mailing API
message.getSession().getProperties().clear();
message.getSession().getProperties().setProperty("mail.smtp.host", forwardHost);
// setting appropriate headers. // make sure you don't append using .add methods.
message.setFrom(new InternetAddress(emailFrom));
message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setReplyTo(new Address[] { new InternetAddress(replyToEmail)});
Transport.send(message);
System.out.println("Email Sent successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
}
I am new to Akka, Scala.
I have to build a service which sends emails with attachment to emailIds given. I am using Sendgrid as a gateway.
For the attachment I have a file uploaded in S3 of size 28KB.
I have REST service to which I can pass document Id through which I can fetch the document as InputStream. Now this input Stream has to be sent to many email Ids . All this downloading the file is handled by an actor called "attachmentActor" which I am creating below.
Now lets say I have two emailIds which I need to send that attachment to, the problem I am facing is its not sending complete file to both , infact 28KB file gets divided into 16KB and 12KB which are finally sent to emailIds.
so emailId 1 would receive 16KB //it should actually have 28KB
email 2 would receive 12KB //it should actually have 28KB
Following is the code:
class SendgridConsumer{
def receive(request: EmailRequest) = {
val service = Sendgrid(username , password)
val logData = request.logData
var errorMessage = new String
val attachmentRef = system.actorOf(Props[AttachmentRequestConsumer], "attachmentActor")
val future = attachmentRef ? AttachmentRequest(request.documentId.get)
var targetStream = Await.result(future, timeout.duration).asInstanceOf[InputStream]
val results = request.emailContacts.par.map( emailContact => {
val email=postData(new Email(),request , emailContact, targetStream,request.documentName.get)
val sendGridResponse=service.send(email)
}
}
// postData() creates an Email Object
// This is my Attachment Actor
class AttachmentRequestConsumer extends Actor with ActorLogging {
def receive = {
case request:AttachmentRequest => {
log.info(" inside Attachment RequestConsumer with document Id:" + request.documentId)
val req: HttpRequest = Http(url)
val response = req.asBytes
val targetStream = ByteSource.wrap(response.body).openStream()
log.info("response body :" + response.body)
sender ! targetStream
targetStream.close()
}
}
}
One of the things you should know about actors is that you should not be sending mutable objects (such as InputStream) as messages (technically you can as long as you won't mutate them). Another thing is that sending of messages is asynchronous. This means that the targetStream.close() is called before the other actor receives the message. That is probably the reason why you are getting truncated attachments.
One thing that you could do is send the data instead of an InputStream. Something like
def receive = {
case request:AttachmentRequest => {
log.info(" inside Attachment RequestConsumer with document Id:" + request.documentId)
val req: HttpRequest = Http(url)
val response = req.asBytes
val data = ByteSource.wrap(response.body).read.toVector
log.info("response body :" + response.body)
sender ! data
}
}
That is if you can comfortably fit the contents of the attachment into memory. If that is not the case, you can try to break it into chunks or something.
On a side note, you should not be blocking in receive (the Await.result). A better approach would be to just send a message to AttachmentRequestConsumer and then expect a message of type Seq[Byte] (or even better some wrapper like AttachmentResponse) back in SendgridConsumer's receive.
Writing to remote MSMQ seems to be working on/off. I am not sure what is wrong and what else to do to confirm sending.
I am reluctant to setup some kind of ack. It seems to be an overkill.
using (var queue = new MessageQueue(queueName, QueueAccessMode.Send))
{
var messageQueueTransaction = new MessageQueueTransaction();
messageQueueTransaction.Begin();
try
{
queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(EmailMessage) });
var msg = new Message();
msg.Label = emailMessage.Subject;
msg.Body = emailMessage;
queue.Send(msg, messageQueueTransaction);
messageQueueTransaction.Commit();
}
catch (Exception e)
{
LoggerLib.Logger.ErrorException(e, "Error Sending Email using MSMQ", emailMessage);
messageQueueTransaction.Abort();
}
finally
{
queue.Close();
}
}
The Connection string for MSMQ is in the format of:"FormatName:DIRECT=OS:FULLMACHINENAME\private$\emailmessagequeue"
Also, I used "FormatName:DIRECT:TCP:IPAddress\private$\emailmessagequeue".
It works without a glitch when I ran it locally. So, I allowed Everyone to have Full access and It still doesn't work.
Any ideas?
The port number 1801 was blocked. That resolved it. –
Is there anyway to listen for an outbound sms without having to import javax.wireless.messaging?
I'm trying to write an app that listens for an sms sent from the device then emails the message of the sms, but I get the error:
reference to Message is ambiguous, both class
javax.wireless.messaging.Message in javax.wireless.messaging and class
net.rim.blackberry.api.mail.Message in net.rim.blackberry.api.mail
match
I need to import net.rim.blackberry.api.mail.Message in order to sent an email.
Is there a way to get around this as it seems that the two packages are clashing.
My code:
public void notifyIncomingMessage(MessageConnection messageconnection) {}
public void notifyOutgoingMessage(javax.wireless.messaging.Message message) {
try {
String address = message.getAddress();
String msg = null;
if ( message instanceof TextMessage ) {
TextMessage tm = (TextMessage)message;
msg = tm.getPayloadText();
} else if (message instanceof BinaryMessage) {
StringBuffer buf = new StringBuffer();
byte[] data = ((BinaryMessage) message).getPayloadData();
msg = new String(data, "UTF-8");
Store store = Session.getDefaultInstance().getStore();
Folder[] folders = store.list(Folder.SENT);
Folder sentfolder = folders[0];
Message in = new Message(sentfolder);
Address recipients[] = new Address[1];
recipients[0]= new Address("me#us.com", "user");
in.addRecipients(Message.RecipientType.TO, recipients);
in.setSubject("Outgoing sms");
in.setContent("You have just sent an sms to: " + address + "\n" + "Message: " + msg);
in.setPriority(Message.Priority.HIGH);
Transport.send(in);
in.setFlag(Message.Flag.OPENED, true);
Folder folder = in.getFolder();
folder.deleteMessage(in);
}
} catch (IOException me) {
System.out.println(me);
}
}
}
You never should need to import anything in Java. Importing a package is just a shortcut, so that you don't have to fully type out the whole package name. If you have a class named Message that you want to use, and it exists in two packages (both of which you need), then I wouldn't import either of them.
Simply, always refer to each of them by their fully-qualified name:
net.rim.blackberry.api.mail.Message
and
javax.wireless.messaging.Message
It's just a little more typing.
I'm trying to build an app to send bulk report emails to many addresses with various hosts. I'm using Javamail and well, I'm still learning it though.
I found an example and try sending emails with my company server as host (let's say xyz company).
here is the sample code
package mailexample;
import javax.mail.*;
import javax.mail.internet.*;
public class MailExample {
public static void send(String smtpHost, int smtpPort,
String from, String to,
String subject, String content) {
try {
java.util.Properties props = new java.util.Properties();
props.put("mail.smtp.host", smtpHost);
props.put("mail.smtp.port", ""+smtpPort);
Session session = Session.getDefaultInstance(props, null);
//Store store = session.getStore();
//Folder folder = store.getFolder("INBOX");
//System.out.println(folder.getMessage(1));
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(from));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
msg.setSubject(subject);
msg.setText(content);
Transport.send(msg);
}
catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
try {
send("mail.xyz.ac", 25, "asdf#xyz.ac", "qwer#xyz.ac",
"title", "content");
}
catch(Exception e) {
e.printStackTrace();
}
}
}
It works fine and I get an error stacktrace when the address is invalid.
But that is only happen if I send an email to the same server/host which is mail.xyz.ac.
If I send an email to some random gmail or ymail addresses (that likely don't exist), my app return success message but nothing happened after that, only a message (like mailer-daemon in gmail) in sender inbox that said it is not delivered.
The problem is, I need to store that message in my database for further notice.
Is it possible to get that message from my app?
The JavaMail FAQ is your friend while learning JavaMail. This entry and this entry address your question. Also, be sure to read the entry about common mistakes.