james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From adup...@apache.org
Subject [2/3] james-project git commit: MAILET-147 Introduce a new mailet for mime attribute content extracting
Date Wed, 18 Jan 2017 20:20:13 GMT
MAILET-147 Introduce a new mailet for mime attribute content extracting


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

Branch: refs/heads/master
Commit: 6fcd884830e0d04d00edd22e74c19f3c682da71f
Parents: d7ec83f
Author: Antoine Duprat <aduprat@linagora.com>
Authored: Fri Jan 13 15:27:12 2017 +0100
Committer: Antoine Duprat <aduprat@linagora.com>
Committed: Wed Jan 18 14:48:20 2017 +0100

----------------------------------------------------------------------
 .../transport/mailets/AmqpForwardAttribute.java |  26 +---
 .../transport/mailets/MimeDecodingMailet.java   | 110 +++++++++++++
 .../mailets/AmqpForwardAttributeTest.java       |   4 +-
 .../mailets/MimeDecodingMailetTest.java         | 154 +++++++++++++++++++
 .../mailets/AmqpForwardAttachmentTest.java      |   5 +
 5 files changed, 278 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6fcd8848/mailet/standard/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java
----------------------------------------------------------------------
diff --git a/mailet/standard/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java
index 4596c7c..360898d 100644
--- a/mailet/standard/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java
+++ b/mailet/standard/src/main/java/org/apache/james/transport/mailets/AmqpForwardAttribute.java
@@ -19,16 +19,11 @@
 
 package org.apache.james.transport.mailets;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.Serializable;
 import java.util.Map;
 import java.util.concurrent.TimeoutException;
 
-import javax.mail.MessagingException;
-import javax.mail.internet.MimeBodyPart;
-
-import org.apache.commons.io.IOUtils;
 import org.apache.mailet.Mail;
 import org.apache.mailet.MailetException;
 import org.apache.mailet.base.GenericMailet;
