diff --git a/pom.xml b/pom.xml index ec12627..e7c7a4d 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,12 @@ httpclient5 + + javax.mail + mail + 1.4.7 + + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/eu/dnetlib/apps/oai/service/CollectorService.java b/src/main/java/eu/dnetlib/apps/oai/service/CollectorService.java index 4472798..6eba842 100644 --- a/src/main/java/eu/dnetlib/apps/oai/service/CollectorService.java +++ b/src/main/java/eu/dnetlib/apps/oai/service/CollectorService.java @@ -104,20 +104,21 @@ public class CollectorService { info.setExecutionStatus(ExecutionStatus.COMPLETED); info.setEnd(now); info.setExpirationDate(now.plusHours(executionDuration)); - emailSender.notifySuccess(info); - } catch (final Throwable e) { - info.setExecutionStatus(ExecutionStatus.FAILED); - info.setMessage(e.getMessage() + ": " + ExceptionUtils.getStackTrace(e)); - info.setEnd(LocalDateTime.now()); - emailSender.notifyFailure(info); - } finally { - sc.complete(); if (StringUtils.isNotBlank(publicBasePath)) { info.setPublicUrl(publicBasePath + "/" + jobId); } + emailSender.notifySuccess(info); + } catch (final Throwable e) { + info.setExecutionStatus(ExecutionStatus.FAILED); + info.setMessage(e.getMessage() + ": " + ExceptionUtils.getStackTrace(e)); + info.setEnd(LocalDateTime.now()); + + emailSender.notifyFailure(info); + } finally { collectionInfoRepository.save(info); + sc.complete(); } }); @@ -210,7 +211,7 @@ public class CollectorService { } public static void cleanCollectedData(final String storageUrl) throws URISyntaxException { - log.info("[CLEAN] - Deleting: " + storageUrl); + log.info("[CLEAN] Deleting expired storage: " + storageUrl); final URI uri = new URI(storageUrl); final String protocol = uri.getScheme(); diff --git a/src/main/java/eu/dnetlib/apps/oai/utils/EmailSender.java b/src/main/java/eu/dnetlib/apps/oai/utils/EmailSender.java index 9299743..43be7ee 100644 --- a/src/main/java/eu/dnetlib/apps/oai/utils/EmailSender.java +++ b/src/main/java/eu/dnetlib/apps/oai/utils/EmailSender.java @@ -1,6 +1,24 @@ package eu.dnetlib.apps.oai.utils; +import java.util.Date; +import java.util.Properties; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import javax.annotation.PostConstruct; +import javax.mail.Authenticator; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; + import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import eu.dnetlib.apps.oai.model.CollectionInfo; @@ -8,6 +26,50 @@ import eu.dnetlib.apps.oai.model.CollectionInfo; @Service public class EmailSender { + private static final Log log = LogFactory.getLog(EmailSender.class); + + private final BlockingQueue queue = new LinkedBlockingQueue<>(); + + @Value("${oai.conf.notification.sender.name}") + private String fromName; + + @Value("${oai.conf.notification.sender.email}") + private String fromEmail; + + @Value("${oai.conf.notification.smtp.host}") + private String smtpHost; + + @Value("${oai.conf.notification.smtp.host}") + private long smtpPort; + + @Value("${oai.conf.notification.smtp.user}") + private String smtpUser; + + @Value("${oai.conf.notification.smtp.password}") + private String smtpPassword; + + @PostConstruct + private void init() { + new Thread(() -> { + while (true) { + try { + final Message message = this.queue.take(); + if (message != null) { + try { + log.info("Sending mail..."); + Transport.send(message); + log.info("...sent"); + } catch (final MessagingException e) { + log.error("Error sending email", e); + } + } + } catch (final InterruptedException e1) { + throw new RuntimeException(e1); + } + } + }).start(); + } + public void notifySuccess(final CollectionInfo info) { if (StringUtils.isNotBlank(info.getNotificationEmail())) { sendMail(info.getNotificationEmail(), "OAI Harvesting completed", prepareSuccessMessage(info)); @@ -30,8 +92,48 @@ public class EmailSender { return null; } - private void sendMail(final String to, final String subject, final String message) { - // TODO Auto-generated method stub + public void sendMail(final String to, final String subject, final String message) { + try { + final Session session = Session.getInstance(obtainProperties(), obtainAuthenticator()); + final MimeMessage mimeMessage = new MimeMessage(session); + mimeMessage.setFrom(new InternetAddress(fromEmail, fromName)); + mimeMessage.setSubject(subject); + mimeMessage.setContent(message, "text/html; charset=utf-8"); + mimeMessage.setSentDate(new Date()); + + mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(to)); + + this.queue.add(mimeMessage); + + log.info("Mail to " + to + " in queue"); + } catch (final Exception e) { + log.error("Error sending mail", e); + } } + + private Properties obtainProperties() { + final Properties p = new Properties(); + p.put("mail.transport.protocol", "smtp"); + p.put("mail.smtp.host", smtpHost); + p.put("mail.smtp.port", smtpPort); + p.put("mail.smtp.auth", Boolean.toString(StringUtils.isNotBlank(smtpUser))); + return p; + } + + private Authenticator obtainAuthenticator() { + if (StringUtils.isBlank(smtpUser)) { return null; } + + return new Authenticator() { + + private final PasswordAuthentication authentication = new PasswordAuthentication(smtpUser, smtpPassword); + + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return authentication; + } + + }; + } + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2ca1e0f..d1a2a15 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -27,4 +27,10 @@ oai.conf.maxRecords = 1000 oai.conf.enable.export.api = true +oai.conf.notification.sender.name = OAI Collector Service +oai.conf.notification.sender.email = noreply@openaire.eu +oai.conf.notification.smtp.host = localhost +oai.conf.notification.smtp.host = 587 +oai.conf.notification.smtp.user = +oai.conf.notification.smtp.password =