You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2020/02/26 02:26:39 UTC

[sling-org-apache-sling-app-cms] 02/02: Fixes SLING-9152 - Adding support for commons messaging mail

This is an automated email from the ASF dual-hosted git repository.

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git

commit 09cf8aaa4672567d601311c5db68644d45bb21ec
Author: Dan Klco <dk...@apache.org>
AuthorDate: Tue Feb 25 21:26:21 2020 -0500

    Fixes SLING-9152 - Adding support for commons messaging mail
---
 builder/src/main/provisioning/sling.txt            |   5 +
 pom.xml                                            |  28 +++-
 reference/pom.xml                                  |  12 +-
 .../forms/impl/actions/SendEmailAction.java        | 101 ++++---------
 .../forms/impl/actions/SendEmailActonConfig.java   |  40 -----
 ...JasyptRandomIvGeneratorRegistrar-default.config |  19 +++
 ...syptRandomSaltGeneratorRegistrar-default.config |  19 +++
 ...ptStandardPBEStringCryptoService-default.config |  26 ++++
 .../cms/reference/form/impl/FormHandlerTest.java   |  50 ++-----
 .../reference/form/impl/MockMessageBuilder.java    | 165 +++++++++++++++++++++
 .../form/impl/actions/SendEmailActionTest.java     |  64 ++------
 11 files changed, 311 insertions(+), 218 deletions(-)

diff --git a/builder/src/main/provisioning/sling.txt b/builder/src/main/provisioning/sling.txt
index 0665efa..a7a9616 100644
--- a/builder/src/main/provisioning/sling.txt
+++ b/builder/src/main/provisioning/sling.txt
@@ -93,6 +93,11 @@
     org.apache.sling/org.apache.sling.commons.classloader/1.4.4
     org.apache.sling/org.apache.sling.commons.compiler/2.3.6
     org.apache.sling/org.apache.sling.commons.fsclassloader/1.0.12
+    org.apache.servicemix.bundles/org.apache.servicemix.bundles.jasypt/1.9.3_1
+    org.apache.sling/org.apache.sling.commons.crypto/1.0.0
+    com.sun.mail/javax.mail/1.6.2
+    org.apache.sling/org.apache.sling.commons.messaging/1.0.0
+    org.apache.sling/org.apache.sling.commons.messaging.mail/1.0.0
     org.apache.sling/org.apache.sling.commons.mime/2.2.2
     org.apache.sling/org.apache.sling.commons.osgi/2.4.0
     org.apache.sling/org.apache.sling.commons.scheduler/2.7.4
diff --git a/pom.xml b/pom.xml
index 534370b..ee7daa8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?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
@@ -128,6 +128,24 @@
                 <scope>provided</scope>
             </dependency>
             <dependency>
+                <groupId>com.sun.mail</groupId>
+                <artifactId>javax.mail</artifactId>
+                <version>1.6.2</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>org.apache.sling.commons.messaging</artifactId>
+                <version>1.0.0</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.sling</groupId>
+                <artifactId>org.apache.sling.commons.messaging.mail</artifactId>
+                <version>1.0.0</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
                 <groupId>org.apache.sling</groupId>
                 <artifactId>org.apache.sling.commons.johnzon</artifactId>
                 <version>1.1.2</version>
@@ -197,12 +215,6 @@
             </dependency>
             <dependency>
                 <groupId>org.apache.commons</groupId>
-                <artifactId>commons-email</artifactId>
-                <version>1.5</version>
-                <scope>provided</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.commons</groupId>
                 <artifactId>commons-lang3</artifactId>
                 <version>3.8.1</version>
                 <scope>provided</scope>
@@ -355,4 +367,4 @@
         </pluginManagement>
     </build>
 
-</project>
+</project>
\ No newline at end of file
diff --git a/reference/pom.xml b/reference/pom.xml
index d1bc851..8222ed5 100644
--- a/reference/pom.xml
+++ b/reference/pom.xml
@@ -126,13 +126,21 @@
             <version>2.0</version>
         </dependency>
         <dependency>
