Spring Integration 5.x here. I am trying to write an IntegrationFlow
that:
Message<?>
body (as a byte[]
or similar) and I need to send the message off to a bean handler called documentRegistrar
. My best attempt thus far is this:@Configuration
public class GmailIntegrationConfiguration {
private String emailHost;
private String emailUsername;
private String emailPassword;
private DocumentRegistrar documentRegistrar;
@Autowired
public GmailIntegrationConfiguration(
@Value("${email.host}") String emailHost,
@Value("${email.username}") String emailUsername,
@Value("${email.password}") String emailPassword,
DocumentRegistrar documentRegistrar) {
this.emailHost = emailHost;
this.emailUsername = emailUsername;
this.emailPassword = emailPassword;
this.awsAccessKey = awsAccessKey;
}
@Bean
public IntegrationFlow gmailIntegrationFlow() {
return IntegrationFlows.from(emailAdapterSpec ->
Mail.imapInboundAdapter("imap://imapuser:pw@localhost:993/INBOX")
.javaMailProperties(p -> p.put("mail.imap.ssl.enable", "true"))
.autoCloseFolder(false))
.channel(MessageChannels.queue())
.handle(documentRegistrar)
.get();
}
}
The code for Mail.imapInboundAdapter
and createImapAdapterSpec
is just what I was able to Frankenstein together using the Spring Integration docs and a few Google searches, but they are both fraught with compiler errors.
Can anyone help nudge me over the finish line with a concrete working example here? Specifically the Mail.imapInboundAdapter
does not have port
, user
password
, etc. builder methods on it, so how would I configure all of those? And the file attachements filter is definitely wrong as Spring does not appear to have a MimeBodyPart
type defined (at all). Thanks in advance for any and all help!
Not sure what drove you to that configuration style, since it is clear from the Mail.imapInboundAdapter()
API that there is no those props.
There is only this:
public static ImapMailInboundChannelAdapterSpec imapInboundAdapter(String url) {
So, you need to build an URL from those your parts.
Something in style with this sample:
Mail.imapInboundAdapter("imap://imapuser:pw@localhost:993/INBOX")
And yes, folder need to be present as a part of the IMAP URL.
See .autoCloseFolder(false)
option and its Javadocs for mutlipart mail to be parsed downstream:
/**
* Configure a {@code boolean} flag to close the folder automatically after a fetch (default) or
* populate an additional {@link IntegrationMessageHeaderAccessor#CLOSEABLE_RESOURCE} message header instead.
* It is the downstream flow's responsibility to obtain this header and call its {@code close()} whenever
* it is necessary.
* <p> Keeping the folder open is useful in cases where communication with the server is needed
* when parsing multipart content of the email with attachments.
* <p> The {@link #setSimpleContent(boolean)} and {@link #setHeaderMapper(HeaderMapper)} options are not
* affected by this flag.
* @param autoCloseFolder {@code false} do not close the folder automatically after a fetch.
* @since 5.2
*/
public void setAutoCloseFolder(boolean autoCloseFolder) {
If you don't provide a HeaderMapper
, then with .autoCloseFolder(false)
, the whole MimeMessage
is provided in the payload. The channel adapter does not determine if there are some attachments in the mail message or not. More over it seems Gmail always produce mutilpart message even if there is just one simple part in the body.
You probably need to push the parsing and filtering logic down to your documentRegistrar
and don't forget to close the folder from time to time: https://docs.spring.io/spring-integration/docs/current/reference/html/mail.html#mail-inbound