camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject [3/4] camel git commit: 8569 Ability to easily extract email attachments
Date Mon, 13 Apr 2015 06:00:33 GMT
8569 Ability to easily extract email attachments

Code + unit for feature request 8569-Ability to easily extract email attachments


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a0e7002a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a0e7002a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a0e7002a

Branch: refs/heads/master
Commit: a0e7002aca8f82397c249dadb46b79de6617ae16
Parents: eaa84ef
Author: Simon van der Sluis <simon.vandersluis@edmi.co.nz>
Authored: Mon Mar 30 11:42:37 2015 +1300
Committer: Claus Ibsen <davsclaus@apache.org>
Committed: Mon Apr 13 07:54:21 2015 +0200

----------------------------------------------------------------------
 components/camel-mail/pom.xml                   |  6 ++
 .../mail/ExtractAttachmentsExpression.java      | 83 +++++++++++++++++
 .../mail/MailExtractAttachmentsTest.java        | 95 ++++++++++++++++++++
 3 files changed, 184 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/a0e7002a/components/camel-mail/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-mail/pom.xml b/components/camel-mail/pom.xml
index 5eef5a3..c69d445 100644
--- a/components/camel-mail/pom.xml
+++ b/components/camel-mail/pom.xml
@@ -93,6 +93,12 @@
             <artifactId>mockito-core</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+          <groupId>commons-io</groupId>
+          <artifactId>commons-io</artifactId>
+          <version>${commons-io-version}</version>
+          <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>

