You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ro...@apache.org on 2017/01/10 14:18:44 UTC
[29/50] [abbrv] james-project git commit: JAMES-1877 Extract delivery
to single server to MailDelivrer
JAMES-1877 Extract delivery to single server to MailDelivrer
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/f567a5a5
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/f567a5a5
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/f567a5a5
Branch: refs/heads/master
Commit: f567a5a5606aceb53b4bf02beb9384f0d62b31a7
Parents: a0ca1bf
Author: Benoit Tellier <bt...@linagora.com>
Authored: Fri Dec 2 10:20:51 2016 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Jan 10 15:12:51 2017 +0700
----------------------------------------------------------------------
.../remoteDelivery/DeliveryRunnable.java | 126 ++--------------
.../remoteDelivery/MailDelivrerToHost.java | 142 +++++++++++++++++++
2 files changed, 155 insertions(+), 113 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/james-project/blob/f567a5a5/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java
index d62f6f6..37ae531 100644
--- a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/DeliveryRunnable.java
@@ -20,20 +20,16 @@
package org.apache.james.transport.mailets.remoteDelivery;
import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
-import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.SendFailedException;
-import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.ParseException;
@@ -51,24 +47,21 @@ import org.apache.mailet.MailAddress;
import org.apache.mailet.MailetContext;
import org.slf4j.Logger;
-import com.google.common.base.Optional;
-import com.sun.mail.smtp.SMTPTransport;
-
@SuppressWarnings("deprecation")
public class DeliveryRunnable implements Runnable {
- public static final String BIT_MIME_8 = "8BITMIME";
private final MailQueue queue;
private final RemoteDeliveryConfiguration configuration;
private final DNSService dnsServer;
private final Metric outgoingMailsMetric;
private final Logger logger;
private final Bouncer bouncer;
+ private final MailDelivrerToHost mailDelivrerToHost;
private final VolatileIsDestroyed volatileIsDestroyed;
private final MessageComposer messageComposer;
- private final Converter7Bit converter7Bit;
- public DeliveryRunnable(MailQueue queue, RemoteDeliveryConfiguration configuration, DNSService dnsServer, Metric outgoingMailsMetric, Logger logger, MailetContext mailetContext, VolatileIsDestroyed volatileIsDestroyed) {
+ public DeliveryRunnable(MailQueue queue, RemoteDeliveryConfiguration configuration, DNSService dnsServer, Metric outgoingMailsMetric,
+ Logger logger, MailetContext mailetContext, VolatileIsDestroyed volatileIsDestroyed) {
this.queue = queue;
this.configuration = configuration;
this.dnsServer = dnsServer;
@@ -76,8 +69,8 @@ public class DeliveryRunnable implements Runnable {
this.logger = logger;
this.volatileIsDestroyed = volatileIsDestroyed;
this.messageComposer = new MessageComposer(configuration);
- this.converter7Bit = new Converter7Bit(mailetContext);
this.bouncer = new Bouncer(configuration, messageComposer, mailetContext, logger);
+ this.mailDelivrerToHost = new MailDelivrerToHost(configuration, mailetContext, logger);
}
/**
@@ -86,7 +79,6 @@ public class DeliveryRunnable implements Runnable {
*/
@Override
public void run() {
- final Session session = obtainSession(configuration.createFinalJavaxProperties());
try {
while (!Thread.interrupted() && !volatileIsDestroyed.isDestroyed()) {
try {
@@ -100,7 +92,7 @@ public class DeliveryRunnable implements Runnable {
if (configuration.isDebug()) {
logger.debug(Thread.currentThread().getName() + " will process mail " + mail.getName());
}
- attemptDelivery(session, mail);
+ attemptDelivery(mail);
LifecycleUtil.dispose(mail);
mail = null;
queueItem.done(true);
@@ -126,8 +118,8 @@ public class DeliveryRunnable implements Runnable {
}
}
- private void attemptDelivery(Session session, Mail mail) throws MailQueue.MailQueueException {
- ExecutionResult executionResult = deliver(mail, session);
+ private void attemptDelivery(Mail mail) throws MailQueue.MailQueueException {
+ ExecutionResult executionResult = deliver(mail);
switch (executionResult.getExecutionState()) {
case SUCCESS:
outgoingMailsMetric.increment();
@@ -182,9 +174,9 @@ public class DeliveryRunnable implements Runnable {
* @return boolean Whether the delivery was successful and the message can
* be deleted
*/
- private ExecutionResult deliver(Mail mail, Session session) {
+ private ExecutionResult deliver(Mail mail) {
try {
- return tryDeliver(mail, session);
+ return tryDeliver(mail);
} catch (SendFailedException sfe) {
return handleSenderFailedException(mail, sfe);
} catch (MessagingException ex) {
@@ -210,7 +202,7 @@ public class DeliveryRunnable implements Runnable {
}
}
- private ExecutionResult tryDeliver(Mail mail, Session session) throws MessagingException {
+ private ExecutionResult tryDeliver(Mail mail) throws MessagingException {
if (mail.getRecipients().isEmpty()) {
logger.info("No recipients specified... not sure how this could have happened.");
return ExecutionResult.permanentFailure(new Exception("No recipients specified for " + mail.getName() + " sent by " + mail.getSender()));
@@ -239,15 +231,15 @@ public class DeliveryRunnable implements Runnable {
targetServers = getGatewaySMTPHostAddresses(configuration.getGatewayServer());
}
- return doDeliver(mail, session, mail.getMessage(), convertToInetAddr(mail.getRecipients()), targetServers);
+ return doDeliver(mail, mail.getMessage(), convertToInetAddr(mail.getRecipients()), targetServers);
}
- private ExecutionResult doDeliver(Mail mail, Session session, MimeMessage message, InternetAddress[] addr, Iterator<HostAddress> targetServers) throws MessagingException {
+ private ExecutionResult doDeliver(Mail mail, MimeMessage message, InternetAddress[] addr, Iterator<HostAddress> targetServers) throws MessagingException {
MessagingException lastError = null;
while (targetServers.hasNext()) {
try {
- if (tryDeliveryToHost(mail, session, message, addr, targetServers.next())) {
+ if (mailDelivrerToHost.tryDeliveryToHost(mail, message, addr, targetServers.next())) {
return ExecutionResult.success();
}
} catch (SendFailedException sfe) {
@@ -273,39 +265,6 @@ public class DeliveryRunnable implements Runnable {
return ExecutionResult.temporaryFailure();
}
- private boolean tryDeliveryToHost(Mail mail, Session session, MimeMessage message, InternetAddress[] addr, HostAddress outgoingMailServer) throws MessagingException {
- Properties props = session.getProperties();
- if (mail.getSender() == null) {
- props.put("mail.smtp.from", "<>");
- } else {
- String sender = mail.getSender().toString();
- props.put("mail.smtp.from", sender);
- }
- logger.debug("Attempting delivery of " + mail.getName() + " to host " + outgoingMailServer.getHostName()
- + " at " + outgoingMailServer.getHost() + " from " + props.get("mail.smtp.from"));
-
- // Many of these properties are only in later JavaMail versions
- // "mail.smtp.ehlo" //default true
- // "mail.smtp.auth" //default false
- // "mail.smtp.dsn.ret" //default to nothing... appended as
- // RET= after MAIL FROM line.
- // "mail.smtp.dsn.notify" //default to nothing...appended as
- // NOTIFY= after RCPT TO line.
-
- SMTPTransport transport = null;
- try {
- transport = (SMTPTransport) session.getTransport(outgoingMailServer);
- transport.setLocalHost( props.getProperty("mail.smtp.localhost", configuration.getHeloNameProvider().getHeloName()) );
- connect(outgoingMailServer, transport);
- transport.sendMessage(adaptToTransport(message, transport), addr);
- logger.debug("Mail (" + mail.getName() + ") sent successfully to " + outgoingMailServer.getHostName() +
- " at " + outgoingMailServer.getHost() + " from " + props.get("mail.smtp.from") + " for " + mail.getRecipients());
- return true;
- } finally {
- closeTransport(mail, outgoingMailServer, transport);
- }
- }
-
private MessagingException handleMessagingException(Mail mail, MessagingException me) throws MessagingException {
MessagingException lastError;// MessagingException are horribly difficult to figure out what actually happened.
logger.debug("Exception delivering message (" + mail.getName() + ") - " + me.getMessage());
@@ -468,61 +427,6 @@ public class DeliveryRunnable implements Runnable {
return addr;
}
- private MimeMessage adaptToTransport(MimeMessage message, SMTPTransport transport) throws MessagingException {
- // if the transport is a SMTPTransport (from sun) some
- // performance enhancement can be done.
- if (transport.getClass().getName().endsWith(".SMTPTransport")) {
- // if the message is alredy 8bit or binary and the server doesn't support the 8bit extension it has
- // to be converted to 7bit. Javamail api doesn't perform
- // that conversion, but it is required to be a rfc-compliant smtp server.
-
- // Temporarily disabled. See JAMES-638
- if (!transport.supportsExtension(BIT_MIME_8)) {
- try {
- converter7Bit.convertTo7Bit(message);
- } catch (IOException e) {
- // An error has occured during the 7bit conversion.
- // The error is logged and the message is sent anyway.
-
- logger.error("Error during the conversion to 7 bit.", e);
- }
- }
- } else {
- // If the transport is not the one developed by Sun we are not sure of how it
- // handles the 8 bit mime stuff, so I convert the message to 7bit.
- try {
- converter7Bit.convertTo7Bit(message);
- } catch (IOException e) {
- logger.error("Error during the conversion to 7 bit.", e);
- }
- }
- return message;
- }
-
- private void closeTransport(Mail mail, HostAddress outgoingMailServer, SMTPTransport transport) {
- if (transport != null) {
- try {
- // James-899: transport.close() sends QUIT to the server; if that fails
- // (e.g. because the server has already closed the connection) the message
- // should be considered to be delivered because the error happened outside
- // of the mail transaction (MAIL, RCPT, DATA).
- transport.close();
- } catch (MessagingException e) {
- logger.error("Warning: could not close the SMTP transport after sending mail (" + mail.getName() + ") to " + outgoingMailServer.getHostName() + " at " + outgoingMailServer.getHost() + " for " + mail.getRecipients() + "; probably the server has already closed the "
- + "connection. Message is considered to be delivered. Exception: " + e.getMessage());
- }
- transport = null;
- }
- }
-
- private void connect(HostAddress outgoingMailServer, SMTPTransport transport) throws MessagingException {
- if (configuration.getAuthUser() != null) {
- transport.connect(outgoingMailServer.getHostName(), configuration.getAuthUser(), configuration.getAuthPass());
- } else {
- transport.connect();
- }
- }
-
private ExecutionResult handleTemporaryResolutionException(Mail mail, String host) {
ExecutionResult executionResult = ExecutionResult.temporaryFailure(new MessagingException("Temporary problem looking " +
"up mail server for host: " + host + ". I cannot determine where to send this message."));
@@ -548,10 +452,6 @@ public class DeliveryRunnable implements Runnable {
}
}
- protected Session obtainSession(Properties props) {
- return Session.getInstance(props);
- }
-
private long getNextDelay(int retry_count) {
if (retry_count > configuration.getDelayTimes().size()) {
return Delay.DEFAULT_DELAY_TIME;
http://git-wip-us.apache.org/repos/asf/james-project/blob/f567a5a5/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/MailDelivrerToHost.java
----------------------------------------------------------------------
diff --git a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/MailDelivrerToHost.java b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/MailDelivrerToHost.java
new file mode 100644
index 0000000..46bd8f9
--- /dev/null
+++ b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/remoteDelivery/MailDelivrerToHost.java
@@ -0,0 +1,142 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.transport.mailets.remoteDelivery;
+
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.mailet.HostAddress;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailetContext;
+import org.slf4j.Logger;
+
+import com.sun.mail.smtp.SMTPTransport;
+
+@SuppressWarnings("deprecation")
+public class MailDelivrerToHost {
+ public static final String BIT_MIME_8 = "8BITMIME";
+
+ private final RemoteDeliveryConfiguration configuration;
+ private final Converter7Bit converter7Bit;
+ private final Session session;
+ private final Logger logger;
+
+ public MailDelivrerToHost(RemoteDeliveryConfiguration remoteDeliveryConfiguration, MailetContext mailetContext, Logger logger) {
+ this.configuration = remoteDeliveryConfiguration;
+ this.converter7Bit = new Converter7Bit(mailetContext);
+ this.session = Session.getInstance(configuration.createFinalJavaxProperties());
+ this.logger = logger;
+ }
+
+ public boolean tryDeliveryToHost(Mail mail, MimeMessage message, InternetAddress[] addr, HostAddress outgoingMailServer) throws MessagingException {
+ Properties props = session.getProperties();
+ if (mail.getSender() == null) {
+ props.put("mail.smtp.from", "<>");
+ } else {
+ String sender = mail.getSender().toString();
+ props.put("mail.smtp.from", sender);
+ }
+ logger.debug("Attempting delivery of " + mail.getName() + " to host " + outgoingMailServer.getHostName()
+ + " at " + outgoingMailServer.getHost() + " from " + props.get("mail.smtp.from"));
+
+ // Many of these properties are only in later JavaMail versions
+ // "mail.smtp.ehlo" //default true
+ // "mail.smtp.auth" //default false
+ // "mail.smtp.dsn.ret" //default to nothing... appended as
+ // RET= after MAIL FROM line.
+ // "mail.smtp.dsn.notify" //default to nothing...appended as
+ // NOTIFY= after RCPT TO line.
+
+ SMTPTransport transport = null;
+ try {
+ transport = (SMTPTransport) session.getTransport(outgoingMailServer);
+ transport.setLocalHost( props.getProperty("mail.smtp.localhost", configuration.getHeloNameProvider().getHeloName()) );
+ connect(outgoingMailServer, transport);
+ transport.sendMessage(adaptToTransport(message, transport), addr);
+ logger.debug("Mail (" + mail.getName() + ") sent successfully to " + outgoingMailServer.getHostName() +
+ " at " + outgoingMailServer.getHost() + " from " + props.get("mail.smtp.from") + " for " + mail.getRecipients());
+ return true;
+ } finally {
+ closeTransport(mail, outgoingMailServer, transport);
+ }
+ }
+
+ private void connect(HostAddress outgoingMailServer, SMTPTransport transport) throws MessagingException {
+ if (configuration.getAuthUser() != null) {
+ transport.connect(outgoingMailServer.getHostName(), configuration.getAuthUser(), configuration.getAuthPass());
+ } else {
+ transport.connect();
+ }
+ }
+
+ private MimeMessage adaptToTransport(MimeMessage message, SMTPTransport transport) throws MessagingException {
+ // if the transport is a SMTPTransport (from sun) some
+ // performance enhancement can be done.
+ if (transport.getClass().getName().endsWith(".SMTPTransport")) {
+ // if the message is alredy 8bit or binary and the server doesn't support the 8bit extension it has
+ // to be converted to 7bit. Javamail api doesn't perform
+ // that conversion, but it is required to be a rfc-compliant smtp server.
+
+ // Temporarily disabled. See JAMES-638
+ if (!transport.supportsExtension(BIT_MIME_8)) {
+ try {
+ converter7Bit.convertTo7Bit(message);
+ } catch (IOException e) {
+ // An error has occured during the 7bit conversion.
+ // The error is logged and the message is sent anyway.
+
+ logger.error("Error during the conversion to 7 bit.", e);
+ }
+ }
+ } else {
+ // If the transport is not the one developed by Sun we are not sure of how it
+ // handles the 8 bit mime stuff, so I convert the message to 7bit.
+ try {
+ converter7Bit.convertTo7Bit(message);
+ } catch (IOException e) {
+ logger.error("Error during the conversion to 7 bit.", e);
+ }
+ }
+ return message;
+ }
+
+ private void closeTransport(Mail mail, HostAddress outgoingMailServer, SMTPTransport transport) {
+ if (transport != null) {
+ try {
+ // James-899: transport.close() sends QUIT to the server; if that fails
+ // (e.g. because the server has already closed the connection) the message
+ // should be considered to be delivered because the error happened outside
+ // of the mail transaction (MAIL, RCPT, DATA).
+ transport.close();
+ } catch (MessagingException e) {
+ logger.error("Warning: could not close the SMTP transport after sending mail (" + mail.getName() + ") to " + outgoingMailServer.getHostName() + " at " + outgoingMailServer.getHost() + " for " + mail.getRecipients() + "; probably the server has already closed the "
+ + "connection. Message is considered to be delivered. Exception: " + e.getMessage());
+ }
+ transport = null;
+ }
+ }
+
+
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org