You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ol...@apache.org on 2019/12/19 16:50:33 UTC

[sling-org-apache-sling-commons-messaging-mail] branch master updated: SLING-8920 Provide a simple API and implementation to build and send mails

This is an automated email from the ASF dual-hosted git repository.

olli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-messaging-mail.git


The following commit(s) were added to refs/heads/master by this push:
     new 07a318f  SLING-8920 Provide a simple API and implementation to build and send mails
07a318f is described below

commit 07a318f89ed07219b5c328b5faa32ae917497e02
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Thu Dec 19 17:50:09 2019 +0100

    SLING-8920 Provide a simple API and implementation to build and send mails
    
    * Add support for connection listeners
    * Add test for connection and transport listeners
    * Rename test methods
    * Remove unnecessary logging in test
---
 .../messaging/mail/internal/SimpleMailService.java |  14 ++-
 .../internal/SimpleMailServiceConfiguration.java   |   7 ++
 .../messaging/mail/it/tests/MailTestSupport.java   |   4 +
 .../mail/it/tests/SimpleMailServiceIT.java         | 112 ++++++++++++++++++---
 4 files changed, 123 insertions(+), 14 deletions(-)

diff --git a/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java b/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java
index 1e73eab..3c2c87d 100644
--- a/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java
+++ b/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java
@@ -26,6 +26,7 @@ import java.util.concurrent.CompletionException;
 import javax.mail.MessagingException;
 import javax.mail.Session;
 import javax.mail.Transport;
+import javax.mail.event.ConnectionListener;
 import javax.mail.event.TransportListener;
 import javax.mail.internet.MimeMessage;
 
@@ -94,6 +95,13 @@ public class SimpleMailService implements MailService {
         policy = ReferencePolicy.DYNAMIC,
         policyOption = ReferencePolicyOption.GREEDY
     )
+    private volatile List<ConnectionListener> connectionListeners;
+
+    @Reference(
+        cardinality = ReferenceCardinality.MULTIPLE,
+        policy = ReferencePolicy.DYNAMIC,
+        policyOption = ReferencePolicyOption.GREEDY
+    )
     private volatile List<TransportListener> transportListeners;
 
     private ThreadPool threadPool;
