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

kao pushed a commit to branch 3.7.x
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/3.7.x by this push:
     new 5e0a60e6f0 JAMES-3791 Remote Delivery uses a pool of SMTP sessions.
5e0a60e6f0 is described below

commit 5e0a60e6f09a506a9806cf511effd2e2bdb53fb6
Author: Karsten Otto <[email protected]>
AuthorDate: Wed Jul 13 14:23:43 2022 +0200

    JAMES-3791 Remote Delivery uses a pool of SMTP sessions.
    
    This prevents a race condition in setting per-delivery properties.
    
    (cherry picked from commit ad05e797507bbab2bbb3709b402c3627262874c3)
---
 server/mailet/mailets/pom.xml                      |  4 ++
 .../remote/delivery/MailDelivrerToHost.java        | 67 ++++++++++++++++++----
 2 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/server/mailet/mailets/pom.xml b/server/mailet/mailets/pom.xml
index 56f19becde..493d2711fc 100644
--- a/server/mailet/mailets/pom.xml
+++ b/server/mailet/mailets/pom.xml
@@ -215,6 +215,10 @@
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.james</groupId>
             <artifactId>apache-mime4j-dom</artifactId>
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/MailDelivrerToHost.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/MailDelivrerToHost.java
index 64686f1eee..184a8aeb3a 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/MailDelivrerToHost.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remote/delivery/MailDelivrerToHost.java
@@ -39,6 +39,12 @@ import javax.mail.internet.MimeMessage;
 
 import org.apache.commons.lang3.NotImplementedException;
 import org.apache.commons.lang3.tuple.Pair;
+import org.apache.commons.pool2.BasePooledObjectFactory;
+import org.apache.commons.pool2.ObjectPool;
+import org.apache.commons.pool2.PooledObject;
+import org.apache.commons.pool2.impl.DefaultPooledObject;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 import org.apache.james.core.MailAddress;
 import org.apache.mailet.DsnParameters;
 import org.apache.mailet.HostAddress;
@@ -60,21 +66,43 @@ public class MailDelivrerToHost {
 
     private final RemoteDeliveryConfiguration configuration;
     private final Converter7Bit converter7Bit;
-    private final Session smtpSession;
-    private final Session smtpsSession;
+    private final ObjectPool<Session> smtpSessionPool;
+    private final ObjectPool<Session> smtpsSessionPool;
 
     public MailDelivrerToHost(RemoteDeliveryConfiguration 
remoteDeliveryConfiguration, MailetContext mailetContext) {
         this.configuration = remoteDeliveryConfiguration;
         this.converter7Bit = new Converter7Bit(mailetContext);
         if (configuration.isSSLEnable()) {
-            this.smtpSession = 
Session.getInstance(configuration.createFinalJavaxProperties());
-            this.smtpsSession = 
Session.getInstance(configuration.createFinalJavaxPropertiesWithSSL());
+            this.smtpSessionPool = 
createSessionPool(configuration.createFinalJavaxProperties());
+            this.smtpsSessionPool = 
createSessionPool(configuration.createFinalJavaxPropertiesWithSSL());
         } else {
-            this.smtpSession = 
Session.getInstance(configuration.createFinalJavaxProperties());
-            this.smtpsSession = this.smtpSession;
+            this.smtpSessionPool = 
createSessionPool(configuration.createFinalJavaxProperties());
+            this.smtpsSessionPool = smtpSessionPool;
         }
     }
 
+    private ObjectPool<Session> createSessionPool(Properties 
defaultConfiguration) {
+        GenericObjectPoolConfig<Session> poolConfig = new 
GenericObjectPoolConfig<>();
+        poolConfig.setMaxTotal(-1); // unbounded pool, scales to match peak 
delivery thread concurrency
+        return new GenericObjectPool<>(new BasePooledObjectFactory<>() {
+            @Override
+            public Session create() {
+                // Since we modify session properties per delivery, each 
session must have its own properties
+                return Session.getInstance(new 
Properties(defaultConfiguration));
+            }
+
+            @Override
+            public PooledObject<Session> wrap(Session session) {
+                return new DefaultPooledObject<>(session);
+            }
+
+            @Override
+            public void passivateObject(PooledObject<Session> p) {
+                p.getObject().getProperties().clear(); // reset to default 
configuration
+            }
+        }, poolConfig);
+    }
+
     public ExecutionResult tryDeliveryToHost(Mail mail, 
Collection<InternetAddress> addr, HostAddress outgoingMailServer) throws 
MessagingException {
         Session session = selectSession(outgoingMailServer);
         Properties props = getPropertiesForMail(mail, session);
@@ -101,15 +129,32 @@ public class MailDelivrerToHost {
                 outgoingMailServer.getHost(), props.get(inContext(session, 
"mail.smtp.from")), mail.getRecipients());
         } finally {
             closeTransport(mail, outgoingMailServer, transport);
+            releaseSession(outgoingMailServer, session);
         }
         return ExecutionResult.success();
     }
 
-    private Session selectSession(HostAddress host) {
-        if (host.getProtocol().equalsIgnoreCase("smtps")) {
-            return smtpsSession;
-        } else {
-            return smtpSession;
+    private Session selectSession(HostAddress host) throws MessagingException {
+        try {
+            if (host.getProtocol().equalsIgnoreCase("smtps")) {
+                return smtpsSessionPool.borrowObject();
+            } else {
+                return smtpSessionPool.borrowObject();
+            }
+        } catch (Exception e) {
+            throw new MessagingException("could not create SMTP session for 
mail delivery", e);
+        }
+    }
+
+    private void releaseSession(HostAddress host, Session session) {
+        try {
+            if (host.getProtocol().equalsIgnoreCase("smtps")) {
+                smtpsSessionPool.returnObject(session);
+            } else {
+                smtpSessionPool.returnObject(session);
+            }
+        } catch (Exception e) {
+            LOGGER.warn("Warning: failed to release SMTP session after mail 
delivery", e);
         }
     }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to