http://git-wip-us.apache.org/repos/asf/camel/blob/a0e7002a/components/camel-mail/src/main/java/org/apache/camel/component/mail/ExtractAttachmentsExpression.java
----------------------------------------------------------------------
diff --git a/components/camel-mail/src/main/java/org/apache/camel/component/mail/ExtractAttachmentsExpression.java
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/ExtractAttachmentsExpression.java
new file mode 100644
index 0000000..510b52c
--- /dev/null
+++ b/components/camel-mail/src/main/java/org/apache/camel/component/mail/ExtractAttachmentsExpression.java
@@ -0,0 +1,83 @@
+/**
+ * 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.camel.component.mail;
+
+import javax.activation.DataHandler;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.mail.util.BASE64DecoderStream;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.impl.DefaultMessage;
+import org.apache.camel.support.ExpressionAdapter;
+
+/**
+ * A {@link org.apache.camel.Expression} which can be used to split a {@link MailMessage}
+ * per attachment. For example if a mail message has 5 attachments, then this
+ * expression will return a <tt>List&lt;Message&gt;</tt> that contains
5 {@link Message}
+ * where the body of each Message is a byte[] containing an attachment.
+ */
+public class ExtractAttachmentsExpression extends ExpressionAdapter {
+
+    @Override
+    public Object evaluate(Exchange exchange) {
+        // must use getAttachments to ensure attachments is initially populated
+        if (exchange.getIn().getAttachments().isEmpty()) {
+            return null;
+        }
+
+        try {
+            return convertMimeparts(exchange.getIn());
+        } catch (Exception e) {
+            throw new RuntimeCamelException("Unable to extract attachments from MimeMultipart
message", e);
+        }
+    }
+
+    private List<Message> convertMimeparts(Message inMessage) throws Exception {
+        List<Message> outMessages = new ArrayList<>();
+        for (Map.Entry<String, DataHandler> entry : inMessage.getAttachments().entrySet())
{
+            final Message outMessage = new DefaultMessage();
+            final String key = entry.getKey();
+            outMessage.setHeader("CamelSplitAttachmentName", key);
+            Object attachment = inMessage.getAttachment(key).getContent();
+            if (attachment instanceof InputStream) {
+                outMessage.setBody(readMimePart((InputStream) attachment));
+                outMessages.add(outMessage);
+            }
+        }
+        return outMessages;
+    }
+
+    private byte[] readMimePart(InputStream mimePartStream) throws Exception {
+        //  mimePartStream could be base64 encoded, or not, but we dont need to worry about
it as
+        // camel is smart enough to wrap it in a decoder stream (eg Base64DecoderStream)
when required
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        int len;
+        byte[] buf = new byte[1024];
+        while ((len = mimePartStream.read(buf, 0, 1024)) != -1) {
+            bos.write(buf, 0, len);
+        }
+        mimePartStream.close();
+        return bos.toByteArray();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a0e7002a/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailExtractAttachmentsTest.java
----------------------------------------------------------------------
diff --git a/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailExtractAttachmentsTest.java
b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailExtractAttachmentsTest.java
new file mode 100644
index 0000000..7ed1ae7
--- /dev/null
+++ b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailExtractAttachmentsTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015 EDMI NZ
+ * All rights reserved.
+ *
+ * This software is the confidential and proprietary information of EDMI. 
+ * ("Confidential Information").  You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with EDMI.
+ */
+package org.apache.camel.component.mail;
+
+import javax.activation.DataHandler;
+import javax.activation.FileDataSource;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.Producer;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.jvnet.mock_javamail.Mailbox;
+
+/**
+ * Tests
+ *
+ * @author simonvandersluis
+ */
+public class MailExtractAttachmentsTest extends CamelTestSupport {
+
+  @Test
+  public void testExtractAttachments() throws Exception {
+
+    // clear mailbox
+    Mailbox.clearAll();
+
+    // create an exchange with a normal body and attachment to be produced as email
+    Endpoint endpoint = context.getEndpoint("smtp://james@mymailserver.com?password=secret");
+
+    // create the exchange with the mail message that is multipart with a file and a Hello
World text/plain message.
+    Exchange exchange = endpoint.createExchange();
+    Message in = exchange.getIn();
+    in.setBody("Hello World");
+    in.addAttachment("logo.jpeg", new DataHandler(new FileDataSource("src/test/data/logo.jpeg")));
+    in.addAttachment("license.txt", new DataHandler(new FileDataSource("src/main/resources/META-INF/LICENSE.txt")));
+
+    Producer producer = endpoint.createProducer();
+    producer.start();
+    producer.process(exchange);
+
+    Thread.sleep(2000);
+
+    MockEndpoint mock = getMockEndpoint("mock:split");
+    mock.expectedMessageCount(2);
+
+    mock.assertIsSatisfied();
+
+    Message first = mock.getReceivedExchanges().get(0).getIn();
+    Message second = mock.getReceivedExchanges().get(1).getIn();
+
+    // check it's no longer an attachment, but is the message body
+    assertEquals(0, first.getAttachments().size());
+    assertEquals(0, second.getAttachments().size());
+
+    assertEquals("logo.jpeg", first.getHeader("CamelSplitAttachmentName"));
+    assertEquals("license.txt", second.getHeader("CamelSplitAttachmentName"));
+
+    byte[] expected1 = IOUtils.toByteArray(new FileDataSource("src/test/data/logo.jpeg").getInputStream());
+    byte[] expected2 = IOUtils.toByteArray(new FileDataSource("src/main/resources/META-INF/LICENSE.txt").getInputStream());
+
+    assertArrayEquals(expected1, (byte[]) first.getBody());
+    assertArrayEquals(expected2, (byte[]) second.getBody());
+  }
+
+  @Override
+  protected RouteBuilder createRouteBuilder() throws Exception {
+    return new RouteBuilder() {
+      @Override
+      public void configure() throws Exception {
+        // START SNIPPET: e1
+        from("pop3://james@mymailserver.com?password=secret&consumer.delay=1000")
+                .to("log:email")
+                        // use the SplitAttachmentsExpression which will split the message
per attachment
+                .split(new ExtractAttachmentsExpression())
+                        // each message going to this mock has a single attachment
+                .to("mock:split")
+                .end();
+        // END SNIPPET: e1
+      }
+    };
+  }
+}


Mime
View raw message