Package org.cedj.geekseek.service.smtp.test.integration

Source Code of org.cedj.geekseek.service.smtp.test.integration.SMTPMailServiceTestCase

package org.cedj.geekseek.service.smtp.test.integration;

import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.COMPOSITE;
import static org.jboss.as.controller.descriptions.ModelDescriptionConstants.STEPS;

import java.io.File;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.inject.Inject;

import org.cedj.geekseek.service.smtp.MailMessageBuilder;
import org.cedj.geekseek.service.smtp.SMTPMailService;
import org.cedj.geekseek.service.smtp.SMTPMailServiceConstants;
import org.cedj.geekseek.service.smtp.SMTPMessageConsumer;
import org.jboss.arquillian.container.test.api.Deployer;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.container.test.api.RunAsClient;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.arquillian.junit.InSequence;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.as.arquillian.container.ManagementClient;
import org.jboss.as.controller.client.ModelControllerClient;
import org.jboss.as.controller.operations.common.Util;
import org.jboss.dmr.ModelNode;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
* Ensures that our SMTP Service sends emails to an SMTP Server in both
* synchronous and asynchronous calls.
*
* @author ALR
*/
@RunWith(Arquillian.class)
public class SMTPMailServiceTestCase {

    /**
     * Name of the deployment for manual operations
     */
    private static final String DEPLOYMENT_NAME = "mailService";

    /**
     * Deployment to be tested; will be manually deployed/undeployed
     * such that we can configure the server first
     *
     * @return
     */
    @Deployment(managed = false, name = DEPLOYMENT_NAME)
    public static WebArchive getApplicationDeployment() {
        final File[] subethamailandDeps = Maven.resolver().loadPomFromFile("pom.xml").resolve("org.subethamail:subethasmtp").withoutTransitivity().asFile();
        final WebArchive war = ShrinkWrap.create(WebArchive.class).addAsLibraries(subethamailandDeps).
                addClasses(SMTPMailService.class, MailMessageBuilder.class,
                        SMTPMailServiceConstants.class, SMTPMessageConsumer.class, SMTPServerService.class)
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml")
                .addAsWebInfResource("META-INF/geekseek-smtp-queue-jms.xml")
                .addClass(ManagementClient.class);
        System.out.println(war.toString(true));
        return war;
    }

    /**
     * Service which sends email to a backing SMTP Server
     */
    @Inject
    private SMTPMailService mailService;

    /**
     * Hook into the embeddable SMTP server so we can customize its handling from the tests
     */
    @Inject
    private SMTPServerService smtpServerService;

    /**
     * Hook to Arquillian deployer so we can have fine-grained access as to when
     * our deployment is deployed/undeployed, in coordination with server config tasks
     */
    @ArquillianResource
    private Deployer deployer;

    /*
     * Lifecycle events; implemented as tests, though in truth they perform no assertions.  Used to configure
     * the server and deploy/undeploy the @Deployment archive at the appropriate times
     */

    @RunAsClient
    @InSequence(value = 1)
    @Test
    public void configureAppServer(@ArquillianResource ManagementClient managementClient) throws Exception {

        /*
         * First configure a JavaMail Session for the Server to bind into JNDI; this
         * will be used by our MailService EJB.  In a production environment, we'll likely have configured
         * the server before it was started to point to a real SMTP server
         */

        final ModelControllerClient client = managementClient.getControllerClient();

        final ModelNode composite = Util.getEmptyOperation(COMPOSITE, new ModelNode());
        final ModelNode steps = composite.get(STEPS);

        final ModelNode createSocketBindingOperation = new ModelNode();
        createSocketBindingOperation.get("operation").set("add");
        createSocketBindingOperation.get("host").set("localhost");
        createSocketBindingOperation.get("port").set(25000);
        final ModelNode socketBindingAddress = createSocketBindingOperation.get("address");
        socketBindingAddress.add("socket-binding-group", "standard-sockets");
        socketBindingAddress.add("remote-destination-outbound-socket-binding", "mail-smtp-25000");
        steps.add(createSocketBindingOperation);

        final ModelNode createMailServiceOperation = new ModelNode();
        createMailServiceOperation.get("operation").set("add");
        createMailServiceOperation.get("jndi-name").set(SMTPMailServiceConstants.JNDI_BIND_NAME_MAIL_SESSION);
        createMailServiceOperation.get("debug").set("false");
        final ModelNode smtpAddress = createMailServiceOperation.get("address");
        smtpAddress.add("subsystem", "mail");
        smtpAddress.add("mail-session", SMTPMailServiceConstants.JNDI_BIND_NAME_MAIL_SESSION);
        steps.add(createMailServiceOperation);

        final ModelNode createSMTPServer = new ModelNode();
        createSMTPServer.get("operation").set("add");
        createSMTPServer.get("outbound-socket-binding-ref").set("mail-smtp-25000");
        final ModelNode smtpServerAddress = createSMTPServer.get("address");
        smtpServerAddress.add("subsystem", "mail");
        smtpServerAddress.add("mail-session", SMTPMailServiceConstants.JNDI_BIND_NAME_MAIL_SESSION);
        smtpServerAddress.add("server", "smtp");
        steps.add(createSMTPServer);

        System.out.println("Configure mail service :" + client.execute(composite));

        /*
         * With the config all set and dependencies in place, now we can deploy
         */

        deployer.deploy(DEPLOYMENT_NAME);

    }

