How to send Java MimeMultipart via Exchange Server - jakarta-mail

I am using javamail api and I have to send email through Exchange server and then embed image on the email body. How to send embed image in MimeMultipart into EmailMessage using Exchange? I have successfully send the same email using SMTP.
EmailMessage msg = new EmailMessage(service);
msg.setSubject(emailSubject);
msg.getReplyTo().add(emailAdmin);
msg.getToRecipients().add(emailAddress);
// This mail has 2 part, the BODY and the embedded image
MimeMultipart multipart = new MimeMultipart("related");
//1st part (the message)
BodyPart messageBodyPart = new MimeBodyPart();
messageBodyPart.setContent(message,"text/html; charset=UTF-8");
multipart.addBodyPart(messageBodyPart);
// second part (the image)
messageBodyPart = new MimeBodyPart();
DataHandler h = null;
String base64 = configuration.getImageBase64();
//Base64.decodeBase64(string | bytes)
byte[] decode = Base64.decodeBase64(base64.getBytes());
InputStream stream = new ByteArrayInputStream(decode);
try {
h=new DataHandler(new ByteArrayDataSource(stream,"application/octet-stream"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
messageBodyPart.setDataHandler(h);
messageBodyPart.setHeader("Content-ID", "image");
messageBodyPart.setHeader("Content-Type", "image/jpeg; name=image.jpg");
messageBodyPart.setHeader("Content-Disposition", "inline");
// add image to the multipart
multipart.addBodyPart(messageBodyPart);
// put everything together
msg.setContent(multipart);////how to set multipart into msg?
synchronized (msg) {
msg.send();
}

Related

How to write send email test case and read Excel file test case in Selenium

Here is my my code to write a sample send email test case. When running the code email is not getting triggered. Please find attached data for more details
Login User details
Invalid User Details
Booking Data
Can anyone please help to resolve the issue as I am novice in selenium automation testing. Below is sample code of my Java code for configuration and triggering of email.
How to send out an Email notification in Selenium webdriver using Java, whenever some scenario is failed/passed in between?
public class SendEmail {
public SendEmail() {
}
public void email() {
// Create object of Property file
Properties props = new Properties();
// this will set host of server- you can change based on your
// requirement
props.put("mail.smtp.host", "smtp.gmail.com");
// set the port of socket factory
props.put("mail.smtp.socketFactory.port", "465");
// set socket factory
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
// set the authentication to true
props.put("mail.smtp.auth", "true");
// set the port of SMTP server
props.put("mail.smtp.port", "465");
// This will handle the complete authentication
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("seleniumtest201#gmail.com", "Admin12!#");
}
});
try {
// Create object of MimeMessage class
Message message = new MimeMessage(session);
// Set the from address
message.setFrom(new InternetAddress("seleniumtest201#gmail.com"));
// Set the recipient address
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("aniketgupta1993#gmail.com"));
// Add the subject link
message.setSubject("Test Case Execution Report");
// Create object to add multi media type content
BodyPart messageBodyPart1 = new MimeBodyPart();
// Set the body of email
messageBodyPart1.setText("This is auto-generated test case execution report");
// Create another object to add another content
MimeBodyPart messageBodyPart2 = new MimeBodyPart();
// Mention the file which you want to send
String filename = "C://Users//aniket//sampleseleniumproject//test-output//emailable-report.html";
// Create data source and pass the filename
DataSource source = new FileDataSource(filename);
// set the handler
messageBodyPart2.setDataHandler(new DataHandler(source));
// set the file
messageBodyPart2.setFileName(filename);
// Create object of MimeMultipart class
Multipart multipart = new MimeMultipart();
// add body part 1
multipart.addBodyPart(messageBodyPart2);
// add body part 2
multipart.addBodyPart(messageBodyPart1);
// set the content
message.setContent(multipart);
// finally send the email
Transport.send(message);
System.out.println("=====Email Sent=====");
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
}
You can use following code for the getting email when execution is completed and this put in teardown so you can get an Email notification in selenium webdriver, whenever scenario is failed/passed in between
public void tearDown()
{
private static void sendPDFReportByGMail(String from, String pass, String to, String subject, String body)
{
Properties props = System.getProperties();
String host = "smtp.gmail.com";
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", from);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
MimeMessage message = new MimeMessage(session);
try {
//Set from address
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
//Set subject
message.setSubject(subject);
message.setText(body);
BodyPart objMessageBodyPart = new MimeBodyPart();
objMessageBodyPart.setText("Please Find The Attached Report File!");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(objMessageBodyPart);
objMessageBodyPart = new MimeBodyPart();
//Set path to the pdf report file
String filename = System.getProperty("user.dir")+"\\Default test.pdf";
//Create data source to attach the file in mail
DataSource source = new FileDataSource(filename);
objMessageBodyPart.setDataHandler(new DataHandler(source));
objMessageBodyPart.setFileName(filename);
multipart.addBodyPart(objMessageBodyPart);
message.setContent(multipart);
Transport transport = session.getTransport("smtp");
transport.connect(host, from, pass);
transport.sendMessage(message, message.getAllRecipients());
transport.close();
}
catch (AddressException ae) {
ae.printStackTrace();
}
catch (MessagingException me) {
me.printStackTrace();
}
}
}

Send a PDF as an attachment through Sendgrid

I'm using Sendgrid to send emails through an app on GAE. It's working fine, but I also want to be able to send PDFs as an attachment.
I'm not using Sendgrid.jar file in my project. I've just used Sendgrid.java. And this class has no methods by which i can add attachments. Can someone help me?
public static boolean sendEmail(String fromMail, String title, String toMail, String message) throws IOException {
Email from = new Email(fromMail);
String subject = title;
Email to = new Email(toMail);
Content content = new Content("text/html", message);
Mail mail = new Mail(from, subject, to, content);
Path file = Paths.get("file path");
Attachments attachments = new Attachments();
attachments.setFilename(file.getFileName().toString());
attachments.setType("application/pdf");
attachments.setDisposition("attachment");
byte[] attachmentContentBytes = Files.readAllBytes(file);
String attachmentContent = Base64.getMimeEncoder().encodeToString(attachmentContentBytes);
String s = Base64.getEncoder().encodeToString(attachmentContentBytes);
attachments.setContent(s);
mail.addAttachments(attachments);
SendGrid sg = new SendGrid("sendgrid api key");
Request request = new Request();
request.setMethod(Method.POST);
request.setEndpoint("mail/send");
request.setBody(mail.build());
Response response = sg.api(request);
if (response != null) {
return true;
} else {
return false;
}
}
Define above static method and call with relevant arguments as your program wants.
Here is the code of a servlet that sends a mail with a PDF as attachment, through Sendgrid:
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) {
....
ByteArrayOutputStream os = null;
try {
PDFGenerator pdfGenerator = new PDFGenerator(invoiceOut);
os = pdfGenerator.getPDFOutputStream();
} catch (Exception e) {
....
}
SendGrid sendgrid = new SendGrid(Constants.SENDGRID_API_KEY);
SendGrid.Email email = new SendGrid.Email();
email.addTo(....);
email.setFrom(....);
email.setFromName(....);
email.setSubject(....);
email.setHtml("......");
ByteBuffer buf = null;
if (os == null) {
//error...
} else {
buf = ByteBuffer.wrap(os.toByteArray());
}
InputStream attachmentDataStream = new ByteArrayInputStream(buf.array());
try {
email.addAttachment("xxxxx.pdf", attachmentDataStream);
SendGrid.Response response = sendgrid.send(email);
} catch (IOException e) {
....
throw new RuntimeException(e);
} catch (SendGridException e) {
....
throw new RuntimeException(e);
}
}
PDFGenerator is one of my classes in which getPDFOutputStream method returns the PDF as ByteArrayOutputStream.
I personally find it easier to directly construct the JSON request body as described in the API docs than to use Sendgrid's libraries. I only use the Sendgrid library for sending the request after I construct the JSON data myself.
When constructing the JSON data you need to specify at least a filename and the content (i.e., the PDF file). Make sure to Base64 encode the PDF file before adding it to the JASON data.
I'd include some code, but I do Python and not Java so not sure that would help.

