0

This is a continuation of Java mail listener using Spring Integration : mail isn't received by multiple app instances . I'm using below ImapMailReceiver code :

@Bean
    public ImapMailReceiver receiver() {

        ImapMailReceiver receiver = new ImapMailReceiver(
                "imaps://username:pwd@mail.company.com/INBOX");
        receiver.setShouldMarkMessagesAsRead(false);
        receiver.setSimpleContent(true);
        receiver.setUserFlag("test-flag");
        //receiver.setJavaMailProperties(javaMailProperties());
        return receiver;
    } 

My application has been deployed in dev and stage servers.As per the debug logs : This email server does not support RECENT or USER flags. Hence whatever userflag i'm setting via above code isn't useful and mails will be received by only once instance of my application (either dev or stage ) and not all instances.So mails are getting dropped by one instance. How to make it work so that all of my application instances receives new emails? Should i set any javamail properties ? How to make it work

UPDATE used below custom searchTermStrategy . For every poll list of new messages + set of old messages will be received . Haven't tested on multiple application instances yet.

private class CustomSearchTermStrategy implements SearchTermStrategy {

        CustomSearchTermStrategy() {
        }

        @Override
        public SearchTerm generateSearchTerm(Flags supportedFlags, Folder folder) {
            SearchTerm searchTerm = null;
            boolean recentFlagSupported = false;
            if (supportedFlags != null) {
                recentFlagSupported = supportedFlags.contains(Flags.Flag.RECENT);
                if (recentFlagSupported) {
                    searchTerm = new FlagTerm(new Flags(Flags.Flag.RECENT), true);
                }
                if (supportedFlags.contains(Flags.Flag.ANSWERED)) {
                    NotTerm notAnswered = new NotTerm(new FlagTerm(new Flags(Flags.Flag.ANSWERED), true));
                    if (searchTerm == null) {
                        searchTerm = notAnswered;
                    } else {
                        searchTerm = new AndTerm(searchTerm, notAnswered);
                    }
                }
                if (supportedFlags.contains(Flags.Flag.DELETED)) {
                    NotTerm notDeleted = new NotTerm(new FlagTerm(new Flags(Flags.Flag.DELETED), true));
                    if (searchTerm == null) {
                        searchTerm = notDeleted;
                    } else {
                        searchTerm = new AndTerm(searchTerm, notDeleted);
                    }
                }
                if (supportedFlags.contains(Flags.Flag.SEEN)) {
                    NotTerm notSeen = new NotTerm(new FlagTerm(new Flags(Flags.Flag.SEEN), true));
                    if (searchTerm == null) {
                        searchTerm = notSeen;
                    } else {
                        searchTerm = new AndTerm(searchTerm, notSeen);
                    }
                }
            }

//          if (!recentFlagSupported) {
//              searchTerm = applyTermsWhenNoRecentFlag(folder, searchTerm);
//          }
            return searchTerm;
        }
}
VGH
  • 305
  • 6
  • 20

1 Answers1

1

The simplest solution would be to use different accounts for each environment (forward mails from one to the other so both get them).

If that's not possible, the issue is with the FLAGGED flag, which is unconditionally set and excluded in the default search term.

Unfortunately, the method that sets that flag is private so you can't change that behavior.

I think the only solution is a custom search strategy that does not include NOT (FLAGGED) and keep state locally to ignore messages that you have already read.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Sorry i didn't get you . Are you saying i can use a custom search strategy to solve this problem ? If yes can you please provide a working code for it? – VGH Jun 05 '20 at 14:05
  • Because having different accounts isn't possible. – VGH Jun 05 '20 at 14:21
  • See `ImapMailReceiver.DefaultSearchStrategy`; just make a similar implementation that omits the `NotTerm(FLAGGED)`. It should solve the immediate problem but it will mean you will get all the messages each time the app is started (unless you later delete the emails). – Gary Russell Jun 05 '20 at 14:32
  • Updated question with the CustomSearchTermStrategy . For every poll list of new messages + set of old messages will be received . What else should I modify in it? Haven't tested on multiple application instances yet. – VGH Jun 05 '20 at 18:30
  • Unfortunately, it looks like your server (Exchange) has weak IMAP support - if it doesn't support RECENT or USER, you are pretty much out of luck and you'll have to fetch the whole mailbox each time and weed out the messages you have already processed by keeping state locally. Unless you can find some custom MS flags that you can set and use in your search. Complain to your mail vendor. – Gary Russell Jun 05 '20 at 19:19
  • Oh ok. Was looking into IdleManager as well. Do you think if I use folder.addMessageCountListener with IdleManager.watch I can read mails in multiple instances of my application or there also same issue might occur? – VGH Jun 05 '20 at 19:24
  • Interesting; I am not familiar with `IdleEventManager`; given that the new messages arrive in the event, it might work; but I don't know the semantics if you have multiple watchers on the same box; hopefully they are independent. Worth a try. – Gary Russell Jun 05 '20 at 19:32
  • Sure. Thanks a lot Gary for your help and support :) – VGH Jun 05 '20 at 19:38