Package com.uphea.service

Source Code of com.uphea.service.EmailSender

package com.uphea.service;

import com.uphea.domain.EmailMessage;
import jodd.mail.Email;
import jodd.mail.MailException;
import jodd.mail.SendMailSession;
import jodd.mail.SmtpServer;
import jodd.petite.meta.PetiteBean;
import jodd.petite.meta.PetiteInject;
import jodd.util.ThreadUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

/**
* Email sender is a background process that sends queued emails.
*/
@PetiteBean
public class EmailSender implements Runnable {

  private static final Logger log = LoggerFactory.getLogger(EmailSender.class);

  @PetiteInject
  EmailManager emailManager;

  @PetiteInject
  EmailBuilder emailBuilder;

  public void init() {
    log.info("email sender initialized");
    smtpServer = new SmtpServer(host, port, username, password);
    start();
  }

  public void close() {
    log.info("email sender closed");
    shutdown(true);
  }

  // ---------------------------------------------------------------- connection

  protected String host;

  protected int port;

  protected String username;

  protected String password;

  protected SmtpServer smtpServer;

  public String getHost() {
    return host;
  }

  public void setHost(String host) {
    this.host = host;
  }

  public int getPort() {
    return port;
  }

  public void setPort(int port) {
    this.port = port;
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  // ---------------------------------------------------------------- thread

  protected int threadSleepTime = 60;
  protected int pauseBetweenEmails = 500;

  /**
   * Specifies thread sleep time in seconds between two mail sessions.
   */
  public void setThreadSleepTime(int threadSleepTime) {
    this.threadSleepTime = threadSleepTime;
  }

  /**
   * @see #setThreadSleepTime(int)
   */
  public int getThreadSleepTime() {
    return threadSleepTime;
  }

  /**
   * Specifies number of milliseconds between sending of two emails during the batch sending.
   * Some SMTP servers requires some pause between two sending to protected from spammers.
   * This pause applies only during batch mail sending, i.e. when email sender is in
   * SENDING state.
   */
  public void setPauseBetweenEmails(int pauseBetweenEmails) {
    this.pauseBetweenEmails = pauseBetweenEmails;
  }

  /**
   * @see #setPauseBetweenEmails(int)
   */
  public int getPauseBetweenEmails() {
    return pauseBetweenEmails;
  }

  // ---------------------------------------------------------------- thread

  public enum Status {
    IDLE,
    SENDING,
    STOPPED
  }

  protected boolean running;

  protected Status status = Status.IDLE;

  /**
   * Returns send thread status.
   */
  public Status getStatus() {
    return status;
  }

  /**
   * Returns if thread is running or is stopped (or about to be stopped).
   */
  public boolean isRunning() {
    return running;
  }

  protected Thread senderThread;

  /**
   * Starts mail sender and creates new thread if not already started.
   */
  public void start() {
    if (senderThread == null) {
      senderThread = new Thread(this);
      senderThread.setPriority(Thread.NORM_PRIORITY - 1);
      senderThread.start();
      log.info("SenderThread started.");
    } else {
      log.warn("SenderThread already started and is in '" + status.name() + "' status.");
    }
  }

  /**
   * Shutdowns mailer sender and its thread.
   * If wait is required, method will block until
   * thread really stop.
   */
  public void shutdown(boolean wait) {
    log.info("SenderThread is about to stop.");
    running = false;
    if (wait == true) {
      while (status != Status.STOPPED) {
        ThreadUtil.sleep(100);
      }
    }
    senderThread = null;
  }


  /**
   * Sender thread periodically checks for new pending messages.
   */
  @Override
  public void run() {
    running = true;
    while (running) {

      while (status == Status.IDLE) {
        log.debug("sending emails...");

        List<EmailMessage> msgs;
        msgs = emailManager.findPending();
        if (msgs.isEmpty()) {
          break;
        }

        log.info("found {} pending emails", Integer.valueOf(msgs.size()));

        // open
        SendMailSession mailSession = openMailSession();
        if (mailSession == null) {
          status = Status.IDLE;
          break;
        }

        // sending
        status = Status.SENDING;
        int sentCount = 0;
        for (EmailMessage msg: msgs) {
          if (running == false) {
            break;
          }
          if (send(mailSession, msg) == true) {
            emailManager.deleteSent(msg);
            sentCount++;
          } else {
            emailManager.updateFailed(msg);
          }
          if (running == false) {
            break;
          }
          ThreadUtil.sleep(pauseBetweenEmails);
        }

        closeMailSession(mailSession);

        status = Status.IDLE;
        if (sentCount == 0) {
          break// no message sent, means that sending channel is broken, so go to big sleep.
        }
      }

      int secondsToSleep = threadSleepTime;
      while (secondsToSleep > 0) {
        if (running == false) {
          break;
        }
        ThreadUtil.sleep(1000L);
        secondsToSleep--;
      }
    }
    status = Status.STOPPED;
  }

  protected Exception lastException;

  /**
   * Returns last occurred exception.
   */
  public Exception getLastException() {
    return lastException;
  }

  // ---------------------------------------------------------------- smtp

  /**
   * Opens email session.
   */
  protected SendMailSession openMailSession() {
    try {
      SendMailSession sendMailSession = smtpServer.createSession();
      sendMailSession.open();
      lastException = null;
      return sendMailSession;
    } catch (MailException mex) {
      lastException = mex;
      log.error("Unable to open email session", mex);
      return null;
    }
  }

  protected void closeMailSession(SendMailSession sendMailSession) {
    try {
      sendMailSession.close();
      lastException = null;
    } catch (MailException mex) {
      lastException = mex;
      log.error("Closing mail session failed", mex);
    }
  }

  /**
   * Sends single email in open email session.
   */
  protected boolean send(SendMailSession mailSession, EmailMessage msg) {
    try {
      log.debug("send email");

      Email email = new Email();
      email.from(msg.getSource()).to(msg.getDestination()).subject(msg.getSubject());

      emailBuilder.applyTemplate(email, msg);

      mailSession.sendMail(email);

      return true;
    } catch (MailException mex) {
      log.error("Sending email failed", mex);
      return false;
    }

  }

}
TOP

Related Classes of com.uphea.service.EmailSender

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.