Commit f0774f47 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

when too big message is sent via email the content is compressed and sent as attachment

parent aa532dbd
Pipeline #3117 passed with stage
in 47 seconds
package lcsb.mapviewer.services.utils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import lcsb.mapviewer.model.user.ConfigurationElementType;
import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.services.interfaces.IConfigurationService;
import javax.mail.internet.MimeMultipart;
import org.apache.log4j.Logger;
import com.sun.mail.smtp.SMTPTransport;
import lcsb.mapviewer.model.user.ConfigurationElementType;
import lcsb.mapviewer.model.user.User;
import lcsb.mapviewer.services.interfaces.IConfigurationService;
/**
* Class that allows to send emails. It requires access to email account from
* which emails will be sent.
......@@ -29,218 +40,274 @@ import com.sun.mail.smtp.SMTPTransport;
*
*/
public class EmailSender {
/**
* Default class logger.
*/
private Logger logger = Logger.getLogger(EmailSender.class);
/**
* String (usualy email address) that should appear in sender field of the
* email.
*/
private String sender;
/**
* Login used for accessing mail account.
*/
private String login;
/**
* Password used for accessing mail account.
*/
private String password;
/**
* Server used for smtp.
*/
private String smtpHost;
/**
* Port on the server used by imap.
*/
private String imapHost;
/**
* Port on the server used by smtp.
*/
private String smtpPort;
/**
* Default constructor that initializes data.
*
* @param address
* {@link #sender}
* @param login
* {@link #login}
* @param password
* {@link #password}
* @param smtpServerAddress
* {@link #smtpHost}
* @param imapServerAddress
* {@link #imapHost}
* @param smtpServerPort
* {@link #smtpPort}
*/
public EmailSender(String address, String login, String password, String smtpServerAddress, String imapServerAddress, String smtpServerPort) {
this.sender = address;
this.login = login;
this.password = password;
this.smtpHost = smtpServerAddress;
this.imapHost = imapServerAddress;
this.smtpPort = smtpServerPort;
}
/**
* Creates email sender class from data taken from
* {@link IConfigurationService}.
*
* @param configurationService
* configuration service that contains information required to access
* email account
*/
public EmailSender(IConfigurationService configurationService) {
this(configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_ADDRESS), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_LOGIN), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_PASSWORD), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_SMTP_SERVER), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_IMAP_SERVER), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_SMTP_PORT));
}
/**
* Sends email.
*
* @param subject
* subject of the email
* @param message
* content of the message
* @param receiver
* user that should receive email
* @throws MessagingException
* thrown whene there is a problem with sending email
*/
public void sendEmail(String subject, String message, User receiver) throws MessagingException {
if (receiver.getEmail() == null || receiver.getEmail().equals("")) {
logger.warn("Cannot send email to user: " + receiver.getName() + " " + receiver.getSurname() + ". Email set to null");
return;
}
List<String> recipients = new ArrayList<String>();
recipients.add(receiver.getEmail());
sendEmail(recipients, new ArrayList<String>(), subject, message);
}
/**
* Sends email.
*
* @param recipients
* list of email recipients
* @param ccRecipients
* list of cc email recipients
* @param subject
* subject of the email
* @param message
* message content
* @throws MessagingException
* thrown when there is a problem with sending email
*/
public void sendEmail(List<String> recipients, List<String> ccRecipients, String subject, String message) throws MessagingException {
if (smtpHost.equals(ConfigurationElementType.EMAIL_SMTP_SERVER.getDefaultValue())) {
logger.warn("Cannot send email. No smpt server defined");
return;
}
// set data of the mail account
Properties props = System.getProperties();
props.setProperty("mail.smtp.host", smtpHost);
props.setProperty("mail.smtp.port", smtpPort);
props.put("mail.smtps.quitwait", "false");
Session session = Session.getInstance(props, null);
final MimeMessage msg = new MimeMessage(session);
// set from address
msg.setFrom(new InternetAddress(sender));
// add recipients
InternetAddress[] rec = new InternetAddress[recipients.size()];
for (int i = 0; i < recipients.size(); i++) {
rec[i] = new InternetAddress(recipients.get(i));
}
msg.setRecipients(Message.RecipientType.TO, rec);
// add cc recipients
InternetAddress[] cc = new InternetAddress[ccRecipients.size()];
for (int i = 0; i < ccRecipients.size(); i++) {
rec[i] = new InternetAddress(ccRecipients.get(i));
}
msg.setRecipients(Message.RecipientType.CC, cc);
// set subject
msg.setSubject(subject);
// set timestamp
msg.setSentDate(new Date());
// and content
msg.setContent(message, "text/html; charset=utf-8");
// connect and send
SMTPTransport t = (SMTPTransport) session.getTransport("smtp");
t.connect(smtpHost, login, password);
t.sendMessage(msg, msg.getAllRecipients());
t.close();
}
/**
* Returns number of emails in email account.
*
* @return number of emails in email account.
* @throws MessagingException
* thrown when there is a problem with accessing email account
*/
public int getInboxCount() throws MessagingException {
/* Set the mail properties */
Properties props = System.getProperties();
props.setProperty(imapHost, "imaps");
/* Create the session and get the store for read the mail. */
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect(imapHost, login, password);
/* Mention the folder name which you want to read. */
Folder inbox = store.getFolder("Inbox");
int result = inbox.getUnreadMessageCount();
store.close();
return result;
}
/**
* Sends email.
*
* @param subject
* subject of the email
* @param message
* content of the message
* @param emailAddress
* email address that should receive email
* @throws MessagingException
* thrown whene there is a problem with sending email
*/
public void sendEmail(String subject, String message, String emailAddress) throws MessagingException {
if (emailAddress == null || emailAddress.equals("")) {
logger.warn("Cannot send email to user: " + emailAddress + ". Email set to null");
return;
}
List<String> recipients = new ArrayList<String>();
recipients.add(emailAddress);
sendEmail(recipients, new ArrayList<String>(), subject, message);
}
/**
* Max size of the content that is allowed as plain text. For emails with longer
* content the content will be compressed and added as an attachment file.
*/
private static final int MAX_EMAIL_CONTENT_SIZE = 32 * 1024;
/**
* Default class logger.
*/
private Logger logger = Logger.getLogger(EmailSender.class);
/**
* String (usually email address) that should appear in sender field of the
* email.
*/
private String sender;
/**
* Login used for accessing mail account.
*/
private String login;
/**
* Password used for accessing mail account.
*/
private String password;
/**
* Server used for SMTP.
*/
private String smtpHost;
/**
* Port on the server used by IMAP.
*/
private String imapHost;
/**
* Port on the server used by SMTP.
*/
private String smtpPort;
/**
* Default constructor that initializes data.
*
* @param address
* {@link #sender}
* @param login
* {@link #login}
* @param password
* {@link #password}
* @param smtpServerAddress
* {@link #smtpHost}
* @param imapServerAddress
* {@link #imapHost}
* @param smtpServerPort
* {@link #smtpPort}
*/
public EmailSender(String address, String login, String password, String smtpServerAddress, String imapServerAddress,
String smtpServerPort) {
this.sender = address;
this.login = login;
this.password = password;
this.smtpHost = smtpServerAddress;
this.imapHost = imapServerAddress;
this.smtpPort = smtpServerPort;
}
/**
* Creates email sender class from data taken from
* {@link IConfigurationService}.
*
* @param configurationService
* configuration service that contains information required to access
* email account
*/
public EmailSender(IConfigurationService configurationService) {
this(configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_ADDRESS), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_LOGIN), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_PASSWORD), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_SMTP_SERVER), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_IMAP_SERVER), //
configurationService.getConfigurationValue(ConfigurationElementType.EMAIL_SMTP_PORT));
}
/**
* Sends email.
*
* @param subject
* subject of the email
* @param message
* content of the message
* @param receiver
* user that should receive email
* @throws MessagingException
* thrown when there is a problem with sending email
*/
public void sendEmail(String subject, String message, User receiver) throws MessagingException {
if (receiver.getEmail() == null || receiver.getEmail().equals("")) {
logger.warn(
"Cannot send email to user: " + receiver.getName() + " " + receiver.getSurname() + ". Email set to null");
return;
}
List<String> recipients = new ArrayList<String>();
recipients.add(receiver.getEmail());
sendEmail(recipients, new ArrayList<String>(), subject, message);
}
/**
* Sends email.
*
* @param recipients
* list of email recipients
* @param ccRecipients
* list of cc email recipients
* @param subject
* subject of the email
* @param message
* message content
* @throws MessagingException
* thrown when there is a problem with sending email
*/
public void sendEmail(List<String> recipients, List<String> ccRecipients, String subject, String message)
throws MessagingException {
if (smtpHost.equals(ConfigurationElementType.EMAIL_SMTP_SERVER.getDefaultValue())) {
logger.warn("Cannot send email. No smpt server defined");
return;
}
// set data of the mail account
Properties props = System.getProperties();
props.setProperty("mail.smtp.host", smtpHost);
props.setProperty("mail.smtp.port", smtpPort);
// props.setProperty("mail.smtp.user", login);
// props.setProperty("mail.smtp.password", password);
// props.setProperty("mail.smtp.auth", "true");
props.put("mail.smtps.quitwait", "false");
Session session = Session.getInstance(props, null);
final MimeMessage msg = new MimeMessage(session);
// set from address
msg.setFrom(new InternetAddress(sender));
// add recipients
InternetAddress[] rec = new InternetAddress[recipients.size()];
for (int i = 0; i < recipients.size(); i++) {
rec[i] = new InternetAddress(recipients.get(i));
}
msg.setRecipients(Message.RecipientType.TO, rec);
// add cc recipients
InternetAddress[] cc = new InternetAddress[ccRecipients.size()];
for (int i = 0; i < ccRecipients.size(); i++) {
rec[i] = new InternetAddress(ccRecipients.get(i));
}
msg.setRecipients(Message.RecipientType.CC, cc);
// set subject
msg.setSubject(subject);
// set time stamp
msg.setSentDate(new Date());
File attachment = createAttachmentZipForBigMessage(message);
if (attachment != null) {
MimeBodyPart textBodyPart = new MimeBodyPart();
textBodyPart.setText("Content zipped, because it's size exceeded max size: " + MAX_EMAIL_CONTENT_SIZE, "UTF-8");
MimeBodyPart attachmentBodyPart = new MimeBodyPart();
attachmentBodyPart = new MimeBodyPart();
DataSource source = new FileDataSource(attachment);
attachmentBodyPart.setDataHandler(new DataHandler(source));
attachmentBodyPart.setFileName("content.zip");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(textBodyPart);
multipart.addBodyPart(attachmentBodyPart);
msg.setContent(multipart);
} else {
// and content
msg.setContent(message, "text/html; charset=utf-8");
}
// connect and send
SMTPTransport t = (SMTPTransport) session.getTransport("smtp");
t.connect(smtpHost, login, password);
t.sendMessage(msg, msg.getAllRecipients());
t.close();
}
private File createAttachmentZipForBigMessage(String message) {
File attachment = null;
if (message.length() > MAX_EMAIL_CONTENT_SIZE) {
try {
attachment = File.createTempFile("attachment", ".zip");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(attachment));
ZipEntry e = new ZipEntry("content.txt");
out.putNextEntry(e);
byte[] data = message.getBytes();
out.write(data, 0, data.length);
out.closeEntry();
out.close();
} catch (IOException e1) {
logger.error("Problem with creating attachment. Fall back into putting everything into content");
attachment = null;
}
}
return attachment;
}
/**
* Returns number of emails in email account.
*
* @return number of emails in email account.
* @throws MessagingException
* thrown when there is a problem with accessing email account
*/
public int getInboxCount() throws MessagingException {
/* Set the mail properties */
Properties props = System.getProperties();
props.setProperty(imapHost, "imaps");
/* Create the session and get the store for read the mail. */
Session session = Session.getDefaultInstance(props, null);
Store store = session.getStore("imaps");
store.connect(imapHost, login, password);
/* Mention the folder name which you want to read. */
Folder inbox = store.getFolder("Inbox");
int result = inbox.getUnreadMessageCount();
store.close();
return result;
}
/**
* Sends email.
*
* @param subject
* subject of the email
* @param message
* content of the message
* @param emailAddress
* email address that should receive email
* @throws MessagingException
* thrown whene there is a problem with sending email
*/
public void sendEmail(String subject, String message, String emailAddress) throws MessagingException {
if (emailAddress == null || emailAddress.equals("")) {
logger.warn("Cannot send email to user: " + emailAddress + ". Email set to null");
return;
}
List<String> recipients = new ArrayList<String>();
recipients.add(emailAddress);
sendEmail(recipients, new ArrayList<String>(), subject, message);
}
}
......@@ -3,37 +3,37 @@ package lcsb.mapviewer.services.utils;
import java.util.ArrayList;
import java.util.List;
import lcsb.mapviewer.services.ServiceTestFunctions;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import lcsb.mapviewer.services.ServiceTestFunctions;
public class EmailSenderTest extends ServiceTestFunctions {
Logger logger = Logger.getLogger(EmailSenderTest.class);
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
@Ignore("This is just a showcase")
public void test() throws Exception {
try {
EmailSender emailSender = new EmailSender(configurationService);
List<String> recipients = new ArrayList<String>();
recipients.add("piotr.gawron@uni.lu");
emailSender.sendEmail(recipients, new ArrayList<String>(), "Test subject", "Test content");
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
Logger logger = Logger.getLogger(EmailSenderTest.class);
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
@Ignore("This is just a showcase")
public void test() throws Exception {
try {
EmailSender emailSender = new EmailSender(configurationService);
List<String> recipients = new ArrayList<>();
recipients.add("piotr.gawron@uni.lu");
emailSender.sendEmail(recipients, new ArrayList<>(), "Test subject", "Test content");
} catch (Exception e) {