Spring integration mail poller

2019-05-12 09:35发布

问题:

I want to configure a poller for my mail adapter, to run just once or run it programmatically.

This is a standalone app (java -jar xxxx.jar), so I think maybe one option is configure the fixed-rate attribute, to an arbitrary max value and then exit the application, ie: System.exit(0).

Are there more alternatives or some kind of 'correct approach', for this case?

This is my integration-context.xml :

<int-mail:inbound-channel-adapter id="imapAdapter"
                                  store-uri="imaps://${imap.user}:${imap.password}@${imap.server.ip}:${imap.server.port}/inbox"
                                  channel="receiveChannel"
                                  auto-startup="true"
                                  should-delete-messages="false"
                                  should-mark-messages-as-read="false"                                      
                                  java-mail-properties="javaMailProperties" 
                                  mail-filter-expression="subject matches '(?i)*UNSUSCRIBE*'">
    <int:poller max-messages-per-poll="1" fixed-rate="5000"/>
</int-mail:inbound-channel-adapter>

PS: Unfortunately imap-idle-channel-adapter is not an option.

回答1:

I can suggest to you OnlyOnceTrigger:

@Bean
public Trigger onlyOnceTrigger() {
       return new Trigger() {
              private final AtomicBoolean invoked = new AtomicBoolean();
              @Override
              public Date nextExecutionTime(TriggerContext triggerContext) {
                    return this.invoked.getAndSet(true) ? null : new Date();
              }
       };
}

Which should be injected to your <int:poller> of that adapter.

However you should take care about some barrier for the entire application if you say that it is standalone one and you really shouldn't lose process before you decide to close the app.

One of those good choice is CountDownLatch with 1 count as a bean. You should wait on it from your main before System.exit(0) or just use the last one in the end of your process:

<outbound-channel-adapter expression="T(System).exit(0)"/>

However you should think more if it really is suitable for your to run the adapter only once and if that max-messages-per-poll="1" is really good option.

There may be no messages in the mail box, so onlyOnceTrigger may finish without good result for you and your app has strained into the void...