Repository: james-project
Updated Branches:
  refs/heads/master 4bf777b1e -> 4bdc00096


JAMES-2340 Add metrics for SpamAssassin


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/4bdc0009
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/4bdc0009
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/4bdc0009

Branch: refs/heads/master
Commit: 4bdc000960fe867a40b21c6f5881658863d6ee0b
Parents: b296483
Author: benwa <btell...@linagora.com>
Authored: Mon Mar 26 11:31:35 2018 +0700
Committer: Matthieu Baechler <matth...@apache.org>
Committed: Mon Mar 26 15:30:11 2018 +0200

----------------------------------------------------------------------
 .../mailbox/spamassassin/SpamAssassin.java      |  9 ++-
 server/container/util/pom.xml                   |  4 +
 .../james/util/scanner/SpamAssassinInvoker.java | 82 ++++++++++----------
 .../util/scanner/SpamAssassinInvokerTest.java   |  3 +-
 .../james/transport/mailets/SpamAssassin.java   |  7 +-
 .../transport/mailets/SpamAssassinTest.java     |  3 +-
 .../fastfail/SpamAssassinHandler.java           | 11 ++-
 .../smtpserver/SpamAssassinHandlerTest.java     |  7 +-
 8 files changed, 76 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/4bdc0009/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassin.java
----------------------------------------------------------------------
diff --git 
a/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassin.java
 
b/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassin.java
index fb27e9a..a2c19f0 100644
--- 
a/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassin.java
+++ 
b/mailbox/plugin/spamassassin/src/main/java/org/apache/james/mailbox/spamassassin/SpamAssassin.java
@@ -23,6 +23,7 @@ import java.util.List;
 
 import javax.inject.Inject;
 
+import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.Host;
 import org.apache.james.util.scanner.SpamAssassinInvoker;
 