Web api large file download with HttpClient

I have a problem with large file download from the web api to the win forms app. On the win form app I'm using HttpClient for grabbing data. I have following code on server side:
[HttpPost]
[Route]
public async Task<HttpResponseMessage> GetBackup(BackupRequestModel request)
{
HttpResponseMessage response;
try
{
response = await Task.Run<HttpResponseMessage>(() =>
{
var directory = new DirectoryInfo(request.Path);
var files = directory.GetFiles();
var lastCreatedFile = files.OrderByDescending(f => f.CreationTime).FirstOrDefault();
var filestream = lastCreatedFile.OpenRead();
var fileResponse = new HttpResponseMessage(HttpStatusCode.OK);
fileResponse.Content = new StreamContent(filestream);
fileResponse.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return fileResponse;
});
}
catch (Exception e)
{
logger.Error(e);
response = Request.CreateResponse(HttpStatusCode.InternalServerError);
}
return response;
}
on client side:
private async void btnStart_Click(object sender, EventArgs e)
{
var requestModel = new BackupRequestModel();
requestModel.Username = txtUsername.Text;
requestModel.Password = txtPassword.Text;
requestModel.Path = txtServerPath.Text;
var client = new HttpClient();
var result = await client.PostAsJsonAsync("http://localhost:50116/api/backup", requestModel);
var stream = await result.Content.ReadAsStreamAsync();
var localPath = #"d:\test\filenew.bak";
var fileStream = File.Create(localPath);
stream.CopyTo(fileStream);
fileStream.Close();
stream.Close();
fileStream.Dispose();
stream.Dispose();
client.Dispose();
}
}
This is actually working, but the purpose of this program is to grab large files over 3GB and save it to the client.
I have tried this on files sized 630MB what I notice is: When I call web api with http client, http client actually loads 630MB in the memory stream, and from the memory stream to the file stream, but when I try to load a different file I'm getting OutOfMemoryException. This is happening because the application doesn't release memory from the previous loaded file. I can see in task manager that it is holding 635MB of ram memory.
My question is how can I write data directly from HttpClient to file without using memory stream, or in other words how can I write data to file while HttpClient is downloading data?
To make the request, use a SendAsync overload that allows you to specify a HttpCompletionOption and use ResponseHeadersRead. You'll have to manually build the request though, without using the PostAsJsonAsync convenience method.

