Search in sources :

Example 1 with MailParsingException

use of com.google.gerrit.mail.MailParsingException in project gerrit by GerritCodeReview.

the class ImapMailReceiver method handleEmails.

/**
 * Opens a connection to the mail server, removes emails where deletion is pending, reads new
 * email and closes the connection.
 *
 * @param async determines if processing messages should happen asynchronously
 * @throws MailTransferException in case of a known transport failure
 * @throws IOException in case of a low-level transport failure
 */
@Override
public synchronized void handleEmails(boolean async) throws MailTransferException, IOException {
    IMAPClient imap;
    if (mailSettings.encryption != Encryption.NONE) {
        imap = new IMAPSClient(mailSettings.encryption.name(), true);
    } else {
        imap = new IMAPClient();
    }
    if (mailSettings.port > 0) {
        imap.setDefaultPort(mailSettings.port);
    }
    // Set a 30s timeout for each operation
    imap.setDefaultTimeout(30 * 1000);
    imap.connect(mailSettings.host);
    try {
        if (!imap.login(mailSettings.username, mailSettings.password)) {
            throw new MailTransferException("Could not login to IMAP server");
        }
        try {
            if (!imap.select(INBOX_FOLDER)) {
                throw new MailTransferException("Could not select IMAP folder " + INBOX_FOLDER);
            }
            // should fetch.
            if (!imap.fetch("1:*", "(INTERNALDATE)")) {
                // false indicates that there are no messages to fetch
                logger.atInfo().log("Fetched 0 messages via IMAP");
                return;
            }
            // Format of reply is one line per email and one line to indicate
            // that the fetch was successful.
            // Example:
            // * 1 FETCH (INTERNALDATE "Mon, 24 Oct 2016 16:53:22 +0200 (CEST)")
            // * 2 FETCH (INTERNALDATE "Mon, 24 Oct 2016 16:53:22 +0200 (CEST)")
            // AAAC OK FETCH completed.
            int numMessages = imap.getReplyStrings().length - 1;
            logger.atInfo().log("Fetched %d messages via IMAP", numMessages);
            // Fetch the full version of all emails
            List<MailMessage> mailMessages = new ArrayList<>(numMessages);
            for (int i = 1; i <= numMessages; i++) {
                if (imap.fetch(i + ":" + i, "(BODY.PEEK[])")) {
                    // Obtain full reply
                    String[] rawMessage = imap.getReplyStrings();
                    if (rawMessage.length < 2) {
                        continue;
                    }
                    // First and last line are IMAP status codes. We have already
                    // checked, that the fetch returned true (OK), so we safely ignore
                    // those two lines.
                    StringBuilder b = new StringBuilder(2 * (rawMessage.length - 2));
                    for (int j = 1; j < rawMessage.length - 1; j++) {
                        if (j > 1) {
                            b.append("\n");
                        }
                        b.append(rawMessage[j]);
                    }
                    try {
                        MailMessage mailMessage = RawMailParser.parse(b.toString());
                        if (pendingDeletion.contains(mailMessage.id())) {
                            // Mark message as deleted
                            if (imap.store(i + ":" + i, "+FLAGS", "(\\Deleted)")) {
                                pendingDeletion.remove(mailMessage.id());
                            } else {
                                logger.atSevere().log("Could not mark mail message as deleted: %s", mailMessage.id());
                            }
                        } else {
                            mailMessages.add(mailMessage);
                        }
                    } catch (MailParsingException e) {
                        logger.atSevere().withCause(e).log("Exception while parsing email after IMAP fetch");
                    }
                } else {
                    logger.atSevere().log("IMAP fetch failed. Will retry in next fetch cycle.");
                }
            }
            // Permanently delete emails marked for deletion
            if (!imap.expunge()) {
                logger.atSevere().log("Could not expunge IMAP emails");
            }
            dispatchMailProcessor(mailMessages, async);
        } finally {
            imap.logout();
        }
    } finally {
        imap.disconnect();
    }
}
Also used : MailMessage(com.google.gerrit.mail.MailMessage) IMAPSClient(org.apache.commons.net.imap.IMAPSClient) MailParsingException(com.google.gerrit.mail.MailParsingException) IMAPClient(org.apache.commons.net.imap.IMAPClient) ArrayList(java.util.ArrayList)

