From bc9c189ef4f040a7f0b3c45c8c58b106d105eab1 Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Sat, 8 Jan 2011 12:07:19 -0500 Subject: [PATCH] INT-1701 added reconnect logic to ImapIdleChannelAdapter --- .../mail/AbstractMailReceiver.java | 4 +++ .../mail/ImapIdleChannelAdapter.java | 28 +++++++++++++++++-- .../integration/mail/ImapMailReceiver.java | 20 +++++++++++++ .../src/test/java/log4j.properties | 4 +-- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java index 463af76210..5eabda38d2 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/AbstractMailReceiver.java @@ -303,4 +303,8 @@ public abstract class AbstractMailReceiver extends IntegrationObjectSupport impl this.folderOpenMode = Folder.READ_WRITE; } } + + Store getStore(){ + return this.store; + } } diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapIdleChannelAdapter.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapIdleChannelAdapter.java index cd96b01dd7..2bb0eca263 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapIdleChannelAdapter.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapIdleChannelAdapter.java @@ -16,11 +16,15 @@ package org.springframework.integration.mail; +import java.net.UnknownHostException; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; import javax.mail.FolderClosedException; import javax.mail.Message; import javax.mail.MessagingException; +import javax.mail.StoreClosedException; import javax.mail.internet.MimeMessage; import org.springframework.core.task.SimpleAsyncTaskExecutor; @@ -47,6 +51,10 @@ public class ImapIdleChannelAdapter extends MessageProducerSupport { private volatile Executor taskExecutor; private final ImapMailReceiver mailReceiver; + + private volatile boolean reconnecting; + + private volatile int reconnectDelay = 10; // seconds public ImapIdleChannelAdapter(ImapMailReceiver mailReceiver) { @@ -117,6 +125,7 @@ public class ImapIdleChannelAdapter extends MessageProducerSupport { logger.debug("waiting for mail"); } mailReceiver.waitForNewMessages(); + reconnecting = false; Message[] mailMessages = mailReceiver.receive(); if (logger.isDebugEnabled()) { logger.debug("received " + mailMessages.length + " mail messages"); @@ -127,8 +136,13 @@ public class ImapIdleChannelAdapter extends MessageProducerSupport { } } catch (MessagingException e) { - if (e instanceof FolderClosedException && shouldReconnectAutomatically) { - continue; + if (shouldReconnectAutomatically){ + if (e instanceof FolderClosedException || + e instanceof StoreClosedException || + (e.getNextException() instanceof UnknownHostException && reconnecting)){ + waitToReconnect(); + continue; + } } handleMailMessagingException(e); return; @@ -144,4 +158,14 @@ public class ImapIdleChannelAdapter extends MessageProducerSupport { return "mail:imap-idle-channel-adapter"; } + private void waitToReconnect() { + CountDownLatch latch = new CountDownLatch(1); + try { + logger.warn("Waiting " + reconnectDelay + " seconds before attemptong to reconnect to host"); + latch.await(5, TimeUnit.SECONDS); + reconnecting = true; + logger.warn("Will attempt to reconnect to host now"); + } catch (Exception ignore) { + } + } } diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java index f365956259..8122216efd 100755 --- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java +++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/ImapMailReceiver.java @@ -21,6 +21,7 @@ import javax.mail.Flags.Flag; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; +import javax.mail.Store; import javax.mail.event.MessageCountAdapter; import javax.mail.event.MessageCountEvent; import javax.mail.event.MessageCountListener; @@ -29,6 +30,7 @@ import javax.mail.search.FlagTerm; import javax.mail.search.NotTerm; import javax.mail.search.SearchTerm; +import org.springframework.scheduling.TaskScheduler; import org.springframework.util.Assert; import com.sun.mail.imap.IMAPFolder; @@ -48,6 +50,8 @@ import com.sun.mail.imap.IMAPFolder; public class ImapMailReceiver extends AbstractMailReceiver { private volatile boolean shouldMarkMessagesAsRead = true;; private final MessageCountListener messageCountListener = new SimpleMessageCountListener(); + + private volatile long connectionPingInterval = 10000; public ImapMailReceiver() { @@ -179,6 +183,22 @@ public class ImapMailReceiver extends AbstractMailReceiver { if (this.shouldMarkMessagesAsRead){ this.folderOpenMode = Folder.READ_WRITE; } + this.initialized = true; + TaskScheduler scheduler = this.getTaskScheduler(); + if (scheduler != null){ + scheduler.scheduleAtFixedRate(new Runnable() { + public void run() { + try { + Store store = getStore(); + if (initialized && store != null){ + store.isConnected(); + } + } + catch (Throwable ignore) { + } + } + }, connectionPingInterval); + } } /** * diff --git a/spring-integration-mail/src/test/java/log4j.properties b/spring-integration-mail/src/test/java/log4j.properties index cf091a2e8e..e1274e6bd6 100644 --- a/spring-integration-mail/src/test/java/log4j.properties +++ b/spring-integration-mail/src/test/java/log4j.properties @@ -1,8 +1,8 @@ -log4j.rootCategory=DEBUG, stdout +log4j.rootCategory=WARN, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%c{1}: %m%n log4j.category.org.springframework.integration=WARN -log4j.category.org.springframework.integration.file=WARN +log4j.category.org.springframework.integration.mail=WARN