Apache Camel server app receiving a multipart form POST (file upload)

I'm using Camel servlet component in order to receive xml documents and now I also need to receive files (jpegs, gifs, etc). So here is how my client app is sending a file:
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
public class HttpClientUploadHelper {
public boolean upload(final File file, final String url) {
boolean wasSent = false ;
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
MultipartEntity entity = new MultipartEntity();
entity.addPart(file.getName(), new FileBody(file));
post.setEntity(entity);
try {
HttpResponse response = client.execute(post);
wasSent = response.getStatusLine().getStatusCode()==200;
} catch (Exception e) {
}
return wasSent;
}
}
my Camel Processor then extracts the HttpServletRequest this way:
HttpServletRequest req = exchange.getIn().getHeader(Exchange.HTTP_SERVLET_REQUEST, HttpServletRequest.class);
then I have this method to finally parse and save the file:
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils
... class declaration, body, etc...
void parseAndSaveFile(final HttpServletRequest req) throws Exception {
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
FileItemIterator receivedFiles = upload.getItemIterator(req);
while (receivedFiles.hasNext()) {
FileItemStream file = receivedFiles.next();
if (file.isFormField()) {
System.out.println("WTF?");
} else {
String fileName = file.getName();
File uploadedFile = new File("/home/myuser/" + fileName);
FileOutputStream out = new FileOutputStream(uploadedFile);
IOUtils.copy(file.openStream(), out);
}
}
}
when I use above code within Camel, that isMultipart flag is "true" but that receivedFiles iterator doesn't contains any element. When I use above code within another project with just a plain servlet, the code works. In both ways I'm using jetty as the web container.
So is there any other way to extract the file name and it's content within my camel processor ?
Thanks!
Since you're using Jetty, have you considered using the included MultipartFilter instead of the FileUpload project? Super clean and easy to use.
From the javadoc:
"This class decodes the multipart/form-data stream sent by a HTML form that uses a file input item. Any files sent are stored to a temporary file and a File object added to the request as an attribute. All other values are made available via the normal getParameter API and the setCharacterEncoding mechanism is respected when converting bytes to Strings."
Does this help?
public void process(Exchange exchange) throws Exception {
Message in = exchange.getIn();
Set names = in.getAttachmentNames();
for(String n: names) {
System.out.println("attachment "+n);
DataHandler h = in.getAttachment(n);
if(h!=null) {
try {
Object o = h.getContent();
System.out.println(o);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
if(!names.isEmpty())
return;
}

Trying to access google places using google api client in GAE

I am trying to access google places api from appengine using code like this:
String PLACES_DETAILS_URL = "https://maps.googleapis.com/maps/api/place/details/json";
// setup up the HTTP transport
HttpTransport transport = new UrlFetchTransport();
// add default headers
GoogleHeaders defaultHeaders = new GoogleHeaders();
transport.defaultHeaders = defaultHeaders;
transport.defaultHeaders.put("Content-Type", "application/json");
JsonHttpParser parser = new JsonHttpParser();
parser.jsonFactory = new JacksonFactory();
transport.addParser(parser);
// build the HTTP GET request and URL
HttpRequest request = transport.buildGetRequest();
request.setUrl(PLACES_DETAILS_URL);
GenericData data = new GenericData();
data.put("reference", restaurantGoogleId);
data.put("sensor", "false");
data.put("key", ApplicationConstants.GoogleApiKey);
JsonHttpContent content = new JsonHttpContent();
content.jsonFactory=new JacksonFactory();
content.data = data;
request.content = content;
try {
HttpResponse response = request.execute();
String r = response.parseAsString();
r=r;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I don't know even if this is the recommended way. If so, why this doesn't work?If I put a request in the browser directly it works, but with this code it always returns me "Request Denied".
Thanks in advance.
At the end it was easy, I mixed get and post verbs:
HttpTransport transport = new UrlFetchTransport();
// add default headers
GoogleHeaders defaultHeaders = new GoogleHeaders();
transport.defaultHeaders = defaultHeaders;
transport.defaultHeaders.put("Content-Type", "application/json");
JsonCParser parser = new JsonCParser();
parser.jsonFactory = new JacksonFactory();
transport.addParser(parser);
// build the HTTP GET request and URL
HttpRequest request = transport.buildGetRequest();
request.setUrl("https://maps.googleapis.com/maps/api/place/details/json?reference=CmRYAAAAciqGsTRX1mXRvuXSH2ErwW-jCINE1aLiwP64MCWDN5vkXvXoQGPKldMfmdGyqWSpm7BEYCgDm-iv7Kc2PF7QA7brMAwBbAcqMr5i1f4PwTpaovIZjysCEZTry8Ez30wpEhCNCXpynextCld2EBsDkRKsGhSLayuRyFsex6JA6NPh9dyupoTH3g&sensor=true&key=<APIKEY>");
try {
HttpResponse response = request.execute();
String r = response.parseAsString();

Resources