Example 2 with MailParsingException

use of com.google.gerrit.mail.MailParsingException in project gerrit by GerritCodeReview.

the class Pop3MailReceiver method handleEmails.

/**
 * Opens a connection to the mail server, removes emails where deletion is pending, reads new
 * email and closes the connection.
 *
 * @param async determines if processing messages should happen asynchronously
 * @throws MailTransferException in case of a known transport failure
 * @throws IOException in case of a low-level transport failure
 */
@Override
public synchronized void handleEmails(boolean async) throws MailTransferException, IOException {
    POP3Client pop3;
    if (mailSettings.encryption != Encryption.NONE) {
        pop3 = new POP3SClient(mailSettings.encryption.name(), true);
    } else {
        pop3 = new POP3Client();
    }
    if (mailSettings.port > 0) {
        pop3.setDefaultPort(mailSettings.port);
    }
    pop3.connect(mailSettings.host);
    try {
        if (!pop3.login(mailSettings.username, mailSettings.password)) {
            throw new MailTransferException("Could not login to POP3 email server. Check username and password");
        }
        try {
            POP3MessageInfo[] messages = pop3.listMessages();
            if (messages == null) {
                throw new MailTransferException("Could not retrieve message list via POP3");
            }
            logger.atInfo().log("Received %d messages via POP3", messages.length);
            // Fetch messages
            List<MailMessage> mailMessages = new ArrayList<>();
            for (POP3MessageInfo msginfo : messages) {
                if (msginfo == null) {
                    // Message was deleted
                    continue;
                }
                try (BufferedReader reader = (BufferedReader) pop3.retrieveMessage(msginfo.number)) {
                    if (reader == null) {
                        throw new MailTransferException("Could not retrieve POP3 message header for message " + msginfo.identifier);
                    }
                    int[] message = fetchMessage(reader);
                    MailMessage mailMessage = RawMailParser.parse(message);
                    // 822 and delete the message if deletion is pending.
                    if (pendingDeletion.contains(mailMessage.id())) {
                        if (pop3.deleteMessage(msginfo.number)) {
                            pendingDeletion.remove(mailMessage.id());
                        } else {
                            logger.atSevere().log("Could not delete message %d", msginfo.number);
                        }
                    } else {
                        // Process message further
                        mailMessages.add(mailMessage);
                    }
                } catch (MailParsingException e) {
                    logger.atSevere().log("Could not parse message %d", msginfo.number);
                }
            }
            dispatchMailProcessor(mailMessages, async);
        } finally {
            pop3.logout();
        }
    } finally {
        pop3.disconnect();
    }
}
Also used : POP3SClient(org.apache.commons.net.pop3.POP3SClient) POP3MessageInfo(org.apache.commons.net.pop3.POP3MessageInfo) MailMessage(com.google.gerrit.mail.MailMessage) MailParsingException(com.google.gerrit.mail.MailParsingException) POP3Client(org.apache.commons.net.pop3.POP3Client) ArrayList(java.util.ArrayList) BufferedReader(java.io.BufferedReader)

Aggregations

MailMessage (com.google.gerrit.mail.MailMessage)2 MailParsingException (com.google.gerrit.mail.MailParsingException)2 ArrayList (java.util.ArrayList)2 BufferedReader (java.io.BufferedReader)1 IMAPClient (org.apache.commons.net.imap.IMAPClient)1 IMAPSClient (org.apache.commons.net.imap.IMAPSClient)1 POP3Client (org.apache.commons.net.pop3.POP3Client)1 POP3MessageInfo (org.apache.commons.net.pop3.POP3MessageInfo)1 POP3SClient (org.apache.commons.net.pop3.POP3SClient)1