You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ol...@apache.org on 2016/04/07 11:18:07 UTC

svn commit: r1738114 - in /sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/sling/ src/main/java/org/apache/sling/commons/ src/ma...

Author: olli
Date: Thu Apr  7 09:18:07 2016
New Revision: 1738114

URL: http://svn.apache.org/viewvc?rev=1738114&view=rev
Log:
SLING-5644 Provide an messaging implementation based on Commons Email

Added:
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/README.md
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/pom.xml
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailBuilder.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailUtil.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailFailure.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailResult.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilder.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderConfiguration.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/package-info.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailBuilderConfigurations.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailTestSupport.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderIT.java
    sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceIT.java

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/README.md
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/README.md?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/README.md (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/README.md Thu Apr  7 09:18:07 2016
@@ -0,0 +1,19 @@
+Apache Sling Commons Messaging Mail
+===================================
+
+Provide an OSGi Configuration for `SimpleMailBuilder` or a custom `MailBuilder` to send messages using [Apache Commons Email](https://commons.apache.org/proper/commons-email/).
+
+To extend or override `SimpleMailBuilder`​s configuration call `MessageService#send(String, String, Map):Future<Result>` and supply a configuration map `mail` within the third parameter:
+
+```
+{
+  "mail" : {
+    "mail.subject": <String>,
+    "mail.from": <String>,
+    "mail.smtp.hostname": <String>,
+    "mail.smtp.port": <int>,
+    "mail.smtp.username": <String>,
+    "mail.smtp.password": <String>
+  }
+}
+```

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/pom.xml?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/pom.xml (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/pom.xml Thu Apr  7 09:18:07 2016
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.sling</groupId>
+    <artifactId>sling</artifactId>
+    <version>27-SNAPSHOT</version>
+    <relativePath/>
+  </parent>
+
+  <artifactId>org.apache.sling.commons.messaging.mail</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <name>Apache Sling Commons Messaging Mail</name>
+  <description>Messaging service using Commons Email to send mails.</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <sling.java.version>8</sling.java.version>
+  </properties>
+
+  <scm>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail</developerConnection>
+    <url>http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail</url>
+  </scm>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.servicemix.tooling</groupId>
+        <artifactId>depends-maven-plugin</artifactId>
+        <version>1.2</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>generate-depends-file</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-failsafe-plugin</artifactId>
+        <version>2.18.1</version>
+        <executions>
+          <execution>
+            <goals>
+              <goal>integration-test</goal>
+              <goal>verify</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <systemProperties>
+            <property>
+              <name>bundle.filename</name>
+              <value>${basedir}/target/${project.build.finalName}.jar</value>
+            </property>
+          </systemProperties>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <!-- javax -->
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <version>1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.mail</groupId>
+      <artifactId>javax.mail-api</artifactId>
+      <version>1.5.5</version>
+      <scope>provided</scope>
+    </dependency>
+    <!-- Sun -->
+    <dependency>
+      <groupId>com.sun.mail</groupId>
+      <artifactId>javax.mail</artifactId>
+      <version>1.5.5</version>
+      <scope>provided</scope>
+    </dependency>
+    <!-- OSGi -->
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>osgi.core</artifactId>
+      <version>6.0.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>osgi.annotation</artifactId>
+      <version>6.0.1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.service.component.annotations</artifactId>
+      <version>1.3.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.service.metatype.annotations</artifactId>
+      <version>1.3.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <!-- Apache Commons -->
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-email</artifactId>
+      <version>1.4</version>
+      <scope>provided</scope>
+    </dependency>
+    <!-- Apache Felix -->
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.configadmin</artifactId>
+      <version>1.8.8</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.scr</artifactId>
+      <version>2.0.2</version>
+      <scope>test</scope>
+    </dependency>
+    <!-- Apache Sling -->
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.commons.threads</artifactId>
+      <version>3.2.6</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.sling</groupId>
+      <artifactId>org.apache.sling.commons.messaging</artifactId>
+      <version>0.0.1-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+    <!-- logging -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <!-- JSR 305-->
+    <dependency>
+      <groupId>com.google.code.findbugs</groupId>
+      <artifactId>jsr305</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <!-- testing -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-container-forked</artifactId>
+      <version>4.8.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-junit4</artifactId>
+      <version>4.8.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.exam</groupId>
+      <artifactId>pax-exam-link-mvn</artifactId>
+      <version>4.8.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.url</groupId>
+      <artifactId>pax-url-aether</artifactId>
+      <version>2.4.6</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.url</groupId>
+      <artifactId>pax-url-reference</artifactId>
+      <version>2.4.6</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.ops4j.pax.url</groupId>
+      <artifactId>pax-url-wrap</artifactId>
+      <version>2.4.6</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.framework</artifactId>
+      <version>5.4.0</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.subethamail</groupId>
+      <artifactId>subethasmtp</artifactId>
+      <version>3.1.7</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailBuilder.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailBuilder.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailBuilder.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail;
+
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import org.apache.commons.mail.Email;
+import org.apache.commons.mail.EmailException;
+import org.osgi.annotation.versioning.ProviderType;
+
+@ProviderType
+public interface MailBuilder {
+
+    Email build(@Nonnull final String message, @Nonnull final String recipient, @Nonnull final Map data) throws EmailException;
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailUtil.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailUtil.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailUtil.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/MailUtil.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import javax.mail.MessagingException;
+
+import org.apache.commons.mail.Email;
+
+public class MailUtil {
+
+    public static byte[] toByteArray(final Email email) throws IOException, MessagingException {
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        email.getMimeMessage().writeTo(baos);
+        return baos.toByteArray();
+    }
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailFailure.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailFailure.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailFailure.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailFailure.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail.internal;
+
+import org.apache.sling.commons.messaging.Failure;
+
+public class MailFailure implements Failure {
+
+    private final String code;
+
+    private final String type;
+
+    private final String message;
+
+    public MailFailure(final String code, final String type, final String message) {
+        this.code = code;
+        this.type = type;
+        this.message = message;
+    }
+
+    @Override
+    public String getCode() {
+        return code;
+    }
+
+    @Override
+    public String getType() {
+        return type;
+    }
+
+    @Override
+    public String getMessage() {
+        return message;
+    }
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailResult.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailResult.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailResult.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/MailResult.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail.internal;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.sling.commons.messaging.Failure;
+import org.apache.sling.commons.messaging.Result;
+
+public class MailResult implements Result<byte[]> {
+
+    private final byte[] message;
+
+    private final Collection<Failure> failures;
+
+    public MailResult(final byte[] message, final Failure... failures) {
+        this.message = message;
+        this.failures = Arrays.asList(failures);
+    }
+
+    /**
+     * @return the message in <a href="https://tools.ietf.org/html/rfc822">RFC 822</a> format
+     */
+    @Override
+    public byte[] getMessage() {
+        return message;
+    }
+
+    @Override
+    public boolean hasFailures() {
+        return !(failures == null || failures.isEmpty());
+    }
+
+    @Override
+    public Collection<Failure> getFailures() {
+        return failures;
+    }
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilder.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilder.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilder.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail.internal;
+
+import java.util.Collections;
+import java.util.Map;
+
+import javax.annotation.Nonnull;
+
+import org.apache.commons.mail.Email;
+import org.apache.commons.mail.EmailException;
+import org.apache.commons.mail.SimpleEmail;
+import org.apache.sling.commons.messaging.mail.MailBuilder;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.ConfigurationPolicy;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.metatype.annotations.Designate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(
+    service = MailBuilder.class,
+    property = {
+        Constants.SERVICE_DESCRIPTION + "=Service to build simple mails.",
+        Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
+    },
+    configurationPolicy = ConfigurationPolicy.REQUIRE
+)
+@Designate(
+    ocd = SimpleMailBuilderConfiguration.class
+)
+public class SimpleMailBuilder implements MailBuilder {
+
+    // TODO use encryption and support more configuration options
+
+    private String subject;
+
+    private String from;
+
+    private String smtpHostname;
+
+    private int smtpPort;
+
+    private String smtpUsername;
+
+    private String smtpPassword;
+
+    private static final String SUBJECT_KEY = "mail.subject";
+
+    private static final String FROM_KEY = "mail.from";
+
+    private static final String SMTP_HOSTNAME_KEY = "mail.smtp.hostname";
+
+    private static final String SMTP_PORT_KEY = "mail.smtp.port";
+
+    private static final String SMTP_USERNAME_KEY = "mail.smtp.username";
+
+    private static final String SMTP_PASSWORD_KEY = "mail.smtp.password";
+
+    private final Logger logger = LoggerFactory.getLogger(SimpleMailBuilder.class);
+
+    public SimpleMailBuilder() {
+    }
+
+    @Activate
+    private void activate(final SimpleMailBuilderConfiguration configuration) {
+        logger.debug("activate");
+        configure(configuration);
+    }
+
+    @Modified
+    private void modified(final SimpleMailBuilderConfiguration configuration) {
+        logger.debug("modified");
+        configure(configuration);
+    }
+
+    private void configure(final SimpleMailBuilderConfiguration configuration) {
+        subject = configuration.subject();
+        from = configuration.from();
+        smtpHostname = configuration.smtpHostname();
+        smtpPort = configuration.smtpPort();
+        smtpUsername = configuration.smtpUsername();
+        smtpPassword = configuration.smtpPassword();
+    }
+
+    @Override
+    public Email build(@Nonnull final String message, @Nonnull final String recipient, @Nonnull final Map data) throws EmailException {
+        final Map configuration = (Map) data.getOrDefault("mail", Collections.EMPTY_MAP);
+        final String subject = (String) configuration.getOrDefault(SUBJECT_KEY, this.subject);
+        final String from = (String) configuration.getOrDefault(FROM_KEY, this.from);
+        final String smtpHostname = (String) configuration.getOrDefault(SMTP_HOSTNAME_KEY, this.smtpHostname);
+        final int smtpPort = (Integer) configuration.getOrDefault(SMTP_PORT_KEY, this.smtpPort);
+        final String smtpUsername = (String) configuration.getOrDefault(SMTP_USERNAME_KEY, this.smtpUsername);
+        final String smtpPassword = (String) configuration.getOrDefault(SMTP_PASSWORD_KEY, this.smtpPassword);
+
+        final Email email = new SimpleEmail();
+        email.setMsg(message);
+        email.addTo(recipient);
+        email.setSubject(subject);
+        email.setFrom(from);
+        email.setHostName(smtpHostname);
+        email.setSmtpPort(smtpPort);
+        email.setAuthentication(smtpUsername, smtpPassword);
+        return email;
+    }
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderConfiguration.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderConfiguration.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderConfiguration.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderConfiguration.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail.internal;
+
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+@ObjectClassDefinition(
+    name = "Apache Sling Commons Messaging Mail “Simple Mail Builder”",
+    description = "simple mail builder for Sling Commons Messaging Mail"
+)
+@interface SimpleMailBuilderConfiguration {
+
+    @AttributeDefinition(
+        name = "subject",
+        description = "default subject for mails"
+    )
+    String subject();
+
+    @AttributeDefinition(
+        name = "from",
+        description = "default from (sender) address for mails"
+    )
+    String from();
+
+    @AttributeDefinition(
+        name = "SMTP hostname",
+        description = "hostname of SMTP server"
+    )
+    String smtpHostname() default "localhost";
+
+    @AttributeDefinition(
+        name = "SMTP port",
+        description = "port of SMTP server"
+    )
+    int smtpPort() default 25;
+
+    @AttributeDefinition(
+        name = "SMTP username",
+        description = "username for SMTP server"
+    )
+    String smtpUsername();
+
+    @AttributeDefinition(
+        name = "SMTP password",
+        description = "password for SMTP server"
+    )
+    String smtpPassword();
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailService.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail.internal;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+import org.apache.commons.mail.Email;
+import org.apache.sling.commons.messaging.Failure;
+import org.apache.sling.commons.messaging.MessageService;
+import org.apache.sling.commons.messaging.Result;
+import org.apache.sling.commons.messaging.mail.MailBuilder;
+import org.apache.sling.commons.messaging.mail.MailUtil;
+import org.apache.sling.commons.threads.ThreadPool;
+import org.apache.sling.commons.threads.ThreadPoolManager;
+import org.osgi.framework.Constants;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Modified;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.osgi.service.metatype.annotations.Designate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Component(
+    service = MessageService.class,
+    property = {
+        Constants.SERVICE_DESCRIPTION + "=Service to send messages by mail.",
+        Constants.SERVICE_VENDOR + "=The Apache Software Foundation"
+    }
+)
+@Designate(
+    ocd = SimpleMailServiceConfiguration.class
+)
+public class SimpleMailService implements MessageService {
+
+    @Reference(
+        cardinality = ReferenceCardinality.MANDATORY,
+        policy = ReferencePolicy.DYNAMIC,
+        policyOption = ReferencePolicyOption.GREEDY
+    )
+    private volatile MailBuilder mailBuilder;
+
+    @Reference(
+        cardinality = ReferenceCardinality.MANDATORY,
+        policy = ReferencePolicy.DYNAMIC,
+        policyOption = ReferencePolicyOption.GREEDY
+    )
+    private volatile ThreadPoolManager threadPoolManager;
+
+    // the ThreadPool used for sending mails
+    private ThreadPool threadPool;
+
+    private final Logger logger = LoggerFactory.getLogger(SimpleMailService.class);
+
+    public SimpleMailService() {
+    }
+
+    @Activate
+    private void activate(final SimpleMailServiceConfiguration configuration) {
+        logger.debug("activate");
+        configure(configuration);
+    }
+
+    @Modified
+    private void modified(final SimpleMailServiceConfiguration configuration) {
+        logger.debug("modified");
+        configure(configuration);
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        logger.info("deactivate");
+        threadPoolManager.release(threadPool);
+        threadPool = null;
+    }
+
+    private void configure(final SimpleMailServiceConfiguration configuration) {
+        threadPoolManager.release(threadPool);
+        threadPool = threadPoolManager.get(configuration.threadpoolName());
+    }
+
+    @Override
+    public Future<Result> send(final String message, final String recipient) {
+        return send(message, recipient, Collections.emptyMap());
+    }
+
+    @Override
+    public Future<Result> send(final String message, final String recipient, final Map data) {
+        final Mailing mailing = new Mailing(message, recipient, data, mailBuilder);
+        return threadPool.submit(mailing);
+    }
+
+    private class Mailing implements Callable<Result> {
+
+        private final String message;
+
+        private final String recipient;
+
+        private final Map data;
+
+        private MailBuilder mailBuilder;
+
+        Mailing(final String message, final String recipient, final Map data, final MailBuilder mailBuilder) {
+            this.message = message;
+            this.recipient = recipient;
+            this.data = data;
+            this.mailBuilder = mailBuilder;
+        }
+
+        @Override
+        public Result call() {
+            Email mail = null;
+            // build mail
+            try {
+                mail = mailBuilder.build(message, recipient, data);
+            } catch (Exception e) {
+                logger.error("building mail failed: {}", e.getMessage(), e);
+                final Failure failure = new MailFailure(null, null, e.getMessage());
+                return new MailResult(null, failure);
+            } finally {
+                mailBuilder = null;
+            }
+            // send mail
+            try {
+                final String messageId = mail.send();
+                logger.info("mail '{}' sent", messageId);
+                final byte[] bytes = MailUtil.toByteArray(mail);
+                return new MailResult(bytes);
+            } catch (Exception e) {
+                logger.error("sending mail failed: {}", e.getMessage(), e);
+                final Failure failure = new MailFailure(null, null, e.getMessage());
+                return new MailResult(null, failure);
+            }
+        }
+    }
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceConfiguration.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail.internal;
+
+import org.osgi.service.metatype.annotations.AttributeDefinition;
+import org.osgi.service.metatype.annotations.ObjectClassDefinition;
+
+@ObjectClassDefinition(
+    name = "Apache Sling Commons Messaging Mail “Simple Mail Service”",
+    description = "simple mail service for Sling Commons Messaging"
+)
+@interface SimpleMailServiceConfiguration {
+
+    @AttributeDefinition(
+        name = "ThreadPool name",
+        description = "name of the ThreadPool to use for sending mails"
+    )
+    String threadpoolName() default "default";
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/package-info.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/package-info.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/package-info.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/main/java/org/apache/sling/commons/messaging/mail/package-info.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+@Version("1.0.0")
+package org.apache.sling.commons.messaging.mail;
+
+import org.osgi.annotation.versioning.Version;

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailBuilderConfigurations.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailBuilderConfigurations.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailBuilderConfigurations.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailBuilderConfigurations.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+public class MailBuilderConfigurations {
+
+    /**
+     * @return minimal configuration properties for building mails
+     */
+    public static Dictionary<String, Object> minimal() {
+        final Dictionary<String, Object> properties = new Hashtable<>();
+        properties.put("subject", "Rudy, A Message to You");
+        properties.put("from", "dandy.livingstone@kingston.jamaica");
+        properties.put("smtpHostname", "localhost");
+        return properties;
+    }
+
+    /**
+     * @param smtpPort SMTP port to use for sending
+     * @return configuration properties including authentication for sending
+     */
+    public static Dictionary<String, Object> full(final int smtpPort) {
+        final Dictionary<String, Object> properties = new Hashtable<>();
+        properties.put("subject", "Testing the Simple Mail Service");
+        properties.put("from", "sender@example.net");
+        properties.put("smtpHostname", "localhost");
+        properties.put("smtpPort", smtpPort);
+        properties.put("smtpUsername", "test");
+        properties.put("smtpPassword", "test");
+        return properties;
+    }
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailTestSupport.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailTestSupport.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailTestSupport.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/MailTestSupport.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.util.Dictionary;
+
+import javax.inject.Inject;
+
+import org.ops4j.pax.exam.Option;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.ops4j.pax.exam.CoreOptions.bundle;
+import static org.ops4j.pax.exam.CoreOptions.junitBundles;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.CoreOptions.provision;
+import static org.ops4j.pax.exam.CoreOptions.wrappedBundle;
+
+public abstract class MailTestSupport {
+
+    @Inject
+    protected BundleContext bundleContext;
+
+    @Inject
+    protected ConfigurationAdmin configurationAdmin;
+
+    protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+    public MailTestSupport() {
+    }
+
+    protected synchronized int findFreePort() {
+        try {
+            final ServerSocket serverSocket = new ServerSocket(0);
+            final int port = serverSocket.getLocalPort();
+            serverSocket.close();
+            return port;
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    protected void createFactoryConfiguration(final String factoryPid, final Dictionary<String, Object> properties) throws IOException, InterruptedException {
+        final org.osgi.service.cm.Configuration configuration = configurationAdmin.createFactoryConfiguration(factoryPid);
+        configuration.setBundleLocation(null);
+        configuration.update(properties);
+        logger.debug("configuration: {}", configurationAdmin.getConfiguration(factoryPid));
+    }
+
+    protected <T> T getService(Class<T> type) {
+        final ServiceReference<T> serviceReference = bundleContext.getServiceReference(type);
+        return bundleContext.getService(serviceReference);
+    }
+
+    protected Option[] baseConfiguration() {
+        final String filename = System.getProperty("bundle.filename");
+        return options(
+            junitBundles(),
+            provision(
+                wrappedBundle(mavenBundle().groupId("org.subethamail").artifactId("subethasmtp").versionAsInProject()),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.configadmin").versionAsInProject(),
+                mavenBundle().groupId("org.apache.felix").artifactId("org.apache.felix.scr").versionAsInProject(),
+                mavenBundle().groupId("com.sun.mail").artifactId("javax.mail").versionAsInProject(),
+                mavenBundle().groupId("javax.mail").artifactId("javax.mail-api").versionAsInProject(),
+                mavenBundle().groupId("org.apache.commons").artifactId("commons-email").versionAsInProject(),
+                mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.messaging").versionAsInProject(),
+                mavenBundle().groupId("org.apache.sling").artifactId("org.apache.sling.commons.threads").versionAsInProject(),
+                bundle("reference:file:" + filename)
+            )
+        );
+    }
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderIT.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderIT.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderIT.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailBuilderIT.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail.internal;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+
+import org.apache.commons.mail.Email;
+import org.apache.sling.commons.messaging.mail.MailBuilder;
+import org.apache.sling.commons.messaging.mail.MailBuilderConfigurations;
+import org.apache.sling.commons.messaging.mail.MailTestSupport;
+import org.apache.sling.commons.messaging.mail.MailUtil;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerMethod.class)
+public class SimpleMailBuilderIT extends MailTestSupport {
+
+    @Configuration
+    public Option[] configuration() {
+        return baseConfiguration();
+    }
+
+    @Before
+    public void setup() throws Exception {
+        final String factoryPid = "org.apache.sling.commons.messaging.mail.internal.SimpleMailBuilder";
+        final Dictionary<String, Object> properties = MailBuilderConfigurations.minimal();
+        createFactoryConfiguration(factoryPid, properties);
+    }
+
+    @Test
+    public void testBuildWithDefaults() throws Exception {
+        final MailBuilder mailBuilder = getService(MailBuilder.class);
+        final Email email = mailBuilder.build("Stop your messing around, Better think of your future...", "rudy@ghosttown", Collections.emptyMap());
+        email.buildMimeMessage();
+        final byte[] bytes = MailUtil.toByteArray(email);
+        final String mail = new String(bytes, StandardCharsets.UTF_8);
+        logger.debug("mail: " + mail);
+        assertEquals("rudy@ghosttown", email.getToAddresses().get(0).getAddress());
+        assertEquals("Rudy, A Message to You", email.getSubject());
+        assertEquals("dandy.livingstone@kingston.jamaica", email.getFromAddress().getAddress());
+        assertEquals("localhost", email.getHostName());
+        logger.debug(email.getMimeMessage().getContent().toString());
+    }
+
+    @Test
+    public void testBuildWithData() throws Exception {
+        final MailBuilder mailBuilder = getService(MailBuilder.class);
+        final Map<String, String> configuration = new HashMap<>();
+        configuration.put("mail.subject", "Rudy, A Message to You");
+        configuration.put("mail.from", "specials@thespecials.com");
+        final Map data = Collections.singletonMap("mail", configuration);
+        final Email email = mailBuilder.build("A Message to You, Rudy", "rudy@ghosttown", data);
+        email.buildMimeMessage();
+        final byte[] bytes = MailUtil.toByteArray(email);
+        final String mail = new String(bytes, StandardCharsets.UTF_8);
+        logger.debug("mail: " + mail);
+        assertEquals("rudy@ghosttown", email.getToAddresses().get(0).getAddress());
+        assertEquals("Rudy, A Message to You", email.getSubject());
+        assertEquals("specials@thespecials.com", email.getFromAddress().getAddress());
+        assertEquals("localhost", email.getHostName());
+        logger.debug(email.getMimeMessage().getContent().toString());
+    }
+
+}

Added: sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceIT.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceIT.java?rev=1738114&view=auto
==============================================================================
--- sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceIT.java (added)
+++ sling/trunk/bundles/commons/org.apache.sling.commons.messaging.mail/src/test/java/org/apache/sling/commons/messaging/mail/internal/SimpleMailServiceIT.java Thu Apr  7 09:18:07 2016
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.commons.messaging.mail.internal;
+
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Map;
+import java.util.concurrent.Future;
+
+import org.apache.sling.commons.messaging.MessageService;
+import org.apache.sling.commons.messaging.Result;
+import org.apache.sling.commons.messaging.mail.MailBuilderConfigurations;
+import org.apache.sling.commons.messaging.mail.MailTestSupport;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+import org.subethamail.wiser.Wiser;
+
+import static junit.framework.TestCase.assertFalse;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerMethod.class)
+public class SimpleMailServiceIT extends MailTestSupport {
+
+    protected Wiser wiser;
+
+    @Configuration
+    public Option[] configuration() {
+        return baseConfiguration();
+    }
+
+    @Before
+    public void setup() throws Exception {
+        final int smtpPort = findFreePort();
+        wiser = new Wiser(smtpPort);
+        wiser.start();
+        final String factoryPid = "org.apache.sling.commons.messaging.mail.internal.SimpleMailBuilder";
+        final Dictionary<String, Object> properties = MailBuilderConfigurations.full(smtpPort);
+        createFactoryConfiguration(factoryPid, properties);
+    }
+
+    @After
+    public void teardown() {
+        wiser.stop();
+        wiser = null;
+    }
+
+    @Test
+    public void send() throws Exception {
+        final MessageService messageService = getService(MessageService.class);
+        final Future<Result> future = messageService.send("simple test message", "recipient@example.net");
+        final Result result = future.get();
+        assertFalse(result.hasFailures());
+    }
+
+    @Test
+    public void sendWithData() throws Exception {
+        final MessageService messageService = getService(MessageService.class);
+        final Map configuration = Collections.singletonMap("mail.subject", "Testing the Simple Mail Service with a custom subject");
+        final Map data = Collections.singletonMap("mail", configuration);
+        final Future<Result> future = messageService.send("simple test message", "recipient@example.net", data);
+        final Result result = future.get();
+        assertFalse(result.hasFailures());
+    }
+
+}