com.ajah.email.data.AmazonSESTransport.java Source code

Java tutorial

Introduction

Here is the source code for com.ajah.email.data.AmazonSESTransport.java

Source

/*
 *  Copyright 2011-2014 Eric F. Savage, code@efsavage.com
 *
 *   Licensed 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 com.ajah.email.data;

import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import lombok.extern.java.Log;

import org.springframework.transaction.annotation.Transactional;

import com.ajah.email.EmailMessage;
import com.ajah.email.EmailRecipient;
import com.ajah.util.AjahUtils;
import com.ajah.util.StringUtils;
import com.ajah.util.config.Config;
import com.ajah.util.data.format.EmailAddress;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleemail.AWSJavaMailTransport;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient;
import com.amazonaws.services.simpleemail.model.ListVerifiedEmailAddressesResult;
import com.amazonaws.services.simpleemail.model.VerifyEmailAddressRequest;

/**
 * Manages the persistance and transport of email messages.
 * 
 * @author <a href="http://efsavage.com">Eric F. Savage</a>, <a
 *         href="mailto:code@efsavage.com">code@efsavage.com</a>.
 * 
 */
@Transactional(rollbackFor = Exception.class)
@Log
public class AmazonSESTransport implements EmailTransport {

    private static boolean isVerified(final EmailAddress emailAddress, final AmazonSimpleEmailService email,
            final ListVerifiedEmailAddressesResult verifiedEmails) {
        if (!verifiedEmails.getVerifiedEmailAddresses().contains(emailAddress.toString())) {
            email.verifyEmailAddress(new VerifyEmailAddressRequest().withEmailAddress(emailAddress.toString()));
            return false;
        }
        return true;
    }

    /**
     * Sends a message through Amazon's SES service.
     * 
     * @param message
     *            The message to send. Subject, from and to are required.
     * @throws AddressException
     *             If there is a problem with one of the email addresses.
     * @throws MessagingException
     *             If there is a problem with the transport of the message.
     */
    @Override
    public void send(final EmailMessage message) throws AddressException, MessagingException {
        AjahUtils.requireParam(message, "message");
        AjahUtils.requireParam(message.getSubject(), "message.subject");
        AjahUtils.requireParam(message.getFrom(), "message.from");
        AjahUtils.requireParam(message.getRecipients(), "message.recipients");

        final AWSCredentials credentials = new BasicAWSCredentials(Config.i.get("aws.accessKey", null),
                Config.i.get("aws.secretKey", null));
        if (Config.i.getBoolean("aws.ses.verify", false)) {
            // Verification is active so we'll need to check that first
            final AmazonSimpleEmailService email = new AmazonSimpleEmailServiceClient(credentials);
            final ListVerifiedEmailAddressesResult verifiedEmails = email.listVerifiedEmailAddresses();
            boolean verified = true;
            if (!isVerified(message.getFrom(), email, verifiedEmails)) {
                log.warning("Sender " + message.getFrom() + " is not verified");
                verified = false;
            }
            for (final EmailRecipient emailRecipient : message.getRecipients()) {
                if (!isVerified(emailRecipient.getAddress(), email, verifiedEmails)) {
                    log.warning("Recipient " + emailRecipient.getAddress() + " is not verified");
                    verified = false;
                }
            }
            if (!verified) {
                throw new MessagingException("Message not sent because one or more addresses need to be verified");
            }
        }
        final Properties props = new Properties();
        props.setProperty("mail.transport.protocol", "aws");
        props.setProperty("mail.aws.user", credentials.getAWSAccessKeyId());
        props.setProperty("mail.aws.password", credentials.getAWSSecretKey());

        final Session session = Session.getInstance(props);

        final MimeMessage mimeMessage = new MimeMessage(session);
        mimeMessage.setFrom(new InternetAddress(message.getFrom().toString()));
        for (final EmailRecipient emailRecipient : message.getRecipients()) {
            switch (emailRecipient.getType()) {
            case BCC:
                mimeMessage.addRecipient(Message.RecipientType.BCC, new InternetAddress(emailRecipient.toString()));
                break;
            case CC:
                mimeMessage.addRecipient(Message.RecipientType.CC, new InternetAddress(emailRecipient.toString()));
                break;
            case TO:
                mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(emailRecipient.toString()));
                break;
            default:
                mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(emailRecipient.toString()));
                break;
            }
        }
        mimeMessage.setSubject(message.getSubject());
        final String htmlContent = message.getHtml();
        if (StringUtils.isBlank(htmlContent)) {
            // No HTML so we'll just send a plaintext message.
            mimeMessage.setText(message.getText());
        } else {
            final Multipart multiPart = new MimeMultipart("alternative");

            final BodyPart text = new MimeBodyPart();
            text.setText(message.getText());
            multiPart.addBodyPart(text);

            final BodyPart html = new MimeBodyPart();
            html.setContent(message.getHtml(), "text/html");
            multiPart.addBodyPart(html);

            mimeMessage.setContent(multiPart);
        }
        mimeMessage.saveChanges();

        final Transport transport = new AWSJavaMailTransport(session, null);
        transport.connect();
        transport.sendMessage(mimeMessage, null);
        transport.close();

    }

}