@@ -167,8 +175,10 @@ public class SimpleMailService implements MailService {
             Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
             final String password = cryptoService.decrypt(configuration.password());
             try (final Transport transport = session.getTransport(SMTPS_PROTOCOL)) {
-                final List<TransportListener> listeners = this.transportListeners;
-                listeners.forEach(transport::addTransportListener);
+                final List<ConnectionListener> connectionListeners = this.connectionListeners;
+                connectionListeners.forEach(transport::addConnectionListener);
+                final List<TransportListener> transportListeners = this.transportListeners;
+                transportListeners.forEach(transport::addTransportListener);
                 transport.connect(configuration.mail_smtps_host(), configuration.mail_smtps_port(), configuration.username(), password);
                 message.saveChanges();
                 final MessageIdProvider messageIdProvider = this.messageIdProvider;
diff --git a/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java b/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java
index 82a79fd..94e5460 100644
--- a/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java
+++ b/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java
@@ -87,6 +87,13 @@ import org.osgi.service.metatype.annotations.ObjectClassDefinition;
     String cryptoService_target();
 
     @AttributeDefinition(
+        name = "Connection Listeners target",
+        description = "filter expression to target Connection Listeners",
+        required = false
+    )
+    String connectionListeners_target();
+
+    @AttributeDefinition(
         name = "Transport Listeners target",
         description = "filter expression to target Transport Listeners",
         required = false
diff --git a/src/test/java/org/apache/sling/commons/messaging/mail/it/tests/MailTestSupport.java b/src/test/java/org/apache/sling/commons/messaging/mail/it/tests/MailTestSupport.java
index 6938dee..b49107a 100644
--- a/src/test/java/org/apache/sling/commons/messaging/mail/it/tests/MailTestSupport.java
+++ b/src/test/java/org/apache/sling/commons/messaging/mail/it/tests/MailTestSupport.java
@@ -31,6 +31,7 @@ import org.apache.sling.testing.paxexam.SlingOptions;
 import org.apache.sling.testing.paxexam.TestSupport;
 import org.ops4j.pax.exam.options.MavenArtifactProvisionOption;
 import org.ops4j.pax.exam.options.ModifiableCompositeOption;
+import org.osgi.framework.BundleContext;
 import org.osgi.service.cm.ConfigurationAdmin;
 import org.thymeleaf.ITemplateEngine;
 import org.thymeleaf.TemplateEngine;
@@ -51,6 +52,9 @@ import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
 public abstract class MailTestSupport extends TestSupport {
 
     @Inject
+    protected BundleContext bundleContext;
+
+    @Inject
     protected ConfigurationAdmin configurationAdmin;
 
     private ITemplateEngine templateEngine = new TemplateEngine();
diff --git a/src/test/java/org/apache/sling/commons/messaging/mail/it/tests/SimpleMailServiceIT.java b/src/test/java/org/apache/sling/commons/messaging/mail/it/tests/SimpleMailServiceIT.java
index 2557f28..8eeb27d 100644
--- a/src/test/java/org/apache/sling/commons/messaging/mail/it/tests/SimpleMailServiceIT.java
+++ b/src/test/java/org/apache/sling/commons/messaging/mail/it/tests/SimpleMailServiceIT.java
@@ -20,8 +20,11 @@ package org.apache.sling.commons.messaging.mail.it.tests;
 
 import java.io.UnsupportedEncodingException;
 import java.security.Security;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
+import java.util.Dictionary;
+import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -29,10 +32,13 @@ import java.util.Properties;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
-import javax.activation.DataSource;
 import javax.inject.Inject;
 import javax.mail.Message;
 import javax.mail.Session;
+import javax.mail.event.ConnectionEvent;
+import javax.mail.event.ConnectionListener;
+import javax.mail.event.TransportEvent;
+import javax.mail.event.TransportListener;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
 
@@ -56,6 +62,7 @@ import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
 import org.ops4j.pax.exam.spi.reactors.PerClass;
 import org.ops4j.pax.exam.util.Filter;
 import org.ops4j.pax.exam.util.PathUtils;
+import org.osgi.framework.ServiceRegistration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -139,6 +146,8 @@ public class SimpleMailServiceIT extends MailTestSupport {
                 .put("mail.smtps.port", local ? port : Integer.getInteger("sling.test.mail.smtps.port"))
                 .put("username", local ? "username" : System.getProperty("sling.test.mail.smtps.username"))
                 .put("password", local ? "OEKPFL5cVJRqVjh4QaDZhvBiqv8wgWBMJ8PGbYHTqev046oV6888mna9w1mIGCXK" : System.getProperty("sling.test.mail.smtps.password"))
+                .put("connectionListeners.target", "(is=used)")
+                .put("transportListeners.target", "(is=used)")
                 .asOption(),
             // Commons Crypto
             factoryConfiguration("org.apache.sling.commons.crypto.jasypt.internal.JasyptStandardPBEStringCryptoService")
@@ -201,7 +210,7 @@ public class SimpleMailServiceIT extends MailTestSupport {
     }
 
     @Test
-    public void sendText() throws Exception {
+    public void testSendTextMessage() throws Exception {
         final Map<String, Object> variables = Collections.singletonMap("date", new Date());
         final String subject = "Sling Commons Mail: Text [æåëęïįœøüū] \uD83D\uDCE7";
         final String text = renderTextTemplate("/template.txt", variables);
@@ -234,7 +243,7 @@ public class SimpleMailServiceIT extends MailTestSupport {
     }
 
     @Test
-    public void sendTextAndAttachment() throws Exception {
+    public void testSendTextAndAttachmentMessage() throws Exception {
         final Map<String, Object> variables = Collections.singletonMap("date", new Date());
         final String subject = "Sling Commons Mail: Text and Attachment [æåëęïįœøüū] \uD83D\uDCE7";
         final String text = renderTextTemplate("/template.txt", variables);
@@ -268,7 +277,7 @@ public class SimpleMailServiceIT extends MailTestSupport {
     }
 
     @Test
-    public void sendHtml() throws Exception {
+    public void testSendHtmlMessage() throws Exception {
         final Map<String, Object> variables = Collections.singletonMap("date", new Date());
         final String subject = "Sling Commons Mail: HTML [æåëęïįœøüū] \uD83D\uDCE7";
         final String html = renderHtmlTemplate("/template.html", variables);
@@ -300,7 +309,7 @@ public class SimpleMailServiceIT extends MailTestSupport {
     }
 
     @Test
-    public void sendHtmlAndAttachment() throws Exception {
+    public void testSendHtmlAndAttachmentMessage() throws Exception {
         final Map<String, Object> variables = Collections.singletonMap("date", new Date());
         final String subject = "Sling Commons Mail: HTML and Attachment [æåëęïįœøüū] \uD83D\uDCE7";
         final String html = renderHtmlTemplate("/template.html", variables);
@@ -334,7 +343,7 @@ public class SimpleMailServiceIT extends MailTestSupport {
     }
 
     @Test
-    public void sendHtmlWithInlineImageAndAttachment() throws Exception {
+    public void testSendHtmlWithInlineImageAndAttachmentMessage() throws Exception {
         final Map<String, Object> variables = Collections.singletonMap("date", new Date());
         final String subject = "Sling Commons Mail: HTML with Inline Images and Attachment [æåëęïįœøüū] \uD83D\uDCE7";
         final String html = renderHtmlTemplate("/template-inlines.html", variables);
@@ -369,7 +378,7 @@ public class SimpleMailServiceIT extends MailTestSupport {
     }
 
     @Test
-    public void sendHtmlWithInlineImageAndTextAndAttachment() throws Exception {
+    public void testSendHtmlWithInlineImageAndTextAndAttachmentMessage() throws Exception {
         final Map<String, Object> variables = Collections.singletonMap("date", new Date());
         final String subject = "Sling Commons Mail: HTML with Inline Images and Text and Attachment [æåëęïįœøüū] \uD83D\uDCE7";
         final String text = renderTextTemplate("/template.txt", variables);
@@ -402,13 +411,92 @@ public class SimpleMailServiceIT extends MailTestSupport {
             assertThat(parser.getPlainContent()).isEqualTo(text);
             assertThat(parser.getHtmlContent()).isEqualTo(html);
 
-            final List<DataSource> sources = parser.getAttachmentList();
-            for (DataSource source : sources) {
-                logger.info("data source: {}, {}", source.getName(), source.getContentType());
-            }
-
             assertThat(parser.getContentIds()).contains("sling");
         }
     }
 
+    @Test
+    public void testListeners() throws Exception {
+        final Dictionary<String, String> propertiesUsed = new Hashtable<>();
+        propertiesUsed.put("is", "used");
+        final RecordingConnectionListener usedConnectionListener = new RecordingConnectionListener();
+        final ServiceRegistration<ConnectionListener> usedCLSR = bundleContext.registerService(ConnectionListener.class, usedConnectionListener, propertiesUsed);
+        final NoopTransportListener usedTransportListener = new NoopTransportListener();
+        final ServiceRegistration<TransportListener> usedTLSR = bundleContext.registerService(TransportListener.class, usedTransportListener, propertiesUsed);
+
+        final Dictionary<String, String> propertiesUnused = new Hashtable<>();
+        propertiesUnused.put("is", "unused");
+        final RecordingConnectionListener unusedConnectionListener = new RecordingConnectionListener();
+        final ServiceRegistration<ConnectionListener> unusedCLSR = bundleContext.registerService(ConnectionListener.class, unusedConnectionListener, propertiesUnused);
+        final NoopTransportListener unusedTransportListener = new NoopTransportListener();
+        final ServiceRegistration<TransportListener> unusedTLSR = bundleContext.registerService(TransportListener.class, unusedTransportListener, propertiesUnused);
+
+        final MimeMessage message = initializeMessageBuilder()
+            .subject("Sling Commons Mail: Testing Listeners")
+            .text("Testing Connection and Transport Listeners")
+            .build();
+
+        final CompletableFuture<MimeMessage> future = mailService.sendMessage(message);
+        future.get();
+
+        assertThat(unusedCLSR.getReference().getUsingBundles()).isNull();
+        assertThat(unusedTLSR.getReference().getUsingBundles()).isNull();
+
+        assertThat(usedCLSR.getReference().getUsingBundles()).hasLength(1);
+        assertThat(usedTLSR.getReference().getUsingBundles()).hasLength(1);
+
+        assertThat(usedCLSR.getReference().getUsingBundles()[0].getSymbolicName()).isEqualTo("org.apache.sling.commons.messaging.mail");
+        assertThat(usedTLSR.getReference().getUsingBundles()[0].getSymbolicName()).isEqualTo("org.apache.sling.commons.messaging.mail");
+
+        assertThat(usedConnectionListener.opened.size()).isEqualTo(1);
+        assertThat(usedConnectionListener.closed.size()).isEqualTo(1);
+    }
+
+    private static class RecordingConnectionListener implements ConnectionListener {
+
+        public List<ConnectionEvent> opened = new ArrayList<>();
+
+        public List<ConnectionEvent> disconnected = new ArrayList<>();
+
+        public List<ConnectionEvent> closed = new ArrayList<>();
+
+        public RecordingConnectionListener() {
+        }
+
+        @Override
+        public void opened(final ConnectionEvent connectionEvent) {
+            opened.add(connectionEvent);
+        }
+
+        @Override
+        public void disconnected(final ConnectionEvent connectionEvent) {
+            disconnected.add(connectionEvent);
+        }
+
+        @Override
+        public void closed(final ConnectionEvent connectionEvent) {
+            closed.add(connectionEvent);
+        }
+
+    }
+
+    private static class NoopTransportListener implements TransportListener {
+
+        public NoopTransportListener() {
+        }
+
+        @Override
+        public void messageDelivered(final TransportEvent transportEvent) {
+        }
+
+        @Override
+        public void messageNotDelivered(final TransportEvent transportEvent) {
+        }
+
+        @Override
+        public void messagePartiallyDelivered(final TransportEvent transportEvent) {
+        }
+
+    }
+
 }