diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationFlowDefinition.java b/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationFlowDefinition.java index f9fb6bd2d7..a0cc473920 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationFlowDefinition.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dsl/IntegrationFlowDefinition.java @@ -2194,6 +2194,9 @@ public abstract class IntegrationFlowDefinition The full request {@link Message} will be logged. + *
When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @return the current {@link IntegrationFlowDefinition}. * @see #wireTap(WireTapSpec) */ @@ -2207,6 +2210,9 @@ public abstract class IntegrationFlowDefinition The full request {@link Message} will be logged. + *
When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param level the {@link LoggingHandler.Level}. * @return the current {@link IntegrationFlowDefinition}. * @see #wireTap(WireTapSpec) @@ -2220,6 +2226,9 @@ public abstract class IntegrationFlowDefinition The full request {@link Message} will be logged. + *
When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param category the logging category to use. * @return the current {@link IntegrationFlowDefinition}. * @see #wireTap(WireTapSpec) @@ -2233,6 +2242,9 @@ public abstract class IntegrationFlowDefinition The full request {@link Message} will be logged. + *
When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param level the {@link LoggingHandler.Level}. * @param category the logging category to use. * @return the current {@link IntegrationFlowDefinition}. @@ -2247,6 +2259,9 @@ public abstract class IntegrationFlowDefinition When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param level the {@link LoggingHandler.Level}. * @param category the logging category. * @param logExpression the SpEL expression to evaluate logger message at runtime @@ -2264,6 +2279,9 @@ public abstract class IntegrationFlowDefinition When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param function the function to evaluate logger message at runtime * @param
the expected payload type. * against the request {@link Message}. @@ -2281,6 +2299,9 @@ public abstract class IntegrationFlowDefinition When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param logExpression the {@link Expression} to evaluate logger message at runtime * against the request {@link Message}. * @return the current {@link IntegrationFlowDefinition}. @@ -2297,6 +2318,9 @@ public abstract class IntegrationFlowDefinition When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param level the {@link LoggingHandler.Level}. * @param logExpression the {@link Expression} to evaluate logger message at runtime * against the request {@link Message}. @@ -2307,13 +2331,15 @@ public abstract class IntegrationFlowDefinition When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param category the logging category. * @param logExpression the {@link Expression} to evaluate logger message at runtime * against the request {@link Message}. @@ -2330,6 +2356,9 @@ public abstract class IntegrationFlowDefinition When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param level the {@link LoggingHandler.Level}. * @param function the function to evaluate logger message at runtime * @param
the expected payload type. @@ -2346,6 +2375,9 @@ public abstract class IntegrationFlowDefinition When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param category the logging category. * @param function the function to evaluate logger message at runtime * @param
the expected payload type. @@ -2362,6 +2394,9 @@ public abstract class IntegrationFlowDefinition When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param level the {@link LoggingHandler.Level}. * @param category the logging category. * @param function the function to evaluate logger message at runtime @@ -2375,12 +2410,14 @@ public abstract class IntegrationFlowDefinition(function)); } - /** * Populate a {@link WireTap} for the {@link #currentMessageChannel} * with the {@link LoggingHandler} subscriber for the provided * {@link LoggingHandler.Level} logging level, logging category * and SpEL expression for the log message. + *
When this operator is used in the end of flow, it is treated + * as one-way handler without any replies to continue. + * The {@link #logAndReply()} should be used for request-reply configuration. * @param level the {@link LoggingHandler.Level}. * @param category the logging category. * @param logExpression the {@link Expression} to evaluate logger message at runtime @@ -2406,6 +2443,264 @@ public abstract class IntegrationFlowDefinition The full request {@link Message} will be logged. + *
A {@link #bridge()} is added after this operator to make the flow reply-producing + * if the {@code replyChannel} header is present. + *
This operator can be used only in the end of flow. + * @return an {@link IntegrationFlow} instance based on this builder. + * @see #log() + * @see #bridge() + */ + public IntegrationFlow logAndReply() { + return logAndReply(LoggingHandler.Level.INFO); + } + + /** + * Populate a {@link WireTap} for the {@link #currentMessageChannel} + * with the {@link LoggingHandler} subscriber for provided {@link LoggingHandler.Level} + * logging level and {@code org.springframework.integration.handler.LoggingHandler} + * as a default logging category. + *
The full request {@link Message} will be logged. + *
A {@link #bridge()} is added after this operator to make the flow reply-producing + * if the {@code replyChannel} header is present. + *
This operator can be used only in the end of flow. + * @param level the {@link LoggingHandler.Level}. + * @return an {@link IntegrationFlow} instance based on this builder. + * @see #log() + * @see #bridge() + */ + public IntegrationFlow logAndReply(LoggingHandler.Level level) { + return logAndReply(level, (String) null); + } + + /** + * Populate a {@link WireTap} for the {@link #currentMessageChannel} + * with the {@link LoggingHandler} subscriber for the provided logging category + * and {@code INFO} logging level. + *
The full request {@link Message} will be logged. + *
A {@link #bridge()} is added after this operator to make the flow reply-producing + * if the {@code replyChannel} header is present. + *
This operator can be used only in the end of flow. + * @param category the logging category to use. + * @return an {@link IntegrationFlow} instance based on this builder. + * @see #log() + * @see #bridge() + */ + public IntegrationFlow logAndReply(String category) { + return logAndReply(LoggingHandler.Level.INFO, category); + } + + /** + * Populate a {@link WireTap} for the {@link #currentMessageChannel} + * with the {@link LoggingHandler} subscriber for the provided + * {@link LoggingHandler.Level} logging level and logging category. + *
The full request {@link Message} will be logged. + *
A {@link #bridge()} is added after this operator to make the flow reply-producing + * if the {@code replyChannel} header is present. + *
This operator can be used only in the end of flow. + * @param level the {@link LoggingHandler.Level}. + * @param category the logging category to use. + * @return an {@link IntegrationFlow} instance based on this builder. + * @see #log() + * @see #bridge() + */ + public IntegrationFlow logAndReply(LoggingHandler.Level level, String category) { + return logAndReply(level, category, (Expression) null); + } + + /** + * Populate a {@link WireTap} for the {@link #currentMessageChannel} + * with the {@link LoggingHandler} subscriber for the provided + * {@link LoggingHandler.Level} logging level, logging category + * and SpEL expression for the log message. + *
A {@link #bridge()} is added after this operator to make the flow reply-producing + * if the {@code replyChannel} header is present. + *
This operator can be used only in the end of flow. + * @param level the {@link LoggingHandler.Level}. + * @param category the logging category. + * @param logExpression the SpEL expression to evaluate logger message at runtime + * against the request {@link Message}. + * @return an {@link IntegrationFlow} instance based on this builder. + * @see #log() + * @see #bridge() + */ + public IntegrationFlow logAndReply(LoggingHandler.Level level, String category, String logExpression) { + Assert.hasText(logExpression, "'logExpression' must not be empty"); + return logAndReply(level, category, PARSER.parseExpression(logExpression)); + } + + /** + * Populate a {@link WireTap} for the {@link #currentMessageChannel} + * with the {@link LoggingHandler} subscriber for the {@code INFO} logging level, + * the {@code org.springframework.integration.handler.LoggingHandler} + * as a default logging category and {@link Function} for the log message. + *
A {@link #bridge()} is added after this operator to make the flow reply-producing + * if the {@code replyChannel} header is present. + *
This operator can be used only in the end of flow. + * @param function the function to evaluate logger message at runtime + * @param
the expected payload type. + * against the request {@link Message}. + * @return an {@link IntegrationFlow} instance based on this builder. + * @see #log() + * @see #bridge() + */ + public
IntegrationFlow logAndReply(Function A {@link #bridge()} is added after this operator to make the flow reply-producing
+ * if the {@code replyChannel} header is present.
+ * This operator can be used only in the end of flow.
+ * @param logExpression the {@link Expression} to evaluate logger message at runtime
+ * against the request {@link Message}.
+ * @return an {@link IntegrationFlow} instance based on this builder.
+ * @see #log()
+ * @see #bridge()
+ */
+ public IntegrationFlow logAndReply(Expression logExpression) {
+ return logAndReply(LoggingHandler.Level.INFO, logExpression);
+ }
+
+ /**
+ * Populate a {@link WireTap} for the {@link #currentMessageChannel}
+ * with the {@link LoggingHandler} subscriber for the provided
+ * {@link LoggingHandler.Level} logging level,
+ * the {@code org.springframework.integration.handler.LoggingHandler}
+ * as a default logging category and SpEL expression to evaluate
+ * logger message at runtime against the request {@link Message}.
+ * A {@link #bridge()} is added after this operator to make the flow reply-producing
+ * if the {@code replyChannel} header is present.
+ * This operator can be used only in the end of flow.
+ * @param level the {@link LoggingHandler.Level}.
+ * @param logExpression the {@link Expression} to evaluate logger message at runtime
+ * against the request {@link Message}.
+ * @return an {@link IntegrationFlow} instance based on this builder.
+ * @see #log()
+ * @see #bridge()
+ */
+ public IntegrationFlow logAndReply(LoggingHandler.Level level, Expression logExpression) {
+ return logAndReply(level, null, logExpression);
+ }
+
+ /**
+ * Populate a {@link WireTap} for the {@link #currentMessageChannel}
+ * with the {@link LoggingHandler} subscriber for the {@code INFO}
+ * {@link LoggingHandler.Level} logging level,
+ * the provided logging category and SpEL expression to evaluate
+ * logger message at runtime against the request {@link Message}.
+ * A {@link #bridge()} is added after this operator to make the flow reply-producing
+ * if the {@code replyChannel} header is present.
+ * This operator can be used only in the end of flow.
+ * @param category the logging category.
+ * @param logExpression the {@link Expression} to evaluate logger message at runtime
+ * against the request {@link Message}.
+ * @return an {@link IntegrationFlow} instance based on this builder.
+ * @see #log()
+ * @see #bridge()
+ */
+ public IntegrationFlow logAndReply(String category, Expression logExpression) {
+ return logAndReply(LoggingHandler.Level.INFO, category, logExpression);
+ }
+
+ /**
+ * Populate a {@link WireTap} for the {@link #currentMessageChannel}
+ * with the {@link LoggingHandler} subscriber for the provided
+ * {@link LoggingHandler.Level} logging level,
+ * the {@code org.springframework.integration.handler.LoggingHandler}
+ * as a default logging category and {@link Function} for the log message.
+ * A {@link #bridge()} is added after this operator to make the flow reply-producing
+ * if the {@code replyChannel} header is present.
+ * This operator can be used only in the end of flow.
+ * @param level the {@link LoggingHandler.Level}.
+ * @param function the function to evaluate logger message at runtime
+ * @param the expected payload type.
+ * against the request {@link Message}.
+ * @return an {@link IntegrationFlow} instance based on this builder.
+ * @see #log()
+ * @see #bridge()
+ */
+ public IntegrationFlow logAndReply(LoggingHandler.Level level, Function A {@link #bridge()} is added after this operator to make the flow reply-producing
+ * if the {@code replyChannel} header is present.
+ * This operator can be used only in the end of flow.
+ * @param category the logging category.
+ * @param function the function to evaluate logger message at runtime
+ * @param the expected payload type.
+ * against the request {@link Message}.
+ * @return an {@link IntegrationFlow} instance based on this builder.
+ * @see #log()
+ * @see #bridge()
+ */
+ public IntegrationFlow logAndReply(String category, Function A {@link #bridge()} is added after this operator to make the flow reply-producing
+ * if the {@code replyChannel} header is present.
+ * This operator can be used only in the end of flow.
+ * @param level the {@link LoggingHandler.Level}.
+ * @param category the logging category.
+ * @param function the function to evaluate logger message at runtime
+ * @param the expected payload type.
+ * against the request {@link Message}.
+ * @return an {@link IntegrationFlow} instance based on this builder.
+ * @see #log()
+ * @see #bridge()
+ */
+ public IntegrationFlow logAndReply(LoggingHandler.Level level, String category,
+ Function A {@link #bridge()} is added after this operator to make the flow reply-producing
+ * if the {@code replyChannel} header is present.
+ * This operator can be used only in the end of flow.
+ * @param level the {@link LoggingHandler.Level}.
+ * @param category the logging category.
+ * @param logExpression the {@link Expression} to evaluate logger message at runtime
+ * against the request {@link Message}.
+ * @return an {@link IntegrationFlow} instance based on this builder.
+ * @see #log()
+ * @see #bridge()
+ */
+ public IntegrationFlow logAndReply(LoggingHandler.Level level, String category, Expression logExpression) {
+ return log(level, category, logExpression)
+ .bridge()
+ .get();
+ }
+
/**
* Populate a {@link ScatterGatherHandler} to the current integration flow position
* based on the provided {@link MessageChannel} for scattering function
@@ -2603,6 +2898,7 @@ public abstract class IntegrationFlowDefinition> B register(S endpointSpec,
Consumer endpointConfigurer) {
+
if (endpointConfigurer != null) {
endpointConfigurer.accept(endpointSpec);
}
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java b/spring-integration-core/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java
index 5b65bc3718..efaaa3e24b 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/transformer/HeaderEnricher.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2017 the original author or authors.
+ * Copyright 2002-2018 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.
@@ -29,11 +29,11 @@ import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.context.IntegrationObjectSupport;
import org.springframework.integration.handler.MessageProcessor;
+import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
import org.springframework.integration.support.DefaultMessageBuilderFactory;
import org.springframework.integration.transformer.support.HeaderValueMessageProcessor;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
-import org.springframework.messaging.MessagingException;
/**
* A Transformer that adds statically configured header values to a Message.
@@ -64,12 +64,13 @@ public class HeaderEnricher extends IntegrationObjectSupport implements Transfor
/**
* Create a HeaderEnricher with the given map of headers.
- *
* @param headersToAdd The headers to add.
*/
public HeaderEnricher(Maptrue. Set this to false if a
* null value should trigger removal of the
* corresponding header instead.
- *
* @param shouldSkipNulls true when null values should be skipped.
*/
public void setShouldSkipNulls(boolean shouldSkipNulls) {
@@ -96,52 +96,56 @@ public class HeaderEnricher extends IntegrationObjectSupport implements Transfor
@Override
public String getComponentType() {
- return "transformer"; // backwards compatibility
+ return "header-enricher";
}
@Override
public Message> transform(Message> message) {
- try {
- Map