INT-2543: Relax mail host when mail-props present
JIRA: https://jira.spring.io/browse/INT-2543 We may have a mail server host configured in the properties and the target session will resolve it properly from provided `javaMailProperties`. The same applies for `username` * Do not require `host` and `username`, when `javaMailProperties` is provided * Add additional factory methods into the `Mail` factory for Java DSL * Add Java DSL sample into the `mail.adoc`
This commit is contained in:
committed by
Gary Russell
parent
0ac766040f
commit
a5e437f94a
@@ -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();
|
||||
|
||||
@@ -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}.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:choice minOccurs="0" maxOccurs="2">
|
||||
<xsd:element ref="integration:poller" minOccurs="0" maxOccurs="1"/>
|
||||
<xsd:element name="request-handler-advice-chain" type="integration:handlerAdviceChainType" minOccurs="0" maxOccurs="1" />
|
||||
<xsd:element ref="integration:poller" minOccurs="0"/>
|
||||
<xsd:element name="request-handler-advice-chain" type="integration:handlerAdviceChainType" minOccurs="0"/>
|
||||
</xsd:choice>
|
||||
<xsd:attributeGroup ref="integration:channelAdapterAttributes"/>
|
||||
<xsd:attribute name="mail-sender" type="xsd:string">
|
||||
|
||||
@@ -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<String>("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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration/mail http://www.springframework.org/schema/integration/mail/spring-integration-mail.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
|
||||
xmlns:int-mail="http://www.springframework.org/schema/integration/mail"
|
||||
xmlns:util="http://www.springframework.org/schema/util">
|
||||
xmlns:int-mail="http://www.springframework.org/schema/integration/mail"
|
||||
xmlns:util="http://www.springframework.org/schema/util">
|
||||
|
||||
<int-mail:outbound-channel-adapter
|
||||
id="adapterWithHostProperty" host="somehost" username="someuser"
|
||||
password="somepassword" java-mail-properties="javaMailProperties"/>
|
||||
id="adapterWithHostProperty"
|
||||
password="somepassword"
|
||||
java-mail-properties="javaMailProperties"/>
|
||||
|
||||
<util:properties id="javaMailProperties">
|
||||
<prop key="mail.imap.socketFactory.class">javax.net.ssl.SSLSocketFactory</prop>
|
||||
@@ -18,6 +19,8 @@
|
||||
<prop key="mail.transport.protocol">smtps</prop>
|
||||
<prop key="mail.smtps.auth">true</prop>
|
||||
<prop key="mail.smtp.starttls.enable">true</prop>
|
||||
<prop key="mail.smtp.host">somehost</prop>
|
||||
<prop key="mail.smtp.user">someuser</prop>
|
||||
<prop key="mail.debug">false</prop>
|
||||
</util:properties>
|
||||
</beans>
|
||||
|
||||
@@ -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 `<poller>` element (see <<endpoint-namespace>>).
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
|
||||
Reference in New Issue
Block a user