/* * Copyright 2015-2016 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.http; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.springframework.expression.Expression; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.integration.dsl.core.ComponentsRegistration; import org.springframework.integration.dsl.core.MessagingGatewaySpec; import org.springframework.integration.dsl.support.Consumer; import org.springframework.integration.dsl.support.Function; import org.springframework.integration.dsl.support.FunctionExpression; import org.springframework.integration.http.inbound.CrossOrigin; import org.springframework.integration.http.inbound.HttpRequestHandlingEndpointSupport; import org.springframework.integration.http.inbound.RequestMapping; import org.springframework.integration.http.support.DefaultHttpHeaderMapper; import org.springframework.integration.mapping.HeaderMapper; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.multipart.MultipartResolver; /** * * @param <S> the target {@link BaseHttpInboundEndpointSpec} implementation type. * @param <E> the target {@link HttpRequestHandlingEndpointSupport} implementation type. * * @author Artem Bilan * @since 1.1 */ public abstract class BaseHttpInboundEndpointSpec<S extends BaseHttpInboundEndpointSpec<S, E>, E extends HttpRequestHandlingEndpointSupport> extends MessagingGatewaySpec<S, E> implements ComponentsRegistration { private final RequestMapping requestMapping = new RequestMapping(); private final Map<String, Expression> headerExpressions = new HashMap<String, Expression>(); private final HeaderMapper<HttpHeaders> headerMapper = DefaultHttpHeaderMapper.inboundMapper(); private HeaderMapper<HttpHeaders> explicitHeaderMapper; BaseHttpInboundEndpointSpec(E endpoint, String... path) { super(endpoint); this.requestMapping.setPathPatterns(path); this.target.setRequestMapping(this.requestMapping); this.target.setHeaderExpressions(this.headerExpressions); this.target.setHeaderMapper(this.headerMapper); } public S requestMapping(Consumer<RequestMappingSpec> requestMapping) { requestMapping.accept(new RequestMappingSpec(this.requestMapping)); return _this(); } public S crossOrigin(Consumer<CrossOriginSpec> crossOrigin) { CrossOriginSpec originSpec = new CrossOriginSpec(); crossOrigin.accept(originSpec); this.target.setCrossOrigin(originSpec.crossOrigin); return _this(); } public S payloadExpression(String payloadExpression) { return payloadExpression(PARSER.parseExpression(payloadExpression)); } public S payloadExpression(Expression payloadExpression) { this.target.setPayloadExpression(payloadExpression); return _this(); } public <P> S payloadFunction(Function<HttpEntity<P>, ?> payloadFunction) { return payloadExpression(new FunctionExpression<HttpEntity<P>>(payloadFunction)); } public S headerExpressions(Map<String, Expression> headerExpressions) { Assert.notNull(headerExpressions, "'headerExpressions' must not be null"); this.headerExpressions.clear(); this.headerExpressions.putAll(headerExpressions); return _this(); } public S headerExpression(String header, Expression expression) { this.headerExpressions.put(header, expression); return _this(); } public S headerExpression(String header, String expression) { return headerExpression(header, PARSER.parseExpression(expression)); } /** * @param header the header name to add. * @param headerFunction the function to evaluate the header value against {@link HttpEntity}. * @return the current Spec. * @since 1.1.1 * @see HttpRequestHandlingEndpointSupport#setHeaderExpressions(Map) */ public S headerFunction(String header, Function<HttpEntity<?>, ?> headerFunction) { return headerExpression(header, new FunctionExpression<HttpEntity<?>>(headerFunction)); } public S messageConverters(HttpMessageConverter<?>... messageConverters) { this.target.setMessageConverters(Arrays.asList(messageConverters)); return _this(); } public S mergeWithDefaultConverters(boolean mergeWithDefaultConverters) { this.target.setMergeWithDefaultConverters(mergeWithDefaultConverters); return _this(); } public S headerMapper(HeaderMapper<HttpHeaders> headerMapper) { this.target.setHeaderMapper(headerMapper); this.explicitHeaderMapper = headerMapper; return _this(); } public S mappedRequestHeaders(String... patterns) { Assert.isNull(this.explicitHeaderMapper, "The 'mappedRequestHeaders' must be specified on the provided 'headerMapper': " + this.explicitHeaderMapper); ((DefaultHttpHeaderMapper) this.headerMapper).setInboundHeaderNames(patterns); return _this(); } public S mappedResponseHeaders(String... patterns) { Assert.isNull(this.explicitHeaderMapper, "The 'mappedRequestHeaders' must be specified on the provided 'headerMapper': " + this.explicitHeaderMapper); ((DefaultHttpHeaderMapper) this.headerMapper).setOutboundHeaderNames(patterns); return _this(); } public S requestPayloadType(Class<?> requestPayloadType) { this.target.setRequestPayloadType(requestPayloadType); return _this(); } public S extractReplyPayload(boolean extractReplyPayload) { this.target.setExtractReplyPayload(extractReplyPayload); return _this(); } public S multipartResolver(MultipartResolver multipartResolver) { this.target.setMultipartResolver(multipartResolver); return _this(); } public S statusCodeExpression(Expression statusCodeExpression) { this.target.setStatusCodeExpression(statusCodeExpression); return _this(); } public S statusCodeFunction(Function<Void, ?> statusCodeFunction) { return statusCodeExpression(new FunctionExpression<Void>(statusCodeFunction)); } @Override public Collection<Object> getComponentsToRegister() { HeaderMapper<HttpHeaders> headerMapperToRegister = (this.explicitHeaderMapper != null ? this.explicitHeaderMapper : this.headerMapper); return Collections.<Object>singletonList(headerMapperToRegister); } /** * A fluent API for the {@link RequestMapping}. */ public static final class RequestMappingSpec { private final RequestMapping requestMapping; private RequestMappingSpec(RequestMapping requestMapping) { this.requestMapping = requestMapping; } public RequestMappingSpec methods(HttpMethod... supportedMethods) { this.requestMapping.setMethods(supportedMethods); return this; } public RequestMappingSpec params(String... params) { this.requestMapping.setParams(params); return this; } public RequestMappingSpec headers(String... headers) { this.requestMapping.setHeaders(headers); return this; } public RequestMappingSpec consumes(String... consumes) { this.requestMapping.setConsumes(consumes); return this; } public RequestMappingSpec produces(String... produces) { this.requestMapping.setProduces(produces); return this; } } /** * A fluent API for the {@link CrossOrigin}. */ public static final class CrossOriginSpec { private final CrossOrigin crossOrigin = new CrossOrigin(); private CrossOriginSpec() { } public CrossOriginSpec origin(String... origin) { this.crossOrigin.setOrigin(origin); return this; } public CrossOriginSpec allowedHeaders(String... allowedHeaders) { this.crossOrigin.setAllowedHeaders(allowedHeaders); return this; } public CrossOriginSpec exposedHeaders(String... exposedHeaders) { this.crossOrigin.setExposedHeaders(exposedHeaders); return this; } public CrossOriginSpec method(RequestMethod... method) { this.crossOrigin.setMethod(method); return this; } public CrossOriginSpec allowCredentials(Boolean allowCredentials) { this.crossOrigin.setAllowCredentials(allowCredentials); return this; } public CrossOriginSpec maxAge(long maxAge) { this.crossOrigin.setMaxAge(maxAge); return this; } } }