org.apache.james.transport.mailets.AmqpForwardAttachmentTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.james.transport.mailets.AmqpForwardAttachmentTest.java

Source

/****************************************************************
 * 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.james.transport.mailets;

import static org.assertj.core.api.Assertions.assertThat;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.apache.james.mailbox.model.MailboxConstants;
import org.apache.james.mailets.TemporaryJamesServer;
import org.apache.james.mailets.configuration.CommonProcessors;
import org.apache.james.mailets.configuration.MailetConfiguration;
import org.apache.james.mailets.configuration.MailetContainer;
import org.apache.james.mailets.configuration.ProcessorConfiguration;
import org.apache.james.mailets.utils.IMAPMessageReader;
import org.apache.james.mailets.utils.SMTPMessageSender;
import org.apache.james.util.streams.SwarmGenericContainer;
import org.apache.mailet.Mail;
import org.apache.mailet.MailAddress;
import org.apache.mailet.base.test.FakeMail;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TemporaryFolder;

import com.google.common.base.Charsets;
import com.google.common.net.InetAddresses;
import com.google.common.primitives.Bytes;
import com.jayway.awaitility.Awaitility;
import com.jayway.awaitility.Duration;
import com.jayway.awaitility.core.ConditionFactory;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.GetResponse;

public class AmqpForwardAttachmentTest {

    private static final String LOCALHOST_IP = "127.0.0.1";
    private static final int IMAP_PORT = 1143;
    private static final int SMTP_PORT = 1025;
    private static final String PASSWORD = "secret";

    private static final String JAMES_APACHE_ORG = "james.org";

    private static final String FROM = "fromUser@" + JAMES_APACHE_ORG;
    private static final String RECIPIENT = "touser@" + JAMES_APACHE_ORG;

    private static final String MAIL_ATTRIBUTE = "my.attribute";
    private static final String EXCHANGE_NAME = "myExchange";
    private static final String ROUTING_KEY = "myRoutingKey";

    private static final byte[] TEST_ATTACHMENT_CONTENT = "Test attachment content".getBytes(Charsets.UTF_8);

    public SwarmGenericContainer rabbitMqContainer = new SwarmGenericContainer("rabbitmq:3")
            .withAffinityToContainer();

    public TemporaryFolder temporaryFolder = new TemporaryFolder();

    @Rule
    public final RuleChain chain = RuleChain.outerRule(temporaryFolder).around(rabbitMqContainer);

    private TemporaryJamesServer jamesServer;
    private ConditionFactory calmlyAwait;
    private Channel channel;
    private String queueName;
    private Connection connection;

    @Before
    public void setup() throws Exception {
        @SuppressWarnings("deprecation")
        InetAddress containerIp = InetAddresses
                .forString(rabbitMqContainer.getContainerInfo().getNetworkSettings().getIpAddress());
        String amqpUri = "amqp://" + containerIp.getHostAddress();

        MailetContainer mailetContainer = MailetContainer.builder().postmaster("postmaster@" + JAMES_APACHE_ORG)
                .threads(5).addProcessor(CommonProcessors.root()).addProcessor(CommonProcessors.error())
                .addProcessor(ProcessorConfiguration.builder().state("transport").enableJmx(true)
                        .addMailet(MailetConfiguration.builder().match("All").clazz("RemoveMimeHeader")
                                .addProperty("name", "bcc").build())
                        .addMailet(MailetConfiguration.builder().match("All").clazz("StripAttachment")
                                .addProperty("attribute", MAIL_ATTRIBUTE).addProperty("pattern", ".*").build())
                        .addMailet(MailetConfiguration.builder().match("All").clazz("AmqpForwardAttribute")
                                .addProperty("uri", amqpUri).addProperty("exchange", EXCHANGE_NAME)
                                .addProperty("attribute", MAIL_ATTRIBUTE).addProperty("routing_key", ROUTING_KEY)
                                .build())
                        .addMailet(MailetConfiguration.builder().match("RecipientIsLocal")
                                .clazz("org.apache.james.jmap.mailet.VacationMailet").build())
                        .addMailet(MailetConfiguration.builder().match("RecipientIsLocal").clazz("LocalDelivery")
                                .build())
                        .build())
                .build();

        jamesServer = new TemporaryJamesServer(temporaryFolder, mailetContainer);
        Duration slowPacedPollInterval = Duration.FIVE_HUNDRED_MILLISECONDS;
        calmlyAwait = Awaitility.with().pollInterval(slowPacedPollInterval).and().with()
                .pollDelay(slowPacedPollInterval).await();

        jamesServer.getServerProbe().addDomain(JAMES_APACHE_ORG);
        jamesServer.getServerProbe().addUser(FROM, PASSWORD);
        jamesServer.getServerProbe().addUser(RECIPIENT, PASSWORD);
        jamesServer.getServerProbe().createMailbox(MailboxConstants.USER_NAMESPACE, RECIPIENT, "INBOX");

        ConnectionFactory factory = new ConnectionFactory();
        factory.setUri(amqpUri);
        waitingForRabbitToBeReady(factory);
        connection = factory.newConnection();
        channel = connection.createChannel();
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, EXCHANGE_NAME, ROUTING_KEY);
    }

    @After
    public void tearDown() throws Exception {
        channel.close();
        connection.close();
        jamesServer.shutdown();
    }

    @Test
    public void stripAttachmentShouldPutAttachmentsInMailAttributeWhenConfiguredForIt() throws Exception {
        MimeMessage message = new MimeMessage(Session.getDefaultInstance(new Properties()));

        MimeMultipart multiPart = new MimeMultipart();
        MimeBodyPart part = new MimeBodyPart();
        part.setText("simple text");
        multiPart.addBodyPart(part);
        multiPart.addBodyPart(createAttachmentBodyPart(TEST_ATTACHMENT_CONTENT, "test.txt"));

        message.setSubject("test");
        message.setContent(multiPart);
        message.saveChanges();

        Mail mail = FakeMail.builder().mimeMessage(message).sender(new MailAddress(FROM))
                .recipient(new MailAddress(RECIPIENT)).build();

        try (SMTPMessageSender messageSender = SMTPMessageSender.noAuthentication(LOCALHOST_IP, SMTP_PORT,
                JAMES_APACHE_ORG);
                IMAPMessageReader imapMessageReader = new IMAPMessageReader(LOCALHOST_IP, IMAP_PORT)) {
            messageSender.sendMessage(mail);
            calmlyAwait.atMost(Duration.ONE_MINUTE).until(messageSender::messageHasBeenSent);
            calmlyAwait.atMost(Duration.ONE_MINUTE)
                    .until(() -> imapMessageReader.userReceivedMessage(RECIPIENT, PASSWORD));
        }

        boolean autoAck = true;
        GetResponse basicGet = channel.basicGet(queueName, autoAck);
        assertThat(basicGet.getBody()).isEqualTo(TEST_ATTACHMENT_CONTENT);
    }

    private MimeBodyPart createAttachmentBodyPart(byte[] body, String fileName)
            throws MessagingException, UnsupportedEncodingException {
        MimeBodyPart part = createBodyPart(body);
        part.setDisposition("attachment");
        part.setFileName(fileName);
        return part;
    }

    private MimeBodyPart createBodyPart(byte[] body) throws MessagingException, UnsupportedEncodingException {
        return new MimeBodyPart(new ByteArrayInputStream(Bytes.concat(
                "Content-Transfer-Encoding: 8bit\r\nContent-Type: application/octet-stream; charset=utf-8\r\n\r\n"
                        .getBytes(Charsets.UTF_8),
                body)));
    }

    private void waitingForRabbitToBeReady(ConnectionFactory factory) {
        Awaitility.await().atMost(30, TimeUnit.SECONDS).with().pollInterval(10, TimeUnit.MILLISECONDS)
                .until(() -> isReady(factory));
    }

    private boolean isReady(ConnectionFactory factory) {
        try (Connection connection = factory.newConnection()) {
            return true;
        } catch (IOException e) {
            return false;
        } catch (TimeoutException e) {
            return false;
        }
    }

}