DSL: Add enrichHeaders(Map) EIP-method
* Introduce `MapBuilder` and its custom inheritor - `MailHeadersBuilder` * Add `HeaderEnricherSpec.headers(MapBuilder)` and `.headers(Map)` * Change `MailTests` to use new `Mail.headers()` and new `IntegrationFlowDefinition.enrichHeaders(MapBuilder)` * Change `mailapi` dependency to the IO's `javax.mail` Polishing - Add headerExpressions() More Polishing - Add Configurer Polishing - PR Comments - Move MapBuilderConfigurer to superclass. - Move PropertiesBuilderConfigurer into PropertiesBuilder.
This commit is contained in:
committed by
Gary Russell
parent
238c1f06b9
commit
4b5bbb6412
@@ -18,11 +18,16 @@ package org.springframework.integration.dsl;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.dsl.core.IntegrationComponentSpec;
|
||||
import org.springframework.integration.dsl.support.BeanNameMessageProcessor;
|
||||
import org.springframework.integration.dsl.support.MapBuilder;
|
||||
import org.springframework.integration.dsl.support.MapBuilder.MapBuilderConfigurer;
|
||||
import org.springframework.integration.dsl.support.StringStringMapBuilder;
|
||||
import org.springframework.integration.handler.ExpressionEvaluatingMessageProcessor;
|
||||
import org.springframework.integration.handler.MessageProcessor;
|
||||
import org.springframework.integration.transformer.HeaderEnricher;
|
||||
@@ -34,6 +39,7 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
*/
|
||||
public class HeaderEnricherSpec extends IntegrationComponentSpec<HeaderEnricherSpec, HeaderEnricher> {
|
||||
|
||||
@@ -70,6 +76,43 @@ public class HeaderEnricherSpec extends IntegrationComponentSpec<HeaderEnricherS
|
||||
return this.messageProcessor(new BeanNameMessageProcessor<Object>(beanName, methodName));
|
||||
}
|
||||
|
||||
public HeaderEnricherSpec headers(MapBuilder<?, String, Object> headers) {
|
||||
return headers(headers.get());
|
||||
}
|
||||
|
||||
public HeaderEnricherSpec headers(Map<String, Object> headers) {
|
||||
Assert.notNull(headers);
|
||||
for (Entry<String, Object> entry : headers.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Expression) {
|
||||
header(name, new ExpressionEvaluatingHeaderValueMessageProcessor<Object>((Expression) value, null));
|
||||
}
|
||||
else {
|
||||
header(name, value);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public HeaderEnricherSpec headerExpressions(MapBuilder<?, String, String> headers) {
|
||||
return headerExpressions(headers.get());
|
||||
}
|
||||
|
||||
public HeaderEnricherSpec headerExpressions(MapBuilderConfigurer<StringStringMapBuilder, String, String> configurer) {
|
||||
StringStringMapBuilder builder = new StringStringMapBuilder();
|
||||
configurer.configure(builder);
|
||||
return headerExpressions(builder.get());
|
||||
}
|
||||
|
||||
public HeaderEnricherSpec headerExpressions(Map<String, String> headers) {
|
||||
Assert.notNull(headers);
|
||||
for (Entry<String, String> entry : headers.entrySet()) {
|
||||
header(entry.getKey(), new ExpressionEvaluatingHeaderValueMessageProcessor<Object>(entry.getValue(), null));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public <V> HeaderEnricherSpec header(String name, V value) {
|
||||
return this.header(name, value, null);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.integration.dsl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
@@ -40,6 +41,7 @@ import org.springframework.integration.dsl.support.FixedSubscriberChannelPrototy
|
||||
import org.springframework.integration.dsl.support.GenericHandler;
|
||||
import org.springframework.integration.dsl.support.GenericRouter;
|
||||
import org.springframework.integration.dsl.support.GenericSplitter;
|
||||
import org.springframework.integration.dsl.support.MapBuilder;
|
||||
import org.springframework.integration.dsl.support.MessageChannelReference;
|
||||
import org.springframework.integration.expression.ControlBusMethodFilter;
|
||||
import org.springframework.integration.filter.ExpressionEvaluatingSelector;
|
||||
@@ -76,6 +78,7 @@ import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
*/
|
||||
public abstract class IntegrationFlowDefinition<B extends IntegrationFlowDefinition<B>> {
|
||||
|
||||
@@ -286,6 +289,37 @@ public abstract class IntegrationFlowDefinition<B extends IntegrationFlowDefinit
|
||||
return this.handle(enricherSpec.get(), endpointConfigurer);
|
||||
}
|
||||
|
||||
public B enrichHeaders(MapBuilder<?, String, Object> headers) {
|
||||
return enrichHeaders(headers, null);
|
||||
}
|
||||
|
||||
public B enrichHeaders(MapBuilder<?, String, Object> headers,
|
||||
EndpointConfigurer<GenericEndpointSpec<MessageTransformingHandler>> endpointConfigurer) {
|
||||
return enrichHeaders(headers.get(), endpointConfigurer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept a {@link Map} of values to be used for the
|
||||
* {@link org.springframework.messaging.Message} header enrichment.
|
||||
* {@code values} can apply an {@link org.springframework.expression.Expression}
|
||||
* to be evaluated against a request {@link org.springframework.messaging.Message}.
|
||||
* @param headers the Map of headers to enrich.
|
||||
* @return this.
|
||||
*/
|
||||
public B enrichHeaders(Map<String, Object> headers) {
|
||||
return enrichHeaders(headers, null);
|
||||
}
|
||||
|
||||
public B enrichHeaders(final Map<String, Object> headers,
|
||||
EndpointConfigurer<GenericEndpointSpec<MessageTransformingHandler>> endpointConfigurer) {
|
||||
return enrichHeaders(new ComponentConfigurer<HeaderEnricherSpec>() {
|
||||
@Override
|
||||
public void configure(HeaderEnricherSpec spec) {
|
||||
spec.headers(headers);
|
||||
}
|
||||
}, endpointConfigurer);
|
||||
}
|
||||
|
||||
public B enrichHeaders(ComponentConfigurer<HeaderEnricherSpec> headerEnricherConfigurer) {
|
||||
return this.enrichHeaders(headerEnricherConfigurer, null);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.aopalliance.aop.Advice;
|
||||
import org.springframework.integration.dsl.core.ComponentsRegistration;
|
||||
import org.springframework.integration.dsl.core.MessageProducerSpec;
|
||||
import org.springframework.integration.dsl.support.PropertiesBuilder;
|
||||
import org.springframework.integration.dsl.support.PropertiesConfigurer;
|
||||
import org.springframework.integration.dsl.support.PropertiesBuilder.PropertiesConfigurer;
|
||||
import org.springframework.integration.mail.ImapIdleChannelAdapter;
|
||||
import org.springframework.integration.mail.ImapMailReceiver;
|
||||
import org.springframework.integration.mail.SearchTermStrategy;
|
||||
|
||||
@@ -19,7 +19,7 @@ import org.springframework.integration.mail.ImapMailReceiver;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
*
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class Mail {
|
||||
|
||||
@@ -56,6 +56,10 @@ public class Mail {
|
||||
return imapIdleAdapter(new ImapMailReceiver(url));
|
||||
}
|
||||
|
||||
public static MailHeadersBuilder headers() {
|
||||
return new MailHeadersBuilder();
|
||||
}
|
||||
|
||||
private static ImapIdleChannelAdapterSpec imapIdleAdapter(ImapMailReceiver imapMailReceiver) {
|
||||
return new ImapIdleChannelAdapterSpec(imapMailReceiver);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.dsl.mail;
|
||||
|
||||
import org.springframework.integration.dsl.support.MapBuilder;
|
||||
import org.springframework.integration.mail.MailHeaders;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* @author Gary Russell
|
||||
*/
|
||||
public class MailHeadersBuilder extends MapBuilder<MailHeadersBuilder, String, Object> {
|
||||
|
||||
MailHeadersBuilder() {
|
||||
}
|
||||
|
||||
public MailHeadersBuilder subject(String subject) {
|
||||
return put(MailHeaders.SUBJECT, subject);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder subjectExpression(String subject) {
|
||||
return putExpression(MailHeaders.SUBJECT, subject);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder to(String to) {
|
||||
return put(MailHeaders.TO, to);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder toExpression(String to) {
|
||||
return putExpression(MailHeaders.TO, to);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder cc(String cc) {
|
||||
return put(MailHeaders.CC, cc);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder ccExpression(String cc) {
|
||||
return putExpression(MailHeaders.CC, cc);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder bcc(String bcc) {
|
||||
return put(MailHeaders.BCC, bcc);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder bccExpression(String bcc) {
|
||||
return putExpression(MailHeaders.BCC, bcc);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder from(String from) {
|
||||
return put(MailHeaders.FROM, from);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder fromExpression(String from) {
|
||||
return putExpression(MailHeaders.FROM, from);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder replyTo(String replyTo) {
|
||||
return put(MailHeaders.REPLY_TO, replyTo);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder replyToExpression(String replyTo) {
|
||||
return putExpression(MailHeaders.REPLY_TO, replyTo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param multipartMode header value
|
||||
* @return this
|
||||
* @see org.springframework.mail.javamail.MimeMessageHelper
|
||||
*/
|
||||
public MailHeadersBuilder multipartMode(int multipartMode) {
|
||||
return put(MailHeaders.MULTIPART_MODE, multipartMode);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder multipartModeExpression(String multipartMode) {
|
||||
return putExpression(MailHeaders.MULTIPART_MODE, multipartMode);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder attachmentFilename(String attachmentFilename) {
|
||||
return put(MailHeaders.ATTACHMENT_FILENAME, attachmentFilename);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder attachmentFilenameExpression(String attachmentFilename) {
|
||||
return putExpression(MailHeaders.ATTACHMENT_FILENAME, attachmentFilename);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder contentType(String contentType) {
|
||||
return put(MailHeaders.CONTENT_TYPE, contentType);
|
||||
}
|
||||
|
||||
public MailHeadersBuilder contentTypeExpression(String contentType) {
|
||||
return putExpression(MailHeaders.CONTENT_TYPE, contentType);
|
||||
}
|
||||
|
||||
private MailHeadersBuilder putExpression(String key, String expression) {
|
||||
return put(key, PARSER.parseExpression(expression));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import javax.mail.Session;
|
||||
import org.springframework.integration.dsl.core.ComponentsRegistration;
|
||||
import org.springframework.integration.dsl.core.MessageSourceSpec;
|
||||
import org.springframework.integration.dsl.support.PropertiesBuilder;
|
||||
import org.springframework.integration.dsl.support.PropertiesConfigurer;
|
||||
import org.springframework.integration.dsl.support.PropertiesBuilder.PropertiesConfigurer;
|
||||
import org.springframework.integration.mail.AbstractMailReceiver;
|
||||
import org.springframework.integration.mail.MailReceivingMessageSource;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import javax.activation.FileTypeMap;
|
||||
|
||||
import org.springframework.integration.dsl.core.MessageHandlerSpec;
|
||||
import org.springframework.integration.dsl.support.PropertiesBuilder;
|
||||
import org.springframework.integration.dsl.support.PropertiesConfigurer;
|
||||
import org.springframework.integration.dsl.support.PropertiesBuilder.PropertiesConfigurer;
|
||||
import org.springframework.integration.mail.MailSendingMessageHandler;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2014 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.dsl.support;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class MapBuilder<B extends MapBuilder<B, K, V>, K, V> {
|
||||
|
||||
protected final static SpelExpressionParser PARSER = new SpelExpressionParser();
|
||||
|
||||
private final Map<K, V> map = new HashMap<K, V>();
|
||||
|
||||
public B put(K key, V value) {
|
||||
this.map.put(key, value);
|
||||
return _this();
|
||||
}
|
||||
|
||||
public Map<K, V> get() {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected final B _this() {
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
public interface MapBuilderConfigurer<B extends MapBuilder<B, K, V>, K, V> {
|
||||
|
||||
void configure(MapBuilder<B, K, V> builder);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*
|
||||
*/
|
||||
public class PropertiesBuilder {
|
||||
@@ -35,4 +36,10 @@ public class PropertiesBuilder {
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
public interface PropertiesConfigurer {
|
||||
|
||||
void configure(PropertiesBuilder propertiesBuilder);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.dsl.support;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
* A map builder creating a map with String keys and values.
|
||||
*
|
||||
* @author Gary Russell
|
||||
*
|
||||
*/
|
||||
public interface PropertiesConfigurer {
|
||||
|
||||
void configure(PropertiesBuilder propertiesBuilder);
|
||||
public class StringStringMapBuilder extends MapBuilder<StringStringMapBuilder, String, String> {
|
||||
|
||||
}
|
||||
@@ -129,18 +129,14 @@ public class MailTests {
|
||||
private ImapIdleChannelAdapter imapIdleAdapter;
|
||||
|
||||
@Test
|
||||
public void testOutbound() throws Exception {
|
||||
public void testSmtp() throws Exception {
|
||||
assertEquals("localhost", TestUtils.getPropertyValue(this.sendMailHandler, "mailSender.host"));
|
||||
|
||||
Properties javaMailProperties = TestUtils.getPropertyValue(this.sendMailHandler,
|
||||
"mailSender.javaMailProperties", Properties.class);
|
||||
assertEquals("true", javaMailProperties.getProperty("mail.debug"));
|
||||
|
||||
this.sendMailChannel.send(MessageBuilder.withPayload("foo")
|
||||
.setHeader(MailHeaders.SUBJECT, "foo")
|
||||
.setHeader(MailHeaders.FROM, "foo@bar")
|
||||
.setHeader(MailHeaders.TO, "bar@baz")
|
||||
.build());
|
||||
this.sendMailChannel.send(MessageBuilder.withPayload("foo").build());
|
||||
|
||||
int n = 0;
|
||||
while (n++ < 100 && smtpServer.getMessages().size() == 0) {
|
||||
@@ -163,8 +159,8 @@ public class MailTests {
|
||||
assertNotNull(message);
|
||||
MimeMessage mm = (MimeMessage) message.getPayload();
|
||||
assertEquals("foo@bar", mm.getRecipients(RecipientType.TO)[0].toString());
|
||||
assertEquals("bar@baz", mm.getFrom()[0].toString());
|
||||
assertEquals("Test Email", mm.getSubject());
|
||||
assertEquals("bar@baz", message.getHeaders().get(MailHeaders.FROM));
|
||||
assertEquals("Test Email", message.getHeaders().get(MailHeaders.SUBJECT));
|
||||
assertEquals("foo\r\n", mm.getContent());
|
||||
}
|
||||
|
||||
@@ -199,6 +195,7 @@ public class MailTests {
|
||||
@Bean
|
||||
public IntegrationFlow sendMailFlow() {
|
||||
return IntegrationFlows.from("sendMailChannel")
|
||||
.enrichHeaders(Mail.headers().subject("foo").from("foo@bar").to("bar@baz"))
|
||||
.handle(Mail.outboundAdapter("localhost")
|
||||
.port(smtpPort)
|
||||
.credentials("user", "pw")
|
||||
@@ -215,6 +212,8 @@ public class MailTests {
|
||||
.javaMailProperties(p -> p.put("mail.debug", "true")),
|
||||
e -> e.autoStartup(true)
|
||||
.poller(Pollers.fixedDelay(1000)))
|
||||
.enrichHeaders(s -> s.headerExpressions(c -> c.put(MailHeaders.SUBJECT, "payload.subject")
|
||||
.put(MailHeaders.FROM, "payload.from[0].toString()")))
|
||||
.channel(MessageChannels.queue("pop3Channel"))
|
||||
.get();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user