-            <artifactId>commons-email</artifactId>
-            <groupId>org.apache.commons</groupId>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.messaging</artifactId>
+        </dependency>
+        <dependency>
+            <artifactId>org.apache.sling.commons.messaging.mail</artifactId>
+            <groupId>org.apache.sling</groupId>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.event.api</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.sun.mail</groupId>
+            <artifactId>javax.mail</artifactId>
+        </dependency>
 
         <!-- Testing dependencies -->
         <dependency>
diff --git a/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/SendEmailAction.java b/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/SendEmailAction.java
index b0ebb4c..f4dedc7 100644
--- a/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/SendEmailAction.java
+++ b/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/SendEmailAction.java
@@ -16,35 +16,25 @@
  */
 package org.apache.sling.cms.reference.forms.impl.actions;
 
-import java.util.HashMap;
-import java.util.Map;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
 
 import org.apache.commons.text.StringSubstitutor;
-import org.apache.commons.mail.DefaultAuthenticator;
-import org.apache.commons.mail.Email;
-import org.apache.commons.mail.EmailException;
-import org.apache.commons.mail.SimpleEmail;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.cms.reference.forms.FormAction;
 import org.apache.sling.cms.reference.forms.FormActionResult;
 import org.apache.sling.cms.reference.forms.FormException;
 import org.apache.sling.cms.reference.forms.FormRequest;