    @RunAsClient
    @InSequence(value = 3)
    @Test
    public void resetAppServerConfig(@ArquillianResource ManagementClient managementClient)
            throws Exception {
        final ModelControllerClient client = managementClient.getControllerClient();

        deployer.undeploy(DEPLOYMENT_NAME);

        final ModelNode removeSocketBindingOperation = new ModelNode();
        removeSocketBindingOperation.get("operation").set("remove");
        final ModelNode socketBindingAddress = removeSocketBindingOperation.get("address");
        socketBindingAddress.add("socket-binding-group", "standard-sockets");
        socketBindingAddress.add("remote-destination-outbound-socket-binding", "mail-smtp-25000");
        System.out.println("REMOVE SOCKETS" + client.execute(removeSocketBindingOperation));

        final ModelNode removeMailServiceOperation = new ModelNode();
        removeMailServiceOperation.get("operation").set("remove");
        final ModelNode smtpAddress = removeMailServiceOperation.get("address");
        smtpAddress.add("subsystem", "mail");
        smtpAddress.add("mail-session", SMTPMailServiceConstants.JNDI_BIND_NAME_MAIL_SESSION);
        System.out.println("REMOVE MAIL" + client.execute(removeMailServiceOperation));

        final ModelNode reloadOperation = new ModelNode();
        reloadOperation.get("operation").set("reload");
        System.out.println("Reload config:" + client.execute(reloadOperation));
        Thread.sleep(3000); // Because the operation returns but then server reload continues in the BG
                    // Find from the WildFly team a better notification mechanism upon which to wait
                    // https://github.com/arquillian/continuous-enterprise-development/issues/66
        //no longer needed since WildFly 8 CR1
    }

    /*
     * TESTS
     */

    /**
     * Tests that mail can be sent asynchronously via a JMS Queue
     */
    @InSequence(value = 2)
    @Test
    public void testSmtpAsync() {

        // Set the body of the email to be sent
        final String body = "This is a test of the async SMTP Service";

        // Define a barrier for us to wait upon while email is sent through the JMS Queue
        final CyclicBarrier barrier = new CyclicBarrier(2);

        // Set a handler which will ensure the body was received properly
        smtpServerService.setHandler(new SMTPServerService.TestReceiveHandler() {
            @Override
            public void handle(final String contents) throws AssertionError {
                try {

                    // Perform assertion
                    Assert.assertTrue("message received does not contain body sent in email", contents.contains(body));

                    // Should probably be the second and last to arrive, but this
                    // Thread can block indefinitely w/ no timeout needed.  If
                    // the test waiting on the barrier times out, it'll trigger a test
                    // failure and undeployment of the SMTP Service
                    barrier.await();
                } catch (final InterruptedException e) {
                    // Swallow, this would occur if undeployment were triggered
                    // because the test failed (and we'd get a proper
                    // AssertionFailureError on the client side)
                } catch (final BrokenBarrierException e) {
                    throw new RuntimeException("Broken test setup", e);
                }
            }
        });

        // Construct and send the message async
        final MailMessageBuilder.MailMessage message =
                new MailMessageBuilder().from("alr@continuousdev.org").addTo("alr@continuousdev.org")
                        .subject("Test").body(body).contentType("text/plain").build();
        mailService.queueMailForDelivery(message);

        // Wait on the barrier until the message is received by the SMTP
        // server (pass) or the test times out (failure)
        try {
            barrier.await(5, TimeUnit.SECONDS);
        } catch (final InterruptedException e) {
            throw new RuntimeException("Broken test setup", e);
        } catch (final BrokenBarrierException e) {
            throw new RuntimeException("Broken test setup", e);
        } catch (final TimeoutException e) {
            // If the SMTP server hasn't processed the message in the allotted time
            Assert.fail("Test did not receive confirmation message in the allotted time");
        }
    }

}
TOP

Related Classes of org.cedj.geekseek.service.smtp.test.integration.SMTPMailServiceTestCase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.