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 bt...@apache.org on 2017/01/24 09:49:43 UTC

[1/4] james-project git commit: MAILET-149 ICalToJson should not generate ICAL but take it from raw attachment

Repository: james-project
Updated Branches:
  refs/heads/master dc90ccda5 -> 9ff71bd26


MAILET-149 ICalToJson should not generate ICAL but take it from raw attachment


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

Branch: refs/heads/master
Commit: 6cdc4d503f071a1639b266595641d1d67877738e
Parents: dc90ccd
Author: Raphael Ouazana <ra...@linagora.com>
Authored: Mon Jan 23 17:15:04 2017 +0100
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Jan 24 16:48:58 2017 +0700

----------------------------------------------------------------------
 .../transport/mailets/ICALToJsonAttribute.java  |  36 ++-
 .../james/transport/mailets/model/ICAL.java     |   5 +-
 .../mailets/ICALToJsonAttributeTest.java        | 227 +++++++++--------
 .../james/transport/mailets/model/ICALTest.java |  75 ++----
 .../mailets/ICSAttachmentWorkflowTest.java      | 245 ++++++++++++++++++-
 .../src/test/resources/eml/yahooInvitation.eml  | 162 ++++++++++++
 6 files changed, 585 insertions(+), 165 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/6cdc4d50/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java