-import org.apache.sling.event.jobs.Job;
-import org.apache.sling.event.jobs.JobManager;
-import org.apache.sling.event.jobs.consumer.JobConsumer;
-import org.osgi.service.component.annotations.Activate;
+import org.apache.sling.commons.messaging.mail.MailService;
+import org.jetbrains.annotations.NotNull;
 import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.ConfigurationPolicy;
 import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.metatype.annotations.Designate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Component(service = { FormAction.class, JobConsumer.class }, property = {
-        JobConsumer.PROPERTY_TOPICS + "=" + SendEmailAction.TOPIC }, configurationPolicy = ConfigurationPolicy.REQUIRE)
-@Designate(ocd = SendEmailActonConfig.class)
-public class SendEmailAction implements JobConsumer, FormAction {
+@Component(service = { FormAction.class })
+public class SendEmailAction implements FormAction {
 
     public static final String FROM = "from";
     private static final Logger log = LoggerFactory.getLogger(SendEmailAction.class);
@@ -52,72 +42,39 @@ public class SendEmailAction implements JobConsumer, FormAction {
     public static final String MESSAGE = "message";
     public static final String SUBJECT = "subject";
     public static final String TO = "to";
-    public static final String TOPIC = "reference/form/sendemail";
-
-    private SendEmailActonConfig config;
 
     @Reference
-    private JobManager jobManager;
-
-    @Activate
-    public void activate(SendEmailActonConfig config) {
-        this.config = config;
-    }
+    private MailService mailService;
 
     @Override
-    public FormActionResult handleForm(Resource actionResource, FormRequest request) throws FormException {
-        StringSubstitutor sub = new StringSubstitutor(request.getFormData());
+    public FormActionResult handleForm(final Resource actionResource, final FormRequest request) throws FormException {
+        final StringSubstitutor sub = new StringSubstitutor(request.getFormData());
 
-        ValueMap properties = actionResource.getValueMap();
-        String to = sub.replace(properties.get(TO, String.class));
-        log.debug("Queueing contact message to {}", to);
+        final ValueMap properties = actionResource.getValueMap();
+        final String to = sub.replace(properties.get(TO, String.class));
+        log.debug("Sending message to {}", to);
 
-        Map<String, Object> data = new HashMap<>();
-        data.put(SendEmailAction.SUBJECT, sub.replace(properties.get(SUBJECT, String.class)));
-        data.put(SendEmailAction.MESSAGE, sub.replace(properties.get(MESSAGE, String.class)));
-        data.put(SendEmailAction.TO, to);
-        data.put(SendEmailAction.FROM, sub.replace(properties.get(FROM, String.class)));
-        jobManager.addJob(TOPIC, data);
-        log.debug("Job queued successfully!");
-        return FormActionResult.success("Email queued successfully!");
+        try {
+            @NotNull
+            final MimeMessage message = mailService.getMessageBuilder()
+                    .from(sub.replace(properties.get(FROM, String.class)))
+                    .to(to)
+                    .subject(sub.replace(properties.get(SUBJECT, String.class)))
+                    .text(sub.replace(properties.get(MESSAGE, String.class))).build();
+
+            log.debug("Sending message...");
+            mailService.sendMessage(message);
+            log.debug("Message sent successfully!");
+            return FormActionResult.success("Message sent successfully!");
+        } catch (final MessagingException e) {
+            log.error("Failed to send message", e);
+            return FormActionResult.failure("Failed to send message: " + e.toString());
+        }
     }
 
     @Override
-    public boolean handles(Resource actionResource) {
+    public boolean handles(final Resource actionResource) {
         return "reference/components/forms/actions/sendemail".equals(actionResource.getResourceType());
     }
 
-    public JobResult process(final Job job) {
-        log.trace("process");
-
-        try {
-
-            log.debug("Configuring connection to {}:{} with username {}", config.hostName(), config.smtpPort(),
-                    config.username());
-            Email email = new SimpleEmail();
-            email.setHostName(config.hostName());
-            email.setSmtpPort(config.smtpPort());
-            email.setAuthenticator(new DefaultAuthenticator(config.username(), config.password()));
-            email.setStartTLSEnabled(config.tlsEnabled());
-
-            String from = job.getProperty(FROM, String.class);
-            String to = job.getProperty(TO, String.class);
-            String subject = job.getProperty(SUBJECT, String.class);
-            String message = job.getProperty(MESSAGE, String.class);
-            log.debug("Sending email from {} to {} with subject {}", from, to, subject);
-
-            email.setFrom(from);
-            email.setSubject(subject);
-            email.setMsg(message);
-            email.addTo(to);
-
-            email.send();
-        } catch (EmailException e) {
-            log.warn("Exception sending email for job " + job.getId(), e);
-            return JobResult.FAILED;
-        }
-
-        // process the job and return the result
-        return JobResult.OK;
-    }
 }
diff --git a/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/SendEmailActonConfig.java b/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/SendEmailActonConfig.java
deleted file mode 100644
index 4a16377..0000000
--- a/reference/src/main/java/org/apache/sling/cms/reference/forms/impl/actions/SendEmailActonConfig.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.cms.reference.forms.impl.actions;
-
-import org.osgi.service.metatype.annotations.AttributeDefinition;
-import org.osgi.service.metatype.annotations.AttributeType;
-import org.osgi.service.metatype.annotations.ObjectClassDefinition;
-
-@ObjectClassDefinition(name = "%cms.reference.sendemail.name", description = "%cms.reference.sendemail.description", localization = "OSGI-INF/l10n/bundle")
-public @interface SendEmailActonConfig {
-    
-    @AttributeDefinition(name = "%cms.reference.sendemail.hostName.name", description = "%cms.reference.sendemail.hostName.description")
-    String hostName();
-
-    @AttributeDefinition(name = "%cms.reference.sendemail.smtpPort.name", description = "%cms.reference.sendemail.smtpPort.description")
-    int smtpPort();
-
-    @AttributeDefinition(name = "%cms.reference.sendemail.tlsEnabled.name", description = "%cms.reference.sendemail.tlsEnabled.description")
-    boolean tlsEnabled();
-
-    @AttributeDefinition(name = "%cms.reference.sendemail.username.name", description = "%cms.reference.sendemail.username.description")
-    String username();
-
-    @AttributeDefinition(name = "%cms.reference.sendemail.password.name", description = "%cms.reference.sendemail.password.description", type=AttributeType.PASSWORD)
-    String password();
-}
diff --git a/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptRandomIvGeneratorRegistrar-default.config b/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptRandomIvGeneratorRegistrar-default.config
new file mode 100644
index 0000000..488bb44
--- /dev/null
+++ b/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptRandomIvGeneratorRegistrar-default.config
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+algorithm="SHA1PRNG"
\ No newline at end of file
diff --git a/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptRandomSaltGeneratorRegistrar-default.config b/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptRandomSaltGeneratorRegistrar-default.config
new file mode 100644
index 0000000..488bb44
--- /dev/null
+++ b/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptRandomSaltGeneratorRegistrar-default.config
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+algorithm="SHA1PRNG"
\ No newline at end of file
diff --git a/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptStandardPBEStringCryptoService-default.config b/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptStandardPBEStringCryptoService-default.config
new file mode 100644
index 0000000..1d0e9c6
--- /dev/null
+++ b/reference/src/main/resources/jcr_root/apps/reference/install/org.apache.sling.commons.crypto.jasypt.internal.JasyptStandardPBEStringCryptoService-default.config
@@ -0,0 +1,26 @@
+#
+# 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.
+#
+algorithm="PBEWITHHMACSHA512ANDAES_256"
+saltGenerator.target=""
+securityProviderName=""
+ivGenerator.target=""
+securityProvider.target=""
+keyObtentionIterations=I"1000"
+names=["default"]
+stringOutputType="base64"
\ No newline at end of file
diff --git a/reference/src/test/java/org/apache/sling/cms/reference/form/impl/FormHandlerTest.java b/reference/src/test/java/org/apache/sling/cms/reference/form/impl/FormHandlerTest.java
index a22ac43..cb601b5 100644
--- a/reference/src/test/java/org/apache/sling/cms/reference/form/impl/FormHandlerTest.java
+++ b/reference/src/test/java/org/apache/sling/cms/reference/form/impl/FormHandlerTest.java
@@ -17,7 +17,6 @@
 package org.apache.sling.cms.reference.form.impl;
 
 import java.io.IOException;
-import java.lang.annotation.Annotation;
 import java.util.Arrays;
 
 import javax.servlet.ServletException;
@@ -28,11 +27,10 @@ import org.apache.sling.cms.reference.forms.FormRequest;
 import org.apache.sling.cms.reference.forms.impl.FormHandler;
 import org.apache.sling.cms.reference.forms.impl.FormRequestImpl;
 import org.apache.sling.cms.reference.forms.impl.actions.SendEmailAction;
-import org.apache.sling.cms.reference.forms.impl.actions.SendEmailActonConfig;
 import org.apache.sling.cms.reference.forms.impl.fields.SelectionHandler;
 import org.apache.sling.cms.reference.forms.impl.fields.TextareaHandler;
 import org.apache.sling.cms.reference.forms.impl.fields.TextfieldHandler;
-import org.apache.sling.event.jobs.JobManager;
+import org.apache.sling.commons.messaging.mail.MailService;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Before;
 import org.junit.Rule;
@@ -46,6 +44,7 @@ public class FormHandlerTest {
     @Rule
     public final SlingContext context = new SlingContext();
     private FormHandler formHandler;
+    private MailService mailService;
 
     @Before
     public void init() throws NoSuchFieldException, SecurityException, FormException {
@@ -59,7 +58,7 @@ public class FormHandlerTest {
                         .put("patternfield", "123").put("double", "2.7").put("integer", "2")
                         .put("datefield", "2019-02-02").build());
 
-        FormRequestImpl formRequest = new FormRequestImpl(context.request());
+        final FormRequestImpl formRequest = new FormRequestImpl(context.request());
 
         FieldSetter.setField(formRequest, formRequest.getClass().getDeclaredField("fieldHandlers"),
                 Arrays.asList(new SelectionHandler(), new TextareaHandler(), new TextfieldHandler()));
@@ -69,47 +68,15 @@ public class FormHandlerTest {
         formHandler = new FormHandler() {
             private static final long serialVersionUID = 1L;
 
-            protected FormRequest getFormRequest(SlingHttpServletRequest request) {
+            protected FormRequest getFormRequest(final SlingHttpServletRequest request) {
                 return formRequest;
             }
         };
 
-        SendEmailAction sendEmailAction = new SendEmailAction();
-        sendEmailAction.activate(new SendEmailActonConfig() {
-
-            @Override
-            public String hostName() {
-                return "smtp.mailtrap.io";
-            }
-
-            @Override
-            public int smtpPort() {
-                return 587;
-            }
-
-            @Override
-            public boolean tlsEnabled() {
-                return true;
-            }
-
-            @Override
-            public String username() {
-                return "e7cfc0e9bb9b80";
-            }
-
-            @Override
-            public String password() {
-                return "b9902898ce236a";
-            }
-
-            @Override
-            public Class<? extends Annotation> annotationType() {
-                return null;
-            }
-
-        });
-        FieldSetter.setField(sendEmailAction, SendEmailAction.class.getDeclaredField("jobManager"),
-                Mockito.mock(JobManager.class));
+        final SendEmailAction sendEmailAction = new SendEmailAction();
+        mailService = Mockito.mock(MailService.class);
+        Mockito.when(mailService.getMessageBuilder()).thenReturn(new MockMessageBuilder());
+        FieldSetter.setField(sendEmailAction, sendEmailAction.getClass().getDeclaredField("mailService"), mailService);
 
         FieldSetter.setField(formHandler, FormHandler.class.getDeclaredField("formActions"),
                 Arrays.asList(sendEmailAction));
@@ -119,6 +86,7 @@ public class FormHandlerTest {
     @Test
     public void testPost() throws ServletException, IOException {
         formHandler.service(context.request(), context.response());
+        Mockito.verify(mailService).sendMessage(Mockito.any());
     }
 
 }
diff --git a/reference/src/test/java/org/apache/sling/cms/reference/form/impl/MockMessageBuilder.java b/reference/src/test/java/org/apache/sling/cms/reference/form/impl/MockMessageBuilder.java
new file mode 100644
index 0000000..689f2d0
--- /dev/null
+++ b/reference/src/test/java/org/apache/sling/cms/reference/form/impl/MockMessageBuilder.java
@@ -0,0 +1,165 @@
+/*
+ * 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.cms.reference.form.impl;
+
+import javax.mail.Header;
+import javax.mail.MessagingException;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.InternetHeaders;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.sling.commons.messaging.mail.MessageBuilder;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.mockito.Mockito;
+
+public class MockMessageBuilder implements MessageBuilder {
+
+    @Override
+    public @NotNull MessageBuilder to(@NotNull final String address, @NotNull final String name)
+            throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder to(@NotNull final String address) throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder to(@NotNull final InternetAddress to) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder text(@NotNull final String text) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder subject(@NotNull final String subject) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder replyTo(@NotNull final String address, final String name) throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder replyTo(@NotNull final String address) throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder replyTo(@NotNull final InternetAddress replyTo) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder inline(@NotNull final byte[] content, @NotNull final String type,
+            @NotNull final String cid, @Nullable final Header[] headers) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder inline(@NotNull final byte[] content, @NotNull final String type,
+            @NotNull final String cid) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder html(@NotNull final String html) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder headers(@NotNull final InternetHeaders headers) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder header(@NotNull final String name, @Nullable final String value) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder from(@NotNull final String address, @NotNull final String name)
+            throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder from(@NotNull final String address) throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder from(@NotNull final InternetAddress from) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder cc(@NotNull final String address, @NotNull final String name)
+            throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder cc(@NotNull final String address) throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder cc(@NotNull final InternetAddress cc) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MimeMessage build() throws MessagingException {
+        return Mockito.mock(MimeMessage.class);
+    }
+
+    @Override
+    public @NotNull MessageBuilder bcc(@NotNull final String address, final String name) throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder bcc(@NotNull final String address) throws AddressException {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder bcc(@NotNull final InternetAddress bcc) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder attachment(@NotNull final byte[] content, @NotNull final String type,
+            @NotNull final String filename, @Nullable final Header[] headers) {
+        return this;
+    }
+
+    @Override
+    public @NotNull MessageBuilder attachment(@NotNull final byte[] content, @NotNull final String type,
+            @NotNull final String filename) {
+        return this;
+    }
+
+}
\ No newline at end of file
diff --git a/reference/src/test/java/org/apache/sling/cms/reference/form/impl/actions/SendEmailActionTest.java b/reference/src/test/java/org/apache/sling/cms/reference/form/impl/actions/SendEmailActionTest.java
index 1435533..7d713fe 100644
--- a/reference/src/test/java/org/apache/sling/cms/reference/form/impl/actions/SendEmailActionTest.java
+++ b/reference/src/test/java/org/apache/sling/cms/reference/form/impl/actions/SendEmailActionTest.java
@@ -19,19 +19,15 @@ package org.apache.sling.cms.reference.form.impl.actions;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import java.lang.annotation.Annotation;
-
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.cms.reference.form.impl.MockMessageBuilder;
 import org.apache.sling.cms.reference.form.impl.SlingContextHelper;
 import org.apache.sling.cms.reference.forms.FormActionResult;
 import org.apache.sling.cms.reference.forms.FormException;
 import org.apache.sling.cms.reference.forms.FormRequest;
 import org.apache.sling.cms.reference.forms.impl.FormRequestImpl;
 import org.apache.sling.cms.reference.forms.impl.actions.SendEmailAction;
-import org.apache.sling.cms.reference.forms.impl.actions.SendEmailActonConfig;
-import org.apache.sling.event.jobs.Job;
-import org.apache.sling.event.jobs.JobManager;
-import org.apache.sling.event.jobs.consumer.JobConsumer.JobResult;
+import org.apache.sling.commons.messaging.mail.MailService;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
 import org.junit.Before;
 import org.junit.Rule;
@@ -45,6 +41,7 @@ public class SendEmailActionTest {
     public final SlingContext context = new SlingContext();
     private SendEmailAction action;
     private ResourceResolver resolver;
+    private MailService mailService;
 
     @Before
     public void init() throws NoSuchFieldException, SecurityException {
@@ -54,41 +51,10 @@ public class SendEmailActionTest {
         resolver = context.resourceResolver();
         action = new SendEmailAction();
 
-        FieldSetter.setField(action, action.getClass().getDeclaredField("jobManager"), Mockito.mock(JobManager.class));
-
-        action.activate(new SendEmailActonConfig() {
-
-            @Override
-            public String hostName() {
-                return "smtp.mailtrap.io";
-            }
-
-            @Override
-            public int smtpPort() {
-                return 587;
-            }
-
-            @Override
-            public boolean tlsEnabled() {
-                return true;
-            }
-
-            @Override
-            public String username() {
-                return "e7cfc0e9bb9b80";
-            }
-
-            @Override
-            public String password() {
-                return "b9902898ce236a";
-            }
+        mailService = Mockito.mock(MailService.class);
+        Mockito.when(mailService.getMessageBuilder()).thenReturn(new MockMessageBuilder());
 
-            @Override
-            public Class<? extends Annotation> annotationType() {
-                return null;
-            }
-
-        });
+        FieldSetter.setField(action, action.getClass().getDeclaredField("mailService"), mailService);
     }
 
     @Test
@@ -105,24 +71,12 @@ public class SendEmailActionTest {
     @Test
     public void testHandleForm() throws FormException {
 
-        FormRequest formRequest = new FormRequestImpl(context.request());
-        FormActionResult result = action
+        final FormRequest formRequest = new FormRequestImpl(context.request());
+        final FormActionResult result = action
                 .handleForm(resolver.getResource("/form/jcr:content/container/form/actions/sendemail"), formRequest);
 
         assertTrue(result.isSucceeded());
-    }
-
-    @Test
-    public void testProcess() throws FormException {
-
-        Job job = Mockito.mock(Job.class);
-        Mockito.when(job.getProperty(SendEmailAction.TO, String.class)).thenReturn("test@user.com");
-        Mockito.when(job.getProperty(SendEmailAction.FROM, String.class)).thenReturn("another@user.com");
-        Mockito.when(job.getProperty(SendEmailAction.SUBJECT, String.class)).thenReturn("SLING CMS");
-        Mockito.when(job.getProperty(SendEmailAction.MESSAGE, String.class)).thenReturn("WOW!");
-
-        JobResult result = action.process(job);
-        assertTrue(result == JobResult.OK);
+        Mockito.verify(mailService).sendMessage(Mockito.any());
     }
 
 }