From e2e7adabe43be4af55abea8ed5d051fccbc94835 Mon Sep 17 00:00:00 2001
From: Dave Syer
Date: Mon, 17 Jul 2017 13:59:46 +0100
Subject: [PATCH] Update some deps and remove gateway (moved to separate
project)
---
pom.xml | 7 +-
spring-cloud-function-gateway/.jdk8 | 0
spring-cloud-function-gateway/pom.xml | 33 -
.../cloud/function/gateway/ProxyExchange.java | 644 ------------------
.../config/ProxyExchangeArgumentResolver.java | 83 ---
.../gateway/config/ProxyProperties.java | 70 --
.../ProxyResponseAutoConfiguration.java | 89 ---
.../main/resources/META-INF/spring.factories | 5 -
.../gateway/ProductionConfigurationTests.java | 445 ------------
.../src/test/resources/static/test.html | 4 -
10 files changed, 3 insertions(+), 1377 deletions(-)
delete mode 100644 spring-cloud-function-gateway/.jdk8
delete mode 100644 spring-cloud-function-gateway/pom.xml
delete mode 100644 spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/ProxyExchange.java
delete mode 100644 spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyExchangeArgumentResolver.java
delete mode 100644 spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyProperties.java
delete mode 100644 spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyResponseAutoConfiguration.java
delete mode 100644 spring-cloud-function-gateway/src/main/resources/META-INF/spring.factories
delete mode 100644 spring-cloud-function-gateway/src/test/java/org/springframework/cloud/function/web/gateway/ProductionConfigurationTests.java
delete mode 100644 spring-cloud-function-gateway/src/test/resources/static/test.html
diff --git a/pom.xml b/pom.xml
index 183ca6f34..ca504c914 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,16 +10,16 @@
org.springframework.cloud
spring-cloud-build
- 1.3.0.BUILD-SNAPSHOT
+ 1.3.3.RELEASE
1.8
- Aluminium-BUILD-SNAPSHOT
+ Aluminium-SR3
Chelsea.SR1
1.0.5.RELEASE
- 1.5.2.RELEASE
+ 1.5.4.RELEASE
@@ -52,7 +52,6 @@
spring-cloud-function-compiler
spring-cloud-function-core
spring-cloud-function-context
- spring-cloud-function-gateway
spring-cloud-function-stream
spring-cloud-function-task
spring-cloud-function-web
diff --git a/spring-cloud-function-gateway/.jdk8 b/spring-cloud-function-gateway/.jdk8
deleted file mode 100644
index e69de29bb..000000000
diff --git a/spring-cloud-function-gateway/pom.xml b/spring-cloud-function-gateway/pom.xml
deleted file mode 100644
index c412ec863..000000000
--- a/spring-cloud-function-gateway/pom.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
- 4.0.0
-
- spring-cloud-function-gateway
- jar
- spring-cloud-function-gateway
- Spring Cloud Function Gateway Support
-
-
- org.springframework.cloud
- spring-cloud-function-parent
- 1.0.0.BUILD-SNAPSHOT
-
-
-
-
- org.springframework.boot
- spring-boot-starter-web
-
-
- org.springframework.boot
- spring-boot-starter-test
- test
-
-
- org.springframework.boot
- spring-boot-configuration-processor
- true
-
-
-
diff --git a/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/ProxyExchange.java b/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/ProxyExchange.java
deleted file mode 100644
index a8764f7e9..000000000
--- a/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/ProxyExchange.java
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * 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.cloud.function.gateway;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.lang.reflect.WildcardType;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashSet;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.Vector;
-import java.util.function.Function;
-
-import javax.servlet.ReadListener;
-import javax.servlet.ServletInputStream;
-import javax.servlet.ServletOutputStream;
-import javax.servlet.WriteListener;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletResponseWrapper;
-
-import org.springframework.core.Conventions;
-import org.springframework.core.MethodParameter;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.RequestEntity;
-import org.springframework.http.RequestEntity.BodyBuilder;
-import org.springframework.http.ResponseEntity;
-import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.http.converter.HttpMessageNotWritableException;
-import org.springframework.util.ClassUtils;
-import org.springframework.validation.BindingResult;
-import org.springframework.web.HttpMediaTypeNotAcceptableException;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.bind.support.WebDataBinderFactory;
-import org.springframework.web.client.RequestCallback;
-import org.springframework.web.client.ResponseExtractor;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.context.request.NativeWebRequest;
-import org.springframework.web.context.request.ServletWebRequest;
-import org.springframework.web.context.request.WebRequest;
-import org.springframework.web.method.support.ModelAndViewContainer;
-import org.springframework.web.servlet.HandlerMapping;
-import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
-import org.springframework.web.util.AbstractUriTemplateHandler;
-
-/**
- * A @RequestMapping argument type that can proxy the request to a backend.
- * Spring will inject one of these into your MVC handler method, and you get return a
- * ResponseEntity that you get from one of the HTTP methods {@link #get()},
- * {@link #post()}, {@link #put()}, {@link #patch()}, {@link #delete()} etc. Example:
- *
- *
- * @GetMapping("/proxy/{id}")
- * public ResponseEntity<?> proxy(@PathVariable Integer id, ProxyExchange<?> proxy)
- * throws Exception {
- * return proxy.uri("http://localhost:9000/foos/" + id).get();
- * }
- *
- *
- *
- * By default the incoming request body and headers are sent intact to the downstream
- * service (with the exception of "sensitive" headers). To manipulate the downstream
- * request there are "builder" style methods in {@link ProxyExchange}, but only the
- * {@link #uri(String)} is mandatory. You can change the sensitive headers by calling the
- * {@link #sensitive(String...)} method (Authorization and Cookie are sensitive by
- * default).
- *
- *
- * The type parameter T in ProxyExchange<T> is the type of
- * the response body, so it comes out in the {@link ResponseEntity} that you return from
- * your @RequestMapping. If you don't care about the type of the request and
- * response body (e.g. if it's just a passthru) then use a wildcard, or
- * byte[] or Object. Use a concrete type if you want to
- * transform or manipulate the response, or if you want to assert that it is convertible
- * to the type you declare.
- *
- *
- * To manipulate the response use the overloaded HTTP methods with a Function
- * argument and pass in code to transform the response. E.g.
- *
- *
- * @PostMapping("/proxy")
- * public ResponseEntity<Foo> proxy(ProxyExchange<Foo> proxy) throws Exception {
- * return proxy.uri("http://localhost:9000/foos/") //
- * .post(response -> ResponseEntity.status(response.getStatusCode()) //
- * .headers(response.getHeaders()) //
- * .header("X-Custom", "MyCustomHeader") //
- * .body(response.getBody()) //
- * );
- * }
- *
- *
- *
- *
- *
- * The full machinery of Spring {@link HttpMessageConverter message converters} is applied
- * to the incoming request and response and also to the backend request. If you need
- * additional converters then they need to be added upstream in the MVC configuration and
- * also to the {@link RestTemplate} that is used in the backend calls (see the
- * {@link ProxyExchange#ProxyExchange(RestTemplate, NativeWebRequest, ModelAndViewContainer, WebDataBinderFactory, Type)
- * constructor} for details).
- *
- *
- * As well as the HTTP methods for a backend call you can also use
- * {@link #forward(String)} for a local in-container dispatch.
- *
- *
- * @author Dave Syer
- *
- */
-public class ProxyExchange {
-
- public static Set DEFAULT_SENSITIVE = new HashSet<>(
- Arrays.asList("cookie", "authorization"));
-
- private URI uri;
-
- private NestedTemplate rest;
-
- private Object body;
-
- private RequestResponseBodyMethodProcessor delegate;
-
- private NativeWebRequest webRequest;
-
- private ModelAndViewContainer mavContainer;
-
- private WebDataBinderFactory binderFactory;
-
- private Set sensitive;
-
- private HttpHeaders headers = new HttpHeaders();
-
- private Type responseType;
-
- public ProxyExchange(RestTemplate rest, NativeWebRequest webRequest,
- ModelAndViewContainer mavContainer, WebDataBinderFactory binderFactory,
- Type type) {
- this.responseType = type;
- this.rest = createTemplate(rest);
- this.webRequest = webRequest;
- this.mavContainer = mavContainer;
- this.binderFactory = binderFactory;
- this.delegate = new RequestResponseBodyMethodProcessor(
- rest.getMessageConverters());
- }
-
- /**
- * Sets the body for the downstream request (if using {@link #post()}, {@link #put()}
- * or {@link #patch()}). The body can be omitted if you just want to pass the incoming
- * request downstream without changing it. If you want to transform the incoming
- * request you can declare it as a @RequestBody in your
- * @RequestMapping in the usual Spring MVC way.
- *
- * @param body the request body to send downstream
- * @return this for convenience
- */
- public ProxyExchange body(Object body) {
- this.body = body;
- return this;
- }
-
- /**
- * Sets a header for the downstream call.
- *
- * @param name
- * @param value
- * @return this for convenience
- */
- public ProxyExchange header(String name, String... value) {
- this.headers.put(name, Arrays.asList(value));
- return this;
- }
-
- /**
- * Additional headers, or overrides of the incoming ones, to be used in the downstream
- * call.
- *
- * @param headers the http headers to use in the downstream call
- * @return this for convenience
- */
- public ProxyExchange headers(HttpHeaders headers) {
- this.headers.putAll(headers);
- return this;
- }
-
- /**
- * Sets the names of sensitive headers that are not passed downstream to the backend
- * service.
- *
- * @param names the names of sensitive headers
- * @return this for convenience
- */
- public ProxyExchange sensitive(String... names) {
- if (this.sensitive == null) {
- this.sensitive = new HashSet<>();
- }
- for (String name : names) {
- this.sensitive.add(name.toLowerCase());
- }
- return this;
- }
-
- /**
- * Sets the uri for the backend call when triggered by the HTTP methods.
- *
- * @param uri the backend uri to send the request to
- * @return this for convenience
- */
- public ProxyExchange uri(String uri) {
- try {
- this.uri = new URI(uri);
- }
- catch (URISyntaxException e) {
- throw new IllegalStateException("Cannot create URI", e);
- }
- return this;
- }
-
- public String path() {
- return (String) this.webRequest.getAttribute(
- HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE,
- WebRequest.SCOPE_REQUEST);
- }
-
- public String path(String prefix) {
- String path = path();
- if (!path.startsWith(prefix)) {
- throw new IllegalArgumentException(
- "Path does not start with prefix (" + prefix + "): " + path);
- }
- return path.substring(prefix.length());
- }
-
- public void forward(String path) {
- HttpServletRequest request = this.webRequest
- .getNativeRequest(HttpServletRequest.class);
- HttpServletResponse response = this.webRequest
- .getNativeResponse(HttpServletResponse.class);
- try {
- request.getRequestDispatcher(path).forward(
- new BodyForwardingHttpServletRequest(request, response), response);
- }
- catch (Exception e) {
- throw new IllegalStateException("Cannot forward request", e);
- }
- }
-
- public ResponseEntity get() {
- RequestEntity> requestEntity = headers((BodyBuilder) RequestEntity.get(uri))
- .build();
- return exchange(requestEntity);
- }
-
- public ResponseEntity get(
- Function, ResponseEntity> converter) {
- return converter.apply(get());
- }
-
- public ResponseEntity head() {
- RequestEntity> requestEntity = headers((BodyBuilder) RequestEntity.head(uri))
- .build();
- return exchange(requestEntity);
- }
-
- public ResponseEntity head(
- Function, ResponseEntity> converter) {
- return converter.apply(head());
- }
-
- public ResponseEntity options() {
- RequestEntity> requestEntity = headers((BodyBuilder) RequestEntity.options(uri))
- .build();
- return exchange(requestEntity);
- }
-
- public ResponseEntity options(
- Function, ResponseEntity> converter) {
- return converter.apply(options());
- }
-
- public ResponseEntity post() {
- RequestEntity requestEntity = headers(RequestEntity.post(uri))
- .body(body());
- return exchange(requestEntity);
- }
-
- public ResponseEntity post(
- Function, ResponseEntity> converter) {
- return converter.apply(post());
- }
-
- public ResponseEntity delete() {
- RequestEntity requestEntity = headers(
- (BodyBuilder) RequestEntity.delete(uri)).build();
- return exchange(requestEntity);
- }
-
- public ResponseEntity delete(
- Function, ResponseEntity> converter) {
- return converter.apply(delete());
- }
-
- public ResponseEntity put() {
- RequestEntity requestEntity = headers(RequestEntity.put(uri))
- .body(body());
- return exchange(requestEntity);
- }
-
- public ResponseEntity put(
- Function, ResponseEntity> converter) {
- return converter.apply(put());
- }
-
- public ResponseEntity patch() {
- RequestEntity requestEntity = headers(RequestEntity.patch(uri))
- .body(body());
- return exchange(requestEntity);
- }
-
- public ResponseEntity patch(
- Function, ResponseEntity> converter) {
- return converter.apply(patch());
- }
-
- private ResponseEntity exchange(RequestEntity> requestEntity) {
- Type type = this.responseType;
- if (type instanceof TypeVariable || type instanceof WildcardType) {
- type = Object.class;
- }
- RequestCallback requestCallback = rest.httpEntityCallback((Object) requestEntity,
- type);
- ResponseExtractor> responseExtractor = rest
- .responseEntityExtractor(type);
- return rest.execute(requestEntity.getUrl(), requestEntity.getMethod(),
- requestCallback, responseExtractor);
- }
-
- private BodyBuilder headers(BodyBuilder builder) {
- Set sensitive = this.sensitive;
- if (sensitive == null) {
- sensitive = DEFAULT_SENSITIVE;
- }
- proxy();
- for (String name : headers.keySet()) {
- if (sensitive.contains(name.toLowerCase())) {
- continue;
- }
- builder.header(name, headers.get(name).toArray(new String[0]));
- }
- return builder;
- }
-
- private void proxy() {
- try {
- URI uri = new URI(webRequest.getNativeRequest(HttpServletRequest.class)
- .getRequestURL().toString());
- appendForwarded(uri);
- appendXForwarded(uri);
- }
- catch (URISyntaxException e) {
- throw new IllegalStateException("Cannot create URI for request: " + webRequest
- .getNativeRequest(HttpServletRequest.class).getRequestURL());
- }
- }
-
- private void appendXForwarded(URI uri) {
- // Append the legacy headers if they were already added upstream
- String host = headers.getFirst("x-forwarded-host");
- if (host == null) {
- return;
- }
- host = host + "," + uri.getHost();
- headers.set("x-forwarded-host", host);
- String proto = headers.getFirst("x-forwarded-proto");
- if (proto == null) {
- return;
- }
- proto = proto + "," + uri.getScheme();
- headers.set("x-forwarded-proto", proto);
- }
-
- private void appendForwarded(URI uri) {
- String forwarded = headers.getFirst("forwarded");
- if (forwarded != null) {
- forwarded = forwarded + ",";
- } else {
- forwarded = "";
- }
- forwarded = forwarded + forwarded(uri);
- headers.set("forwarded", forwarded);
- }
-
- private String forwarded(URI uri) {
- if ("http".equals(uri.getScheme())) {
- return "host=" + uri.getHost();
- }
- return String.format("host=%s;proto=%s", uri.getHost(), uri.getScheme());
- }
-
- private Object body() {
- if (body != null) {
- return body;
- }
- body = getRequestBody();
- return body;
- }
-
- /**
- * Search for the request body if it was already deserialized using
- * @RequestBody. If it is not found then deserialize it in the same way
- * that it would have been for a @RequestBody.
- *
- * @return the request body
- */
- private Object getRequestBody() {
- for (String key : mavContainer.getModel().keySet()) {
- if (key.startsWith(BindingResult.MODEL_KEY_PREFIX)) {
- BindingResult result = (BindingResult) mavContainer.getModel().get(key);
- return result.getTarget();
- }
- }
- MethodParameter input = new MethodParameter(
- ClassUtils.getMethod(BodyGrabber.class, "body", Object.class), 0);
- try {
- delegate.resolveArgument(input, mavContainer, webRequest, binderFactory);
- }
- catch (Exception e) {
- throw new IllegalStateException("Cannot resolve body", e);
- }
- String name = Conventions.getVariableNameForParameter(input);
- BindingResult result = (BindingResult) mavContainer.getModel()
- .get(BindingResult.MODEL_KEY_PREFIX + name);
- return result.getTarget();
- }
-
- private NestedTemplate createTemplate(RestTemplate input) {
- NestedTemplate rest = new NestedTemplate();
- rest.setMessageConverters(input.getMessageConverters());
- rest.setErrorHandler(input.getErrorHandler());
- rest.setDefaultUriVariables(
- ((AbstractUriTemplateHandler) input.getUriTemplateHandler())
- .getDefaultUriVariables());
- rest.setRequestFactory(input.getRequestFactory());
- rest.setInterceptors(input.getInterceptors());
- return rest;
- }
-
- /**
- * A special {@link RestTemplate} that knows about the {@link Type} of its response
- * body explicitly (rather than through a {@link ParameterizedTypeReference}, which is
- * the only way to access this feature in a regular template).
- *
- */
- class NestedTemplate extends RestTemplate {
- @Override
- protected RequestCallback httpEntityCallback(Object requestBody,
- Type responseType) {
- return super.httpEntityCallback(requestBody, responseType);
- }
-
- @Override
- protected ResponseExtractor> responseEntityExtractor(
- Type responseType) {
- return super.responseEntityExtractor(responseType);
- }
- }
-
- /**
- * A servlet request wrapper that can be safely passed downstream to an internal
- * forward dispatch, caching its body, and making it available in converted form using
- * Spring message converters.
- *
- */
- class BodyForwardingHttpServletRequest extends HttpServletRequestWrapper {
- private HttpServletRequest request;
- private HttpServletResponse response;
-
- BodyForwardingHttpServletRequest(HttpServletRequest request,
- HttpServletResponse response) {
- super(request);
- this.request = request;
- this.response = response;
- }
-
- private List header(String name) {
- List list = headers.get(name);
- return list;
- }
-
- @Override
- public ServletInputStream getInputStream() throws IOException {
- Object body = body();
- MethodParameter output = new MethodParameter(
- ClassUtils.getMethod(BodySender.class, "body"), -1);
- ServletOutputToInputConverter response = new ServletOutputToInputConverter(
- this.response);
- ServletWebRequest webRequest = new ServletWebRequest(this.request, response);
- try {
- delegate.handleReturnValue(body, output, mavContainer, webRequest);
- }
- catch (HttpMessageNotWritableException
- | HttpMediaTypeNotAcceptableException e) {
- throw new IllegalStateException("Cannot convert body", e);
- }
- return response.getInputStream();
- }
-
- @Override
- public Enumeration getHeaderNames() {
- Set names = headers.keySet();
- if (names.isEmpty()) {
- return super.getHeaderNames();
- }
- Set result = new LinkedHashSet<>(names);
- result.addAll(Collections.list(super.getHeaderNames()));
- return new Vector(result).elements();
- }
-
- @Override
- public Enumeration getHeaders(String name) {
- List list = header(name);
- if (list != null) {
- return new Vector(list).elements();
- }
- return super.getHeaders(name);
- }
-
- @Override
- public String getHeader(String name) {
- List list = header(name);
- if (list != null && !list.isEmpty()) {
- return list.iterator().next();
- }
- return super.getHeader(name);
- }
- }
-
- protected static class BodyGrabber {
- public Object body(@RequestBody Object body) {
- return body;
- }
- }
-
- protected static class BodySender {
- @ResponseBody
- public Object body() {
- return null;
- }
- }
-
-}
-
-/**
- * Convenience class that converts an incoming request input stream into a form that can
- * be easily deserialized to a Java object using Spring message converters. It is only
- * used in a local forward dispatch, in which case there is a danger that the request body
- * will need to be read and analysed more than once. Apart from using the message
- * converters the other main feature of this class is that the request body is cached and
- * can be read repeatedly as necessary.
- *
- * @author Dave Syer
- *
- */
-class ServletOutputToInputConverter extends HttpServletResponseWrapper {
-
- private StringBuilder builder = new StringBuilder();
-
- public ServletOutputToInputConverter(HttpServletResponse response) {
- super(response);
- }
-
- @Override
- public ServletOutputStream getOutputStream() throws IOException {
- return new ServletOutputStream() {
-
- @Override
- public void write(int b) throws IOException {
- builder.append(new Character((char) b));
- }
-
- @Override
- public void setWriteListener(WriteListener listener) {
- }
-
- @Override
- public boolean isReady() {
- return true;
- }
- };
- }
-
- public ServletInputStream getInputStream() {
- ByteArrayInputStream body = new ByteArrayInputStream(
- builder.toString().getBytes());
- return new ServletInputStream() {
-
- @Override
- public int read() throws IOException {
- return body.read();
- }
-
- @Override
- public void setReadListener(ReadListener listener) {
- }
-
- @Override
- public boolean isReady() {
- return true;
- }
-
- @Override
- public boolean isFinished() {
- return body.available() <= 0;
- }
- };
- }
-
-}
diff --git a/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyExchangeArgumentResolver.java b/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyExchangeArgumentResolver.java
deleted file mode 100644
index bc9e143be..000000000
--- a/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyExchangeArgumentResolver.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.cloud.function.gateway.config;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.util.Set;
-
-import org.springframework.cloud.function.gateway.ProxyExchange;
-import org.springframework.core.MethodParameter;
-import org.springframework.http.HttpHeaders;
-import org.springframework.web.bind.support.WebDataBinderFactory;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.context.request.NativeWebRequest;
-import org.springframework.web.method.support.HandlerMethodArgumentResolver;
-import org.springframework.web.method.support.ModelAndViewContainer;
-
-/**
- * @author Dave Syer
- *
- */
-public class ProxyExchangeArgumentResolver implements HandlerMethodArgumentResolver {
-
- private RestTemplate rest;
-
- private HttpHeaders headers;
-
- private Set sensitive;
-
- public ProxyExchangeArgumentResolver(RestTemplate builder) {
- this.rest = builder;
- }
-
- public void setHeaders(HttpHeaders headers) {
- this.headers = headers;
- }
-
- public void setSensitive(Set sensitive) {
- this.sensitive = sensitive;
- }
-
- @Override
- public boolean supportsParameter(MethodParameter parameter) {
- return ProxyExchange.class.isAssignableFrom(parameter.getParameterType());
- }
-
- @Override
- public Object resolveArgument(MethodParameter parameter,
- ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
- WebDataBinderFactory binderFactory) throws Exception {
- ProxyExchange> proxy = new ProxyExchange<>(rest, webRequest, mavContainer,
- binderFactory, type(parameter));
- proxy.headers(headers);
- if (sensitive != null) {
- proxy.sensitive(sensitive.toArray(new String[0]));
- }
- return proxy;
- }
-
- private Type type(MethodParameter parameter) {
- Type type = parameter.getGenericParameterType();
- if (type instanceof ParameterizedType) {
- ParameterizedType param = (ParameterizedType) type;
- type = param.getActualTypeArguments()[0];
- }
- return type;
- }
-
-}
diff --git a/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyProperties.java b/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyProperties.java
deleted file mode 100644
index 01419f35d..000000000
--- a/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyProperties.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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.cloud.function.gateway.config;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.cloud.function.gateway.ProxyExchange;
-import org.springframework.http.HttpHeaders;
-
-/**
- * Configuration properties for the {@link ProxyExchange} argument handler in
- * @RequestMapping methods.
- * @author Dave Syer
- *
- */
-@ConfigurationProperties("spring.cloud.gateway.proxy")
-public class ProxyProperties {
-
- /**
- * Fixed header values that will be added to all downstream requests.
- */
- private Map headers = new LinkedHashMap<>();
-
- /**
- * A set of sensitive header names that will not be sent downstream by default.
- */
- private Set sensitive = null;
-
- public Map getHeaders() {
- return headers;
- }
-
- public void setHeaders(Map headers) {
- this.headers = headers;
- }
-
- public Set getSensitive() {
- return sensitive;
- }
-
- public void setSensitive(Set sensitive) {
- this.sensitive = sensitive;
- }
-
- public HttpHeaders convertHeaders() {
- HttpHeaders headers = new HttpHeaders();
- for (String key : this.headers.keySet()) {
- headers.set(key, this.headers.get(key));
- }
- return headers;
- }
-
-}
diff --git a/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyResponseAutoConfiguration.java b/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyResponseAutoConfiguration.java
deleted file mode 100644
index ddfd07676..000000000
--- a/spring-cloud-function-gateway/src/main/java/org/springframework/cloud/function/gateway/config/ProxyResponseAutoConfiguration.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.cloud.function.gateway.config;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Optional;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.boot.web.client.RestTemplateBuilder;
-import org.springframework.cloud.function.gateway.ProxyExchange;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.http.client.ClientHttpResponse;
-import org.springframework.http.converter.ByteArrayHttpMessageConverter;
-import org.springframework.web.client.DefaultResponseErrorHandler;
-import org.springframework.web.client.RestTemplate;
-import org.springframework.web.method.support.HandlerMethodArgumentResolver;
-import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
-
-/**
- * Autoconfiguration for the {@link ProxyExchange} argument handler in Spring MVC
- * @RequestMapping methods.
- *
- * @author Dave Syer
- */
-@Configuration
-@ConditionalOnWebApplication
-@ConditionalOnClass({ HandlerMethodReturnValueHandler.class })
-@EnableConfigurationProperties(ProxyProperties.class)
-public class ProxyResponseAutoConfiguration extends WebMvcConfigurerAdapter {
-
- @Autowired
- private ApplicationContext context;
-
- @Bean
- @ConditionalOnMissingBean
- public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver(
- Optional optional, ProxyProperties proxy) {
- RestTemplateBuilder builder = optional.orElse(new RestTemplateBuilder());
- RestTemplate template = builder.build();
- template.setErrorHandler(new NoOpResponseErrorHandler());
- template.getMessageConverters().add(new ByteArrayHttpMessageConverter() {
- @Override
- public boolean supports(Class> clazz) {
- return true;
- }
- });
- ProxyExchangeArgumentResolver resolver = new ProxyExchangeArgumentResolver(
- template);
- resolver.setHeaders(proxy.convertHeaders());
- resolver.setSensitive(proxy.getSensitive()); // can be null
- return resolver;
- }
-
- @Override
- public void addArgumentResolvers(
- List argumentResolvers) {
- argumentResolvers.add(context.getBean(ProxyExchangeArgumentResolver.class));
- }
-
- private static class NoOpResponseErrorHandler extends DefaultResponseErrorHandler {
-
- @Override
- public void handleError(ClientHttpResponse response) throws IOException {
- }
-
- }
-}
diff --git a/spring-cloud-function-gateway/src/main/resources/META-INF/spring.factories b/spring-cloud-function-gateway/src/main/resources/META-INF/spring.factories
deleted file mode 100644
index 8a98f9330..000000000
--- a/spring-cloud-function-gateway/src/main/resources/META-INF/spring.factories
+++ /dev/null
@@ -1,5 +0,0 @@
-org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.springframework.cloud.function.gateway.config.ProxyResponseAutoConfiguration
-
-org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc=\
-org.springframework.cloud.function.gateway.config.ProxyResponseAutoConfiguration
diff --git a/spring-cloud-function-gateway/src/test/java/org/springframework/cloud/function/web/gateway/ProductionConfigurationTests.java b/spring-cloud-function-gateway/src/test/java/org/springframework/cloud/function/web/gateway/ProductionConfigurationTests.java
deleted file mode 100644
index ec2772920..000000000
--- a/spring-cloud-function-gateway/src/test/java/org/springframework/cloud/function/web/gateway/ProductionConfigurationTests.java
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- * 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.cloud.function.web.gateway;
-
-import java.net.URI;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.context.embedded.LocalServerPort;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
-import org.springframework.boot.test.web.client.TestRestTemplate;
-import org.springframework.cloud.function.gateway.ProxyExchange;
-import org.springframework.cloud.function.web.gateway.ProductionConfigurationTests.TestApplication;
-import org.springframework.cloud.function.web.gateway.ProductionConfigurationTests.TestApplication.Bar;
-import org.springframework.cloud.function.web.gateway.ProductionConfigurationTests.TestApplication.Foo;
-import org.springframework.core.ParameterizedTypeReference;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.RequestEntity;
-import org.springframework.http.ResponseEntity;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestHeader;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.util.UriComponentsBuilder;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
-@ContextConfiguration(classes = TestApplication.class)
-public class ProductionConfigurationTests {
-
- @Autowired
- private TestRestTemplate rest;
-
- @Autowired
- private TestApplication application;
-
- @LocalServerPort
- private int port;
-
- @Before
- public void init() throws Exception {
- application.setHome(new URI("http://localhost:" + port));
- }
-
- @Test
- public void get() throws Exception {
- assertThat(rest.getForObject("/proxy/0", Foo.class).getName()).isEqualTo("bye");
- }
-
- @Test
- public void path() throws Exception {
- assertThat(rest.getForObject("/proxy/path/1", Foo.class).getName())
- .isEqualTo("foo");
- }
-
- @Test
- public void resource() throws Exception {
- assertThat(rest.getForObject("/proxy/html/test.html", String.class))
- .contains("Test");
- }
-
- @Test
- public void resourceWithNoType() throws Exception {
- assertThat(rest.getForObject("/proxy/typeless/test.html", String.class))
- .contains("Test");
- }
-
- @Test
- public void missing() throws Exception {
- assertThat(rest.getForEntity("/proxy/missing/0", Foo.class).getStatusCode())
- .isEqualTo(HttpStatus.NOT_FOUND);
- }
-
- @Test
- public void uri() throws Exception {
- assertThat(rest.getForObject("/proxy/0", Foo.class).getName()).isEqualTo("bye");
- }
-
- @Test
- public void post() throws Exception {
- assertThat(rest.postForObject("/proxy/0", Collections.singletonMap("name", "foo"),
- Bar.class).getName()).isEqualTo("host=localhost;foo");
- }
-
- @Test
- public void forward() throws Exception {
- assertThat(rest.getForObject("/forward/foos/0", Foo.class).getName())
- .isEqualTo("bye");
- }
-
- @Test
- public void forwardHeader() throws Exception {
- ResponseEntity result = rest.getForEntity("/forward/special/foos/0",
- Foo.class);
- assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
- assertThat(result.getBody().getName()).isEqualTo("FOO");
- }
-
- @Test
- public void postForwardHeader() throws Exception {
- ResponseEntity> result = rest.exchange(
- RequestEntity
- .post(rest.getRestTemplate().getUriTemplateHandler().expand(
- "/forward/special/bars"))
- .body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
- new ParameterizedTypeReference>() {
- });
- assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
- assertThat(result.getBody().iterator().next().getName()).isEqualTo("FOOfoo");
- }
-
- @Test
- public void postForwardBody() throws Exception {
- ResponseEntity result = rest.exchange(
- RequestEntity
- .post(rest.getRestTemplate().getUriTemplateHandler().expand(
- "/forward/body/bars"))
- .body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
- String.class);
- assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
- assertThat(result.getBody()).contains("foo");
- }
-
- @Test
- public void postForwardForgetBody() throws Exception {
- ResponseEntity result = rest.exchange(
- RequestEntity
- .post(rest.getRestTemplate().getUriTemplateHandler().expand(
- "/forward/forget/bars"))
- .body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
- String.class);
- assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
- assertThat(result.getBody()).contains("foo");
- }
-
- @Test
- public void postForwardBodyFoo() throws Exception {
- ResponseEntity> result = rest.exchange(
- RequestEntity
- .post(rest.getRestTemplate().getUriTemplateHandler().expand(
- "/forward/body/bars"))
- .body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
- new ParameterizedTypeReference>() {
- });
- assertThat(result.getStatusCode()).isEqualTo(HttpStatus.OK);
- assertThat(result.getBody().iterator().next().getName()).isEqualTo("foo");
- }
-
- @Test
- public void list() throws Exception {
- assertThat(rest.exchange(
- RequestEntity
- .post(rest.getRestTemplate().getUriTemplateHandler().expand(
- "/proxy"))
- .body(Collections.singletonList(Collections.singletonMap("name", "foo"))),
- new ParameterizedTypeReference>() {
- }).getBody().iterator().next().getName()).isEqualTo("host=localhost;foo");
- }
-
- @Test
- public void bodyless() throws Exception {
- assertThat(rest.postForObject("/proxy/0", Collections.singletonMap("name", "foo"),
- Bar.class).getName()).isEqualTo("host=localhost;foo");
- }
-
- @Test
- public void entity() throws Exception {
- assertThat(rest.exchange(
- RequestEntity
- .post(rest.getRestTemplate().getUriTemplateHandler()
- .expand("/proxy/entity"))
- .body(Collections.singletonMap("name", "foo")),
- new ParameterizedTypeReference>() {
- }).getBody().iterator().next().getName()).isEqualTo("host=localhost;foo");
- }
-
- @Test
- public void entityWithType() throws Exception {
- assertThat(rest.exchange(
- RequestEntity
- .post(rest.getRestTemplate().getUriTemplateHandler()
- .expand("/proxy/type"))
- .body(Collections.singletonMap("name", "foo")),
- new ParameterizedTypeReference>() {
- }).getBody().iterator().next().getName()).isEqualTo("host=localhost;foo");
- }
-
- @Test
- public void single() throws Exception {
- assertThat(rest.postForObject("/proxy/single",
- Collections.singletonMap("name", "foobar"), Bar.class).getName())
- .isEqualTo("host=localhost;foobar");
- }
-
- @Test
- public void converter() throws Exception {
- assertThat(rest.postForObject("/proxy/converter",
- Collections.singletonMap("name", "foobar"), Bar.class).getName())
- .isEqualTo("host=localhost;foobar");
- }
-
- @SpringBootApplication
- static class TestApplication {
-
- @RestController
- static class ProxyController {
-
- private URI home;
-
- public void setHome(URI home) {
- this.home = home;
- }
-
- @GetMapping("/proxy/{id}")
- public ResponseEntity> proxyFoos(@PathVariable Integer id,
- ProxyExchange> proxy) throws Exception {
- return proxy.uri(home.toString() + "/foos/" + id).get();
- }
-
- @GetMapping("/proxy/path/**")
- public ResponseEntity> proxyPath(ProxyExchange> proxy,
- UriComponentsBuilder uri) throws Exception {
- String path = proxy.path("/proxy/path/");
- return proxy.uri(home.toString() + "/foos/" + path).get();
- }
-
- @GetMapping("/proxy/html/**")
- public ResponseEntity proxyHtml(ProxyExchange proxy,
- UriComponentsBuilder uri) throws Exception {
- String path = proxy.path("/proxy/html");
- return proxy.uri(home.toString() + path).get();
- }
-
- @GetMapping("/proxy/typeless/**")
- public ResponseEntity> proxyTypeless(ProxyExchange> proxy,
- UriComponentsBuilder uri) throws Exception {
- String path = proxy.path("/proxy/typeless");
- return proxy.uri(home.toString() + path).get();
- }
-
- @GetMapping("/proxy/missing/{id}")
- public ResponseEntity> proxyMissing(@PathVariable Integer id,
- ProxyExchange> proxy) throws Exception {
- return proxy.uri(home.toString() + "/missing/" + id).get();
- }
-
- @GetMapping("/proxy")
- public ResponseEntity> proxyUri(ProxyExchange> proxy) throws Exception {
- return proxy.uri(home.toString() + "/foos").get();
- }
-
- @PostMapping("/proxy/{id}")
- public ResponseEntity> proxyBars(@PathVariable Integer id,
- @RequestBody Map body,
- ProxyExchange> proxy) throws Exception {
- body.put("id", id);
- return proxy.uri(home.toString() + "/bars").body(Arrays.asList(body))
- .post(this::first);
- }
-
- @PostMapping("/proxy")
- public ResponseEntity> barsWithNoBody(ProxyExchange> proxy)
- throws Exception {
- return proxy.uri(home.toString() + "/bars").post();
- }
-
- @PostMapping("/proxy/entity")
- public ResponseEntity> explicitEntity(@RequestBody Foo foo,
- ProxyExchange> proxy) throws Exception {
- return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
- .post();
- }
-
- @PostMapping("/proxy/type")
- public ResponseEntity> explicitEntityWithType(@RequestBody Foo foo,
- ProxyExchange> proxy) throws Exception {
- return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
- .post();
- }
-
- @PostMapping("/proxy/single")
- public ResponseEntity> implicitEntity(@RequestBody Foo foo,
- ProxyExchange> proxy) throws Exception {
- return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
- .post(this::first);
- }
-
- @PostMapping("/proxy/converter")
- public ResponseEntity implicitEntityWithConverter(@RequestBody Foo foo,
- ProxyExchange> proxy) throws Exception {
- return proxy.uri(home.toString() + "/bars").body(Arrays.asList(foo))
- .post(response -> ResponseEntity.status(response.getStatusCode())
- .headers(response.getHeaders())
- .body(response.getBody().iterator().next()));
- }
-
- @GetMapping("/forward/**")
- public void forward(ProxyExchange> proxy) throws Exception {
- String path = proxy.path("/forward");
- if (path.startsWith("/special")) {
- proxy.header("X-Custom", "FOO");
- path = proxy.path("/forward/special");
- }
- proxy.forward(path);
- }
-
- @PostMapping("/forward/**")
- public void postForward(ProxyExchange> proxy) throws Exception {
- String path = proxy.path("/forward");
- if (path.startsWith("/special")) {
- proxy.header("X-Custom", "FOO");
- path = proxy.path("/forward/special");
- }
- proxy.forward(path);
- }
-
- @PostMapping("/forward/body/**")
- public void postForwardBody(@RequestBody byte[] body, ProxyExchange> proxy)
- throws Exception {
- String path = proxy.path("/forward/body");
- proxy.body(body).forward(path);
- }
-
- @PostMapping("/forward/forget/**")
- public void postForwardForgetBody(@RequestBody byte[] body,
- ProxyExchange> proxy) throws Exception {
- String path = proxy.path("/forward/forget");
- proxy.forward(path);
- }
-
- private ResponseEntity first(ResponseEntity> response) {
- return ResponseEntity.status(response.getStatusCode())
- .headers(response.getHeaders())
- .body(response.getBody().iterator().next());
- }
-
- }
-
- @Autowired
- private ProxyController controller;
-
- public void setHome(URI home) {
- controller.setHome(home);
- }
-
- @RestController
- static class TestController {
-
- @GetMapping("/foos")
- public List foos() {
- return Arrays.asList(new Foo("hello"));
- }
-
- @GetMapping("/foos/{id}")
- public Foo foo(@PathVariable Integer id, @RequestHeader HttpHeaders headers) {
- String custom = headers.getFirst("X-Custom");
- return new Foo(id == 1 ? "foo" : custom != null ? custom : "bye");
- }
-
- @PostMapping("/bars")
- public List bars(@RequestBody List foos,
- @RequestHeader HttpHeaders headers) {
- String custom = headers.getFirst("X-Custom");
- custom = custom == null ? "" : custom;
- custom = headers.getFirst("forwarded")==null ? custom : headers.getFirst("forwarded") + ";" + custom;
- return Arrays.asList(new Bar(custom + foos.iterator().next().getName()));
- }
-
- }
-
- @JsonIgnoreProperties(ignoreUnknown = true)
- static class Foo {
- private String name;
-
- public Foo() {
- }
-
- public Foo(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }
-
- @JsonIgnoreProperties(ignoreUnknown = true)
- static class Bar {
- private String name;
-
- public Bar() {
- }
-
- public Bar(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/spring-cloud-function-gateway/src/test/resources/static/test.html b/spring-cloud-function-gateway/src/test/resources/static/test.html
deleted file mode 100644
index 0cfed139f..000000000
--- a/spring-cloud-function-gateway/src/test/resources/static/test.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-Test
-
-
\ No newline at end of file