Skip to content

Commit

Permalink
issue #92 : add JobReportEmailSender
Browse files Browse the repository at this point in the history
  • Loading branch information
fmbenhassine committed Feb 24, 2017
1 parent 899f40c commit c58caaa
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 0 deletions.
12 changes: 12 additions & 0 deletions easybatch-tools/pom.xml
Expand Up @@ -62,6 +62,18 @@
<version>1.7</version>
</dependency>

<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.6</version>
</dependency>

<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.6</version>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
@@ -0,0 +1,123 @@
/**
* The MIT License
*
* Copyright (c) 2017, Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.easybatch.tools.reporting;

import org.easybatch.core.job.JobParameters;
import org.easybatch.core.job.JobReport;
import org.easybatch.core.listener.JobListener;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Properties;

/**
* Job listener that sends the job report by email to a given account.
*
* @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
*/
public class JobReportEmailSender implements JobListener {

public static final String USER = "org.easybatch.tools.reporting.email.user";
public static final String PASSWORD = "org.easybatch.tools.reporting.email.password";
public static final String SENDER = "org.easybatch.tools.reporting.email.sender";
public static final String RECIPIENT = "org.easybatch.tools.reporting.email.recipient";
public static final String SUBJECT = "org.easybatch.tools.reporting.email.subject";

private Properties properties;
private EmailSender messageSender;

/**
* Create a new {@link JobReportEmailSender}.
*
* @param properties configuration properties. This should contain all email server configuration properties plus ( {@link JobReportEmailSender#USER}, {@link JobReportEmailSender#PASSWORD},
* {@link JobReportEmailSender#SENDER}, {@link JobReportEmailSender#RECIPIENT} and {@link JobReportEmailSender#SUBJECT} )
*/
public JobReportEmailSender(final Properties properties) {
validate(properties);
this.properties = properties;
this.messageSender = new EmailSender();
}

JobReportEmailSender(final Properties properties, final EmailSender emailSender) {
validate(properties);
this.properties = properties;
this.messageSender = emailSender;
}

@Override
public void beforeJobStart(JobParameters jobParameters) {
// no op
}

@Override
public void afterJobEnd(JobReport jobReport) {
send(jobReport);
}

private void send(JobReport jobReport) {
Session session = Session.getInstance(properties, getAuthenticator());
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(properties.getProperty(SENDER)));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(properties.getProperty(RECIPIENT)));
message.setSubject(properties.getProperty(SUBJECT));
message.setText(jobReport.toString());
messageSender.send(message);
} catch (MessagingException e) {
throw new RuntimeException("Unable to send job report by email", e);
}
}

private Authenticator getAuthenticator() {
final String username = properties.getProperty(USER);
final String password = properties.getProperty(PASSWORD);
return new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
};
}

private void validate(Properties properties) {
check(properties, USER);
check(properties, PASSWORD);
check(properties, SENDER);
check(properties, RECIPIENT);
check(properties, SUBJECT);
}

private void check(Properties properties, String property) {
if (properties.getProperty(property) == null) {
throw new IllegalArgumentException(String.format("Property %s is mandatory", property));
}
}

class EmailSender {
void send(Message message) throws MessagingException {
Transport.send(message);
}
}

}
@@ -0,0 +1,91 @@
/**
* The MIT License
*
* Copyright (c) 2017, Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.easybatch.tools.reporting;

import org.easybatch.core.job.JobReport;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

import javax.mail.Message;
import java.util.Properties;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class JobReportEmailSenderTest {

@Mock
private JobReport jobReport;
@Mock
private JobReportEmailSender.EmailSender emailSender;

private JobReportEmailSender jobReportEmailSender;

@Before
public void setUp() throws Exception {
Properties properties = new Properties();
properties.setProperty(JobReportEmailSender.USER, "foo");
properties.setProperty(JobReportEmailSender.PASSWORD, "bar");
properties.setProperty(JobReportEmailSender.SENDER, "foo");
properties.setProperty(JobReportEmailSender.RECIPIENT, "foo@yopmail.com");
properties.setProperty(JobReportEmailSender.SUBJECT, "test");
jobReportEmailSender = new JobReportEmailSender(properties, emailSender);
}

@Test
public void afterJobEnd() throws Exception {
jobReportEmailSender.afterJobEnd(jobReport);
verify(emailSender).send(any(Message.class));
}

@Ignore("This test works with a real Gmail account. Gmail settings should allow 'less secured apps' to send emails")
@Test
public void emailSendingTest() throws Exception {
// FIXME use http://www.icegreen.com/greenmail/ for this test
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.socketFactory.port", "465");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", "465");
props.put(JobReportEmailSender.USER, "");// fill in user
props.put(JobReportEmailSender.PASSWORD, "");// fill in password
props.put(JobReportEmailSender.SENDER, "");// fill in sender
props.put(JobReportEmailSender.RECIPIENT, "");// fill in recipient
props.put(JobReportEmailSender.SUBJECT, ""); // fill in subject

JobReportEmailSender jobReportEmailSender = new JobReportEmailSender(props);
jobReportEmailSender.afterJobEnd(new JobReport () {
@Override
public String toString() {
return "it works!";
}
});
}
}

0 comments on commit c58caaa

Please sign in to comment.