/* * Copyright 2016-2017 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; import java.util.HashMap; import java.util.Map; import java.util.function.Function; import org.springframework.expression.Expression; import org.springframework.integration.channel.DirectChannel; import org.springframework.integration.config.ConsumerEndpointFactoryBean; import org.springframework.integration.expression.FunctionExpression; import org.springframework.integration.expression.ValueExpression; import org.springframework.integration.transformer.ContentEnricher; import org.springframework.integration.transformer.support.AbstractHeaderValueMessageProcessor; import org.springframework.integration.transformer.support.ExpressionEvaluatingHeaderValueMessageProcessor; import org.springframework.integration.transformer.support.HeaderValueMessageProcessor; import org.springframework.integration.transformer.support.StaticHeaderValueMessageProcessor; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; import org.springframework.util.Assert; import reactor.util.function.Tuple2; /** * A {@link ConsumerEndpointSpec} extension for the {@link ContentEnricher}. * * @author Artem Bilan * @author Tim Ysewyn * @author Ian Bondoc * * @since 5.0 */ public class EnricherSpec extends ConsumerEndpointSpec<EnricherSpec, ContentEnricher> { private final Map<String, Expression> propertyExpressions = new HashMap<String, Expression>(); private final Map<String, HeaderValueMessageProcessor<?>> headerExpressions = new HashMap<String, HeaderValueMessageProcessor<?>>(); EnricherSpec() { super(new ContentEnricher()); } /** * @param requestChannel the request channel. * @return the enricher spec. * @see ContentEnricher#setRequestChannel(MessageChannel) */ public EnricherSpec requestChannel(MessageChannel requestChannel) { this.handler.setRequestChannel(requestChannel); return _this(); } /** * @param requestChannel the request channel. * @return the enricher spec. * @see ContentEnricher#setRequestChannelName(String) */ public EnricherSpec requestChannel(String requestChannel) { this.handler.setRequestChannelName(requestChannel); return _this(); } /** * @param replyChannel the reply channel. * @return the enricher spec. * @see ContentEnricher#setReplyChannel(MessageChannel) */ public EnricherSpec replyChannel(MessageChannel replyChannel) { this.handler.setReplyChannel(replyChannel); return _this(); } /** * @param replyChannel the reply channel. * @return the enricher spec. * @see ContentEnricher#setReplyChannelName(String) */ public EnricherSpec replyChannel(String replyChannel) { this.handler.setReplyChannelName(replyChannel); return _this(); } /** * @param requestTimeout the requestTimeout * @return the enricher spec. * @see ContentEnricher#setRequestTimeout(Long) */ public EnricherSpec requestTimeout(Long requestTimeout) { this.handler.setRequestTimeout(requestTimeout); return _this(); } /** * @param replyTimeout the replyTimeout * @return the enricher spec. * @see ContentEnricher#setReplyTimeout(Long) */ public EnricherSpec replyTimeout(Long replyTimeout) { this.handler.setReplyTimeout(replyTimeout); return _this(); } /** * @param requestPayloadExpression the requestPayloadExpression. * @return the enricher spec. * @see ContentEnricher#setRequestPayloadExpression(Expression) */ public EnricherSpec requestPayloadExpression(String requestPayloadExpression) { this.handler.setRequestPayloadExpression(PARSER.parseExpression(requestPayloadExpression)); return _this(); } /** * @param requestPayloadFunction the requestPayloadFunction. * @param <P> the payload type. * @return the enricher spec. * @see ContentEnricher#setRequestPayloadExpression(Expression) * @see FunctionExpression */ public <P> EnricherSpec requestPayload(Function<Message<P>, ?> requestPayloadFunction) { this.handler.setRequestPayloadExpression(new FunctionExpression<>(requestPayloadFunction)); return _this(); } /** * The request sub-flow. * @param subFlow the subFlowDefinition * @return the enricher spec */ public EnricherSpec requestSubFlow(IntegrationFlow subFlow) { Assert.notNull(subFlow, "'subFlow' must not be null"); DirectChannel requestChannel = new DirectChannel(); IntegrationFlowBuilder flowBuilder = IntegrationFlows.from(requestChannel); subFlow.configure(flowBuilder); this.componentsToRegister.add(flowBuilder.get()); return requestChannel(requestChannel); } /** * @param shouldClonePayload the shouldClonePayload. * @return the enricher spec. * @see ContentEnricher#setShouldClonePayload(boolean) */ public EnricherSpec shouldClonePayload(boolean shouldClonePayload) { this.handler.setShouldClonePayload(shouldClonePayload); return _this(); } /** * @param key the key. * @param value the value. * @param <V> the value type. * @return the enricher spec. * @see ContentEnricher#setPropertyExpressions(Map) */ public <V> EnricherSpec property(String key, V value) { this.propertyExpressions.put(key, new ValueExpression<V>(value)); return _this(); } /** * @param key the key. * @param expression the expression. * @return the enricher spec. * @see ContentEnricher#setPropertyExpressions(Map) */ public EnricherSpec propertyExpression(String key, String expression) { Assert.notNull(key, "'key' must not be null"); this.propertyExpressions.put(key, PARSER.parseExpression(expression)); return _this(); } /** * @param key the key. * @param function the function (usually a JDK8 lambda). * @param <P> the payload type. * @return the enricher spec. * @see ContentEnricher#setPropertyExpressions(Map) * @see FunctionExpression */ public <P> EnricherSpec propertyFunction(String key, Function<Message<P>, Object> function) { this.propertyExpressions.put(key, new FunctionExpression<>(function)); return _this(); } /** * Set a header with the value if it is not already present. * @param name the header name. * @param value the value. * @param <V> the value type. * @return the enricher spec. * @see ContentEnricher#setHeaderExpressions(Map) */ public <V> EnricherSpec header(String name, V value) { return this.header(name, value, null); } /** * @param name the header name. * @param value the value. * @param overwrite true to overwrite the header if already present. * @param <V> the value type. * @return the enricher spec. * @see ContentEnricher#setHeaderExpressions(Map) */ public <V> EnricherSpec header(String name, V value, Boolean overwrite) { AbstractHeaderValueMessageProcessor<V> headerValueMessageProcessor = new StaticHeaderValueMessageProcessor<V>(value); headerValueMessageProcessor.setOverwrite(overwrite); return header(name, headerValueMessageProcessor); } /** * Set a header with the expression evaluation if the header is not already present. * @param name the header name. * @param expression the expression to be evaluated against the reply message to obtain the value. * @return the enricher spec. * @see ContentEnricher#setHeaderExpressions(Map) */ public EnricherSpec headerExpression(String name, String expression) { return headerExpression(name, expression, null); } /** * @param name the header name. * @param expression the expression to be evaluated against the reply message to obtain the value. * @param overwrite true to overwrite the header if already present. * @return the enricher spec. * @see ContentEnricher#setHeaderExpressions(Map) */ public EnricherSpec headerExpression(String name, String expression, Boolean overwrite) { Assert.hasText(expression, "'expression' must not be empty"); return headerExpression(name, PARSER.parseExpression(expression), overwrite); } /** * Set a header with the function return value if the header is not already present. * @param name the header name. * @param function the function (usually a JDK8 lambda). * @param <P> the payload type. * @return the enricher spec. * @see ContentEnricher#setHeaderExpressions(Map) * @see FunctionExpression */ public <P> EnricherSpec headerFunction(String name, Function<Message<P>, Object> function) { return headerFunction(name, function, null); } /** * @param name the header name. * @param function the function (usually a JDK8 lambda). * @param overwrite true to overwrite the header if already present. * @param <P> the payload type. * @return the enricher spec. * @see ContentEnricher#setHeaderExpressions(Map) * @see FunctionExpression */ public <P> EnricherSpec headerFunction(String name, Function<Message<P>, Object> function, Boolean overwrite) { return headerExpression(name, new FunctionExpression<>(function), overwrite); } private EnricherSpec headerExpression(String name, Expression expression, Boolean overwrite) { AbstractHeaderValueMessageProcessor<?> headerValueMessageProcessor = new ExpressionEvaluatingHeaderValueMessageProcessor<>(expression, null); headerValueMessageProcessor.setOverwrite(overwrite); return header(name, headerValueMessageProcessor); } /** * Set a header value using an explicit {@link HeaderValueMessageProcessor}. * @param headerName the header name. * @param headerValueMessageProcessor the headerValueMessageProcessor. * @param <V> the value type. * @return the enricher spec. * @see ContentEnricher#setHeaderExpressions(Map) */ public <V> EnricherSpec header(String headerName, HeaderValueMessageProcessor<V> headerValueMessageProcessor) { Assert.hasText(headerName, "'headerName' must not be empty"); this.headerExpressions.put(headerName, headerValueMessageProcessor); return _this(); } @Override protected Tuple2<ConsumerEndpointFactoryBean, ContentEnricher> doGet() { if (!this.propertyExpressions.isEmpty()) { this.handler.setPropertyExpressions(this.propertyExpressions); } if (!this.headerExpressions.isEmpty()) { this.handler.setHeaderExpressions(this.headerExpressions); } return super.doGet(); } }