----------------------------------------------------------------------
diff --git a/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java b/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java
index 1e314af..b62ab33 100644
--- a/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java
+++ b/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java
@@ -75,12 +75,15 @@ import net.fortuna.ical4j.model.Calendar;
 public class ICALToJsonAttribute extends GenericMailet {
 
     public static final String SOURCE_ATTRIBUTE_NAME = "source";
+    public static final String RAW_SOURCE_ATTRIBUTE_NAME = "rawSource";
     public static final String DESTINATION_ATTRIBUTE_NAME = "destination";
     public static final String DEFAULT_SOURCE_ATTRIBUTE_NAME = "icalendar";
+    public static final String DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME = "attachments";
     public static final String DEFAULT_DESTINATION_ATTRIBUTE_NAME = "icalendarJson";
 
     private final ObjectMapper objectMapper;
     private String sourceAttributeName;
+    private String rawSourceAttributeName;
     private String destinationAttributeName;
 
     public ICALToJsonAttribute() {
@@ -92,6 +95,10 @@ public class ICALToJsonAttribute extends GenericMailet {
         return sourceAttributeName;
     }
 
+    public String getRawSourceAttributeName() {
+        return rawSourceAttributeName;
+    }
+
     public String getDestinationAttributeName() {
         return destinationAttributeName;
     }
@@ -104,10 +111,14 @@ public class ICALToJsonAttribute extends GenericMailet {
     @Override
     public void init() throws MessagingException {
         sourceAttributeName = getInitParameter(SOURCE_ATTRIBUTE_NAME, DEFAULT_SOURCE_ATTRIBUTE_NAME);
+        rawSourceAttributeName = getInitParameter(RAW_SOURCE_ATTRIBUTE_NAME, DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME);
         destinationAttributeName = getInitParameter(DESTINATION_ATTRIBUTE_NAME, DEFAULT_DESTINATION_ATTRIBUTE_NAME);
         if (Strings.isNullOrEmpty(sourceAttributeName)) {
             throw new MessagingException(SOURCE_ATTRIBUTE_NAME + " configuration parameter can not be null or empty");
         }
+        if (Strings.isNullOrEmpty(rawSourceAttributeName)) {
+            throw new MessagingException(RAW_SOURCE_ATTRIBUTE_NAME + " configuration parameter can not be null or empty");
+        }
         if (Strings.isNullOrEmpty(destinationAttributeName)) {
             throw new MessagingException(DESTINATION_ATTRIBUTE_NAME + " configuration parameter can not be null or empty");
         }
@@ -118,15 +129,19 @@ public class ICALToJsonAttribute extends GenericMailet {
         if (mail.getAttribute(sourceAttributeName) == null) {
             return;
         }
+        if (mail.getAttribute(rawSourceAttributeName) == null) {
+            return;
+        }
         if (mail.getSender() == null) {
             log("Skipping " + mail.getName() + " because no sender");
             return;
         }
         try {
             Map<String, Calendar> calendars = getCalendarMap(mail);
+            Map<String, byte[]> rawCalendars = getRawCalendarMap(mail);
             Map<String, byte[]> jsonsInByteForm = calendars.entrySet()
                 .stream()
-                .flatMap(calendar -> toJson(calendar, mail))
+                .flatMap(calendar -> toJson(calendar, rawCalendars, mail))
                 .collect(Guavate.toImmutableMap(Pair::getKey, Pair::getValue));
             mail.setAttribute(destinationAttributeName, (Serializable) jsonsInByteForm);
         } catch (ClassCastException e) {
@@ -139,10 +154,15 @@ public class ICALToJsonAttribute extends GenericMailet {
         return (Map<String, Calendar>) mail.getAttribute(sourceAttributeName);
     }
 
-    private Stream<Pair<String, byte[]>> toJson(Map.Entry<String, Calendar> entry, Mail mail) {
+    @SuppressWarnings("unchecked")
+    private Map<String, byte[]> getRawCalendarMap(Mail mail) {
+        return (Map<String, byte[]>) mail.getAttribute(rawSourceAttributeName);
+    }
+
+    private Stream<Pair<String, byte[]>> toJson(Map.Entry<String, Calendar> entry, Map<String, byte[]> rawCalendars, Mail mail) {
         return mail.getRecipients()
             .stream()
-            .flatMap(recipient -> toICAL(entry.getValue(), recipient, mail.getSender()))
+            .flatMap(recipient -> toICAL(entry, rawCalendars, recipient, mail.getSender()))
             .flatMap(ical -> toJson(ical, mail.getName()))
             .map(json -> Pair.of(UUID.randomUUID().toString(), json.getBytes(Charsets.UTF_8)));
     }
@@ -159,10 +179,16 @@ public class ICALToJsonAttribute extends GenericMailet {
         }
     }
 
-    private Stream<ICAL> toICAL(Calendar calendar, MailAddress recipient, MailAddress sender) {
+    private Stream<ICAL> toICAL(Map.Entry<String, Calendar> entry, Map<String, byte[]> rawCalendars, MailAddress recipient, MailAddress sender) {
+        Calendar calendar = entry.getValue();
+        byte[] rawICal = rawCalendars.get(entry.getKey());
+        if (rawICal == null) {
+            log("Cannot find matching raw ICAL from key: " + entry.getKey());
+            return Stream.of();
+        }
         try {
             return Stream.of(ICAL.builder()
-                .from(calendar)
+                .from(calendar, rawICal)
                 .recipient(recipient)
                 .sender(sender)
                 .build());

http://git-wip-us.apache.org/repos/asf/james-project/blob/6cdc4d50/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java
----------------------------------------------------------------------
diff --git a/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java b/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java
index b873a93..80f1555 100644
--- a/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java
+++ b/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java
@@ -25,6 +25,7 @@ import java.util.Optional;
 import org.apache.mailet.MailAddress;
 
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Charsets;
 import com.google.common.base.Preconditions;
 
 import net.fortuna.ical4j.model.Calendar;
@@ -45,8 +46,8 @@ public class ICAL {
         private Optional<String> method = Optional.empty();
         private Optional<String> recurrenceId = Optional.empty();
 
-        public Builder from(Calendar calendar) {
-            this.ical = calendar.toString();
+        public Builder from(Calendar calendar, byte[] originalEvent) {
+            this.ical = new String(originalEvent, Charsets.UTF_8);
             VEvent vevent = (VEvent) calendar.getComponent("VEVENT");
             this.uid = optionalOf(vevent.getUid());
             this.method = optionalOf(calendar.getMethod());

http://git-wip-us.apache.org/repos/asf/james-project/blob/6cdc4d50/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java
----------------------------------------------------------------------
diff --git a/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java b/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java
index fdddcaa..574878b 100644
--- a/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java
+++ b/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java
@@ -22,6 +22,8 @@ package org.apache.james.transport.mailets;
 import static net.javacrumbs.jsonunit.fluent.JsonFluentAssert.assertThatJson;
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -38,79 +40,16 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 
+import com.fasterxml.jackson.core.io.JsonStringEncoder;
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.io.ByteStreams;
 
 import net.fortuna.ical4j.data.CalendarBuilder;
 import net.fortuna.ical4j.model.Calendar;
 
 public class ICALToJsonAttributeTest {
     public static final MailAddress SENDER = MailAddressFixture.ANY_AT_JAMES;
-    public static final String MEETING_ICS = "\"BEGIN:VCALENDAR\\r\\n" +
-        "PRODID:-//Aliasource Groupe LINAGORA//OBM Calendar 3.2.1-rc2//FR\\r\\n" +
-        "CALSCALE:GREGORIAN\\r\\n" +
-        "X-OBM-TIME:1483703436\\r\\n" +
-        "VERSION:2.0\\r\\n" +
-        "METHOD:REQUEST\\r\\n" +
-        "BEGIN:VEVENT\\r\\n" +
-        "CREATED:20170106T115035Z\\r\\n" +
-        "LAST-MODIFIED:20170106T115036Z\\r\\n" +
-        "DTSTAMP:20170106T115036Z\\r\\n" +
-        "DTSTART:20170111T090000Z\\r\\n" +
-        "DURATION:PT1H30M\\r\\n" +
-        "TRANSP:OPAQUE\\r\\n" +
-        "SEQUENCE:0\\r\\n" +
-        "SUMMARY:Sprint planning #23\\r\\n" +
-        "DESCRIPTION:\\r\\n" +
-        "CLASS:PUBLIC\\r\\n" +
-        "PRIORITY:5\\r\\n" +
-        "ORGANIZER;X-OBM-ID=128;CN=Raphael OUAZANA:MAILTO:ouazana@linagora.com\\r\\n" +
-        "X-OBM-DOMAIN:linagora.com\\r\\n" +
-        "X-OBM-DOMAIN-UUID:02874f7c-d10e-102f-acda-0015176f7922\\r\\n" +
-        "LOCATION:Hangout\\r\\n" +
-        "CATEGORIES:\\r\\n" +
-        "X-OBM-COLOR:\\r\\n" +
-        "UID:f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\\r\\n" +
-        "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Matthieu EXT_BAECHLER;PARTSTAT=NEEDS-ACTION;X-OBM-ID=302:MAILTO:baechler@linagora.com\\r\\n" +
-        "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Laura ROYET;PARTSTAT=NEEDS-ACTION;X-OBM-ID=723:MAILTO:royet@linagora.com\\r\\n" +
-        "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Raphael OUAZANA;PARTSTAT=ACCEPTED;X-OBM-ID=128:MAILTO:ouazana@linagora.com\\r\\n" +
-        "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Luc DUZAN;PARTSTAT=NEEDS-ACTION;X-OBM-ID=715:MAILTO:duzan@linagora.com\\r\\n" +
-        "ATTENDEE;CUTYPE=RESOURCE;CN=Salle de reunion Lyon;PARTSTAT=ACCEPTED;X-OBM-ID=66:MAILTO:noreply@linagora.com\\r\\n" +
-        "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Antoine DUPRAT;PARTSTAT=NEEDS-ACTION;X-OBM-ID=453:MAILTO:duprat@linagora.com\\r\\n" +
-        "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=\\\"Beno�t TELLIER\\\";PARTSTAT=NEEDS-ACTION;X-OBM-ID=623:MAILTO:tellier@linagora.com\\r\\n" +
-        "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Quynh Quynh N NGUYEN;PARTSTAT=NEEDS-ACTION;X-OBM-ID=769:MAILTO:nguyen@linagora.com\\r\\n" +
-        "END:VEVENT\\r\\n" +
-        "END:VCALENDAR\\r\\n" +
-        "\"";
-    public static final String SMALL_ICS = "\"BEGIN:VCALENDAR\\r\\n" +
-        "PRODID:-//Aliasource Groupe LINAGORA//OBM Calendar 3.2.1-rc2//FR\\r\\n" +
-        "CALSCALE:GREGORIAN\\r\\n" +
-        "X-OBM-TIME:1483439571\\r\\n" +
-        "VERSION:2.0\\r\\n" +
-        "METHOD:REQUEST\\r\\n" +
-        "BEGIN:VEVENT\\r\\n" +
-        "CREATED:20170103T103250Z\\r\\n" +
-        "LAST-MODIFIED:20170103T103250Z\\r\\n" +
-        "DTSTAMP:20170103T103250Z\\r\\n" +
-        "DTSTART:20170120T100000Z\\r\\n" +
-        "DURATION:PT30M\\r\\n" +
-        "TRANSP:OPAQUE\\r\\n" +
-        "SEQUENCE:0\\r\\n" +
-        "SUMMARY:Sprint Social #3 Demo\\r\\n" +
-        "DESCRIPTION:\\r\\n" +
-        "CLASS:PUBLIC\\r\\n" +
-        "PRIORITY:5\\r\\n" +
-        "ORGANIZER;X-OBM-ID=468;CN=Attendee 1:MAILTO:attendee1@linagora.com\\r\\n" +
-        "X-OBM-DOMAIN:linagora.com\\r\\n" +
-        "X-OBM-DOMAIN-UUID:02874f7c-d10e-102f-acda-0015176f7922\\r\\n" +
-        "LOCATION:hangout\\r\\n" +
-        "CATEGORIES:\\r\\n" +
-        "X-OBM-COLOR:\\r\\n" +
-        "UID:f1514f44bf39311568d64072ac247c17656ceafde3b4b3eba961c8c5184cdc6ee047feb2aab16e43439a608f28671ab7c10e754c301b1e32001ad51dd20eac2fc7af20abf4093bbe\\r\\n" +
-        "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Attendee 2;PARTSTAT=NEEDS-ACTION;X-OBM-ID=348:MAILTO:attendee2@linagora.com\\r\\n" +
-        "END:VEVENT\\r\\n" +
-        "END:VCALENDAR\\r\\n" +
-        "\"";
 
     @Rule
     public ExpectedException expectedException = ExpectedException.none();
@@ -145,6 +84,15 @@ public class ICALToJsonAttributeTest {
     }
 
     @Test
+    public void initShouldThrowOnEmptyRawSourceAttribute() throws Exception {
+        expectedException.expect(MessagingException.class);
+
+        testee.init(FakeMailetConfig.builder()
+            .setProperty(ICALToJsonAttribute.RAW_SOURCE_ATTRIBUTE_NAME, "")
+            .build());
+    }
+
+    @Test
     public void initShouldThrowOnEmptyDestinationAttribute() throws Exception {
         expectedException.expect(MessagingException.class);
 
@@ -157,13 +105,16 @@ public class ICALToJsonAttributeTest {
     public void initShouldSetAttributesWhenPresent() throws Exception {
         String destination = "myDestination";
         String source = "mySource";
+        String raw = "myRaw";
         testee.init(FakeMailetConfig.builder()
             .setProperty(ICALToJsonAttribute.SOURCE_ATTRIBUTE_NAME, source)
             .setProperty(ICALToJsonAttribute.DESTINATION_ATTRIBUTE_NAME, destination)
+            .setProperty(ICALToJsonAttribute.RAW_SOURCE_ATTRIBUTE_NAME, raw)
             .build());
 
         assertThat(testee.getSourceAttributeName()).isEqualTo(source);
         assertThat(testee.getDestinationAttributeName()).isEqualTo(destination);
+        assertThat(testee.getRawSourceAttributeName()).isEqualTo(raw);
     }
 
     @Test
@@ -196,12 +147,25 @@ public class ICALToJsonAttributeTest {
     }
 
     @Test
-    public void serviceShouldNotFailOnWrongAttributeParameter() throws Exception {
+    public void serviceShouldNotFailOnWrongRawAttributeType() throws Exception {
         testee.init(FakeMailetConfig.builder().build());
 
-        ImmutableMap<String, String> wrongParametrizedMap = ImmutableMap.<String, String>builder()
-            .put("key", "value")
+        Mail mail = FakeMail.builder()
+            .sender(SENDER)
+            .recipient(MailAddressFixture.OTHER_AT_JAMES)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, "wrong type")
             .build();
+        testee.service(mail);
+
+        assertThat(mail.getAttribute(ICALToJsonAttribute.DEFAULT_DESTINATION_ATTRIBUTE_NAME))
+            .isNull();
+    }
+
+    @Test
+    public void serviceShouldNotFailOnWrongAttributeParameter() throws Exception {
+        testee.init(FakeMailetConfig.builder().build());
+
+        ImmutableMap<String, String> wrongParametrizedMap = ImmutableMap.of("key", "value");
         Mail mail = FakeMail.builder()
             .sender(SENDER)
             .recipient(MailAddressFixture.OTHER_AT_JAMES)
@@ -214,16 +178,32 @@ public class ICALToJsonAttributeTest {
     }
 
     @Test
-    public void serviceShouldFilterMailsWithoutSender() throws Exception {
+    public void serviceShouldNotFailOnWrongRawAttributeParameter() throws Exception {
         testee.init(FakeMailetConfig.builder().build());
 
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
-        ImmutableMap<String, Calendar> icals = ImmutableMap.<String, Calendar>builder()
-            .put("key", calendar)
+        ImmutableMap<String, String> wrongParametrizedMap = ImmutableMap.of("key", "value");
+        Mail mail = FakeMail.builder()
+            .sender(SENDER)
+            .recipient(MailAddressFixture.OTHER_AT_JAMES)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, wrongParametrizedMap)
             .build();
+        testee.service(mail);
+
+        assertThat(mail.getAttribute(ICALToJsonAttribute.DEFAULT_DESTINATION_ATTRIBUTE_NAME))
+            .isNull();
+    }
+
+    @Test
+    public void serviceShouldFilterMailsWithoutSender() throws Exception {
+        testee.init(FakeMailetConfig.builder().build());
+
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar);
         Mail mail = FakeMail.builder()
             .recipient(MailAddressFixture.OTHER_AT_JAMES)
             .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, icals)
             .build();
         testee.service(mail);
 
@@ -235,13 +215,14 @@ public class ICALToJsonAttributeTest {
     public void serviceShouldAttachEmptyListWhenNoRecipient() throws Exception {
         testee.init(FakeMailetConfig.builder().build());
 
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
-        ImmutableMap<String, Calendar> icals = ImmutableMap.<String, Calendar>builder()
-            .put("key", calendar)
-            .build();
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics);
         Mail mail = FakeMail.builder()
             .sender(SENDER)
             .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
             .build();
         testee.service(mail);
 
@@ -254,15 +235,16 @@ public class ICALToJsonAttributeTest {
     public void serviceShouldAttachJson() throws Exception {
         testee.init(FakeMailetConfig.builder().build());
 
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
-        ImmutableMap<String, Calendar> icals = ImmutableMap.<String, Calendar>builder()
-            .put("key", calendar)
-            .build();
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics);
         MailAddress recipient = MailAddressFixture.ANY_AT_JAMES2;
         Mail mail = FakeMail.builder()
             .sender(SENDER)
             .recipient(recipient)
             .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
             .build();
         testee.service(mail);
 
@@ -270,7 +252,7 @@ public class ICALToJsonAttributeTest {
         assertThat(jsons).hasSize(1);
         assertThatJson(new String(jsons.values().iterator().next(), Charsets.UTF_8))
             .isEqualTo("{" +
-                "\"ical\": " + MEETING_ICS +"," +
+                "\"ical\": \"" + toJsonValue(ics) +"\"," +
                 "\"sender\": \"" + SENDER.asString() + "\"," +
                 "\"recipient\": \"" + recipient.asString() + "\"," +
                 "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +
@@ -281,19 +263,24 @@ public class ICALToJsonAttributeTest {
                 "}");
     }
 
+    private String toJsonValue(byte[] ics) throws UnsupportedEncodingException {
+        return new String(JsonStringEncoder.getInstance().quoteAsUTF8(new String(ics, Charsets.UTF_8)), Charsets.UTF_8);
+    }
+
     @SuppressWarnings("unchecked")
     @Test
     public void serviceShouldAttachJsonForSeveralRecipient() throws Exception {
         testee.init(FakeMailetConfig.builder().build());
 
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
-        ImmutableMap<String, Calendar> icals = ImmutableMap.<String, Calendar>builder()
-            .put("key", calendar)
-            .build();
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics);
         Mail mail = FakeMail.builder()
             .sender(SENDER)
             .recipients(MailAddressFixture.OTHER_AT_JAMES, MailAddressFixture.ANY_AT_JAMES2)
             .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
             .build();
         testee.service(mail);
 
@@ -302,7 +289,7 @@ public class ICALToJsonAttributeTest {
         List<String> actual = toSortedValueList(jsons);
 
         assertThatJson(actual.get(0)).isEqualTo("{" +
-            "\"ical\": " + MEETING_ICS +"," +
+            "\"ical\": \"" + toJsonValue(ics) +"\"," +
             "\"sender\": \"" + SENDER.asString() + "\"," +
             "\"recipient\": \"" + MailAddressFixture.ANY_AT_JAMES2.asString() + "\"," +
             "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +
@@ -312,7 +299,7 @@ public class ICALToJsonAttributeTest {
             "\"recurrence-id\": null" +
             "}");
         assertThatJson(actual.get(1)).isEqualTo("{" +
-            "\"ical\": " + MEETING_ICS +"," +
+            "\"ical\": \"" + toJsonValue(ics) +"\"," +
             "\"sender\": \"" + SENDER.asString() + "\"," +
             "\"recipient\": \"" + MailAddressFixture.OTHER_AT_JAMES.asString() + "\"," +
             "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +
@@ -328,17 +315,18 @@ public class ICALToJsonAttributeTest {
     public void serviceShouldAttachJsonForSeveralICALs() throws Exception {
         testee.init(FakeMailetConfig.builder().build());
 
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
-        Calendar calendar2 = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting_2.ics"));
-        ImmutableMap<String, Calendar> icals = ImmutableMap.<String, Calendar>builder()
-            .put("key", calendar)
-            .put("key2", calendar2)
-            .build();
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        byte[] ics2 = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting_2.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        Calendar calendar2 = new CalendarBuilder().build(new ByteArrayInputStream(ics2));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar, "key2", calendar2);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics, "key2", ics2);
         MailAddress recipient = MailAddressFixture.OTHER_AT_JAMES;
         Mail mail = FakeMail.builder()
             .sender(SENDER)
             .recipient(recipient)
             .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
             .build();
         testee.service(mail);
 
@@ -347,7 +335,7 @@ public class ICALToJsonAttributeTest {
         List<String> actual = toSortedValueList(jsons);
 
         assertThatJson(actual.get(0)).isEqualTo("{" +
-            "\"ical\": " + SMALL_ICS +"," +
+            "\"ical\": \"" + toJsonValue(ics2) +"\"," +
             "\"sender\": \"" + SENDER.asString() + "\"," +
             "\"recipient\": \"" + recipient.asString() + "\"," +
             "\"uid\": \"f1514f44bf39311568d64072ac247c17656ceafde3b4b3eba961c8c5184cdc6ee047feb2aab16e43439a608f28671ab7c10e754c301b1e32001ad51dd20eac2fc7af20abf4093bbe\"," +
@@ -357,7 +345,7 @@ public class ICALToJsonAttributeTest {
             "\"recurrence-id\": null" +
             "}");
         assertThatJson(actual.get(1)).isEqualTo("{" +
-            "\"ical\": " + MEETING_ICS +"," +
+            "\"ical\": \"" + toJsonValue(ics) +"\"," +
             "\"sender\": \"" + SENDER.asString() + "\"," +
             "\"recipient\": \"" + recipient.asString() + "\"," +
             "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +
@@ -373,17 +361,54 @@ public class ICALToJsonAttributeTest {
     public void serviceShouldFilterInvalidICS() throws Exception {
         testee.init(FakeMailetConfig.builder().build());
 
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
-        Calendar calendar2 = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting_without_uid.ics"));
-        ImmutableMap<String, Calendar> icals = ImmutableMap.<String, Calendar>builder()
-            .put("key", calendar)
-            .put("key2", calendar2)
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        byte[] ics2 = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting_without_uid.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        Calendar calendar2 = new CalendarBuilder().build(new ByteArrayInputStream(ics2));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar, "key2", calendar2);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics, "key2", ics2);
+        MailAddress recipient = MailAddressFixture.OTHER_AT_JAMES;
+        Mail mail = FakeMail.builder()
+            .sender(SENDER)
+            .recipient(recipient)
+            .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
             .build();
+        testee.service(mail);
+
+        Map<String, byte[]> jsons = (Map<String, byte[]>) mail.getAttribute(ICALToJsonAttribute.DEFAULT_DESTINATION_ATTRIBUTE_NAME);
+        assertThat(jsons).hasSize(1);
+        List<String> actual = toSortedValueList(jsons);
+
+        assertThatJson(actual.get(0)).isEqualTo("{" +
+            "\"ical\": \"" + toJsonValue(ics) + "\"," +
+            "\"sender\": \"" + SENDER.asString() + "\"," +
+            "\"recipient\": \"" + recipient.asString() + "\"," +
+            "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +
+            "\"sequence\": \"0\"," +
+            "\"dtstamp\": \"20170106T115036Z\"," +
+            "\"method\": \"REQUEST\"," +
+            "\"recurrence-id\": null" +
+            "}");
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void serviceShouldFilterNonExistingKeys() throws Exception {
+        testee.init(FakeMailetConfig.builder().build());
+
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        byte[] ics2 = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting_2.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        Calendar calendar2 = new CalendarBuilder().build(new ByteArrayInputStream(ics2));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar, "key2", calendar2);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics);
         MailAddress recipient = MailAddressFixture.OTHER_AT_JAMES;
         Mail mail = FakeMail.builder()
             .sender(SENDER)
             .recipient(recipient)
             .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
             .build();
         testee.service(mail);
 
@@ -392,7 +417,7 @@ public class ICALToJsonAttributeTest {
         List<String> actual = toSortedValueList(jsons);
 
         assertThatJson(actual.get(0)).isEqualTo("{" +
-            "\"ical\": " + MEETING_ICS + "," +
+            "\"ical\": \"" + toJsonValue(ics) + "\"," +
             "\"sender\": \"" + SENDER.asString() + "\"," +
             "\"recipient\": \"" + recipient.asString() + "\"," +
             "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +

http://git-wip-us.apache.org/repos/asf/james-project/blob/6cdc4d50/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java
----------------------------------------------------------------------
diff --git a/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java b/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java
index f8ab4ab..b4ce81e 100644
--- a/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java
+++ b/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java
@@ -21,12 +21,16 @@ package org.apache.james.transport.mailets.model;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import java.io.ByteArrayInputStream;
+
 import org.apache.mailet.MailAddress;
 import org.apache.mailet.base.MailAddressFixture;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 
+import com.google.common.io.ByteStreams;
+
 import net.fortuna.ical4j.data.CalendarBuilder;
 import net.fortuna.ical4j.model.Calendar;
 import nl.jqno.equalsverifier.EqualsVerifier;
@@ -50,11 +54,12 @@ public class ICALTest {
     public void buildShouldFailWhenNoSender() throws Exception {
         expectedException.expect(NullPointerException.class);
 
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
 
         ICAL.builder()
             .recipient(MailAddressFixture.ANY_AT_JAMES)
-            .from(calendar)
+            .from(calendar, ics)
             .build();
     }
 
@@ -62,25 +67,27 @@ public class ICALTest {
     public void buildShouldFailWhenNoRecipient() throws Exception {
         expectedException.expect(NullPointerException.class);
 
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
 
         ICAL.builder()
             .sender(MailAddressFixture.OTHER_AT_JAMES)
-            .from(calendar)
+            .from(calendar, ics)
             .build();
     }
 
 
     @Test
     public void buildShouldWork() throws Exception {
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
 
         MailAddress recipient = MailAddressFixture.ANY_AT_JAMES;
         MailAddress sender = MailAddressFixture.OTHER_AT_JAMES;
         ICAL ical = ICAL.builder()
             .recipient(recipient)
             .sender(sender)
-            .from(calendar)
+            .from(calendar, ics)
             .build();
 
         assertThat(ical.getRecipient()).isEqualTo(recipient.asString());
@@ -92,41 +99,7 @@ public class ICALTest {
         assertThat(ical.getRecurrenceId()).isEmpty();
         assertThat(ical.getDtstamp()).contains("20170106T115036Z");
         assertThat(ical.getSequence()).isEqualTo("0");
-        assertThat(ical.getIcal()).isEqualTo("BEGIN:VCALENDAR\r\n" +
-            "PRODID:-//Aliasource Groupe LINAGORA//OBM Calendar 3.2.1-rc2//FR\r\n" +
-            "CALSCALE:GREGORIAN\r\n" +
-            "X-OBM-TIME:1483703436\r\n" +
-            "VERSION:2.0\r\n" +
-            "METHOD:REQUEST\r\n" +
-            "BEGIN:VEVENT\r\n" +
-            "CREATED:20170106T115035Z\r\n" +
-            "LAST-MODIFIED:20170106T115036Z\r\n" +
-            "DTSTAMP:20170106T115036Z\r\n" +
-            "DTSTART:20170111T090000Z\r\n" +
-            "DURATION:PT1H30M\r\n" +
-            "TRANSP:OPAQUE\r\n" +
-            "SEQUENCE:0\r\n" +
-            "SUMMARY:Sprint planning #23\r\n" +
-            "DESCRIPTION:\r\n" +
-            "CLASS:PUBLIC\r\n" +
-            "PRIORITY:5\r\n" +
-            "ORGANIZER;X-OBM-ID=128;CN=Raphael OUAZANA:MAILTO:ouazana@linagora.com\r\n" +
-            "X-OBM-DOMAIN:linagora.com\r\n" +
-            "X-OBM-DOMAIN-UUID:02874f7c-d10e-102f-acda-0015176f7922\r\n" +
-            "LOCATION:Hangout\r\n" +
-            "CATEGORIES:\r\n" +
-            "X-OBM-COLOR:\r\n" +
-            "UID:f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\r\n" +
-            "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Matthieu EXT_BAECHLER;PARTSTAT=NEEDS-ACTION;X-OBM-ID=302:MAILTO:baechler@linagora.com\r\n" +
-            "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Laura ROYET;PARTSTAT=NEEDS-ACTION;X-OBM-ID=723:MAILTO:royet@linagora.com\r\n" +
-            "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Raphael OUAZANA;PARTSTAT=ACCEPTED;X-OBM-ID=128:MAILTO:ouazana@linagora.com\r\n" +
-            "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Luc DUZAN;PARTSTAT=NEEDS-ACTION;X-OBM-ID=715:MAILTO:duzan@linagora.com\r\n" +
-            "ATTENDEE;CUTYPE=RESOURCE;CN=Salle de reunion Lyon;PARTSTAT=ACCEPTED;X-OBM-ID=66:MAILTO:noreply@linagora.com\r\n" +
-            "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Antoine DUPRAT;PARTSTAT=NEEDS-ACTION;X-OBM-ID=453:MAILTO:duprat@linagora.com\r\n" +
-            "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=\"Beno�t TELLIER\";PARTSTAT=NEEDS-ACTION;X-OBM-ID=623:MAILTO:tellier@linagora.com\r\n" +
-            "ATTENDEE;CUTYPE=INDIVIDUAL;RSVP=TRUE;CN=Quynh Quynh N NGUYEN;PARTSTAT=NEEDS-ACTION;X-OBM-ID=769:MAILTO:nguyen@linagora.com\r\n" +
-            "END:VEVENT\r\n" +
-            "END:VCALENDAR\r\n");
+        assertThat(ical.getIcal()).isEqualTo(new String(ics, "UTF-8"));
     }
 
     @Test
@@ -136,7 +109,8 @@ public class ICALTest {
 
     @Test
     public void buildShouldThrowOnCalendarWithoutDtstamp() throws Exception {
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting_without_dtstamp.ics"));
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting_without_dtstamp.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
 
         expectedException.expect(IllegalStateException.class);
 
@@ -145,13 +119,14 @@ public class ICALTest {
         ICAL.builder()
             .recipient(recipient)
             .sender(sender)
-            .from(calendar)
+            .from(calendar, ics)
             .build();
     }
 
     @Test
     public void buildShouldThrowOnCalendarWithoutUid() throws Exception {
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting_without_uid.ics"));
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting_without_uid.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
 
         expectedException.expect(IllegalStateException.class);
 
@@ -160,13 +135,14 @@ public class ICALTest {
         ICAL.builder()
             .recipient(recipient)
             .sender(sender)
-            .from(calendar)
+            .from(calendar, ics)
             .build();
     }
 
     @Test
     public void buildShouldThrowOnCalendarWithoutMethod() throws Exception {
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting_without_method.ics"));
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting_without_method.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
 
         expectedException.expect(IllegalStateException.class);
 
@@ -175,20 +151,21 @@ public class ICALTest {
         ICAL.builder()
             .recipient(recipient)
             .sender(sender)
-            .from(calendar)
+            .from(calendar, ics)
             .build();
     }
 
     @Test
     public void buildShouldSetDefaultValueWhenCalendarWithoutSequence() throws Exception {
-        Calendar calendar = new CalendarBuilder().build(ClassLoader.getSystemResourceAsStream("ics/meeting_without_sequence.ics"));
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting_without_sequence.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
 
         MailAddress recipient = MailAddressFixture.ANY_AT_JAMES;
         MailAddress sender = MailAddressFixture.OTHER_AT_JAMES;
         ICAL ical = ICAL.builder()
             .recipient(recipient)
             .sender(sender)
-            .from(calendar)
+            .from(calendar, ics)
             .build();
 
         assertThat(ical.getSequence()).isEqualTo(ICAL.DEFAULT_SEQUENCE_VALUE);

http://git-wip-us.apache.org/repos/asf/james-project/blob/6cdc4d50/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java
index 9302fe7..2cd1b5c 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java
@@ -33,6 +33,7 @@ import org.apache.james.mailets.configuration.MailetContainer;
 import org.apache.james.mailets.configuration.ProcessorConfiguration;
 import org.apache.james.mailets.utils.IMAPMessageReader;
 import org.apache.james.mailets.utils.SMTPMessageSender;
+import org.apache.james.queue.activemq.MimeMessageBlobMessageSource;
 import org.apache.james.transport.mailets.amqp.AmqpRule;
 import org.apache.james.util.streams.SwarmGenericContainer;
 import org.apache.mailet.Mail;
@@ -68,7 +69,9 @@ public class ICSAttachmentWorkflowTest {
     private static final String FROM = "fromUser@" + JAMES_APACHE_ORG;
     private static final String RECIPIENT = "touser@" + JAMES_APACHE_ORG;
 
-    private static final String MAIL_ATTRIBUTE = "my.attribute";
+    private static final String MAIL_ATTRIBUTE = "ical.attachments";
+    private static final String PARSED_ICAL_MAIL_ATTRIBUTE = "ical.parsed";
+    private static final String JSON_MAIL_ATTRIBUTE = "ical.json";
     private static final String EXCHANGE_NAME = "myExchange";
     private static final String ROUTING_KEY = "myRoutingKey";
     
@@ -228,8 +231,202 @@ public class ICSAttachmentWorkflowTest {
         "LU1PRElGSUVEOjIwMTcwMTE5VDE5MTgyM1oNCkxPQ0FUSU9OOg0KU0VRVUVOQ0U6MA0KU1RB\n" +
         "VFVTOkNPTkZJUk1FRA0KU1VNTUFSWToNClRSQU5TUDpPUEFRVUUNCkVORDpWRVZFTlQNCkVO\n" +
         "RDpWQ0FMRU5EQVINCg==";
-    public static final String ICS_BASE64_UID = "ah86k5m342bmcrbe9khkkhln00@google.com";
-    public static final String ICS_BASE64_DTSTAMP = "20170119T191823Z";
+    private static final String ICS_BASE64_UID = "ah86k5m342bmcrbe9khkkhln00@google.com";
+    private static final String ICS_BASE64_DTSTAMP = "20170119T191823Z";
+    private static final String ICS_YAHOO = "BEGIN:VCALENDAR\r\n" +
+            "PRODID://Yahoo//Calendar//EN\r\n" +
+            "VERSION:2.0\r\n" +
+            "METHOD:REQUEST\r\n" +
+            "BEGIN:VEVENT\r\n" +
+            "SUMMARY:Test from Yahoo\r\n" +
+            "CLASS:PUBLIC\r\n" +
+            "DTSTART;TZID=Europe/Brussels:20170127T150000\r\n" +
+            "DTEND;TZID=Europe/Brussels:20170127T160000\r\n" +
+            "LOCATION:Somewhere\r\n" +
+            "PRIORITY:0\r\n" +
+            "SEQUENCE:0\r\n" +
+            "STATUS:CONFIRMED\r\n" +
+            "UID:5014513f-1026-4b58-82cf-80d4fc060bbe\r\n" +
+            "DTSTAMP:20170123T121635Z\r\n" +
+            "ATTENDEE;PARTSTAT=NEEDS-ACTION;ROLE=REQ_PARTICIPANT;RSVP=TRUE;SCHEDULE-STAT\r\n" +
+            " US=1.1:mailto:ddolcimascolo@linagora.com\r\n" +
+            "ATTENDEE;PARTSTAT=NEEDS-ACTION;ROLE=REQ_PARTICIPANT;RSVP=TRUE;SCHEDULE-STAT\r\n" +
+            " US=1.1:mailto:rouazana@linagora.com\r\n" +
+            "ATTENDEE;PARTSTAT=NEEDS-ACTION;ROLE=REQ_PARTICIPANT;RSVP=TRUE;SCHEDULE-STAT\r\n" +
+            " US=1.1:mailto:aduprat@linagora.com\r\n" +
+            "ATTENDEE;PARTSTAT=NEEDS-ACTION;ROLE=REQ_PARTICIPANT;RSVP=TRUE;SCHEDULE-STAT\r\n" +
+            " US=1.1:mailto:btellier@linagora.com\r\n" +
+            "ORGANIZER;CN=OBM Linagora;SENT-BY=\"mailto:obmlinagora@yahoo.fr\":mailto:obml\r\n" +
+            " inagora@yahoo.fr\r\n" +
+            "X-YAHOO-YID:obmlinagora\r\n" +
+            "TRANSP:OPAQUE\r\n" +
+            "STATUS:CONFIRMED\r\n" +
+            "X-YAHOO-USER-STATUS:BUSY\r\n" +
+            "X-YAHOO-EVENT-STATUS:BUSY\r\n" +
+            "END:VEVENT\r\n" +
+            "BEGIN:VTIMEZONE\r\n" +
+            "TZID:Europe/Brussels\r\n" +
+            "TZURL:http://tzurl.org/zoneinfo/Europe/Brussels\r\n" +
+            "X-LIC-LOCATION:Europe/Brussels\r\n" +
+            "BEGIN:DAYLIGHT\r\n" +
+            "TZOFFSETFROM:+0100\r\n" +
+            "TZOFFSETTO:+0200\r\n" +
+            "TZNAME:CEST\r\n" +
+            "DTSTART:19810329T020000\r\n" +
+            "RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\n" +
+            "END:DAYLIGHT\r\n" +
+            "BEGIN:STANDARD\r\n" +
+            "TZOFFSETFROM:+0200\r\n" +
+            "TZOFFSETTO:+0100\r\n" +
+            "TZNAME:CET\r\n" +
+            "DTSTART:19961027T030000\r\n" +
+            "RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\n" +
+            "END:STANDARD\r\n" +
+            "BEGIN:STANDARD\r\n" +
+            "TZOFFSETFROM:+001730\r\n" +
+            "TZOFFSETTO:+001730\r\n" +
+            "TZNAME:BMT\r\n" +
+            "DTSTART:18800101T000000\r\n" +
+            "RDATE:18800101T000000\r\n" +
+            "END:STANDARD\r\n" +
+            "BEGIN:STANDARD\r\n" +
+            "TZOFFSETFROM:+001730\r\n" +
+            "TZOFFSETTO:+0000\r\n" +
+            "TZNAME:WET\r\n" +
+            "DTSTART:18920501T120000\r\n" +
+            "RDATE:18920501T120000\r\n" +
+            "END:STANDARD\r\n" +
+            "BEGIN:STANDARD\r\n" +
+            "TZOFFSETFROM:+0000\r\n" +
+            "TZOFFSETTO:+0100\r\n" +
+            "TZNAME:CET\r\n" +
+            "DTSTART:19141108T000000\r\n" +
+            "RDATE:19141108T000000\r\n" +
+            "END:STANDARD\r\n" +
+            "BEGIN:DAYLIGHT\r\n" +
+            "TZOFFSETFROM:+0100\r\n" +
+            "TZOFFSETTO:+0200\r\n" +
+            "TZNAME:CEST\r\n" +
+            "DTSTART:19160501T000000\r\n" +
+            "RDATE:19160501T000000\r\n" +
+            "RDATE:19170416T020000\r\n" +
+            "RDATE:19180415T020000\r\n" +
+            "RDATE:19400520T030000\r\n" +
+            "RDATE:19430329T020000\r\n" +
+            "RDATE:19440403T020000\r\n" +
+            "RDATE:19450402T020000\r\n" +
+            "RDATE:19460519T020000\r\n" +
+            "RDATE:19770403T020000\r\n" +
+            "RDATE:19780402T020000\r\n" +
+            "RDATE:19790401T020000\r\n" +
+            "RDATE:19800406T020000\r\n" +
+            "END:DAYLIGHT\r\n" +
+            "BEGIN:STANDARD\r\n" +
+            "TZOFFSETFROM:+0200\r\n" +
+            "TZOFFSETTO:+0100\r\n" +
+            "TZNAME:CET\r\n" +
+            "DTSTART:19161001T010000\r\n" +
+            "RDATE:19161001T010000\r\n" +
+            "RDATE:19170917T030000\r\n" +
+            "RDATE:19180916T030000\r\n" +
+            "RDATE:19421102T030000\r\n" +
+            "RDATE:19431004T030000\r\n" +
+            "RDATE:19440917T030000\r\n" +
+            "RDATE:19450916T030000\r\n" +
+            "RDATE:19461007T030000\r\n" +
+            "RDATE:19770925T030000\r\n" +
+            "RDATE:19781001T030000\r\n" +
+            "RDATE:19790930T030000\r\n" +
+            "RDATE:19800928T030000\r\n" +
+            "RDATE:19810927T030000\r\n" +
+            "RDATE:19820926T030000\r\n" +
+            "RDATE:19830925T030000\r\n" +
+            "RDATE:19840930T030000\r\n" +
+            "RDATE:19850929T030000\r\n" +
+            "RDATE:19860928T030000\r\n" +
+            "RDATE:19870927T030000\r\n" +
+            "RDATE:19880925T030000\r\n" +
+            "RDATE:19890924T030000\r\n" +
+            "RDATE:19900930T030000\r\n" +
+            "RDATE:19910929T030000\r\n" +
+            "RDATE:19920927T030000\r\n" +
+            "RDATE:19930926T030000\r\n" +
+            "RDATE:19940925T030000\r\n" +
+            "RDATE:19950924T030000\r\n" +
+            "END:STANDARD\r\n" +
+            "BEGIN:STANDARD\r\n" +
+            "TZOFFSETFROM:+0100\r\n" +
+            "TZOFFSETTO:+0000\r\n" +
+            "TZNAME:WET\r\n" +
+            "DTSTART:19181111T120000\r\n" +
+            "RDATE:19181111T120000\r\n" +
+            "RDATE:19191005T000000\r\n" +
+            "RDATE:19201024T000000\r\n" +
+            "RDATE:19211026T000000\r\n" +
+            "RDATE:19221008T000000\r\n" +
+            "RDATE:19231007T000000\r\n" +
+            "RDATE:19241005T000000\r\n" +
+            "RDATE:19251004T000000\r\n" +
+            "RDATE:19261003T000000\r\n" +
+            "RDATE:19271002T000000\r\n" +
+            "RDATE:19281007T030000\r\n" +
+            "RDATE:19291006T030000\r\n" +
+            "RDATE:19301005T030000\r\n" +
+            "RDATE:19311004T030000\r\n" +
+            "RDATE:19321002T030000\r\n" +
+            "RDATE:19331008T030000\r\n" +
+            "RDATE:19341007T030000\r\n" +
+            "RDATE:19351006T030000\r\n" +
+            "RDATE:19361004T030000\r\n" +
+            "RDATE:19371003T030000\r\n" +
+            "RDATE:19381002T030000\r\n" +
+            "RDATE:19391119T030000\r\n" +
+            "END:STANDARD\r\n" +
+            "BEGIN:DAYLIGHT\r\n" +
+            "TZOFFSETFROM:+0000\r\n" +
+            "TZOFFSETTO:+0100\r\n" +
+            "TZNAME:WEST\r\n" +
+            "DTSTART:19190301T230000\r\n" +
+            "RDATE:19190301T230000\r\n" +
+            "RDATE:19200214T230000\r\n" +
+            "RDATE:19210314T230000\r\n" +
+            "RDATE:19220325T230000\r\n" +
+            "RDATE:19230421T230000\r\n" +
+            "RDATE:19240329T230000\r\n" +
+            "RDATE:19250404T230000\r\n" +
+            "RDATE:19260417T230000\r\n" +
+            "RDATE:19270409T230000\r\n" +
+            "RDATE:19280414T230000\r\n" +
+            "RDATE:19290421T020000\r\n" +
+            "RDATE:19300413T020000\r\n" +
+            "RDATE:19310419T020000\r\n" +
+            "RDATE:19320403T020000\r\n" +
+            "RDATE:19330326T020000\r\n" +
+            "RDATE:19340408T020000\r\n" +
+            "RDATE:19350331T020000\r\n" +
+            "RDATE:19360419T020000\r\n" +
+            "RDATE:19370404T020000\r\n" +
+            "RDATE:19380327T020000\r\n" +
+            "RDATE:19390416T020000\r\n" +
+            "RDATE:19400225T020000\r\n" +
+            "END:DAYLIGHT\r\n" +
+            "BEGIN:DAYLIGHT\r\n" +
+            "TZOFFSETFROM:+0200\r\n" +
+            "TZOFFSETTO:+0200\r\n" +
+            "TZNAME:CEST\r\n" +
+            "DTSTART:19440903T000000\r\n" +
+            "RDATE:19440903T000000\r\n" +
+            "END:DAYLIGHT\r\n" +
+            "BEGIN:STANDARD\r\n" +
+            "TZOFFSETFROM:+0100\r\n" +
+            "TZOFFSETTO:+0100\r\n" +
+            "TZNAME:CET\r\n" +
+            "DTSTART:19770101T000000\r\n" +
+            "RDATE:19770101T000000\r\n" +
+            "END:STANDARD\r\n" +
+            "END:VTIMEZONE\r\n" +
+            "END:VCALENDAR\r\n" +
+            "";
 
     public SwarmGenericContainer rabbitMqContainer = new SwarmGenericContainer("rabbitmq:3")
             .withAffinityToContainer();
@@ -245,6 +442,7 @@ public class ICSAttachmentWorkflowTest {
     private MimeMessage messageWithICSAttached;
     private MimeMessage messageWithICSBase64Attached;
     private MimeMessage messageWithThreeICSAttached;
+    private MimeMessage yahooInvitationMessage;
 
     @Before
     public void setup() throws Exception {
@@ -276,25 +474,26 @@ public class ICSAttachmentWorkflowTest {
                             .match("All")
                             .clazz("ICalendarParser")
                             .addProperty("sourceAttribute", MAIL_ATTRIBUTE)
-                            .addProperty("destinationAttribute", MAIL_ATTRIBUTE)
+                            .addProperty("destinationAttribute", PARSED_ICAL_MAIL_ATTRIBUTE)
                             .build())
                     .addMailet(MailetConfiguration.builder()
                             .match("All")
                             .clazz("ICALToHeader")
-                            .addProperty("attribute", MAIL_ATTRIBUTE)
+                            .addProperty("attribute", PARSED_ICAL_MAIL_ATTRIBUTE)
                             .build())
                     .addMailet(MailetConfiguration.builder()
                             .match("All")
                             .clazz("ICALToJsonAttribute")
-                            .addProperty("source", MAIL_ATTRIBUTE)
-                            .addProperty("destination", MAIL_ATTRIBUTE)
+                            .addProperty("source", PARSED_ICAL_MAIL_ATTRIBUTE)
+                            .addProperty("rawSource", MAIL_ATTRIBUTE)
+                            .addProperty("destination", JSON_MAIL_ATTRIBUTE)
                             .build())
                     .addMailet(MailetConfiguration.builder()
                             .match("All")
                             .clazz("AmqpForwardAttribute")
                             .addProperty("uri", amqpRule.getAmqpUri())
                             .addProperty("exchange", EXCHANGE_NAME)
-                            .addProperty("attribute", MAIL_ATTRIBUTE)
+                            .addProperty("attribute", JSON_MAIL_ATTRIBUTE)
                             .addProperty("routing_key", ROUTING_KEY)
                             .build())
                     .addMailet(MailetConfiguration.builder()
@@ -352,6 +551,8 @@ public class ICSAttachmentWorkflowTest {
             .setSubject("test")
             .build();
 
+        yahooInvitationMessage = new MimeMessage(null, ClassLoader.getSystemResourceAsStream("yahooInvitation.eml"));
+
         messageWithThreeICSAttached = MimeMessageBuilder.mimeMessageBuilder()
             .setMultipartWithBodyParts(
                 MimeMessageBuilder.bodyPartBuilder()
@@ -531,6 +732,34 @@ public class ICSAttachmentWorkflowTest {
     }
 
     @Test
+    public void yahooBase64CalendarAttachmentShouldBePublishedInMQWhenMatchingWorkflowConfiguration() throws Exception {
+        Mail mail = FakeMail.builder()
+            .mimeMessage(yahooInvitationMessage)
+            .sender(new MailAddress(FROM))
+            .recipient(new MailAddress(RECIPIENT))
+            .build();
+
+        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT, JAMES_APACHE_ORG);
+             IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
+            messageSender.sendMessage(mail);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
+            calmlyAwait.atMost(Duration.ONE_MINUTE).until(() -> imapMessageReader.userReceivedMessage(RECIPIENT, PASSWORD));
+        }
+
+        Optional<String> content = amqpRule.readContent();
+        assertThat(content).isPresent();
+        DocumentContext jsonPath = toJsonPath(content.get());
+        assertThat(jsonPath.<String> read("sender")).isEqualTo(FROM);
+        assertThat(jsonPath.<String> read("recipient")).isEqualTo(RECIPIENT);
+        assertThat(jsonPath.<String> read("uid")).isEqualTo("5014513f-1026-4b58-82cf-80d4fc060bbe");
+        assertThat(jsonPath.<String> read("sequence")).isEqualTo("0");
+        assertThat(jsonPath.<String> read("dtstamp")).isEqualTo("20170123T121635Z");
+        assertThat(jsonPath.<String> read("method")).isEqualTo("REQUEST");
+        assertThat(jsonPath.<String> read("ical")).isEqualTo(ICS_YAHOO);
+        assertThat(jsonPath.<String> read("recurrence-id")).isNull();
+    }
+
+    @Test
     public void headersShouldBeFilledOnlyWithOneICalAttachmentWhenMailHasSeveral() throws Exception {
         Mail mail = FakeMail.builder()
               .mimeMessage(messageWithThreeICSAttached)

http://git-wip-us.apache.org/repos/asf/james-project/blob/6cdc4d50/server/mailet/integration-testing/src/test/resources/eml/yahooInvitation.eml
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/resources/eml/yahooInvitation.eml b/server/mailet/integration-testing/src/test/resources/eml/yahooInvitation.eml
new file mode 100644
index 0000000..aef88a8
--- /dev/null
+++ b/server/mailet/integration-testing/src/test/resources/eml/yahooInvitation.eml
@@ -0,0 +1,162 @@
+Return-Path: <do...@yahoo.com>
+Date: 23 Jan 2017 12:16:35 +0000
+To: raph.ouazana@linagora.com
+From: "OBM Linagora" <ob...@yahoo.fr>
+Reply-To: "OBM Linagora" <ob...@yahoo.fr> 
+MIME-Version: 1.0
+X-Yahoo-Newman-Property: calendar-remind
+X-Yahoo-Newman-Id: calendar-remind-87cf88d6-0909-4010-99a4-f156b375adbd
+Subject: ***SPAM*** =?UTF-8?Q?Invitation=C3=82=C2=A0:?= Test from Yahoo
+Content-Type: multipart/mixed;
+        boundary="_004_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_"
+Message-Id: <20...@obm3-ui.linagora.dc1>
+
+
+--_004_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_
+Content-Type: multipart/alternative;
+        boundary="_000_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_"
+
+--_000_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_
+Content-Type: text/plain; charset="utf-8"
+Content-Transfer-Encoding: quoted-printable
+
+
+--_000_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_
+Content-Type: text/html; charset="utf-8"
+Content-Transfer-Encoding: 8bit
+
+<div style="min-width: 300px; max-width: 585px; padding: 15px 15px 15px 15px; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: 13px; ">
+
+    <table style="margin: 0px 0px 0px 0px" cellspacing="0" cellpadding="0">
+			<tr>
+                <td>
+<div style="width:55px;height:55px;border-radius:5px;text-align:center;font-family:Helvetica Neue medium, Helvetica, Arial, sans-serif;color:white;background-color:#400090;">
+                        <div style="padding-top:5px;line-height:20px">
+                                <div style="font-size:12px;font-weight:lighter;">
+                                    JANV.
+                                </div>
+                                <div style="font-size:32px;font-weight:bolder;font-family:Helvetica Neue bold, Helvetica, Arial, sans-serif;">
+                                    27
+                                </div>
+                        </div>
+				    </div>
+					</td>
+				<td width="40px" />
+				<td
+					style="font-size: 24px; vertical-align: middle; color: #454545; font-weight: lighter; line-height: 26px;">
+                        
+    		"Test from Yahoo"
+	                        
+			
+	                </td>
+			</tr>
+
+		</table>
+    
+		<table style="text-shadow: white; border-collapse: collapse; margin-top: 30px; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; font-size: 13px; color: #454545"
+				cellspacing="0" cellpadding="0">
+			<tr>
+                <td style="color: #888888; vertical-align: top;">
+
+                                        	Quand
+                                    
+               </td>
+
+				<td width="40px" />
+				<td style="line-height: 18px;">
+                    vendredi, 27 janvier 2017<br>
+                    						03:00 PM � 04:00 PM <br>
+ 		                (GMT+01:00) Bruxelles/Copenhague/Madrid/Paris <br>
+                    
+										
+				</td>
+				
+			</tr>
+			<tr height="30px" />
+			
+			
+					<tr>
+				<td style="color: #888888; vertical-align: top;">
+                                         	O�
+                                    </td>
+				<td width="40px" />
+				<td>
+					Somewhere
+				</td>
+			</tr>
+			<tr height="30px" />
+				
+				
+
+                    
+            				                    
+			<tr>
+				<td style="color: #888888; vertical-align: top;">
+                                        	Invit�s
+                                    </td>
+                
+				<td width="40px" />
+				<td style="line-height: 18px;">
+                    
+																						ddolcimascolo@linagora.com<br>
+																								rouazana@linagora.com<br>
+																								aduprat@linagora.com<br>
+																								btellier@linagora.com<br>
+															                    
+				</td>
+			</tr>
+			<tr height="30px" />
+			    
+				<tr>
+					<td></td>
+					<td width="40px" />
+					<td>
+                 		<div style="background-color:#400090;border-radius:5px;height:35px;width:170px;text-align:center;text-shadow:white;line-height:30px;">
+						<a target="_top" href="http://calendar.yahoo.com/obmlinagora/rsvp?e=rouazana@linagora.com&uid=5014513f-1026-4b58-82cf-80d4fc060bbe&tk=0A1DKATbQagrUVo_7LICZiJtPyY-&hh=Ku0PHoAKTgogl3Ops44PvkDuKNM-"
+							style="text-decoration:none;font-size:15px;color:white;font-weight:normal;">R�pondre</a>
+						</div>    
+					</td>
+				</tr>
+                			
+		</table>     
+					                <div style="border-bottom: 1px solid #d5d5d5; margin-top: 50px; max-width: 590px; width: 100%;">
+                   
+            
+		
+		</div>
+            
+		<div
+			style="text-align: center; margin-top: 15px; font-family: helvetical, Arial, sans-serif; color: #878787; font-size: 12px; padding-bottom: 10px; max-width: 590px;">
+			<span style="font-size: 12px; font-family: Helvetica Neue, Helvetica, Arial, sans-serif; color: #454545; text-shadow: white;"> Cette invitation � un �v�nement a �t� envoy�e � partir de &nbsp; <a target="_blank" href="http://calendar.yahoo.com"
+				style="text-decoration: none; text-shadow: white; color: #2862c5;">Yahoo Agenda</a>
+			</span>
+		</div>
+	</div>
+</div>
+
+
+
+--_000_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_
+Content-Type: text/calendar; method=REQUEST; charset=UTF-8
+Content-Transfer-Encoding: base64
+
+QkVHSU46VkNBTEVOREFSDQpQUk9ESUQ6Ly9ZYWhvby8vQ2FsZW5kYXIvL0VODQpWRVJTSU9OOjIuMA0KTUVUSE9EOlJFUVVFU1QNCkJFR0lOOlZFVkVOVA0KU1VNTUFSWTpUZXN0IGZyb20gWWFob28NCkNMQVNTOlBVQkxJQw0KRFRTVEFSVDtUWklEPUV1cm9wZS9CcnVzc2VsczoyMDE3MDEyN1QxNTAwMDANCkRURU5EO1RaSUQ9RXVyb3BlL0JydXNzZWxzOjIwMTcwMTI3VDE2MDAwMA0KTE9DQVRJT046U29tZXdoZXJlDQpQUklPUklUWTowDQpTRVFVRU5DRTowDQpTVEFUVVM6Q09ORklSTUVEDQpVSUQ6NTAxNDUxM2YtMTAyNi00YjU4LTgyY2YtODBkNGZjMDYwYmJlDQpEVFNUQU1QOjIwMTcwMTIzVDEyMTYzNVoNCkFUVEVOREVFO1BBUlRTVEFUPU5FRURTLUFDVElPTjtST0xFPVJFUV9QQVJUSUNJUEFOVDtSU1ZQPVRSVUU7U0NIRURVTEUtU1RBVA0KIFVTPTEuMTptYWlsdG86ZGRvbGNpbWFzY29sb0BsaW5hZ29yYS5jb20NCkFUVEVOREVFO1BBUlRTVEFUPU5FRURTLUFDVElPTjtST0xFPVJFUV9QQVJUSUNJUEFOVDtSU1ZQPVRSVUU7U0NIRURVTEUtU1RBVA0KIFVTPTEuMTptYWlsdG86cm91YXphbmFAbGluYWdvcmEuY29tDQpBVFRFTkRFRTtQQVJUU1RBVD1ORUVEUy1BQ1RJT047Uk9MRT1SRVFfUEFSVElDSVBBTlQ7UlNWUD1UUlVFO1NDSEVEVUxFLVNUQVQNCiBVUz0xLjE6bWFpbHRvOmFkdXByYXRAbGluYWdvcmEuY29tDQpBVFRFTkRFRTtQQVJUU1RBVD1ORUVEUy1BQ1RJT047Uk9MRT1SRVFfUEFSVElDSVBBT
 l
+ Q7UlNWUD1UUlVFO1NDSEVEVUxFLVNUQVQNCiBVUz0xLjE6bWFpbHRvOmJ0ZWxsaWVyQGxpbmFnb3JhLmNvbQ0KT1JHQU5JWkVSO0NOPU9CTSBMaW5hZ29yYTtTRU5ULUJZPSJtYWlsdG86b2JtbGluYWdvcmFAeWFob28uZnIiOm1haWx0bzpvYm1sDQogaW5hZ29yYUB5YWhvby5mcg0KWC1ZQUhPTy1ZSUQ6b2JtbGluYWdvcmENClRSQU5TUDpPUEFRVUUNClNUQVRVUzpDT05GSVJNRUQNClgtWUFIT08tVVNFUi1TVEFUVVM6QlVTWQ0KWC1ZQUhPTy1FVkVOVC1TVEFUVVM6QlVTWQ0KRU5EOlZFVkVOVA0KQkVHSU46VlRJTUVaT05FDQpUWklEOkV1cm9wZS9CcnVzc2Vscw0KVFpVUkw6aHR0cDovL3R6dXJsLm9yZy96b25laW5mby9FdXJvcGUvQnJ1c3NlbHMNClgtTElDLUxPQ0FUSU9OOkV1cm9wZS9CcnVzc2Vscw0KQkVHSU46REFZTElHSFQNClRaT0ZGU0VURlJPTTorMDEwMA0KVFpPRkZTRVRUTzorMDIwMA0KVFpOQU1FOkNFU1QNCkRUU1RBUlQ6MTk4MTAzMjlUMDIwMDAwDQpSUlVMRTpGUkVRPVlFQVJMWTtCWU1PTlRIPTM7QllEQVk9LTFTVQ0KRU5EOkRBWUxJR0hUDQpCRUdJTjpTVEFOREFSRA0KVFpPRkZTRVRGUk9NOiswMjAwDQpUWk9GRlNFVFRPOiswMTAwDQpUWk5BTUU6Q0VUDQpEVFNUQVJUOjE5OTYxMDI3VDAzMDAwMA0KUlJVTEU6RlJFUT1ZRUFSTFk7QllNT05USD0xMDtCWURBWT0tMVNVDQpFTkQ6U1RBTkRBUkQNCkJFR0lOOlNUQU5EQVJEDQpUWk9GRlNFVEZST006KzAwMTczMA0KVFpPRkZTRVRUTzorMD
 A
+ xNzMwDQpUWk5BTUU6Qk1UDQpEVFNUQVJUOjE4ODAwMTAxVDAwMDAwMA0KUkRBVEU6MTg4MDAxMDFUMDAwMDAwDQpFTkQ6U1RBTkRBUkQNCkJFR0lOOlNUQU5EQVJEDQpUWk9GRlNFVEZST006KzAwMTczMA0KVFpPRkZTRVRUTzorMDAwMA0KVFpOQU1FOldFVA0KRFRTVEFSVDoxODkyMDUwMVQxMjAwMDANClJEQVRFOjE4OTIwNTAxVDEyMDAwMA0KRU5EOlNUQU5EQVJEDQpCRUdJTjpTVEFOREFSRA0KVFpPRkZTRVRGUk9NOiswMDAwDQpUWk9GRlNFVFRPOiswMTAwDQpUWk5BTUU6Q0VUDQpEVFNUQVJUOjE5MTQxMTA4VDAwMDAwMA0KUkRBVEU6MTkxNDExMDhUMDAwMDAwDQpFTkQ6U1RBTkRBUkQNCkJFR0lOOkRBWUxJR0hUDQpUWk9GRlNFVEZST006KzAxMDANClRaT0ZGU0VUVE86KzAyMDANClRaTkFNRTpDRVNUDQpEVFNUQVJUOjE5MTYwNTAxVDAwMDAwMA0KUkRBVEU6MTkxNjA1MDFUMDAwMDAwDQpSREFURToxOTE3MDQxNlQwMjAwMDANClJEQVRFOjE5MTgwNDE1VDAyMDAwMA0KUkRBVEU6MTk0MDA1MjBUMDMwMDAwDQpSREFURToxOTQzMDMyOVQwMjAwMDANClJEQVRFOjE5NDQwNDAzVDAyMDAwMA0KUkRBVEU6MTk0NTA0MDJUMDIwMDAwDQpSREFURToxOTQ2MDUxOVQwMjAwMDANClJEQVRFOjE5NzcwNDAzVDAyMDAwMA0KUkRBVEU6MTk3ODA0MDJUMDIwMDAwDQpSREFURToxOTc5MDQwMVQwMjAwMDANClJEQVRFOjE5ODAwNDA2VDAyMDAwMA0KRU5EOkRBWUxJR0hUDQpCRUdJTjpTVEFOREFSRA0KVFpPRkZTRVRGUk9
 N
+ OiswMjAwDQpUWk9GRlNFVFRPOiswMTAwDQpUWk5BTUU6Q0VUDQpEVFNUQVJUOjE5MTYxMDAxVDAxMDAwMA0KUkRBVEU6MTkxNjEwMDFUMDEwMDAwDQpSREFURToxOTE3MDkxN1QwMzAwMDANClJEQVRFOjE5MTgwOTE2VDAzMDAwMA0KUkRBVEU6MTk0MjExMDJUMDMwMDAwDQpSREFURToxOTQzMTAwNFQwMzAwMDANClJEQVRFOjE5NDQwOTE3VDAzMDAwMA0KUkRBVEU6MTk0NTA5MTZUMDMwMDAwDQpSREFURToxOTQ2MTAwN1QwMzAwMDANClJEQVRFOjE5NzcwOTI1VDAzMDAwMA0KUkRBVEU6MTk3ODEwMDFUMDMwMDAwDQpSREFURToxOTc5MDkzMFQwMzAwMDANClJEQVRFOjE5ODAwOTI4VDAzMDAwMA0KUkRBVEU6MTk4MTA5MjdUMDMwMDAwDQpSREFURToxOTgyMDkyNlQwMzAwMDANClJEQVRFOjE5ODMwOTI1VDAzMDAwMA0KUkRBVEU6MTk4NDA5MzBUMDMwMDAwDQpSREFURToxOTg1MDkyOVQwMzAwMDANClJEQVRFOjE5ODYwOTI4VDAzMDAwMA0KUkRBVEU6MTk4NzA5MjdUMDMwMDAwDQpSREFURToxOTg4MDkyNVQwMzAwMDANClJEQVRFOjE5ODkwOTI0VDAzMDAwMA0KUkRBVEU6MTk5MDA5MzBUMDMwMDAwDQpSREFURToxOTkxMDkyOVQwMzAwMDANClJEQVRFOjE5OTIwOTI3VDAzMDAwMA0KUkRBVEU6MTk5MzA5MjZUMDMwMDAwDQpSREFURToxOTk0MDkyNVQwMzAwMDANClJEQVRFOjE5OTUwOTI0VDAzMDAwMA0KRU5EOlNUQU5EQVJEDQpCRUdJTjpTVEFOREFSRA0KVFpPRkZTRVRGUk9NOiswMTAwDQpUWk9GRlNFVFRPOisw
 M
+ DAwDQpUWk5BTUU6V0VUDQpEVFNUQVJUOjE5MTgxMTExVDEyMDAwMA0KUkRBVEU6MTkxODExMTFUMTIwMDAwDQpSREFURToxOTE5MTAwNVQwMDAwMDANClJEQVRFOjE5MjAxMDI0VDAwMDAwMA0KUkRBVEU6MTkyMTEwMjZUMDAwMDAwDQpSREFURToxOTIyMTAwOFQwMDAwMDANClJEQVRFOjE5MjMxMDA3VDAwMDAwMA0KUkRBVEU6MTkyNDEwMDVUMDAwMDAwDQpSREFURToxOTI1MTAwNFQwMDAwMDANClJEQVRFOjE5MjYxMDAzVDAwMDAwMA0KUkRBVEU6MTkyNzEwMDJUMDAwMDAwDQpSREFURToxOTI4MTAwN1QwMzAwMDANClJEQVRFOjE5MjkxMDA2VDAzMDAwMA0KUkRBVEU6MTkzMDEwMDVUMDMwMDAwDQpSREFURToxOTMxMTAwNFQwMzAwMDANClJEQVRFOjE5MzIxMDAyVDAzMDAwMA0KUkRBVEU6MTkzMzEwMDhUMDMwMDAwDQpSREFURToxOTM0MTAwN1QwMzAwMDANClJEQVRFOjE5MzUxMDA2VDAzMDAwMA0KUkRBVEU6MTkzNjEwMDRUMDMwMDAwDQpSREFURToxOTM3MTAwM1QwMzAwMDANClJEQVRFOjE5MzgxMDAyVDAzMDAwMA0KUkRBVEU6MTkzOTExMTlUMDMwMDAwDQpFTkQ6U1RBTkRBUkQNCkJFR0lOOkRBWUxJR0hUDQpUWk9GRlNFVEZST006KzAwMDANClRaT0ZGU0VUVE86KzAxMDANClRaTkFNRTpXRVNUDQpEVFNUQVJUOjE5MTkwMzAxVDIzMDAwMA0KUkRBVEU6MTkxOTAzMDFUMjMwMDAwDQpSREFURToxOTIwMDIxNFQyMzAwMDANClJEQVRFOjE5MjEwMzE0VDIzMDAwMA0KUkRBVEU6MTkyMjAzMjVUMjMwMDAwDQpSR
 E
+ FURToxOTIzMDQyMVQyMzAwMDANClJEQVRFOjE5MjQwMzI5VDIzMDAwMA0KUkRBVEU6MTkyNTA0MDRUMjMwMDAwDQpSREFURToxOTI2MDQxN1QyMzAwMDANClJEQVRFOjE5MjcwNDA5VDIzMDAwMA0KUkRBVEU6MTkyODA0MTRUMjMwMDAwDQpSREFURToxOTI5MDQyMVQwMjAwMDANClJEQVRFOjE5MzAwNDEzVDAyMDAwMA0KUkRBVEU6MTkzMTA0MTlUMDIwMDAwDQpSREFURToxOTMyMDQwM1QwMjAwMDANClJEQVRFOjE5MzMwMzI2VDAyMDAwMA0KUkRBVEU6MTkzNDA0MDhUMDIwMDAwDQpSREFURToxOTM1MDMzMVQwMjAwMDANClJEQVRFOjE5MzYwNDE5VDAyMDAwMA0KUkRBVEU6MTkzNzA0MDRUMDIwMDAwDQpSREFURToxOTM4MDMyN1QwMjAwMDANClJEQVRFOjE5MzkwNDE2VDAyMDAwMA0KUkRBVEU6MTk0MDAyMjVUMDIwMDAwDQpFTkQ6REFZTElHSFQNCkJFR0lOOkRBWUxJR0hUDQpUWk9GRlNFVEZST006KzAyMDANClRaT0ZGU0VUVE86KzAyMDANClRaTkFNRTpDRVNUDQpEVFNUQVJUOjE5NDQwOTAzVDAwMDAwMA0KUkRBVEU6MTk0NDA5MDNUMDAwMDAwDQpFTkQ6REFZTElHSFQNCkJFR0lOOlNUQU5EQVJEDQpUWk9GRlNFVEZST006KzAxMDANClRaT0ZGU0VUVE86KzAxMDANClRaTkFNRTpDRVQNCkRUU1RBUlQ6MTk3NzAxMDFUMDAwMDAwDQpSREFURToxOTc3MDEwMVQwMDAwMDANCkVORDpTVEFOREFSRA0KRU5EOlZUSU1FWk9ORQ0KRU5EOlZDQUxFTkRBUg0K
+--_000_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_--
+    
+--_004_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_
+Content-Type: application/ics; name="invite.ics"
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment; filename="invite.ics"
+
+QkVHSU46VkNBTEVOREFSDQpQUk9ESUQ6Ly9ZYWhvby8vQ2FsZW5kYXIvL0VODQpWRVJTSU9OOjIuMA0KTUVUSE9EOlJFUVVFU1QNCkJFR0lOOlZFVkVOVA0KU1VNTUFSWTpUZXN0IGZyb20gWWFob28NCkNMQVNTOlBVQkxJQw0KRFRTVEFSVDtUWklEPUV1cm9wZS9CcnVzc2VsczoyMDE3MDEyN1QxNTAwMDANCkRURU5EO1RaSUQ9RXVyb3BlL0JydXNzZWxzOjIwMTcwMTI3VDE2MDAwMA0KTE9DQVRJT046U29tZXdoZXJlDQpQUklPUklUWTowDQpTRVFVRU5DRTowDQpTVEFUVVM6Q09ORklSTUVEDQpVSUQ6NTAxNDUxM2YtMTAyNi00YjU4LTgyY2YtODBkNGZjMDYwYmJlDQpEVFNUQU1QOjIwMTcwMTIzVDEyMTYzNVoNCkFUVEVOREVFO1BBUlRTVEFUPU5FRURTLUFDVElPTjtST0xFPVJFUV9QQVJUSUNJUEFOVDtSU1ZQPVRSVUU7U0NIRURVTEUtU1RBVA0KIFVTPTEuMTptYWlsdG86ZGRvbGNpbWFzY29sb0BsaW5hZ29yYS5jb20NCkFUVEVOREVFO1BBUlRTVEFUPU5FRURTLUFDVElPTjtST0xFPVJFUV9QQVJUSUNJUEFOVDtSU1ZQPVRSVUU7U0NIRURVTEUtU1RBVA0KIFVTPTEuMTptYWlsdG86cm91YXphbmFAbGluYWdvcmEuY29tDQpBVFRFTkRFRTtQQVJUU1RBVD1ORUVEUy1BQ1RJT047Uk9MRT1SRVFfUEFSVElDSVBBTlQ7UlNWUD1UUlVFO1NDSEVEVUxFLVNUQVQNCiBVUz0xLjE6bWFpbHRvOmFkdXByYXRAbGluYWdvcmEuY29tDQpBVFRFTkRFRTtQQVJUU1RBVD1ORUVEUy1BQ1RJT047Uk9MRT1SRVFfUEFSVElDSVBBT
 l
+ Q7UlNWUD1UUlVFO1NDSEVEVUxFLVNUQVQNCiBVUz0xLjE6bWFpbHRvOmJ0ZWxsaWVyQGxpbmFnb3JhLmNvbQ0KT1JHQU5JWkVSO0NOPU9CTSBMaW5hZ29yYTtTRU5ULUJZPSJtYWlsdG86b2JtbGluYWdvcmFAeWFob28uZnIiOm1haWx0bzpvYm1sDQogaW5hZ29yYUB5YWhvby5mcg0KWC1ZQUhPTy1ZSUQ6b2JtbGluYWdvcmENClRSQU5TUDpPUEFRVUUNClNUQVRVUzpDT05GSVJNRUQNClgtWUFIT08tVVNFUi1TVEFUVVM6QlVTWQ0KWC1ZQUhPTy1FVkVOVC1TVEFUVVM6QlVTWQ0KRU5EOlZFVkVOVA0KQkVHSU46VlRJTUVaT05FDQpUWklEOkV1cm9wZS9CcnVzc2Vscw0KVFpVUkw6aHR0cDovL3R6dXJsLm9yZy96b25laW5mby9FdXJvcGUvQnJ1c3NlbHMNClgtTElDLUxPQ0FUSU9OOkV1cm9wZS9CcnVzc2Vscw0KQkVHSU46REFZTElHSFQNClRaT0ZGU0VURlJPTTorMDEwMA0KVFpPRkZTRVRUTzorMDIwMA0KVFpOQU1FOkNFU1QNCkRUU1RBUlQ6MTk4MTAzMjlUMDIwMDAwDQpSUlVMRTpGUkVRPVlFQVJMWTtCWU1PTlRIPTM7QllEQVk9LTFTVQ0KRU5EOkRBWUxJR0hUDQpCRUdJTjpTVEFOREFSRA0KVFpPRkZTRVRGUk9NOiswMjAwDQpUWk9GRlNFVFRPOiswMTAwDQpUWk5BTUU6Q0VUDQpEVFNUQVJUOjE5OTYxMDI3VDAzMDAwMA0KUlJVTEU6RlJFUT1ZRUFSTFk7QllNT05USD0xMDtCWURBWT0tMVNVDQpFTkQ6U1RBTkRBUkQNCkJFR0lOOlNUQU5EQVJEDQpUWk9GRlNFVEZST006KzAwMTczMA0KVFpPRkZTRVRUTzorMD
 A
+ xNzMwDQpUWk5BTUU6Qk1UDQpEVFNUQVJUOjE4ODAwMTAxVDAwMDAwMA0KUkRBVEU6MTg4MDAxMDFUMDAwMDAwDQpFTkQ6U1RBTkRBUkQNCkJFR0lOOlNUQU5EQVJEDQpUWk9GRlNFVEZST006KzAwMTczMA0KVFpPRkZTRVRUTzorMDAwMA0KVFpOQU1FOldFVA0KRFRTVEFSVDoxODkyMDUwMVQxMjAwMDANClJEQVRFOjE4OTIwNTAxVDEyMDAwMA0KRU5EOlNUQU5EQVJEDQpCRUdJTjpTVEFOREFSRA0KVFpPRkZTRVRGUk9NOiswMDAwDQpUWk9GRlNFVFRPOiswMTAwDQpUWk5BTUU6Q0VUDQpEVFNUQVJUOjE5MTQxMTA4VDAwMDAwMA0KUkRBVEU6MTkxNDExMDhUMDAwMDAwDQpFTkQ6U1RBTkRBUkQNCkJFR0lOOkRBWUxJR0hUDQpUWk9GRlNFVEZST006KzAxMDANClRaT0ZGU0VUVE86KzAyMDANClRaTkFNRTpDRVNUDQpEVFNUQVJUOjE5MTYwNTAxVDAwMDAwMA0KUkRBVEU6MTkxNjA1MDFUMDAwMDAwDQpSREFURToxOTE3MDQxNlQwMjAwMDANClJEQVRFOjE5MTgwNDE1VDAyMDAwMA0KUkRBVEU6MTk0MDA1MjBUMDMwMDAwDQpSREFURToxOTQzMDMyOVQwMjAwMDANClJEQVRFOjE5NDQwNDAzVDAyMDAwMA0KUkRBVEU6MTk0NTA0MDJUMDIwMDAwDQpSREFURToxOTQ2MDUxOVQwMjAwMDANClJEQVRFOjE5NzcwNDAzVDAyMDAwMA0KUkRBVEU6MTk3ODA0MDJUMDIwMDAwDQpSREFURToxOTc5MDQwMVQwMjAwMDANClJEQVRFOjE5ODAwNDA2VDAyMDAwMA0KRU5EOkRBWUxJR0hUDQpCRUdJTjpTVEFOREFSRA0KVFpPRkZTRVRGUk9
 N
+ OiswMjAwDQpUWk9GRlNFVFRPOiswMTAwDQpUWk5BTUU6Q0VUDQpEVFNUQVJUOjE5MTYxMDAxVDAxMDAwMA0KUkRBVEU6MTkxNjEwMDFUMDEwMDAwDQpSREFURToxOTE3MDkxN1QwMzAwMDANClJEQVRFOjE5MTgwOTE2VDAzMDAwMA0KUkRBVEU6MTk0MjExMDJUMDMwMDAwDQpSREFURToxOTQzMTAwNFQwMzAwMDANClJEQVRFOjE5NDQwOTE3VDAzMDAwMA0KUkRBVEU6MTk0NTA5MTZUMDMwMDAwDQpSREFURToxOTQ2MTAwN1QwMzAwMDANClJEQVRFOjE5NzcwOTI1VDAzMDAwMA0KUkRBVEU6MTk3ODEwMDFUMDMwMDAwDQpSREFURToxOTc5MDkzMFQwMzAwMDANClJEQVRFOjE5ODAwOTI4VDAzMDAwMA0KUkRBVEU6MTk4MTA5MjdUMDMwMDAwDQpSREFURToxOTgyMDkyNlQwMzAwMDANClJEQVRFOjE5ODMwOTI1VDAzMDAwMA0KUkRBVEU6MTk4NDA5MzBUMDMwMDAwDQpSREFURToxOTg1MDkyOVQwMzAwMDANClJEQVRFOjE5ODYwOTI4VDAzMDAwMA0KUkRBVEU6MTk4NzA5MjdUMDMwMDAwDQpSREFURToxOTg4MDkyNVQwMzAwMDANClJEQVRFOjE5ODkwOTI0VDAzMDAwMA0KUkRBVEU6MTk5MDA5MzBUMDMwMDAwDQpSREFURToxOTkxMDkyOVQwMzAwMDANClJEQVRFOjE5OTIwOTI3VDAzMDAwMA0KUkRBVEU6MTk5MzA5MjZUMDMwMDAwDQpSREFURToxOTk0MDkyNVQwMzAwMDANClJEQVRFOjE5OTUwOTI0VDAzMDAwMA0KRU5EOlNUQU5EQVJEDQpCRUdJTjpTVEFOREFSRA0KVFpPRkZTRVRGUk9NOiswMTAwDQpUWk9GRlNFVFRPOisw
 M
+ DAwDQpUWk5BTUU6V0VUDQpEVFNUQVJUOjE5MTgxMTExVDEyMDAwMA0KUkRBVEU6MTkxODExMTFUMTIwMDAwDQpSREFURToxOTE5MTAwNVQwMDAwMDANClJEQVRFOjE5MjAxMDI0VDAwMDAwMA0KUkRBVEU6MTkyMTEwMjZUMDAwMDAwDQpSREFURToxOTIyMTAwOFQwMDAwMDANClJEQVRFOjE5MjMxMDA3VDAwMDAwMA0KUkRBVEU6MTkyNDEwMDVUMDAwMDAwDQpSREFURToxOTI1MTAwNFQwMDAwMDANClJEQVRFOjE5MjYxMDAzVDAwMDAwMA0KUkRBVEU6MTkyNzEwMDJUMDAwMDAwDQpSREFURToxOTI4MTAwN1QwMzAwMDANClJEQVRFOjE5MjkxMDA2VDAzMDAwMA0KUkRBVEU6MTkzMDEwMDVUMDMwMDAwDQpSREFURToxOTMxMTAwNFQwMzAwMDANClJEQVRFOjE5MzIxMDAyVDAzMDAwMA0KUkRBVEU6MTkzMzEwMDhUMDMwMDAwDQpSREFURToxOTM0MTAwN1QwMzAwMDANClJEQVRFOjE5MzUxMDA2VDAzMDAwMA0KUkRBVEU6MTkzNjEwMDRUMDMwMDAwDQpSREFURToxOTM3MTAwM1QwMzAwMDANClJEQVRFOjE5MzgxMDAyVDAzMDAwMA0KUkRBVEU6MTkzOTExMTlUMDMwMDAwDQpFTkQ6U1RBTkRBUkQNCkJFR0lOOkRBWUxJR0hUDQpUWk9GRlNFVEZST006KzAwMDANClRaT0ZGU0VUVE86KzAxMDANClRaTkFNRTpXRVNUDQpEVFNUQVJUOjE5MTkwMzAxVDIzMDAwMA0KUkRBVEU6MTkxOTAzMDFUMjMwMDAwDQpSREFURToxOTIwMDIxNFQyMzAwMDANClJEQVRFOjE5MjEwMzE0VDIzMDAwMA0KUkRBVEU6MTkyMjAzMjVUMjMwMDAwDQpSR
 E
+ FURToxOTIzMDQyMVQyMzAwMDANClJEQVRFOjE5MjQwMzI5VDIzMDAwMA0KUkRBVEU6MTkyNTA0MDRUMjMwMDAwDQpSREFURToxOTI2MDQxN1QyMzAwMDANClJEQVRFOjE5MjcwNDA5VDIzMDAwMA0KUkRBVEU6MTkyODA0MTRUMjMwMDAwDQpSREFURToxOTI5MDQyMVQwMjAwMDANClJEQVRFOjE5MzAwNDEzVDAyMDAwMA0KUkRBVEU6MTkzMTA0MTlUMDIwMDAwDQpSREFURToxOTMyMDQwM1QwMjAwMDANClJEQVRFOjE5MzMwMzI2VDAyMDAwMA0KUkRBVEU6MTkzNDA0MDhUMDIwMDAwDQpSREFURToxOTM1MDMzMVQwMjAwMDANClJEQVRFOjE5MzYwNDE5VDAyMDAwMA0KUkRBVEU6MTkzNzA0MDRUMDIwMDAwDQpSREFURToxOTM4MDMyN1QwMjAwMDANClJEQVRFOjE5MzkwNDE2VDAyMDAwMA0KUkRBVEU6MTk0MDAyMjVUMDIwMDAwDQpFTkQ6REFZTElHSFQNCkJFR0lOOkRBWUxJR0hUDQpUWk9GRlNFVEZST006KzAyMDANClRaT0ZGU0VUVE86KzAyMDANClRaTkFNRTpDRVNUDQpEVFNUQVJUOjE5NDQwOTAzVDAwMDAwMA0KUkRBVEU6MTk0NDA5MDNUMDAwMDAwDQpFTkQ6REFZTElHSFQNCkJFR0lOOlNUQU5EQVJEDQpUWk9GRlNFVEZST006KzAxMDANClRaT0ZGU0VUVE86KzAxMDANClRaTkFNRTpDRVQNCkRUU1RBUlQ6MTk3NzAxMDFUMDAwMDAwDQpSREFURToxOTc3MDEwMVQwMDAwMDANCkVORDpTVEFOREFSRA0KRU5EOlZUSU1FWk9ORQ0KRU5EOlZDQUxFTkRBUg0K
+--_004_CD15A92E9002734AADB6F2075789C4D70108100CB8EDEGLEX07VS01_--


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


[4/4] james-project git commit: MAILET-149 JSON created from ICAL should better use From when available and backup to sender envelope

Posted by bt...@apache.org.
MAILET-149 JSON created from ICAL should better use From when available and backup to sender envelope


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

Branch: refs/heads/master
Commit: 9ff71bd26ccb4e54788ed70a61ff1aa13b06f5f5
Parents: 84ecf06
Author: Benoit Tellier <bt...@linagora.com>
Authored: Tue Jan 24 09:29:54 2017 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Jan 24 16:49:07 2017 +0700

----------------------------------------------------------------------
 .../transport/mailets/ICALToJsonAttribute.java  |  34 +++++-
 .../james/transport/mailets/model/ICAL.java     |   4 +-
 .../mailets/ICALToJsonAttributeTest.java        | 109 +++++++++++++++++++
 .../james/transport/mailets/model/ICALTest.java |  14 +--
 .../mailets/ICSAttachmentWorkflowTest.java      |   5 +-
 5 files changed, 148 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/9ff71bd2/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java
----------------------------------------------------------------------
diff --git a/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java b/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java
index b62ab33..84ebabb 100644
--- a/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java
+++ b/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/ICALToJsonAttribute.java
@@ -20,11 +20,16 @@
 package org.apache.james.transport.mailets;
 
 import java.io.Serializable;
+import java.util.Arrays;
 import java.util.Map;
+import java.util.Optional;
 import java.util.UUID;
 import java.util.stream.Stream;
 
+import javax.mail.Address;
 import javax.mail.MessagingException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
 
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.transport.mailets.model.ICAL;
@@ -35,6 +40,7 @@ import org.apache.mailet.base.GenericMailet;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.github.fge.lambdas.Throwing;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Charsets;
 import com.google.common.base.Strings;
@@ -132,8 +138,9 @@ public class ICALToJsonAttribute extends GenericMailet {
         if (mail.getAttribute(rawSourceAttributeName) == null) {
             return;
         }
-        if (mail.getSender() == null) {
-            log("Skipping " + mail.getName() + " because no sender");
+        Optional<String> sender = retrieveSender(mail);
+        if (!sender.isPresent()) {
+            log("Skipping " + mail.getName() + " because no sender and no from");
             return;
         }
         try {
@@ -141,7 +148,7 @@ public class ICALToJsonAttribute extends GenericMailet {
             Map<String, byte[]> rawCalendars = getRawCalendarMap(mail);
             Map<String, byte[]> jsonsInByteForm = calendars.entrySet()
                 .stream()
-                .flatMap(calendar -> toJson(calendar, rawCalendars, mail))
+                .flatMap(calendar -> toJson(calendar, rawCalendars, mail, sender.get()))
                 .collect(Guavate.toImmutableMap(Pair::getKey, Pair::getValue));
             mail.setAttribute(destinationAttributeName, (Serializable) jsonsInByteForm);
         } catch (ClassCastException e) {
@@ -159,10 +166,10 @@ public class ICALToJsonAttribute extends GenericMailet {
         return (Map<String, byte[]>) mail.getAttribute(rawSourceAttributeName);
     }
 
-    private Stream<Pair<String, byte[]>> toJson(Map.Entry<String, Calendar> entry, Map<String, byte[]> rawCalendars, Mail mail) {
+    private Stream<Pair<String, byte[]>> toJson(Map.Entry<String, Calendar> entry, Map<String, byte[]> rawCalendars, Mail mail, String sender) {
         return mail.getRecipients()
             .stream()
-            .flatMap(recipient -> toICAL(entry, rawCalendars, recipient, mail.getSender()))
+            .flatMap(recipient -> toICAL(entry, rawCalendars, recipient, sender))
             .flatMap(ical -> toJson(ical, mail.getName()))
             .map(json -> Pair.of(UUID.randomUUID().toString(), json.getBytes(Charsets.UTF_8)));
     }
@@ -179,7 +186,7 @@ public class ICALToJsonAttribute extends GenericMailet {
         }
     }
 
-    private Stream<ICAL> toICAL(Map.Entry<String, Calendar> entry, Map<String, byte[]> rawCalendars, MailAddress recipient, MailAddress sender) {
+    private Stream<ICAL> toICAL(Map.Entry<String, Calendar> entry, Map<String, byte[]> rawCalendars, MailAddress recipient, String sender) {
         Calendar calendar = entry.getValue();
         byte[] rawICal = rawCalendars.get(entry.getKey());
         if (rawICal == null) {
@@ -197,4 +204,19 @@ public class ICALToJsonAttribute extends GenericMailet {
             return Stream.of();
         }
     }
+
+    private Optional<String> retrieveSender(Mail mail) throws MessagingException {
+        Optional<String> from = Optional.ofNullable(mail.getMessage())
+            .map(Throwing.function(MimeMessage::getFrom).orReturn(new Address[]{}))
+            .map(Arrays::stream)
+            .orElse(Stream.of())
+            .map(address -> (InternetAddress) address)
+            .map(InternetAddress::getAddress)
+            .findFirst();
+        if (from.isPresent()) {
+            return from;
+        }
+        return Optional.ofNullable(mail.getSender())
+            .map(MailAddress::asString);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/9ff71bd2/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java
----------------------------------------------------------------------
diff --git a/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java b/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java
index 80f1555..14db606 100644
--- a/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java
+++ b/mailet/icalendar/src/main/java/org/apache/james/transport/mailets/model/ICAL.java
@@ -61,8 +61,8 @@ public class ICAL {
             return Optional.ofNullable(property).map(Property::getValue);
         }
 
-        public Builder sender(MailAddress sender) {
-            this.sender = sender.asString();
+        public Builder sender(String sender) {
+            this.sender = sender;
             return this;
         }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/9ff71bd2/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java
----------------------------------------------------------------------
diff --git a/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java b/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java
index 574878b..76147ee 100644
--- a/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java
+++ b/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/ICALToJsonAttributeTest.java
@@ -35,6 +35,7 @@ import org.apache.mailet.MailAddress;
 import org.apache.mailet.base.MailAddressFixture;
 import org.apache.mailet.base.test.FakeMail;
 import org.apache.mailet.base.test.FakeMailetConfig;
+import org.apache.mailet.base.test.MimeMessageBuilder;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -428,6 +429,114 @@ public class ICALToJsonAttributeTest {
             "}");
     }
 
+    @SuppressWarnings("unchecked")
+    @Test
+    public void serviceShouldUseFromWhenSpecified() throws Exception {
+        testee.init(FakeMailetConfig.builder().build());
+
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics);
+        MailAddress recipient = MailAddressFixture.ANY_AT_JAMES2;
+        String from = MailAddressFixture.OTHER_AT_JAMES.asString();
+        Mail mail = FakeMail.builder()
+            .sender(SENDER)
+            .recipient(recipient)
+            .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+                .setFrom(from)
+                .build())
+            .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
+            .build();
+        testee.service(mail);
+
+        Map<String, byte[]> jsons = (Map<String, byte[]>) mail.getAttribute(ICALToJsonAttribute.DEFAULT_DESTINATION_ATTRIBUTE_NAME);
+        assertThat(jsons).hasSize(1);
+        assertThatJson(new String(jsons.values().iterator().next(), Charsets.UTF_8))
+            .isEqualTo("{" +
+                "\"ical\": \"" + toJsonValue(ics) +"\"," +
+                "\"sender\": \"" + from + "\"," +
+                "\"recipient\": \"" + recipient.asString() + "\"," +
+                "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +
+                "\"sequence\": \"0\"," +
+                "\"dtstamp\": \"20170106T115036Z\"," +
+                "\"method\": \"REQUEST\"," +
+                "\"recurrence-id\": null" +
+                "}");
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void serviceShouldSupportMimeMessagesWithoutFromFields() throws Exception {
+        testee.init(FakeMailetConfig.builder().build());
+
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics);
+        MailAddress recipient = MailAddressFixture.ANY_AT_JAMES2;
+        Mail mail = FakeMail.builder()
+            .sender(SENDER)
+            .recipient(recipient)
+            .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+                .build())
+            .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
+            .build();
+        testee.service(mail);
+
+        Map<String, byte[]> jsons = (Map<String, byte[]>) mail.getAttribute(ICALToJsonAttribute.DEFAULT_DESTINATION_ATTRIBUTE_NAME);
+        assertThat(jsons).hasSize(1);
+        assertThatJson(new String(jsons.values().iterator().next(), Charsets.UTF_8))
+            .isEqualTo("{" +
+                "\"ical\": \"" + toJsonValue(ics) +"\"," +
+                "\"sender\": \"" + SENDER.asString() + "\"," +
+                "\"recipient\": \"" + recipient.asString() + "\"," +
+                "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +
+                "\"sequence\": \"0\"," +
+                "\"dtstamp\": \"20170106T115036Z\"," +
+                "\"method\": \"REQUEST\"," +
+                "\"recurrence-id\": null" +
+                "}");
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void serviceShouldUseFromWhenSpecifiedAndNoSender() throws Exception {
+        testee.init(FakeMailetConfig.builder().build());
+
+        byte[] ics = ByteStreams.toByteArray(ClassLoader.getSystemResourceAsStream("ics/meeting.ics"));
+        Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
+        ImmutableMap<String, Calendar> icals = ImmutableMap.of("key", calendar);
+        ImmutableMap<String, byte[]> rawIcals = ImmutableMap.of("key", ics);
+        MailAddress recipient = MailAddressFixture.ANY_AT_JAMES2;
+        String from = MailAddressFixture.OTHER_AT_JAMES.asString();
+        Mail mail = FakeMail.builder()
+            .recipient(recipient)
+            .mimeMessage(MimeMessageBuilder.mimeMessageBuilder()
+                .setFrom(from)
+                .build())
+            .attribute(ICALToJsonAttribute.DEFAULT_SOURCE_ATTRIBUTE_NAME, icals)
+            .attribute(ICALToJsonAttribute.DEFAULT_RAW_SOURCE_ATTRIBUTE_NAME, rawIcals)
+            .build();
+        testee.service(mail);
+
+        Map<String, byte[]> jsons = (Map<String, byte[]>) mail.getAttribute(ICALToJsonAttribute.DEFAULT_DESTINATION_ATTRIBUTE_NAME);
+        assertThat(jsons).hasSize(1);
+        assertThatJson(new String(jsons.values().iterator().next(), Charsets.UTF_8))
+            .isEqualTo("{" +
+                "\"ical\": \"" + toJsonValue(ics) +"\"," +
+                "\"sender\": \"" + from + "\"," +
+                "\"recipient\": \"" + recipient.asString() + "\"," +
+                "\"uid\": \"f1514f44bf39311568d640727cff54e819573448d09d2e5677987ff29caa01a9e047feb2aab16e43439a608f28671ab7c10e754ce92be513f8e04ae9ff15e65a9819cf285a6962bc\"," +
+                "\"sequence\": \"0\"," +
+                "\"dtstamp\": \"20170106T115036Z\"," +
+                "\"method\": \"REQUEST\"," +
+                "\"recurrence-id\": null" +
+                "}");
+    }
+
     private List<String> toSortedValueList(Map<String, byte[]> jsons) {
         return jsons.values()
                 .stream()

http://git-wip-us.apache.org/repos/asf/james-project/blob/9ff71bd2/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java
----------------------------------------------------------------------
diff --git a/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java b/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java
index b4ce81e..99db64b 100644
--- a/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java
+++ b/mailet/icalendar/src/test/java/org/apache/james/transport/mailets/model/ICALTest.java
@@ -46,7 +46,7 @@ public class ICALTest {
 
         ICAL.builder()
             .recipient(MailAddressFixture.ANY_AT_JAMES)
-            .sender(MailAddressFixture.OTHER_AT_JAMES)
+            .sender(MailAddressFixture.OTHER_AT_JAMES.asString())
             .build();
     }
 
@@ -71,7 +71,7 @@ public class ICALTest {
         Calendar calendar = new CalendarBuilder().build(new ByteArrayInputStream(ics));
 
         ICAL.builder()
-            .sender(MailAddressFixture.OTHER_AT_JAMES)
+            .sender(MailAddressFixture.OTHER_AT_JAMES.asString())
             .from(calendar, ics)
             .build();
     }
@@ -86,7 +86,7 @@ public class ICALTest {
         MailAddress sender = MailAddressFixture.OTHER_AT_JAMES;
         ICAL ical = ICAL.builder()
             .recipient(recipient)
-            .sender(sender)
+            .sender(sender.asString())
             .from(calendar, ics)
             .build();
 
@@ -118,7 +118,7 @@ public class ICALTest {
         MailAddress sender = MailAddressFixture.OTHER_AT_JAMES;
         ICAL.builder()
             .recipient(recipient)
-            .sender(sender)
+            .sender(sender.asString())
             .from(calendar, ics)
             .build();
     }
@@ -134,7 +134,7 @@ public class ICALTest {
         MailAddress sender = MailAddressFixture.OTHER_AT_JAMES;
         ICAL.builder()
             .recipient(recipient)
-            .sender(sender)
+            .sender(sender.asString())
             .from(calendar, ics)
             .build();
     }
@@ -150,7 +150,7 @@ public class ICALTest {
         MailAddress sender = MailAddressFixture.OTHER_AT_JAMES;
         ICAL.builder()
             .recipient(recipient)
-            .sender(sender)
+            .sender(sender.asString())
             .from(calendar, ics)
             .build();
     }
@@ -164,7 +164,7 @@ public class ICALTest {
         MailAddress sender = MailAddressFixture.OTHER_AT_JAMES;
         ICAL ical = ICAL.builder()
             .recipient(recipient)
-            .sender(sender)
+            .sender(sender.asString())
             .from(calendar, ics)
             .build();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/9ff71bd2/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java
index 2cd1b5c..1ed4020 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/ICSAttachmentWorkflowTest.java
@@ -33,7 +33,6 @@ import org.apache.james.mailets.configuration.MailetContainer;
 import org.apache.james.mailets.configuration.ProcessorConfiguration;
 import org.apache.james.mailets.utils.IMAPMessageReader;
 import org.apache.james.mailets.utils.SMTPMessageSender;
-import org.apache.james.queue.activemq.MimeMessageBlobMessageSource;
 import org.apache.james.transport.mailets.amqp.AmqpRule;
 import org.apache.james.util.streams.SwarmGenericContainer;
 import org.apache.mailet.Mail;
@@ -551,7 +550,7 @@ public class ICSAttachmentWorkflowTest {
             .setSubject("test")
             .build();
 
-        yahooInvitationMessage = new MimeMessage(null, ClassLoader.getSystemResourceAsStream("yahooInvitation.eml"));
+        yahooInvitationMessage = MimeMessageBuilder.mimeMessageFromStream(ClassLoader.getSystemResourceAsStream("eml/yahooInvitation.eml"));
 
         messageWithThreeICSAttached = MimeMessageBuilder.mimeMessageBuilder()
             .setMultipartWithBodyParts(
@@ -749,7 +748,7 @@ public class ICSAttachmentWorkflowTest {
         Optional<String> content = amqpRule.readContent();
         assertThat(content).isPresent();
         DocumentContext jsonPath = toJsonPath(content.get());
-        assertThat(jsonPath.<String> read("sender")).isEqualTo(FROM);
+        assertThat(jsonPath.<String> read("sender")).isEqualTo("obmlinagora@yahoo.fr");
         assertThat(jsonPath.<String> read("recipient")).isEqualTo(RECIPIENT);
         assertThat(jsonPath.<String> read("uid")).isEqualTo("5014513f-1026-4b58-82cf-80d4fc060bbe");
         assertThat(jsonPath.<String> read("sequence")).isEqualTo("0");


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


[3/4] james-project git commit: MAILET-149 Factorize exception handling in Amqp Junit rule

Posted by bt...@apache.org.
MAILET-149 Factorize exception handling in Amqp Junit rule


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

Branch: refs/heads/master
Commit: 84ecf060147204f1b3c0a1688bb73a87f933fbc2
Parents: 65cf1c8
Author: Benoit Tellier <bt...@linagora.com>
Authored: Tue Jan 24 08:48:00 2017 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Jan 24 16:49:07 2017 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/transport/mailets/amqp/AmqpRule.java   | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/84ecf060/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java
index 08e831f..3923fc9 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java
@@ -102,9 +102,7 @@ public class AmqpRule extends ExternalResource {
     private boolean isReady(ConnectionFactory factory) {
         try (Connection connection = factory.newConnection()) {
             return true;
-        } catch (IOException e) {
-            return false;
-        } catch (TimeoutException e) {
+        } catch (IOException | TimeoutException e) {
             return false;
         }
     }


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


[2/4] james-project git commit: MAILET-149 Factorize uses of getIp on SwarmGenericContainer

Posted by bt...@apache.org.
MAILET-149 Factorize uses of getIp on SwarmGenericContainer


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

Branch: refs/heads/master
Commit: 65cf1c8cb704e6c1db930c943223f23abe6fd530
Parents: 6cdc4d5
Author: Benoit Tellier <bt...@linagora.com>
Authored: Tue Jan 24 08:45:01 2017 +0700
Committer: Benoit Tellier <bt...@linagora.com>
Committed: Tue Jan 24 16:49:03 2017 +0700

----------------------------------------------------------------------
 .../main/java/org/apache/james/mpt/smtp/ForwardSmtpTest.java   | 6 ++----
 .../src/test/java/org/apache/james/DockerCassandraRule.java    | 6 ++----
 .../org/apache/james/util/streams/SwarmGenericContainer.java   | 5 +++++
 .../java/org/apache/james/transport/mailets/amqp/AmqpRule.java | 6 +-----
 4 files changed, 10 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/65cf1c8c/mpt/impl/smtp/core/src/main/java/org/apache/james/mpt/smtp/ForwardSmtpTest.java
----------------------------------------------------------------------
diff --git a/mpt/impl/smtp/core/src/main/java/org/apache/james/mpt/smtp/ForwardSmtpTest.java b/mpt/impl/smtp/core/src/main/java/org/apache/james/mpt/smtp/ForwardSmtpTest.java
index e27c9e0..293e364 100644
--- a/mpt/impl/smtp/core/src/main/java/org/apache/james/mpt/smtp/ForwardSmtpTest.java
+++ b/mpt/impl/smtp/core/src/main/java/org/apache/james/mpt/smtp/ForwardSmtpTest.java
@@ -35,7 +35,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.RuleChain;
 import org.junit.rules.TemporaryFolder;
-import org.testcontainers.containers.GenericContainer;
 
 import com.google.common.base.Charsets;
 import com.google.common.collect.ImmutableList;
@@ -52,7 +51,7 @@ public class ForwardSmtpTest extends AbstractSimpleScriptedTestProtocol {
     public static final String PASSWORD = "secret";
 
     private final TemporaryFolder folder = new TemporaryFolder();
-    private final GenericContainer<?> fakeSmtp = new SwarmGenericContainer("weave/rest-smtp-sink:latest")
+    private final SwarmGenericContainer fakeSmtp = new SwarmGenericContainer("weave/rest-smtp-sink:latest")
             .withAffinityToContainer();
     
     @Rule
@@ -66,10 +65,9 @@ public class ForwardSmtpTest extends AbstractSimpleScriptedTestProtocol {
     }
 
     @Before
-    @SuppressWarnings("deprecation")
     public void setUp() throws Exception {
         super.setUp();
-        InetAddress containerIp = InetAddresses.forString(fakeSmtp.getContainerInfo().getNetworkSettings().getIpAddress());
+        InetAddress containerIp = InetAddresses.forString(fakeSmtp.getIp());
         hostSystem.getInMemoryDnsService()
             .registerRecord("yopmail.com", new InetAddress[]{containerIp}, ImmutableList.of("yopmail.com"), ImmutableList.of());
         hostSystem.addAddressMapping(USER, DOMAIN, "ray@yopmail.com");

http://git-wip-us.apache.org/repos/asf/james-project/blob/65cf1c8c/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
----------------------------------------------------------------------
diff --git a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
index fa01e1c..e482214 100644
--- a/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
+++ b/server/container/guice/cassandra-guice/src/test/java/org/apache/james/DockerCassandraRule.java
@@ -25,7 +25,6 @@ import org.apache.james.modules.mailbox.CassandraSessionConfiguration;
 import org.apache.james.util.streams.SwarmGenericContainer;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
-import org.testcontainers.containers.GenericContainer;
 import org.testcontainers.shaded.com.github.dockerjava.api.model.ExposedPort;
 import org.testcontainers.shaded.com.github.dockerjava.api.model.Ports;
 import org.testcontainers.shaded.com.github.dockerjava.api.model.Ports.Binding;
@@ -54,7 +53,7 @@ public class DockerCassandraRule implements GuiceModuleTestRule {
         return configuration;
     }
 
-    private GenericContainer<SwarmGenericContainer> cassandraContainer = new SwarmGenericContainer("cassandra:2.2");
+    private SwarmGenericContainer cassandraContainer = new SwarmGenericContainer("cassandra:2.2");
 
     @Override
     public Statement apply(Statement base, Description description) {
@@ -70,9 +69,8 @@ public class DockerCassandraRule implements GuiceModuleTestRule {
         return (binder) -> binder.bind(CassandraSessionConfiguration.class).toInstance(this::getCassandraConfigurationForDocker);
     }
 
-    @SuppressWarnings("deprecation")
     public String getIp() {
-        return cassandraContainer.getContainerInfo().getNetworkSettings().getIpAddress();
+        return cassandraContainer.getIp();
     }
 
     public int getBindingPort() {

http://git-wip-us.apache.org/repos/asf/james-project/blob/65cf1c8c/server/container/util-java8/src/test/java/org/apache/james/util/streams/SwarmGenericContainer.java
----------------------------------------------------------------------
diff --git a/server/container/util-java8/src/test/java/org/apache/james/util/streams/SwarmGenericContainer.java b/server/container/util-java8/src/test/java/org/apache/james/util/streams/SwarmGenericContainer.java
index cad3018..6bbe0af 100644
--- a/server/container/util-java8/src/test/java/org/apache/james/util/streams/SwarmGenericContainer.java
+++ b/server/container/util-java8/src/test/java/org/apache/james/util/streams/SwarmGenericContainer.java
@@ -47,4 +47,9 @@ public class SwarmGenericContainer extends GenericContainer<SwarmGenericContaine
         setEnv(envVariables);
         return self();
     }
+
+    @SuppressWarnings("deprecation")
+    public String getIp() {
+        return getContainerInfo().getNetworkSettings().getIpAddress();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/65cf1c8c/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java
----------------------------------------------------------------------
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java
index c59f2c3..08e831f 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/transport/mailets/amqp/AmqpRule.java
@@ -20,7 +20,6 @@
 package org.apache.james.transport.mailets.amqp;
 
 import java.io.IOException;
-import java.net.InetAddress;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -30,7 +29,6 @@ import org.junit.rules.ExternalResource;
 
 import com.google.common.base.Charsets;
 import com.google.common.base.Throwables;
-import com.google.common.net.InetAddresses;
 import com.jayway.awaitility.Awaitility;
 import com.rabbitmq.client.BuiltinExchangeType;
 import com.rabbitmq.client.Channel;
@@ -56,9 +54,7 @@ public class AmqpRule extends ExternalResource {
 
     @Override
     protected void before() throws Throwable {
-        @SuppressWarnings("deprecation")
-        InetAddress containerIp = InetAddresses.forString(rabbitMqContainer.getContainerInfo().getNetworkSettings().getIpAddress());
-        amqpUri = "amqp://" + containerIp.getHostAddress();
+        amqpUri = "amqp://" + rabbitMqContainer.getIp();
         ConnectionFactory factory = new ConnectionFactory();
         factory.setUri(amqpUri);
         waitingForRabbitToBeReady(factory);


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