diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailOutboundChannelAdapterParser.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailOutboundChannelAdapterParser.java
index 0a20f3dce2..f5b41b3aaa 100644
--- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailOutboundChannelAdapterParser.java
+++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/config/MailOutboundChannelAdapterParser.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2011 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundChannelAdapterParser;
-import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
import org.springframework.integration.mail.MailSendingMessageHandler;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.util.Assert;
@@ -33,6 +32,7 @@ import org.springframework.util.StringUtils;
* Parser for the <outbound-channel-adapter/> element of the 'mail' namespace.
*
* @author Mark Fisher
+ * @author Artem Bilan
*/
public class MailOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
@@ -41,20 +41,28 @@ public class MailOutboundChannelAdapterParser extends AbstractOutboundChannelAda
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MailSendingMessageHandler.class);
String mailSenderRef = element.getAttribute("mail-sender");
String host = element.getAttribute("host");
+ boolean hasHost = StringUtils.hasText(host);
String port = element.getAttribute("port");
String username = element.getAttribute("username");
String password = element.getAttribute("password");
+ String javaMailProperties = element.getAttribute("java-mail-properties");
+ boolean hasJavaMailProperties = StringUtils.hasText(javaMailProperties);
if (StringUtils.hasText(mailSenderRef)) {
- Assert.isTrue(!StringUtils.hasText(host) && !StringUtils.hasText(username) && !StringUtils.hasText(password),
+ Assert.isTrue(!hasHost
+ && !StringUtils.hasText(username)
+ && !StringUtils.hasText(password),
"The 'host', 'username', and 'password' properties " +
- "should not be provided when using a 'mail-sender' reference.");
+ "should not be provided when using a 'mail-sender' reference.");
builder.addConstructorArgReference(mailSenderRef);
}
else {
- Assert.hasText(host, "Either a 'mail-sender' reference or 'host' property is required.");
+ Assert.isTrue(!hasHost || !hasJavaMailProperties,
+ "Either a 'mail-sender' or 'java-mail-properties' reference or 'host' property is required.");
BeanDefinitionBuilder mailSenderBuilder =
BeanDefinitionBuilder.genericBeanDefinition(JavaMailSenderImpl.class);
- mailSenderBuilder.addPropertyValue("host", host);
+ if (hasHost) {
+ mailSenderBuilder.addPropertyValue("host", host);
+ }
if (StringUtils.hasText(username)) {
mailSenderBuilder.addPropertyValue("username", username);
}
@@ -64,11 +72,13 @@ public class MailOutboundChannelAdapterParser extends AbstractOutboundChannelAda
if (StringUtils.hasText(port)) {
mailSenderBuilder.addPropertyValue("port", port);
}
- IntegrationNamespaceUtils.setReferenceIfAttributeDefined(
- mailSenderBuilder, element, "java-mail-properties", "javaMailProperties");
+ if (hasJavaMailProperties) {
+ mailSenderBuilder.addPropertyReference("javaMailProperties", javaMailProperties);
+ }
- String mailSenderBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(
- mailSenderBuilder.getBeanDefinition(), parserContext.getRegistry());
+ String mailSenderBeanName =
+ BeanDefinitionReaderUtils.registerWithGeneratedName(mailSenderBuilder.getBeanDefinition(),
+ parserContext.getRegistry());
builder.addConstructorArgReference(mailSenderBeanName);
}
return builder.getBeanDefinition();
diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/Mail.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/Mail.java
index 2a171457b2..864d6adc8b 100644
--- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/Mail.java
+++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/Mail.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 the original author or authors.
+ * Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,22 +17,53 @@
package org.springframework.integration.mail.dsl;
import org.springframework.integration.mail.ImapMailReceiver;
+import org.springframework.integration.mail.MailSendingMessageHandler;
import org.springframework.integration.mail.Pop3MailReceiver;
import org.springframework.integration.mail.transformer.MailToStringTransformer;
+import org.springframework.lang.Nullable;
+import org.springframework.mail.MailSender;
/**
* The factory for Spring Integration Mail components.
*
* @author Gary Russell
* @author Artem Bilan
+ *
* @since 5.0
*/
public final class Mail {
- public static MailSendingMessageHandlerSpec outboundAdapter(String host) {
+ /**
+ * A {@link MailSendingMessageHandlerSpec} factory.
+ * Note: the Java Mail properties must be provided with the particular host.
+ * @return the {@link MailSendingMessageHandlerSpec} instance.
+ * @since 5.1.3
+ * @see MailSendingMessageHandlerSpec#javaMailProperties
+ */
+ public static MailSendingMessageHandlerSpec outboundAdapter() {
+ return new MailSendingMessageHandlerSpec(null);
+ }
+
+ /**
+ * A {@link MailSendingMessageHandlerSpec} factory based on provide {@code host}.
+ * @param host the mail host to connect to.
+ * @return the {@link MailSendingMessageHandlerSpec} instance.
+ */
+ public static MailSendingMessageHandlerSpec outboundAdapter(@Nullable String host) {
return new MailSendingMessageHandlerSpec(host);
}
+ /**
+ * A convenient factory method to produce {@link MailSendingMessageHandler}
+ * based on provided {@link MailSender}.
+ * @param mailSender the {@link MailSender} to use mail sending operations.
+ * @return the {@link MailSendingMessageHandler} instance.
+ * @since 5.1.3
+ */
+ public static MailSendingMessageHandler outboundAdapter(MailSender mailSender) {
+ return new MailSendingMessageHandler(mailSender);
+ }
+
/**
* A {@link Pop3MailInboundChannelAdapterSpec} factory using a default
* {@link Pop3MailReceiver}.
diff --git a/spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/MailSendingMessageHandlerSpec.java b/spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/MailSendingMessageHandlerSpec.java
index 7bfc0aac15..164d116829 100644
--- a/spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/MailSendingMessageHandlerSpec.java
+++ b/spring-integration-mail/src/main/java/org/springframework/integration/mail/dsl/MailSendingMessageHandlerSpec.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 the original author or authors.
+ * Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,11 +24,13 @@ import javax.activation.FileTypeMap;
import org.springframework.integration.dsl.MessageHandlerSpec;
import org.springframework.integration.mail.MailSendingMessageHandler;
import org.springframework.integration.support.PropertiesBuilder;
+import org.springframework.lang.Nullable;
import org.springframework.mail.javamail.JavaMailSenderImpl;
/**
* @author Gary Russell
* @author Artem Bilan
+ *
* @since 5.0
*/
public class MailSendingMessageHandlerSpec
@@ -36,7 +38,7 @@ public class MailSendingMessageHandlerSpec
private final JavaMailSenderImpl sender = new JavaMailSenderImpl();
- MailSendingMessageHandlerSpec(String host) {
+ MailSendingMessageHandlerSpec(@Nullable String host) {
this.sender.setHost(host);
this.target = new MailSendingMessageHandler(this.sender);
}
@@ -70,7 +72,7 @@ public class MailSendingMessageHandlerSpec
* @return the spec.
* @see JavaMailSenderImpl#setProtocol(String)
*/
- public MailSendingMessageHandlerSpec protocol(String protocol) {
+ public MailSendingMessageHandlerSpec protocol(@Nullable String protocol) {
this.sender.setProtocol(protocol);
return this;
}
@@ -94,19 +96,33 @@ public class MailSendingMessageHandlerSpec
* @see JavaMailSenderImpl#setUsername(String)
* @see JavaMailSenderImpl#setPassword(String)
*/
- public MailSendingMessageHandlerSpec credentials(String username, String password) {
+ public MailSendingMessageHandlerSpec credentials(@Nullable String username, @Nullable String password) {
this.sender.setUsername(username);
this.sender.setPassword(password);
return this;
}
+ /**
+ * Set the mail user password.
+ * A convenient method when {@code username} is provided in the Java mail properties.
+ * @param password the password.
+ * @return the spec.
+ * @since 5.1.3
+ * @see JavaMailSenderImpl#setPassword(String)
+ * @see #javaMailProperties(Properties)
+ */
+ public MailSendingMessageHandlerSpec password(@Nullable String password) {
+ this.sender.setPassword(password);
+ return this;
+ }
+
/**
* Set the default encoding.
* @param defaultEncoding the default encoding.
* @return the spec.
* @see JavaMailSenderImpl#setDefaultEncoding(String)
*/
- public MailSendingMessageHandlerSpec defaultEncoding(String defaultEncoding) {
+ public MailSendingMessageHandlerSpec defaultEncoding(@Nullable String defaultEncoding) {
this.sender.setDefaultEncoding(defaultEncoding);
return this;
}
@@ -117,7 +133,7 @@ public class MailSendingMessageHandlerSpec
* @return the spec.
* @see JavaMailSenderImpl#setDefaultFileTypeMap(FileTypeMap)
*/
- public MailSendingMessageHandlerSpec defaultFileTypeMap(FileTypeMap defaultFileTypeMap) {
+ public MailSendingMessageHandlerSpec defaultFileTypeMap(@Nullable FileTypeMap defaultFileTypeMap) {
this.sender.setDefaultFileTypeMap(defaultFileTypeMap);
return this;
}
diff --git a/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-5.1.xsd b/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-5.1.xsd
index 219cbaca32..8f84394dc1 100644
--- a/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-5.1.xsd
+++ b/spring-integration-mail/src/main/resources/org/springframework/integration/mail/config/spring-integration-mail-5.1.xsd
@@ -29,8 +29,8 @@
-
-
+
+
diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/MailOutboundChannelAdapterParserTests.java b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/MailOutboundChannelAdapterParserTests.java
index 601ea14e1a..0939c572b2 100644
--- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/MailOutboundChannelAdapterParserTests.java
+++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/MailOutboundChannelAdapterParserTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2016 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,6 +40,7 @@ import org.springframework.messaging.support.GenericMessage;
* @author Mark Fisher
* @author Gary Russell
* @author Gunnar Hillert
+ * @author Artem Bilan
*/
public class MailOutboundChannelAdapterParserTests {
@@ -66,7 +67,7 @@ public class MailOutboundChannelAdapterParserTests {
Object adapter = context.getBean("advised.adapter");
MessageHandler handler = (MessageHandler)
new DirectFieldAccessor(adapter).getPropertyValue("handler");
- handler.handleMessage(new GenericMessage("foo"));
+ handler.handleMessage(new GenericMessage<>("foo"));
assertEquals(1, adviceCalled);
context.close();
}
@@ -105,7 +106,7 @@ public class MailOutboundChannelAdapterParserTests {
MailSender mailSender = (MailSender) fieldAccessor.getPropertyValue("mailSender");
assertNotNull(mailSender);
Properties javaMailProperties = (Properties) TestUtils.getPropertyValue(mailSender, "javaMailProperties");
- assertEquals(7, javaMailProperties.size());
+ assertEquals(9, javaMailProperties.size());
assertNotNull(javaMailProperties);
assertEquals("true", javaMailProperties.get("mail.smtps.auth"));
context.close();
@@ -114,10 +115,11 @@ public class MailOutboundChannelAdapterParserTests {
public static class FooAdvice extends AbstractRequestHandlerAdvice {
@Override
- protected Object doInvoke(ExecutionCallback callback, Object target, Message> message) throws Exception {
+ protected Object doInvoke(ExecutionCallback callback, Object target, Message> message) {
adviceCalled++;
return null;
}
}
+
}
diff --git a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/MailOutboundWithJavamailProperties-context.xml b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/MailOutboundWithJavamailProperties-context.xml
index a0634aca65..afa183d550 100644
--- a/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/MailOutboundWithJavamailProperties-context.xml
+++ b/spring-integration-mail/src/test/java/org/springframework/integration/mail/config/MailOutboundWithJavamailProperties-context.xml
@@ -1,15 +1,16 @@
+ xmlns:int-mail="http://www.springframework.org/schema/integration/mail"
+ xmlns:util="http://www.springframework.org/schema/util">
+ id="adapterWithHostProperty"
+ password="somepassword"
+ java-mail-properties="javaMailProperties"/>
javax.net.ssl.SSLSocketFactory
@@ -18,6 +19,8 @@
smtps
true
true
+ somehost
+ someuser
false
diff --git a/src/reference/asciidoc/mail.adoc b/src/reference/asciidoc/mail.adoc
index e42d14c7f8..c5138d7e9f 100644
--- a/src/reference/asciidoc/mail.adoc
+++ b/src/reference/asciidoc/mail.adoc
@@ -232,6 +232,18 @@ Alternatively, you can provide the host, username, and password, as the followin
----
====
+Starting with version 5.1.3, the `host`, `username` ane `mail-sender` can be omitted, if `java-mail-properties` is provided.
+However the `host` and `username` has to be configured with appropriate Java mail properties, e.g. for SMTP:
+
+====
+[source]
+----
+mail.user=someuser@gmail.com
+mail.smtp.host=smtp.gmail.com
+mail.smtp.port=587
+----
+====
+
NOTE: As with any outbound Channel Adapter, if the referenced channel is a `PollableChannel`, you should provide a `` element (see <>).
When you use the namespace support, you can also use a `header-enricher` message transformer.
@@ -322,8 +334,7 @@ By default, the `ImapMailReceiver` searches for messages based on the default `S
* hHave not been processed by this mail receiver (enabled by the use of the custom USER flag or simply NOT FLAGGED if not supported)
The custom user flag is `spring-integration-mail-adapter`, but you can configure it.
-Since version 2.2, the `SearchTerm` used by the `ImapMailReceiver` is fully configurable with `SearchTermStrategy`,
-which you can inject by using the `search-term-strategy` attribute.
+Since version 2.2, the `SearchTerm` used by the `ImapMailReceiver` is fully configurable with `SearchTermStrategy`, which you can inject by using the `search-term-strategy` attribute.
`SearchTermStrategy` is a strategy interface with a single method that lets you create an instance of the `SearchTerm` used by the `ImapMailReceiver`.
The following listing shows the `SearchTermStrategy` interface:
@@ -548,3 +559,53 @@ public class Mover {
====
IMPORTANT: For the message to be still available for manipulation after the transaction, _should-delete-messages_ must be set to 'false'.
+
+[[java-dsl-configuration]]
+=== Configuring channel adapters with the Java DSL
+
+To configure mail mail component in Java DSL, the framework provides a `o.s.i.mail.dsl.Mail` factory, which can be used like this:
+
+====
+[source, java]
+----
+@SpringBootApplication
+public class MailApplication {
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder(MailApplication.class)
+ .web(false)
+ .run(args);
+ }
+
+ @Bean
+ public IntegrationFlow imapMailFlow() {
+ return IntegrationFlows
+ .from(Mail.imapInboundAdapter("imap://user:pw@host:port/INBOX")
+ .searchTermStrategy(this::fromAndNotSeenTerm)
+ .userFlag("testSIUserFlag")
+ .simpleContent(true)
+ .javaMailProperties(p -> p.put("mail.debug", "false")),
+ e -> e.autoStartup(true)
+ .poller(p -> p.fixedDelay(1000)))
+ .channel(MessageChannels.queue("imapChannel"))
+ .get();
+ }
+
+ @Bean
+ public IntegrationFlow sendMailFlow() {
+ return IntegrationFlows.from("sendMailChannel")
+ .enrichHeaders(Mail.headers()
+ .subjectFunction(m -> "foo")
+ .from("foo@bar")
+ .toFunction(m -> new String[] { "bar@baz" }))
+ .handle(Mail.outboundAdapter("gmail")
+ .port(smtpServer.getPort())
+ .credentials("user", "pw")
+ .protocol("smtp")),
+ e -> e.id("sendMailEndpoint"))
+ .get();
+ }
+}
+----
+====
+