@@ -70,6 +65,7 @@ public class AmqpForwardAttribute extends GenericMailet {
     private ConnectionFactory connectionFactory;
     @VisibleForTesting String routingKey;
 
+    @Override
     public void init() throws MailetException {
         String uri = getInitParameter(URI_PARAMETER_NAME);
         if (Strings.isNullOrEmpty(uri)) {
@@ -100,6 +96,7 @@ public class AmqpForwardAttribute extends GenericMailet {
         this.connectionFactory = connectionFactory;
     }
 
+    @Override
     public void service(Mail mail) throws MailetException {
         if (mail.getAttribute(attribute) == null) {
             return;
@@ -144,22 +141,15 @@ public class AmqpForwardAttribute extends GenericMailet {
     }
 
     private void sendContentOnChannel(Channel channel, Map<String, byte[]> content)
throws IOException {
-        for (Map.Entry<String, byte[]> entry: content.entrySet()) {
-            byte[] rawMime = entry.getValue();
-            byte[] attachmentContent = extractContent(rawMime);
-            channel.basicPublish(exchange, routingKey, new AMQP.BasicProperties(), attachmentContent);
-        }
-    }
-
-    private byte[] extractContent(byte[] rawMime) throws IOException {
-        try {
-            MimeBodyPart mimeBodyPart = new MimeBodyPart(new ByteArrayInputStream(rawMime));
-            return IOUtils.toByteArray(mimeBodyPart.getInputStream());
-        } catch (MessagingException e) {
-            throw new IOException(e);
+        for (byte[] body: content.values()) {
+            channel.basicPublish(exchange, 
+                    routingKey, 
+                    new AMQP.BasicProperties(), 
+                    body);
         }
     }
 
+    @Override
     public String getMailetInfo() {
         return "AmqpForwardAttribute";
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/6fcd8848/mailet/standard/src/main/java/org/apache/james/transport/mailets/MimeDecodingMailet.java
----------------------------------------------------------------------
diff --git a/mailet/standard/src/main/java/org/apache/james/transport/mailets/MimeDecodingMailet.java
b/mailet/standard/src/main/java/org/apache/james/transport/mailets/MimeDecodingMailet.java
new file mode 100644
index 0000000..78fcf02
--- /dev/null
+++ b/mailet/standard/src/main/java/org/apache/james/transport/mailets/MimeDecodingMailet.java
@@ -0,0 +1,110 @@
+/****************************************************************
+ * 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;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.Map;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeBodyPart;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.mailet.Mail;
+import org.apache.mailet.MailetException;
+import org.apache.mailet.base.GenericMailet;
+
+import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * This mailet replace the mail attribute map of key to MimePart
+ * by a map of key to the MimePart content (as bytes).
+ * <br />
+ * It takes only one parameter:
+ * <ul>
+ * <li>attribute (mandatory): mime content to be decoded, expected to be a Map&lt;String,
byte[]&gt;
+ * </ul>
+ *
+ * Then all this map attribute values will be replaced by their content.
+ */
+public class MimeDecodingMailet extends GenericMailet {
+
+    public static final String ATTRIBUTE_PARAMETER_NAME = "attribute";
+
+    private String attribute;
+
+    @Override
+    public void init() throws MessagingException {
+        attribute = getInitParameter(ATTRIBUTE_PARAMETER_NAME);
+        if (Strings.isNullOrEmpty(attribute)) {
+            throw new MailetException("No value for " + ATTRIBUTE_PARAMETER_NAME
+                    + " parameter was provided.");
+        }
+    }
+
+    @Override
+    public void service(Mail mail) throws MessagingException {
+        if (mail.getAttribute(attribute) == null) {
+            return;
+        }
+
+        ImmutableMap.Builder<String, byte[]> extractedMimeContentByName = ImmutableMap.builder();
+        for (Map.Entry<String, byte[]> entry: getAttributeContent(mail).entrySet())
{
+            Optional<byte[]> maybeContent = extractContent(entry.getValue());
+            if (maybeContent.isPresent()) {
+                extractedMimeContentByName.put(entry.getKey(), maybeContent.get());
+            }
+        }
+        mail.setAttribute(attribute, extractedMimeContentByName.build());
+    }
+
+    @SuppressWarnings("unchecked")
+    private Map<String, byte[]> getAttributeContent(Mail mail) throws MailetException
{
+        Serializable attributeContent = mail.getAttribute(attribute);
+        if (! (attributeContent instanceof Map)) {
+            log("Invalid attribute found into attribute "
+                    + attribute + "class Map expected but "
+                    + attributeContent.getClass() + " found.");
+            return ImmutableMap.of();
+        }
+        return (Map<String, byte[]>) attributeContent;
+    }
+
+    private Optional<byte[]> extractContent(Object rawMime) throws MessagingException
{
+        try {
+            MimeBodyPart mimeBodyPart = new MimeBodyPart(new ByteArrayInputStream((byte[])
rawMime));
+            return Optional.fromNullable(IOUtils.toByteArray(mimeBodyPart.getInputStream()));
+        } catch (IOException e) {
+            log("Error while extracting content from mime part", e);
+            return Optional.absent();
+        } catch (ClassCastException e) {
+            log("Invalid map attribute types.", e);
+            return Optional.absent();
+        }
+    }
+
+    @Override
+    public String getMailetInfo() {
+        return "MimeDecodingMailet";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6fcd8848/mailet/standard/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java
----------------------------------------------------------------------
diff --git a/mailet/standard/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java
index 5507b5e..dac1fab 100644
--- a/mailet/standard/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java
+++ b/mailet/standard/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttributeTest.java
@@ -47,7 +47,6 @@ import org.slf4j.Logger;
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.primitives.Bytes;
 import com.rabbitmq.client.AMQP;
 import com.rabbitmq.client.AMQP.BasicProperties;
 import com.rabbitmq.client.Channel;
@@ -60,9 +59,8 @@ public class AmqpForwardAttributeTest {
     private static final String EXCHANGE_NAME = "exchangeName";
     private static final String ROUTING_KEY = "routingKey";
     private static final String AMQP_URI = "amqp://host";
-    private static final byte[] ATTACHMENT_HEADER = "Content-Transfer-Encoding: 8bit\r\nContent-Type:
application/octet-stream; charset=utf-8\r\n\r\n".getBytes(Charsets.UTF_8);
     private static final byte[] ATTACHMENT_CONTENT = "Attachment content".getBytes(Charsets.UTF_8);
-    private static final ImmutableMap<String, byte[]> ATTRIBUTE_CONTENT = ImmutableMap.of("attachment1.txt",
Bytes.concat(ATTACHMENT_HEADER, ATTACHMENT_CONTENT));
+    private static final ImmutableMap<String, byte[]> ATTRIBUTE_CONTENT = ImmutableMap.of("attachment1.txt",
ATTACHMENT_CONTENT);
 
     @Rule
     public ExpectedException expectedException = ExpectedException.none();

http://git-wip-us.apache.org/repos/asf/james-project/blob/6fcd8848/mailet/standard/src/test/java/org/apache/james/transport/mailets/MimeDecodingMailetTest.java
----------------------------------------------------------------------
diff --git a/mailet/standard/src/test/java/org/apache/james/transport/mailets/MimeDecodingMailetTest.java
b/mailet/standard/src/test/java/org/apache/james/transport/mailets/MimeDecodingMailetTest.java
new file mode 100644
index 0000000..c540f44
--- /dev/null
+++ b/mailet/standard/src/test/java/org/apache/james/transport/mailets/MimeDecodingMailetTest.java
@@ -0,0 +1,154 @@
+/****************************************************************
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+
+import java.util.Map;
+
+import javax.mail.MessagingException;
+
+import org.apache.mailet.MailetContext;
+import org.apache.mailet.MailetException;
+import org.apache.mailet.base.test.FakeMail;
+import org.apache.mailet.base.test.FakeMailContext;
+import org.apache.mailet.base.test.FakeMailetConfig;
+import org.assertj.core.data.MapEntry;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.slf4j.Logger;
+
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class MimeDecodingMailetTest {
+
+    private static final String MAIL_ATTRIBUTE = "mime.attachments";
+
+    @Rule
+    public ExpectedException expectedException = ExpectedException.none();
+
+    private Logger logger;
+    private MailetContext mailetContext;
+    private MimeDecodingMailet testee;
+
+    @Before
+    public void setUp() throws Exception {
+        testee = new MimeDecodingMailet();
+        logger = mock(Logger.class);
+        mailetContext = FakeMailContext.builder()
+                .logger(logger)
+                .build();
+    }
+
+    @Test
+    public void initShouldThrowWhenNoAttributeParameter() throws MessagingException {
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .mailetContext(mailetContext)
+                .build();
+        expectedException.expect(MailetException.class);
+        testee.init(mailetConfig);
+    }
+
+    @Test
+    public void initShouldThrowWhenAttributeParameterIsEmpty() throws MessagingException
{
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .mailetContext(mailetContext)
+                .setProperty(MimeDecodingMailet.ATTRIBUTE_PARAMETER_NAME, "")
+                .build();
+        expectedException.expect(MailetException.class);
+        testee.init(mailetConfig);
+    }
+
+    @Test
+    public void serviceShouldNotThrowWhenAttributeContentIsNotAMap() throws MessagingException
{
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .mailetContext(mailetContext)
+                .setProperty(MimeDecodingMailet.ATTRIBUTE_PARAMETER_NAME, MAIL_ATTRIBUTE)
+                .build();
+        testee.init(mailetConfig);
+
+        FakeMail mail = FakeMail.defaultFakeMail();
+        mail.setAttribute(MAIL_ATTRIBUTE, ImmutableList.of());
+
+        testee.service(mail);
+    }
+
+    @Test
+    public void serviceShouldNotThrowWhenAttributeContentIsAMapOfWrongTypes() throws MessagingException
{
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .mailetContext(mailetContext)
+                .setProperty(MimeDecodingMailet.ATTRIBUTE_PARAMETER_NAME, MAIL_ATTRIBUTE)
+                .build();
+        testee.init(mailetConfig);
+
+        FakeMail mail = FakeMail.defaultFakeMail();
+        mail.setAttribute(MAIL_ATTRIBUTE, ImmutableMap.of("1", "2"));
+
+        testee.service(mail);
+    }
+
+    @Test
+    public void serviceShouldNotSetAttributeWhenNone() throws MessagingException {
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .mailetContext(mailetContext)
+                .setProperty(MimeDecodingMailet.ATTRIBUTE_PARAMETER_NAME, MAIL_ATTRIBUTE)
+                .build();
+        testee.init(mailetConfig);
+
+        FakeMail mail = FakeMail.defaultFakeMail();
+
+        testee.service(mail);
+        assertThat(mail.getAttribute(MAIL_ATTRIBUTE)).isNull();
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void serviceShouldChangeAttributeWhenDefined() throws MessagingException {
+        FakeMailetConfig mailetConfig = FakeMailetConfig.builder()
+                .mailetName("Test")
+                .mailetContext(mailetContext)
+                .setProperty(MimeDecodingMailet.ATTRIBUTE_PARAMETER_NAME, MAIL_ATTRIBUTE)
+                .build();
+        testee.init(mailetConfig);
+
+        FakeMail mail = FakeMail.defaultFakeMail();
+        String text = "Attachment content";
+        String content = "Content-Transfer-Encoding: 8bit\r\n"
+                + "Content-Type: application/octet-stream; charset=utf-8\r\n\r\n"
+                + text;
+        String expectedKey = "mimePart1";
+        mail.setAttribute(MAIL_ATTRIBUTE, ImmutableMap.of(expectedKey, content.getBytes(Charsets.UTF_8)));
+
+        byte[] expectedValue = text.getBytes(Charsets.UTF_8);
+        testee.service(mail);
+
+        Map<String, byte[]> processedAttribute = (Map<String, byte[]>) mail.getAttribute(MAIL_ATTRIBUTE);
+        assertThat(processedAttribute).containsExactly(MapEntry.entry(expectedKey, expectedValue));
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/6fcd8848/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttachmentTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttachmentTest.java
b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttachmentTest.java
index eb94ebf..67f63cd 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttachmentTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/AmqpForwardAttachmentTest.java
@@ -125,6 +125,11 @@ public class AmqpForwardAttachmentTest {
                             .build())
                     .addMailet(MailetConfiguration.builder()
                             .match("All")
+                            .clazz("MimeDecodingMailet")
+                            .addProperty("attribute", MAIL_ATTRIBUTE)
+                            .build())
+                    .addMailet(MailetConfiguration.builder()
+                            .match("All")
                             .clazz("AmqpForwardAttribute")
                             .addProperty("uri", amqpUri)
                             .addProperty("exchange", EXCHANGE_NAME)


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


Mime
View raw message