diff --git a/distro/changelog.xml b/distro/changelog.xml index 75e40f8..aa27c74 100644 --- a/distro/changelog.xml +++ b/distro/changelog.xml @@ -42,4 +42,10 @@ Fixed bug when notifications involved groups and email buffer was not cleared + +Fixed bug when notifications involved error in the SMTP server + + +Implemented direct email sending through an external SMTP Server (if available in the infrastructure) + diff --git a/pom.xml b/pom.xml index d1201af..2c9f035 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ org.gcube.applicationsupportlayer aslsocial - 0.10.1-SNAPSHOT + 0.11.0-SNAPSHOT jar Social Portal ASL Extension diff --git a/src/main/java/org/gcube/applicationsupportlayer/social/mailing/EmailNotificationsConsumer.java b/src/main/java/org/gcube/applicationsupportlayer/social/mailing/EmailNotificationsConsumer.java index acc3ba0..5a4d98b 100644 --- a/src/main/java/org/gcube/applicationsupportlayer/social/mailing/EmailNotificationsConsumer.java +++ b/src/main/java/org/gcube/applicationsupportlayer/social/mailing/EmailNotificationsConsumer.java @@ -1,15 +1,28 @@ package org.gcube.applicationsupportlayer.social.mailing; +import static org.gcube.resources.discovery.icclient.ICFactory.clientFor; +import static org.gcube.resources.discovery.icclient.ICFactory.queryFor; + import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.Properties; import javax.mail.Address; import javax.mail.Message; import javax.mail.MessagingException; +import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; +import org.gcube.common.encryption.StringEncrypter; +import org.gcube.common.portal.PortalContext; +import org.gcube.common.resources.gcore.ServiceEndpoint; +import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.portal.databook.shared.ex.TooManyRunningClustersException; +import org.gcube.resources.discovery.client.api.DiscoveryClient; +import org.gcube.resources.discovery.client.queries.api.SimpleQuery; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,25 +33,90 @@ import org.slf4j.LoggerFactory; */ public class EmailNotificationsConsumer extends Thread { private static Logger _log = LoggerFactory.getLogger(EmailNotificationsConsumer.class); + private static final String SERVICE_ENDPOINT_CATEGORY = "SMTPServer"; + private static final String SERVICE_ENDPOINT_NAME = "SMTP-ISTI"; - + private String smtpUsername; + private String smtpPasswd; + private String mailServiceHost = "localhost"; + private String mailServicePort = "25"; public EmailNotificationsConsumer() { super(); - _log.info("EmailNotificationsConsumer thread started at " + new Date()); + _log.info("EmailNotificationsConsumer thread started at " + new Date() + " trying to fetch SMTP configuration from infrastructure ..."); + + //query + try { + List resources = getConfigurationFromIS(); + if (resources.size() > 1) { + _log.error("Too many Service Endpoints having name " + SERVICE_ENDPOINT_NAME +" in this scope having Category " + SERVICE_ENDPOINT_CATEGORY); + } + else if (resources.size() == 0){ + _log.warn("There is no Service Endpoint having name " + SERVICE_ENDPOINT_NAME +" and Category " + SERVICE_ENDPOINT_CATEGORY + " in this scope. Using localhost:25"); + } + else { + for (ServiceEndpoint res : resources) { + AccessPoint found = res.profile().accessPoints().iterator().next(); + mailServiceHost = found.address().split(":")[0].trim(); + mailServicePort = found.address().split(":")[1].trim(); + smtpUsername = found.username(); + + PortalContext context = PortalContext.getConfiguration(); + String currScope = ScopeProvider.instance.get(); + String scope = "/" + context.getInfrastructureName(); + ScopeProvider.instance.set(scope); + smtpPasswd = StringEncrypter.getEncrypter().decrypt(found.password()); + ScopeProvider.instance.set(currScope); + _log.info("Found SMTP Configuration: "+mailServiceHost+":"+mailServicePort+ " usr="+smtpUsername+ " pwd=*******"); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + /** + * + * @return the + * @throws Exception + */ + private List getConfigurationFromIS() throws Exception { + PortalContext context = PortalContext.getConfiguration(); + String scope = "/" + context.getInfrastructureName(); + String currScope = ScopeProvider.instance.get(); + ScopeProvider.instance.set(scope); + SimpleQuery query = queryFor(ServiceEndpoint.class); + query.addCondition("$resource/Profile/Category/text() eq '"+ SERVICE_ENDPOINT_CATEGORY +"'"); + query.addCondition("$resource/Profile/Platform/Name/text() eq '"+ SERVICE_ENDPOINT_NAME +"'"); + DiscoveryClient client = clientFor(ServiceEndpoint.class); + List toReturn = client.submit(query); + ScopeProvider.instance.set(currScope); + return toReturn; + } @Override public void run() { - Properties props = System.getProperties(); - String mailServiceHost = "localhost"; + Session session = null; props.put("mail.smtp.host", mailServiceHost); - String mailServicePort = "25"; props.put("mail.smtp.port", mailServicePort); - Session session = Session.getDefaultInstance(props); + //if there is a service endpoint defined in the infrastructure for the SMTP Server authenticate against it + if (smtpUsername != null) { + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.starttls.enable", "false"); + session = Session.getInstance(props, + new javax.mail.Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(smtpUsername, smtpPasswd); + } + }); + } + else { //use localhost (probaly postfix instance) + session = Session.getDefaultInstance(props); + } + session.setDebug(true); - + for (;;) { try { Thread.sleep(1000*EmailPlugin.SECONDS2WAIT); @@ -50,7 +128,6 @@ public class EmailNotificationsConsumer extends Thread { _log.debug("Emails Buffer not empty, sending emails "); Transport t = null; try { - t = session.getTransport(); t.connect(); @@ -61,8 +138,15 @@ public class EmailNotificationsConsumer extends Thread { if (m != null) { m.saveChanges(); Address[] addresses = m.getAllRecipients(); - t.sendMessage(m, addresses); - _log.debug("Message sent to " + mail.getSenderEmail()); + try { + t.sendMessage(m, addresses); + } + catch (com.sun.mail.smtp.SMTPSendFailedException ex) { + _log.error("Error while trying to send emails, emptying the buffer..."); + EmailPlugin.BUFFER_EMAILS = new ArrayList(); + ex.printStackTrace(); + } + _log.debug("Message sent to " + mail.getNotification2Send().getUserid()); } else { _log.warn("Message not sent to " + mail.getNotification2Send().getUserid()); @@ -76,6 +160,8 @@ public class EmailNotificationsConsumer extends Thread { } catch (Exception e) { + _log.error("Exception while trying to send emails, emptying the buffer..."); + EmailPlugin.BUFFER_EMAILS = new ArrayList(); e.printStackTrace(); try { t.close(); diff --git a/src/main/java/org/gcube/applicationsupportlayer/social/mailing/EmailPlugin.java b/src/main/java/org/gcube/applicationsupportlayer/social/mailing/EmailPlugin.java index 7bd18b4..7e1fea2 100644 --- a/src/main/java/org/gcube/applicationsupportlayer/social/mailing/EmailPlugin.java +++ b/src/main/java/org/gcube/applicationsupportlayer/social/mailing/EmailPlugin.java @@ -31,7 +31,7 @@ import com.liferay.portal.util.PortalUtil; public class EmailPlugin { private static final Logger _log = LoggerFactory.getLogger(EmailPlugin.class); - protected static final int SECONDS2WAIT = 45; + protected static final int SECONDS2WAIT = 60; private static EmailPlugin singleton;