@@ -30,17 +31,19 @@ import com.github.fge.lambdas.Throwing;
 
 public class SpamAssassin {
 
+    private final MetricFactory metricFactory;
     private final SpamAssassinConfiguration spamAssassinConfiguration;
 
     @Inject
-    public SpamAssassin(SpamAssassinConfiguration spamAssassinConfiguration) {
+    public SpamAssassin(MetricFactory metricFactory, SpamAssassinConfiguration 
spamAssassinConfiguration) {
+        this.metricFactory = metricFactory;
         this.spamAssassinConfiguration = spamAssassinConfiguration;
     }
 
     public void learnSpam(List<InputStream> messages, String user) {
         if (spamAssassinConfiguration.isEnable()) {
             Host host = spamAssassinConfiguration.getHost().get();
-            SpamAssassinInvoker invoker = new 
SpamAssassinInvoker(host.getHostName(), host.getPort());
+            SpamAssassinInvoker invoker = new 
SpamAssassinInvoker(metricFactory, host.getHostName(), host.getPort());
             messages
                 .forEach(Throwing.consumer(message -> 
invoker.learnAsSpam(message, user)));
         }
@@ -49,7 +52,7 @@ public class SpamAssassin {
     public void learnHam(List<InputStream> messages, String user) {
         if (spamAssassinConfiguration.isEnable()) {
             Host host = spamAssassinConfiguration.getHost().get();
-            SpamAssassinInvoker invoker = new 
SpamAssassinInvoker(host.getHostName(), host.getPort());
+            SpamAssassinInvoker invoker = new 
SpamAssassinInvoker(metricFactory, host.getHostName(), host.getPort());
             messages
                 .forEach(Throwing.consumer(message -> 
invoker.learnAsHam(message, user)));
         }

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bdc0009/server/container/util/pom.xml
----------------------------------------------------------------------
diff --git a/server/container/util/pom.xml b/server/container/util/pom.xml
index c602027..653949f 100644
--- a/server/container/util/pom.xml
+++ b/server/container/util/pom.xml
@@ -40,6 +40,10 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>metrics-api</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
         </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bdc0009/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java
----------------------------------------------------------------------
diff --git 
a/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java
 
b/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java
index 80d1534..fdc3560 100644
--- 
a/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java
+++ 
b/server/container/util/src/main/java/org/apache/james/util/scanner/SpamAssassinInvoker.java
@@ -34,9 +34,11 @@ import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
 import org.apache.commons.io.IOUtils;
+import org.apache.james.metrics.api.MetricFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.github.fge.lambdas.Throwing;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Lists;
 
@@ -47,24 +49,35 @@ import com.google.common.collect.Lists;
 public class SpamAssassinInvoker {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(SpamAssassinInvoker.class);
 
+    enum MessageClass {
+        HAM("ham"),
+        SPAM("spam");
+
+        private final String value;
+
+        MessageClass(String value) {
+            this.value = value;
+        }
+    }
+
     private static final int SPAM_INDEX = 1;
     private static final int HITS_INDEX = 3;
     private static final int REQUIRED_HITS_INDEX = 5;
     private static final String CRLF = "\r\n";
 
+    private final MetricFactory metricFactory;
     private final String spamdHost;
-
     private final int spamdPort;
 
     /**
      * Init the spamassassin invoker
-     * 
+     *
      * @param spamdHost
      *            The host on which spamd runs
      * @param spamdPort
-     *            The port on which spamd listen
      */
-    public SpamAssassinInvoker(String spamdHost, int spamdPort) {
+    public SpamAssassinInvoker(MetricFactory metricFactory, String spamdHost, 
int spamdPort) {
+        this.metricFactory = metricFactory;
         this.spamdHost = spamdHost;
         this.spamdPort = spamdPort;
     }
@@ -84,7 +97,11 @@ public class SpamAssassinInvoker {
     }
 
     public SpamAssassinResult scanMail(MimeMessage message) throws 
MessagingException {
-        return scanMailWithAdditionalHeaders(message);
+        return metricFactory.withMetric(
+            "spamAssassin-check",
+            Throwing.supplier(
+                () -> scanMailWithoutAdditionalHeaders(message))
+            .sneakyThrow());
     }
 
     public SpamAssassinResult scanMailWithAdditionalHeaders(MimeMessage 
message, String... additionalHeaders) throws MessagingException {
@@ -122,6 +139,10 @@ public class SpamAssassinInvoker {
         }
     }
 
+    public SpamAssassinResult scanMailWithoutAdditionalHeaders(MimeMessage 
message) throws MessagingException {
+        return scanMailWithAdditionalHeaders(message);
+    }
+
     private SpamAssassinResult processSpam(String line) {
         List<String> elements = Lists.newArrayList(Splitter.on(' 
').split(line));
 
@@ -161,36 +182,11 @@ public class SpamAssassinInvoker {
      *             if an error occured during learning.
      */
     public boolean learnAsSpam(InputStream message, String user) throws 
MessagingException {
-        try (Socket socket = new Socket(spamdHost, spamdPort);
-                OutputStream out = socket.getOutputStream();
-                PrintWriter writer = new PrintWriter(out);
-                BufferedReader in = new BufferedReader(new 
InputStreamReader(socket.getInputStream()))) {
-
-            byte[] byteArray = IOUtils.toByteArray(message);
-            writer.write("TELL SPAMC/1.2");
-            writer.write(CRLF);
-            writer.write("Content-length: " + byteArray.length);
-            writer.write(CRLF);
-            writer.write("Message-class: spam");
-            writer.write(CRLF);
-            writer.write("Set: local, remote");
-            writer.write(CRLF);
-            writer.write("User: " + user);
-            writer.write(CRLF);
-            writer.write(CRLF);
-            writer.flush();
-
-            out.write(byteArray);
-            out.flush();
-            socket.shutdownOutput();
-
-            return in.lines()
-                .anyMatch(this::hasBeenSet);
-        } catch (UnknownHostException e) {
-            throw new MessagingException("Error communicating with spamd. 
Unknown host: " + spamdHost);
-        } catch (IOException e) {
-            throw new MessagingException("Error communicating with spamd on " 
+ spamdHost + ":" + spamdPort, e);
-        }
+        return metricFactory.withMetric(
+            "spamAssassin-spam-report",
+            Throwing.supplier(
+                () -> reportMessageAs(message, user, MessageClass.SPAM))
+                .sneakyThrow());
     }
 
     /**
@@ -202,17 +198,25 @@ public class SpamAssassinInvoker {
      *             if an error occured during learning.
      */
     public boolean learnAsHam(InputStream message, String user) throws 
MessagingException {
+        return metricFactory.withMetric(
+            "spamAssassin-ham-report",
+            Throwing.supplier(
+                () -> reportMessageAs(message, user, MessageClass.HAM))
+                .sneakyThrow());
+    }
+
+    private boolean reportMessageAs(InputStream message, String user, 
MessageClass messageClass) throws MessagingException {
         try (Socket socket = new Socket(spamdHost, spamdPort);
-                OutputStream out = socket.getOutputStream();
-                PrintWriter writer = new PrintWriter(out);
-                BufferedReader in = new BufferedReader(new 
InputStreamReader(socket.getInputStream()))) {
+             OutputStream out = socket.getOutputStream();
+             PrintWriter writer = new PrintWriter(out);
+             BufferedReader in = new BufferedReader(new 
InputStreamReader(socket.getInputStream()))) {
 
             byte[] byteArray = IOUtils.toByteArray(message);
             writer.write("TELL SPAMC/1.2");
             writer.write(CRLF);
             writer.write("Content-length: " + byteArray.length);
             writer.write(CRLF);
-            writer.write("Message-class: ham");
+            writer.write("Message-class: " + messageClass.value);
             writer.write(CRLF);
             writer.write("Set: local, remote");
             writer.write(CRLF);

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bdc0009/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java
----------------------------------------------------------------------
diff --git 
a/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java
 
b/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java
index 0f995a0..4901ba4 100644
--- 
a/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java
+++ 
b/server/container/util/src/test/java/org/apache/james/util/scanner/SpamAssassinInvokerTest.java
@@ -25,6 +25,7 @@ import java.nio.charset.StandardCharsets;
 
 import javax.mail.internet.MimeMessage;
 
+import org.apache.james.metrics.api.NoopMetricFactory;
 import org.apache.james.util.MimeMessageUtil;
 import org.apache.james.util.scanner.SpamAssassinExtension.SpamAssassin;
 import org.junit.jupiter.api.BeforeEach;
@@ -41,7 +42,7 @@ public class SpamAssassinInvokerTest {
     @BeforeEach
     public void setup(SpamAssassin spamAssassin) throws Exception {
         this.spamAssassin = spamAssassin;
-        testee = new SpamAssassinInvoker(spamAssassin.getIp(), 
spamAssassin.getBindingPort());
+        testee = new SpamAssassinInvoker(new NoopMetricFactory(), 
spamAssassin.getIp(), spamAssassin.getBindingPort());
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bdc0009/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SpamAssassin.java
----------------------------------------------------------------------
diff --git 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SpamAssassin.java
 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SpamAssassin.java
index bb8189c..6112cb3 100644
--- 
a/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SpamAssassin.java
+++ 
b/server/mailet/mailets/src/main/java/org/apache/james/transport/mailets/SpamAssassin.java
@@ -26,6 +26,7 @@ import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
 import org.apache.james.core.MailAddress;
+import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.user.api.UsersRepository;
 import org.apache.james.user.api.UsersRepositoryException;
 import org.apache.james.util.Port;
@@ -69,13 +70,15 @@ public class SpamAssassin extends GenericMailet {
     public static final String DEFAULT_HOST = "127.0.0.1";
     public static final int DEFAULT_PORT = 783;
 
+    private final MetricFactory metricFactory;
     private final UsersRepository usersRepository;
 
     private String spamdHost;
     private int spamdPort;
 
     @Inject
-    public SpamAssassin(UsersRepository usersRepository) {
+    public SpamAssassin(MetricFactory metricFactory, UsersRepository 
usersRepository) {
+        this.metricFactory = metricFactory;
         this.usersRepository = usersRepository;
     }
 
@@ -94,7 +97,7 @@ public class SpamAssassin extends GenericMailet {
         MimeMessage message = mail.getMessage();
 
         // Invoke SpamAssassin connection and scan the message
-        SpamAssassinInvoker sa = new SpamAssassinInvoker(spamdHost, spamdPort);
+        SpamAssassinInvoker sa = new SpamAssassinInvoker(metricFactory, 
spamdHost, spamdPort);
         mail.getRecipients()
             .forEach(
                 Throwing.consumer((MailAddress recipient) -> 
querySpamAssassin(mail, message, sa, recipient))

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bdc0009/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
----------------------------------------------------------------------
diff --git 
a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
 
b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
index a4a1049..466ad0c 100644
--- 
a/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
+++ 
b/server/mailet/mailets/src/test/java/org/apache/james/transport/mailets/SpamAssassinTest.java
@@ -25,6 +25,7 @@ import static 
org.assertj.core.api.Assertions.assertThatThrownBy;
 import javax.mail.MessagingException;
 
 import org.apache.james.core.builder.MimeMessageBuilder;
+import org.apache.james.metrics.api.NoopMetricFactory;
 import org.apache.james.user.memory.MemoryUsersRepository;
 import org.apache.james.util.Port;
 import org.apache.james.util.scanner.SpamAssassinResult;
@@ -41,7 +42,7 @@ public class SpamAssassinTest {
     @Rule
     public MockSpamdTestRule spamd = new MockSpamdTestRule();
 
-    private SpamAssassin mailet = new 
SpamAssassin(MemoryUsersRepository.withVirtualHosting());
+    private SpamAssassin mailet = new SpamAssassin(new NoopMetricFactory(), 
MemoryUsersRepository.withVirtualHosting());
 
     @Test
     public void initShouldSetDefaultSpamdHostWhenNone() throws Exception {

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bdc0009/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/SpamAssassinHandler.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/SpamAssassinHandler.java
 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/SpamAssassinHandler.java
index 14e6095..efa9611 100644
--- 
a/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/SpamAssassinHandler.java
+++ 
b/server/protocols/protocols-smtp/src/main/java/org/apache/james/smtpserver/fastfail/SpamAssassinHandler.java
@@ -19,11 +19,13 @@
 
 package org.apache.james.smtpserver.fastfail;
 
+import javax.inject.Inject;
 import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.configuration.ConfigurationException;
+import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.protocols.api.ProtocolSession.State;
 import org.apache.james.protocols.api.handler.ProtocolHandler;
 import org.apache.james.protocols.smtp.SMTPSession;
@@ -69,6 +71,8 @@ import org.slf4j.LoggerFactory;
 public class SpamAssassinHandler implements JamesMessageHook, ProtocolHandler {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(SpamAssassinHandler.class);
 
+    private final MetricFactory metricFactory;
+
     /** The port spamd is listen on */
     private int spamdPort = 783;
 
@@ -78,6 +82,11 @@ public class SpamAssassinHandler implements 
JamesMessageHook, ProtocolHandler {
     /** The hits on which the message get rejected */
     private double spamdRejectionHits = 0.0;
 
+    @Inject
+    public SpamAssassinHandler(MetricFactory metricFactory) {
+        this.metricFactory = metricFactory;
+    }
+
     /**
      * Set the host the spamd daemon is running at
      * 
@@ -114,7 +123,7 @@ public class SpamAssassinHandler implements 
JamesMessageHook, ProtocolHandler {
 
         try {
             MimeMessage message = mail.getMessage();
-            SpamAssassinInvoker sa = new SpamAssassinInvoker(spamdHost, 
spamdPort);
+            SpamAssassinInvoker sa = new SpamAssassinInvoker(metricFactory, 
spamdHost, spamdPort);
             SpamAssassinResult result = sa.scanMail(message);
 
             // Add the headers

http://git-wip-us.apache.org/repos/asf/james-project/blob/4bdc0009/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SpamAssassinHandlerTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SpamAssassinHandlerTest.java
 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SpamAssassinHandlerTest.java
index eeb79af..5507679 100644
--- 
a/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SpamAssassinHandlerTest.java
+++ 
b/server/protocols/protocols-smtp/src/test/java/org/apache/james/smtpserver/SpamAssassinHandlerTest.java
@@ -27,6 +27,7 @@ import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
 import org.apache.james.core.builder.MimeMessageBuilder;
+import org.apache.james.metrics.api.NoopMetricFactory;
 import org.apache.james.protocols.smtp.SMTPSession;
 import org.apache.james.protocols.smtp.hook.HookResult;
 import org.apache.james.protocols.smtp.hook.HookReturnCode;
@@ -111,7 +112,7 @@ public class SpamAssassinHandlerTest {
     public void testNonSpam() throws Exception {
         SMTPSession session = 
setupMockedSMTPSession(setupMockedMail(setupMockedMimeMessage("test")));
 
-        SpamAssassinHandler handler = new SpamAssassinHandler();
+        SpamAssassinHandler handler = new SpamAssassinHandler(new 
NoopMetricFactory());
 
         handler.setSpamdHost(SPAMD_HOST);
         handler.setSpamdPort(spamd.getPort());
@@ -128,7 +129,7 @@ public class SpamAssassinHandlerTest {
     public void testSpam() throws Exception {
         SMTPSession session = 
setupMockedSMTPSession(setupMockedMail(setupMockedMimeMessage(MockSpamd.GTUBE)));
 
-        SpamAssassinHandler handler = new SpamAssassinHandler();
+        SpamAssassinHandler handler = new SpamAssassinHandler(new 
NoopMetricFactory());
 
         handler.setSpamdHost(SPAMD_HOST);
         handler.setSpamdPort(spamd.getPort());
@@ -144,7 +145,7 @@ public class SpamAssassinHandlerTest {
     public void testSpamReject() throws Exception {
         SMTPSession session = 
setupMockedSMTPSession(setupMockedMail(setupMockedMimeMessage(MockSpamd.GTUBE)));
 
-        SpamAssassinHandler handler = new SpamAssassinHandler();
+        SpamAssassinHandler handler = new SpamAssassinHandler(new 
NoopMetricFactory());
 
         handler.setSpamdHost(SPAMD_HOST);
         handler.setSpamdPort(spamd.getPort());


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org
For additional commands, e-mail: server-dev-h...@james.apache.org

Reply via email to