Removes most deprecated items.

This commit is contained in:
spencergibb
2025-06-13 15:17:37 -04:00
parent 4e2cd48b20
commit 17ea1148b1
45 changed files with 18 additions and 3546 deletions

View File

@@ -46,7 +46,6 @@ import jakarta.servlet.http.HttpServletRequestWrapper;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import org.springframework.cloud.gateway.mvc.config.ProxyProperties;
import org.springframework.core.Conventions;
import org.springframework.core.MethodParameter;
import org.springframework.core.ParameterizedTypeReference;
@@ -139,12 +138,6 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBody
*/
public class ProxyExchange<T> {
/**
* Contains headers that are considered case-sensitive by default.
* @deprecated {@link ProxyProperties#DEFAULT_SENSITIVE}
*/
public static Set<String> DEFAULT_SENSITIVE = ProxyProperties.DEFAULT_SENSITIVE;
private URI uri;
private RestTemplate rest;
@@ -211,17 +204,6 @@ public class ProxyExchange<T> {
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
* @deprecated {@link #excluded(String...)}
*/
public ProxyExchange<T> sensitive(String... names) {
return excluded(names);
}
/**
* Sets the names of excluded headers that are not passed downstream to the backend
* service.

View File

@@ -64,11 +64,6 @@ public class ProxyExchangeArgumentResolver implements HandlerMethodArgumentResol
: autoForwardedHeaders.stream().map(String::toLowerCase).collect(toSet());
}
@Deprecated
public void setSensitive(Set<String> excluded) {
setExcluded(excluded);
}
public void setExcluded(Set<String> excluded) {
this.excluded = excluded;
}

View File

@@ -1,119 +0,0 @@
/*
* Copyright 2016-2019 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
*
* https://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.gateway.mvc.config;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.cloud.gateway.mvc.ProxyExchange;
import org.springframework.http.HttpHeaders;
/**
* Configuration properties for the {@link ProxyExchange} argument handler in
* <code>@RequestMapping</code> methods.
*
* @author Dave Syer
* @author Tim Ysewyn
* @author Joris Kuipers
* @author Spencer Gibb
* @deprecated {@link ProxyExchangeWebMvcProperties}
*/
@Deprecated
@ConfigurationProperties("spring.cloud.gateway.proxy")
public class ProxyProperties {
/**
* Contains headers that are considered case-sensitive by default.
*/
public static Set<String> DEFAULT_SENSITIVE = Set.of("cookie", "authorization");
/**
* Contains headers that are skipped by default.
*/
public static Set<String> DEFAULT_SKIPPED = Set.of("content-length", "host");
/**
* Fixed header values that will be added to all downstream requests.
*/
private Map<String, String> headers = new LinkedHashMap<>();
/**
* A set of header names that should be sent downstream by default.
*/
private Set<String> autoForward = new HashSet<>();
/**
* A set of sensitive header names that will not be sent downstream by default.
*/
private Set<String> sensitive = DEFAULT_SENSITIVE;
/**
* A set of header names that will not be sent downstream because they could be
* problematic.
*/
private Set<String> skipped = DEFAULT_SKIPPED;
@DeprecatedConfigurationProperty(replacement = ProxyExchangeWebMvcProperties.PREFIX + ".headers", since = "4.3.0")
public Map<String, String> getHeaders() {
return headers;
}
public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}
@DeprecatedConfigurationProperty(replacement = ProxyExchangeWebMvcProperties.PREFIX + ".auto-forward",
since = "4.3.0")
public Set<String> getAutoForward() {
return autoForward;
}
public void setAutoForward(Set<String> autoForward) {
this.autoForward = autoForward;
}
@DeprecatedConfigurationProperty(replacement = ProxyExchangeWebMvcProperties.PREFIX + ".sensitive", since = "4.3.0")
public Set<String> getSensitive() {
return sensitive;
}
public void setSensitive(Set<String> sensitive) {
this.sensitive = sensitive;
}
@DeprecatedConfigurationProperty(replacement = ProxyExchangeWebMvcProperties.PREFIX + ".skipped", since = "4.3.0")
public Set<String> getSkipped() {
return skipped;
}
public void setSkipped(Set<String> skipped) {
this.skipped = skipped;
}
public HttpHeaders convertHeaders() {
HttpHeaders headers = new HttpHeaders();
for (String key : this.headers.keySet()) {
headers.set(key, this.headers.get(key));
}
return headers;
}
}

View File

@@ -58,7 +58,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@ConditionalOnClass({ HandlerMethodReturnValueHandler.class })
@EnableConfigurationProperties({ ProxyExchangeWebMvcProperties.class, ProxyProperties.class })
@EnableConfigurationProperties({ ProxyExchangeWebMvcProperties.class })
public class ProxyResponseAutoConfiguration implements WebMvcConfigurer {
@Autowired

View File

@@ -33,7 +33,7 @@ import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.gateway.mvc.GetWithBodyRequestTests.TestApplication.Foo;
import org.springframework.cloud.gateway.mvc.config.ProxyExchangeArgumentResolver;
import org.springframework.cloud.gateway.mvc.config.ProxyProperties;
import org.springframework.cloud.gateway.mvc.config.ProxyExchangeWebMvcProperties;
import org.springframework.cloud.gateway.mvc.http.GetWithBodyRequestClientHttpRequestFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
@@ -108,7 +108,7 @@ public class GetWithBodyRequestTests {
}
@Bean
public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver(final ProxyProperties proxy) {
public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver(final ProxyExchangeWebMvcProperties proxy) {
ProxyExchangeArgumentResolver resolver = new ProxyExchangeArgumentResolver(
generateConfiguredRestTemplate());
resolver.setHeaders(proxy.convertHeaders());

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2013-2025 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
*
* https://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.gateway.mvc.config;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("unchecked")
@SpringBootTest(properties = {}, webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("propertiesmigrationtests")
public class ProxyExchangeWebmvcPropertiesMigrationTests {
@Autowired
ProxyExchangeWebMvcProperties properties;
@Test
public void deprecatedRoutePropertiesWork() {
assertThat(properties.getHeaders()).hasSize(2);
assertThat(properties.getAutoForward()).hasSize(2);
assertThat(properties.getSensitive()).hasSize(2);
assertThat(properties.getSkipped()).hasSize(3);
}
@SpringBootConfiguration
@EnableAutoConfiguration
protected static class TestConfiguration {
}
}

View File

@@ -16,7 +16,6 @@
package org.springframework.cloud.gateway.server.mvc.config;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
@@ -26,7 +25,6 @@ import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.core.style.ToStringCreator;
import org.springframework.http.MediaType;
@@ -52,8 +50,6 @@ public class GatewayMvcProperties {
@Valid
private LinkedHashMap<String, RouteProperties> routesMap = new LinkedHashMap<>();
private HttpClient httpClient = new HttpClient();
/**
* Mime-types that are streaming.
*/
@@ -88,10 +84,6 @@ public class GatewayMvcProperties {
this.routesMap = routesMap;
}
public HttpClient getHttpClient() {
return httpClient;
}
public List<MediaType> getStreamingMediaTypes() {
return streamingMediaTypes;
}
@@ -118,8 +110,7 @@ public class GatewayMvcProperties {
@Override
public String toString() {
return new ToStringCreator(this).append("httpClient", httpClient)
.append("routes", routes)
return new ToStringCreator(this).append("routes", routes)
.append("routesMap", routesMap)
.append("streamingMediaTypes", streamingMediaTypes)
.append("streamingBufferSize", streamingBufferSize)
@@ -127,86 +118,4 @@ public class GatewayMvcProperties {
.toString();
}
/**
* @deprecated in favor of spring.http.client.
*/
@Deprecated
public static class HttpClient {
/** The HttpClient connect timeout. */
private Duration connectTimeout;
/** The HttpClient read timeout. */
private Duration readTimeout;
/** The name of the SSL bundle to use. */
private String sslBundle;
/** The HttpClient type. Defaults to JDK. */
private HttpClientType type = HttpClientType.JDK;
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.http.client.connect-timeout", since = "4.2.0")
public Duration getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(Duration connectTimeout) {
this.connectTimeout = connectTimeout;
}
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.http.client.read-timeout", since = "4.2.0")
public Duration getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(Duration readTimeout) {
this.readTimeout = readTimeout;
}
@Deprecated
@DeprecatedConfigurationProperty(replacement = "spring.http.client.ssl.bundle", since = "4.2.0")
public String getSslBundle() {
return sslBundle;
}
public void setSslBundle(String sslBundle) {
this.sslBundle = sslBundle;
}
@Deprecated
public HttpClientType getType() {
return type;
}
public void setType(HttpClientType type) {
this.type = type;
}
@Override
public String toString() {
return new ToStringCreator(this).append("connectTimeout", connectTimeout)
.append("readTimeout", readTimeout)
.append("sslBundle", sslBundle)
.append("type", type)
.toString();
}
}
public enum HttpClientType {
/**
* Use JDK HttpClient.
*/
JDK,
/**
* Auto-detect the HttpClient.
*/
AUTODETECT
}
}

View File

@@ -1,189 +0,0 @@
/*
* Copyright 2013-2025 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
*
* https://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.gateway.server.mvc.config;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.SpringApplicationEvent;
import org.springframework.boot.context.properties.source.ConfigurationProperty;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.boot.context.properties.source.IterableConfigurationPropertySource;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.OriginTrackedValue;
import org.springframework.boot.origin.PropertySourceOrigin;
import org.springframework.boot.origin.TextResourceOrigin;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap;
class GatewayServerWebMvcPropertiesMigrationListener implements ApplicationListener<SpringApplicationEvent> {
private static final Log logger = LogFactory.getLog(GatewayServerWebMvcPropertiesMigrationListener.class);
private static final String PROPERTIES_MIGRATOR_CLASS = "org.springframework.boot.context.properties.migrator.PropertiesMigrationListener";
private static final String DEPRECATED_ROOT = "spring.cloud.gateway.mvc";
private static final String DEPRECATED_ROUTES_LIST_KEY = DEPRECATED_ROOT + ".routes";
private static final String DEPRECATED_ROUTES_MAP_KEY = DEPRECATED_ROOT + ".routes-map";
private static final String GATEWAY_PROPERTY_SOURCE_PREFIX = "migrategatewaymvc";
private static final String NEW_ROUTES_LIST_KEY = GatewayMvcProperties.PREFIX + ".routes";
private static final String NEW_ROUTES_MAP_KEY = GatewayMvcProperties.PREFIX + ".routes-map";
private final List<Migration> routesMigrations = new ArrayList<>();
@Override
public void onApplicationEvent(SpringApplicationEvent event) {
// only run if spring-boot-properties-migrator is on the classpath
if (!ClassUtils.isPresent(PROPERTIES_MIGRATOR_CLASS, null)) {
return;
}
if (event instanceof ApplicationPreparedEvent preparedEvent) {
onApplicationPreparedEvent(preparedEvent);
}
if (event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent) {
logLegacyPropertiesReport();
}
}
private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
// find deprecated keys
ConfigurableEnvironment env = event.getApplicationContext().getEnvironment();
ConfigurationPropertySources.get(env).forEach(propertySource -> {
routesMigrations.addAll(migrate(env, propertySource, GATEWAY_PROPERTY_SOURCE_PREFIX + "routes-",
DEPRECATED_ROUTES_LIST_KEY, NEW_ROUTES_LIST_KEY));
routesMigrations.addAll(migrate(env, propertySource, GATEWAY_PROPERTY_SOURCE_PREFIX + "routes-map-",
DEPRECATED_ROUTES_MAP_KEY, NEW_ROUTES_MAP_KEY));
});
}
private List<Migration> migrate(ConfigurableEnvironment env, ConfigurationPropertySource propertySource,
String propertySourcePrefix, String deprecatedKey, String newKeyPrefix) {
List<Migration> migrations = new ArrayList<>();
if (propertySource instanceof IterableConfigurationPropertySource iterableSource) {
ConfigurationPropertyName routesParentName = ConfigurationPropertyName.of(deprecatedKey);
List<ConfigurationPropertyName> matchingConfigProps = iterableSource.filter(n -> {
if (n.getNumberOfElements() < routesParentName.getNumberOfElements()) {
return false;
}
ConfigurationPropertyName chop = n.chop(routesParentName.getNumberOfElements());
return routesParentName.equals(chop);
}).stream().toList();
if (!matchingConfigProps.isEmpty()) {
String originalPropertySourceName;
if (propertySource.getUnderlyingSource() instanceof PropertySource<?> underlyingSource) {
originalPropertySourceName = underlyingSource.getName();
}
else {
originalPropertySourceName = propertySource.getUnderlyingSource().toString();
}
String newPropertySourceName = propertySourcePrefix + originalPropertySourceName;
Map<String, OriginTrackedValue> content = new LinkedHashMap<>();
// migrate to new keys
for (ConfigurationPropertyName originalPropertyName : matchingConfigProps) {
ConfigurationPropertyName suffix = originalPropertyName
.subName(routesParentName.getNumberOfElements());
ConfigurationPropertyName newProperty = ConfigurationPropertyName.of(newKeyPrefix).append(suffix);
ConfigurationProperty configurationProperty = propertySource
.getConfigurationProperty(originalPropertyName);
Object value = configurationProperty.getValue();
OriginTrackedValue originTrackedValue = OriginTrackedValue.of(value,
configurationProperty.getOrigin());
content.put(newProperty.toString(), originTrackedValue);
migrations.add(new Migration(originalPropertySourceName, originalPropertyName,
configurationProperty, newProperty));
}
env.getPropertySources()
.addBefore(originalPropertySourceName,
new OriginTrackedMapPropertySource(newPropertySourceName, content));
}
}
return migrations;
}
private void logLegacyPropertiesReport() {
// log warnings
if (!routesMigrations.isEmpty()) {
LinkedMultiValueMap<String, Migration> content = new LinkedMultiValueMap<>();
routesMigrations.forEach(migration -> content.add(migration.originalPropertySourceName(), migration));
StringBuilder report = new StringBuilder();
report.append(String
.format("%nThe use of configuration keys that have been renamed was found in the environment:%n%n"));
content.forEach((name, properties) -> {
report.append(String.format("Property source '%s':%n", name));
// properties.sort(PropertyMigration.COMPARATOR);
properties.forEach((property) -> {
ConfigurationPropertyName originalPropertyName = property.originalPropertyName();
report.append(String.format("\tKey: %s%n", originalPropertyName));
Integer lineNumber = property.determineLineNumber();
if (lineNumber != null) {
report.append(String.format("\t\tLine: %d%n", lineNumber));
}
report.append(String.format("\t\tReplacement: %s%n", property.newProperty().toString()));
});
report.append(String.format("%n"));
});
report.append(String.format("%n"));
report.append("Each configuration key has been temporarily mapped to its "
+ "replacement for your convenience. To silence this warning, please "
+ "update your configuration to use the new keys.");
report.append(String.format("%n"));
logger.warn(report.toString());
}
}
private record Migration(String originalPropertySourceName, ConfigurationPropertyName originalPropertyName,
ConfigurationProperty originalProperty, ConfigurationPropertyName newProperty) {
private Integer determineLineNumber() {
Origin origin = originalProperty.getOrigin();
if (origin instanceof PropertySourceOrigin propertySourceOrigin) {
origin = propertySourceOrigin.getOrigin();
}
if (origin instanceof TextResourceOrigin textOrigin) {
if (textOrigin.getLocation() != null) {
return textOrigin.getLocation().getLine() + 1;
}
}
return null;
}
}
}

View File

@@ -120,11 +120,6 @@ public class RouterFunctionHolderFactory {
private final ConversionService conversionService;
@Deprecated
public RouterFunctionHolderFactory(Environment env) {
this(env, null, null, null);
}
public RouterFunctionHolderFactory(Environment env, BeanFactory beanFactory,
FilterBeanFactoryDiscoverer filterBeanFactoryDiscoverer,
PredicateBeanFactoryDiscoverer predicateBeanFactoryDiscoverer) {

View File

@@ -33,12 +33,6 @@ public class ClientHttpRequestFactoryProxyExchange extends AbstractProxyExchange
private final ClientHttpRequestFactory requestFactory;
@Deprecated
public ClientHttpRequestFactoryProxyExchange(ClientHttpRequestFactory requestFactory) {
super(new GatewayMvcProperties());
this.requestFactory = requestFactory;
}
public ClientHttpRequestFactoryProxyExchange(ClientHttpRequestFactory requestFactory,
GatewayMvcProperties properties) {
super(properties);

View File

@@ -41,12 +41,6 @@ public class HandlerDiscoverer extends AbstractGatewayDiscoverer {
private final List<HandlerFilterFunction<ServerResponse, ServerResponse>> higherPrecedenceFilters;
@Deprecated
public Result(HandlerFunction<ServerResponse> handlerFunction,
List<HandlerFilterFunction<ServerResponse, ServerResponse>> filters) {
this(handlerFunction, Collections.emptyList(), filters);
}
public Result(HandlerFunction<ServerResponse> handlerFunction,
List<HandlerFilterFunction<ServerResponse, ServerResponse>> lowerPrecedenceFilters,
List<HandlerFilterFunction<ServerResponse, ServerResponse>> higherPrecedenceFilters) {
@@ -59,11 +53,6 @@ public class HandlerDiscoverer extends AbstractGatewayDiscoverer {
return handlerFunction;
}
@Deprecated
public List<HandlerFilterFunction<ServerResponse, ServerResponse>> getFilters() {
return getHigherPrecedenceFilters();
}
public List<HandlerFilterFunction<ServerResponse, ServerResponse>> getLowerPrecedenceFilters() {
return lowerPrecedenceFilters;
}

View File

@@ -17,9 +17,6 @@
package org.springframework.cloud.gateway.server.mvc.handler;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -140,23 +137,6 @@ public abstract class HandlerFunctions {
});
}
// TODO: current discovery only goes by method name
// so last one wins, so put parameterless last
@Deprecated
public static HandlerFunction<ServerResponse> http(String uri) {
return http(URI.create(uri));
}
@Deprecated
public static HandlerFunction<ServerResponse> http(URI uri) {
return new LookupProxyExchangeHandlerFunction(uri);
}
@Deprecated
public static HandlerFunction<ServerResponse> https(URI uri) {
return new LookupProxyExchangeHandlerFunction(uri);
}
public static HandlerFunction<ServerResponse> https() {
return http();
}
@@ -171,26 +151,10 @@ public abstract class HandlerFunctions {
static class LookupProxyExchangeHandlerFunction implements HandlerFunction<ServerResponse> {
@Deprecated
private final URI uri;
private AtomicReference<ProxyExchangeHandlerFunction> proxyExchangeHandlerFunction = new AtomicReference<>();
LookupProxyExchangeHandlerFunction() {
this.uri = null;
}
@Deprecated
LookupProxyExchangeHandlerFunction(URI uri) {
this.uri = uri;
}
@Override
public ServerResponse handle(ServerRequest serverRequest) {
if (uri != null) {
// TODO: log warning of deprecated usage
MvcUtils.setRequestUrl(serverRequest, uri);
}
return proxyExchangeHandlerFunction.updateAndGet(function -> {
if (function == null) {
return lookup(serverRequest);
@@ -214,15 +178,4 @@ public abstract class HandlerFunctions {
}
@Deprecated
public static class HandlerSupplier
implements org.springframework.cloud.gateway.server.mvc.handler.HandlerSupplier {
@Override
public Collection<Method> get() {
return Collections.emptyList();
}
}
}

View File

@@ -33,12 +33,6 @@ public class RestClientProxyExchange extends AbstractProxyExchange {
private final RestClient restClient;
@Deprecated
public RestClientProxyExchange(RestClient restClient) {
super(new GatewayMvcProperties());
this.restClient = restClient;
}
public RestClientProxyExchange(RestClient restClient, GatewayMvcProperties properties) {
super(properties);
this.restClient = restClient;

View File

@@ -17,8 +17,4 @@
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.cloud.gateway.server.mvc.GatewayServerMvcAutoConfiguration.GatewayHttpClientEnvironmentPostProcessor,\
org.springframework.cloud.gateway.server.mvc.common.MultipartEnvironmentPostProcessor
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.cloud.gateway.server.mvc.config.GatewayServerWebMvcPropertiesMigrationListener
org.springframework.cloud.gateway.server.mvc.common.MultipartEnvironmentPostProcessor

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2013-2023 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
*
* https://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.gateway.server.mvc;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.gateway.server.mvc.config.GatewayMvcProperties;
import org.springframework.cloud.gateway.server.mvc.filter.FormFilter;
import org.springframework.cloud.gateway.server.mvc.filter.ForwardedRequestHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.RemoveContentLengthRequestHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.RemoveHopByHopRequestHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.RemoveHopByHopResponseHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.RemoveHttp2StatusResponseHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.TransferEncodingNormalizationRequestHeadersFilter;
import org.springframework.cloud.gateway.server.mvc.filter.WeightCalculatorFilter;
import org.springframework.cloud.gateway.server.mvc.filter.XForwardedRequestHeadersFilter;
import org.springframework.context.ApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("unchecked")
@SpringBootTest(properties = {}, webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("propertiesmigrationtests")
public class GatewayMvcPropertiesMigrationTests {
@Autowired
ApplicationContext context;
@Autowired
GatewayMvcProperties properties;
@SuppressWarnings("rawtypes")
@Test
public void deprecatedFilterEnabledPropertiesWork() {
assertBeanDoesNotExist(FormFilter.class);
assertBeanDoesNotExist(ForwardedRequestHeadersFilter.class);
assertBeanDoesNotExist(RemoveContentLengthRequestHeadersFilter.class);
assertBeanDoesNotExist(RemoveHopByHopRequestHeadersFilter.class);
assertBeanDoesNotExist(RemoveHopByHopResponseHeadersFilter.class);
assertBeanDoesNotExist(RemoveHttp2StatusResponseHeadersFilter.class);
assertBeanDoesNotExist(TransferEncodingNormalizationRequestHeadersFilter.class);
assertBeanDoesNotExist(WeightCalculatorFilter.class);
assertBeanDoesNotExist(XForwardedRequestHeadersFilter.class);
}
@Test
public void deprecatedRoutePropertiesWork() {
assertThat(properties.getRoutes()).hasSize(2);
assertThat(properties.getRoutesMap()).hasSize(2);
}
@Test
public void deprecatedStreamingMediaTypesWork() {
assertThat(properties.getStreamingMediaTypes()).hasSize(1)
.containsOnly(new MediaType("application", "activemessage"));
}
private void assertBeanDoesNotExist(Class<?> type) {
assertThat(context.getBeanNamesForType(type)).isEmpty();
}
@SpringBootConfiguration
@EnableAutoConfiguration
protected static class TestConfiguration {
}
}

View File

@@ -181,16 +181,6 @@ public class ExchangeResult {
return this.response.getStatusCode();
}
/**
* Return the HTTP status code as an integer.
* @since 5.1.10
* @deprecated as of 6.0, in favor of {@link #getStatus()}
*/
@Deprecated(since = "6.0", forRemoval = true)
public int getRawStatusCode() {
return getStatus().value();
}
/**
* Return the response headers received from the server.
*/

View File

@@ -1,7 +1,7 @@
spring:
cloud:
gateway:
mvc:
server.webmvc:
routes:
- id: test
uri: lb://httpbin

View File

@@ -92,15 +92,6 @@ public class AbstractGatewayControllerEndpoint implements ApplicationEventPublis
private final SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory();
@Deprecated
public AbstractGatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator,
List<GlobalFilter> globalFilters, List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> routePredicates, RouteDefinitionWriter routeDefinitionWriter,
RouteLocator routeLocator) {
this(routeDefinitionLocator, globalFilters, gatewayFilters, routePredicates, routeDefinitionWriter,
routeLocator, new WebEndpointProperties());
}
public AbstractGatewayControllerEndpoint(RouteDefinitionLocator routeDefinitionLocator,
List<GlobalFilter> globalFilters, List<GatewayFilterFactory> gatewayFilters,
List<RoutePredicateFactory> routePredicates, RouteDefinitionWriter routeDefinitionWriter,

View File

@@ -213,16 +213,6 @@ public class GatewayAutoConfiguration {
return new StringToZonedDateTimeConverter();
}
/**
* @deprecated in favour of
* {@link org.springframework.cloud.gateway.support.config.KeyValueConverter}
*/
@Deprecated
@Bean
public org.springframework.cloud.gateway.support.KeyValueConverter deprecatedKeyValueConverter() {
return new org.springframework.cloud.gateway.support.KeyValueConverter();
}
@Bean
public KeyValueConverter keyValueConverter() {
return new KeyValueConverter();

View File

@@ -1,189 +0,0 @@
/*
* Copyright 2013-2025 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
*
* https://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.gateway.config;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.boot.context.event.ApplicationFailedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.event.SpringApplicationEvent;
import org.springframework.boot.context.properties.source.ConfigurationProperty;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
import org.springframework.boot.context.properties.source.IterableConfigurationPropertySource;
import org.springframework.boot.env.OriginTrackedMapPropertySource;
import org.springframework.boot.origin.Origin;
import org.springframework.boot.origin.OriginTrackedValue;
import org.springframework.boot.origin.PropertySourceOrigin;
import org.springframework.boot.origin.TextResourceOrigin;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.util.ClassUtils;
import org.springframework.util.LinkedMultiValueMap;
class GatewayServerWebfluxPropertiesMigrationListener implements ApplicationListener<SpringApplicationEvent> {
private static final Log logger = LogFactory.getLog(GatewayServerWebfluxPropertiesMigrationListener.class);
private static final String PROPERTIES_MIGRATOR_CLASS = "org.springframework.boot.context.properties.migrator.PropertiesMigrationListener";
private static final String DEPRECATED_ROOT = "spring.cloud.gateway";
private static final String DEPRECATED_ROUTES_LIST_KEY = DEPRECATED_ROOT + ".routes";
private static final String DEPRECATED_DEFAULT_FILTERS_KEY = DEPRECATED_ROOT + ".default-filters";
private static final String GATEWAY_PROPERTY_SOURCE_PREFIX = "migrategatewayflux";
private static final String NEW_ROUTES_LIST_KEY = GatewayProperties.PREFIX + ".routes";
private static final String NEW_DEFAULT_FILTERS_KEY = GatewayProperties.PREFIX + ".default-filters";
private final List<Migration> routesMigrations = new ArrayList<>();
@Override
public void onApplicationEvent(SpringApplicationEvent event) {
// only run if spring-boot-properties-migrator is on the classpath
if (!ClassUtils.isPresent(PROPERTIES_MIGRATOR_CLASS, null)) {
return;
}
if (event instanceof ApplicationPreparedEvent preparedEvent) {
onApplicationPreparedEvent(preparedEvent);
}
if (event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent) {
logLegacyPropertiesReport();
}
}
private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
// find deprecated keys
ConfigurableEnvironment env = event.getApplicationContext().getEnvironment();
ConfigurationPropertySources.get(env).forEach(propertySource -> {
routesMigrations.addAll(migrate(env, propertySource, GATEWAY_PROPERTY_SOURCE_PREFIX + "routes-",
DEPRECATED_ROUTES_LIST_KEY, NEW_ROUTES_LIST_KEY));
routesMigrations.addAll(migrate(env, propertySource, GATEWAY_PROPERTY_SOURCE_PREFIX + "default-filters-",
DEPRECATED_DEFAULT_FILTERS_KEY, NEW_DEFAULT_FILTERS_KEY));
});
}
private List<Migration> migrate(ConfigurableEnvironment env, ConfigurationPropertySource propertySource,
String propertySourcePrefix, String deprecatedKey, String newKeyPrefix) {
List<Migration> migrations = new ArrayList<>();
if (propertySource instanceof IterableConfigurationPropertySource iterableSource) {
ConfigurationPropertyName routesParentName = ConfigurationPropertyName.of(deprecatedKey);
List<ConfigurationPropertyName> matchingConfigProps = iterableSource.filter(n -> {
if (n.getNumberOfElements() < routesParentName.getNumberOfElements()) {
return false;
}
ConfigurationPropertyName chop = n.chop(routesParentName.getNumberOfElements());
return routesParentName.equals(chop);
}).stream().toList();
if (!matchingConfigProps.isEmpty()) {
String originalPropertySourceName;
if (propertySource.getUnderlyingSource() instanceof PropertySource<?> underlyingSource) {
originalPropertySourceName = underlyingSource.getName();
}
else {
originalPropertySourceName = propertySource.getUnderlyingSource().toString();
}
String newPropertySourceName = propertySourcePrefix + originalPropertySourceName;
Map<String, OriginTrackedValue> content = new LinkedHashMap<>();
// migrate to new keys
for (ConfigurationPropertyName originalPropertyName : matchingConfigProps) {
ConfigurationPropertyName suffix = originalPropertyName
.subName(routesParentName.getNumberOfElements());
ConfigurationPropertyName newProperty = ConfigurationPropertyName.of(newKeyPrefix).append(suffix);
ConfigurationProperty configurationProperty = propertySource
.getConfigurationProperty(originalPropertyName);
Object value = configurationProperty.getValue();
OriginTrackedValue originTrackedValue = OriginTrackedValue.of(value,
configurationProperty.getOrigin());
content.put(newProperty.toString(), originTrackedValue);
migrations.add(new Migration(originalPropertySourceName, originalPropertyName,
configurationProperty, newProperty));
}
env.getPropertySources()
.addBefore(originalPropertySourceName,
new OriginTrackedMapPropertySource(newPropertySourceName, content));
}
}
return migrations;
}
private void logLegacyPropertiesReport() {
// log warnings
if (!routesMigrations.isEmpty()) {
LinkedMultiValueMap<String, Migration> content = new LinkedMultiValueMap<>();
routesMigrations.forEach(migration -> content.add(migration.originalPropertySourceName(), migration));
StringBuilder report = new StringBuilder();
report.append(String
.format("%nThe use of configuration keys that have been renamed was found in the environment:%n%n"));
content.forEach((name, properties) -> {
report.append(String.format("Property source '%s':%n", name));
// properties.sort(PropertyMigration.COMPARATOR);
properties.forEach((property) -> {
ConfigurationPropertyName originalPropertyName = property.originalPropertyName();
report.append(String.format("\tKey: %s%n", originalPropertyName));
Integer lineNumber = property.determineLineNumber();
if (lineNumber != null) {
report.append(String.format("\t\tLine: %d%n", lineNumber));
}
report.append(String.format("\t\tReplacement: %s%n", property.newProperty().toString()));
});
report.append(String.format("%n"));
});
report.append(String.format("%n"));
report.append("Each configuration key has been temporarily mapped to its "
+ "replacement for your convenience. To silence this warning, please "
+ "update your configuration to use the new keys.");
report.append(String.format("%n"));
logger.warn(report.toString());
}
}
private record Migration(String originalPropertySourceName, ConfigurationPropertyName originalPropertyName,
ConfigurationProperty originalProperty, ConfigurationPropertyName newProperty) {
private Integer determineLineNumber() {
Origin origin = originalProperty.getOrigin();
if (origin instanceof PropertySourceOrigin propertySourceOrigin) {
origin = propertySourceOrigin.getOrigin();
}
if (origin instanceof TextResourceOrigin textOrigin) {
if (textOrigin.getLocation() != null) {
return textOrigin.getLocation().getLine() + 1;
}
}
return null;
}
}
}

View File

@@ -89,15 +89,6 @@ public class LocalResponseCacheAutoConfiguration {
return new CacheKeyGenerator();
}
/**
* @deprecated since 4.1.2 for removal in 4.2.0 in favor of
* {@link LocalResponseCacheUtils#createGatewayCacheManager(LocalResponseCacheProperties)}
*/
@Deprecated(since = "4.1.2", forRemoval = true)
public static CaffeineCacheManager createGatewayCacheManager(LocalResponseCacheProperties cacheProperties) {
return LocalResponseCacheUtils.createGatewayCacheManager(cacheProperties);
}
Cache responseCache(CacheManager cacheManager) {
return cacheManager.getCache(RESPONSE_CACHE_NAME);
}

View File

@@ -72,17 +72,6 @@ public class ReactiveLoadBalancerClientFilter implements GlobalFilter, Ordered {
private final GatewayLoadBalancerProperties properties;
/**
* @deprecated in favour of
* {@link ReactiveLoadBalancerClientFilter#ReactiveLoadBalancerClientFilter(LoadBalancerClientFactory, GatewayLoadBalancerProperties)}
*/
@Deprecated
public ReactiveLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory,
GatewayLoadBalancerProperties properties, LoadBalancerProperties loadBalancerProperties) {
this.clientFactory = clientFactory;
this.properties = properties;
}
public ReactiveLoadBalancerClientFilter(LoadBalancerClientFactory clientFactory,
GatewayLoadBalancerProperties properties) {
this.clientFactory = clientFactory;

View File

@@ -1,128 +0,0 @@
/*
* Copyright 2013-2020 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
*
* https://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.gateway.filter;
import java.net.URI;
import java.util.List;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.RequestBodySpec;
import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.filter.headers.HttpHeadersFilter.filterRequest;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.PRESERVE_HOST_HEADER_ATTRIBUTE;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.isAlreadyRouted;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.setAlreadyRouted;
/**
* @author Spencer Gibb
* @deprecated for removal in 5.0
*/
@Deprecated
public class WebClientHttpRoutingFilter implements GlobalFilter, Ordered {
private final WebClient webClient;
private final ObjectProvider<List<HttpHeadersFilter>> headersFiltersProvider;
// do not use this headersFilters directly, use getHeadersFilters() instead.
private volatile List<HttpHeadersFilter> headersFilters;
public WebClientHttpRoutingFilter(WebClient webClient,
ObjectProvider<List<HttpHeadersFilter>> headersFiltersProvider) {
this.webClient = webClient;
this.headersFiltersProvider = headersFiltersProvider;
}
public List<HttpHeadersFilter> getHeadersFilters() {
if (headersFilters == null) {
headersFilters = headersFiltersProvider.getIfAvailable();
}
return headersFilters;
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
URI requestUrl = exchange.getRequiredAttribute(GATEWAY_REQUEST_URL_ATTR);
String scheme = requestUrl.getScheme();
if (isAlreadyRouted(exchange) || (!"http".equals(scheme) && !"https".equals(scheme))) {
return chain.filter(exchange);
}
setAlreadyRouted(exchange);
ServerHttpRequest request = exchange.getRequest();
HttpMethod method = request.getMethod();
HttpHeaders filteredHeaders = filterRequest(getHeadersFilters(), exchange);
boolean preserveHost = exchange.getAttributeOrDefault(PRESERVE_HOST_HEADER_ATTRIBUTE, false);
RequestBodySpec bodySpec = this.webClient.method(method).uri(requestUrl).headers(httpHeaders -> {
httpHeaders.addAll(filteredHeaders);
// TODO: can this support preserviceHostHeader?
if (!preserveHost) {
httpHeaders.remove(HttpHeaders.HOST);
}
});
RequestHeadersSpec<?> headersSpec;
if (requiresBody(method)) {
headersSpec = bodySpec.body(BodyInserters.fromDataBuffers(request.getBody()));
}
else {
headersSpec = bodySpec;
}
return headersSpec.exchangeToMono(Mono::just)
// .log("webClient route")
.flatMap(res -> {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().putAll(res.headers().asHttpHeaders());
response.setStatusCode(res.statusCode());
// Defer committing the response until all route filters have run
// Put client response as ServerWebExchange attribute and write
// response later NettyWriteResponseFilter
exchange.getAttributes().put(CLIENT_RESPONSE_ATTR, res);
return chain.filter(exchange);
});
}
private boolean requiresBody(HttpMethod method) {
return method.equals(HttpMethod.PUT) || method.equals(HttpMethod.POST) || method.equals(HttpMethod.PATCH);
}
}

View File

@@ -1,75 +0,0 @@
/*
* Copyright 2013-2020 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
*
* https://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.gateway.filter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Mono;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.reactive.function.BodyExtractors;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.server.ServerWebExchange;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR;
/**
* @author Spencer Gibb
* @deprecated for removal in 5.0
*/
@Deprecated
public class WebClientWriteResponseFilter implements GlobalFilter, Ordered {
/**
* Order of Write Response Filter.
*/
public static final int WRITE_RESPONSE_FILTER_ORDER = -1;
private static final Log log = LogFactory.getLog(WebClientWriteResponseFilter.class);
@Override
public int getOrder() {
return WRITE_RESPONSE_FILTER_ORDER;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_ATTR is not added
// until the WebHandler is run
return chain.filter(exchange).doOnError(throwable -> cleanup(exchange)).then(Mono.defer(() -> {
ClientResponse clientResponse = exchange.getAttribute(CLIENT_RESPONSE_ATTR);
if (clientResponse == null) {
return Mono.empty();
}
log.trace("WebClientWriteResponseFilter start");
ServerHttpResponse response = exchange.getResponse();
return response.writeWith(clientResponse.body(BodyExtractors.toDataBuffers()))
// .log("webClient response")
.doOnCancel(() -> cleanup(exchange));
}));
}
private void cleanup(ServerWebExchange exchange) {
ClientResponse clientResponse = exchange.getAttribute(CLIENT_RESPONSE_ATTR);
if (clientResponse != null) {
clientResponse.bodyToMono(Void.class).subscribe();
}
}
}

View File

@@ -20,7 +20,6 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -103,12 +102,6 @@ public class WeightCalculatorWebFilter implements WebFilter, Ordered, SmartAppli
this.order = order;
}
@Deprecated
public void setRandom(Random random) {
Assert.notNull(random, "random may not be null");
this.randomFunction = exchange -> random.nextDouble();
}
public void setRandomSupplier(Supplier<Double> randomSupplier) {
Assert.notNull(randomSupplier, "randomSupplier may not be null");
this.randomFunction = exchange -> randomSupplier.get();

View File

@@ -28,6 +28,8 @@ import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.cloud.gateway.support.config.KeyValue;
import org.springframework.cloud.gateway.support.config.KeyValueConfig;
import org.springframework.core.style.ToStringCreator;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.StringUtils;
@@ -41,8 +43,7 @@ import static org.springframework.cloud.gateway.support.GatewayToStringStyler.fi
*
* @author Abel Salgado Romero
*/
public class AddRequestHeadersIfNotPresentGatewayFilterFactory
extends AbstractGatewayFilterFactory<AddRequestHeadersIfNotPresentGatewayFilterFactory.KeyValueConfig> {
public class AddRequestHeadersIfNotPresentGatewayFilterFactory extends AbstractGatewayFilterFactory<KeyValueConfig> {
@Override
public GatewayFilter apply(KeyValueConfig config) {
@@ -126,54 +127,4 @@ public class AddRequestHeadersIfNotPresentGatewayFilterFactory
return KeyValueConfig.class;
}
/**
* @deprecated in favour of
* {@link org.springframework.cloud.gateway.support.config.KeyValueConfig}
*/
@Deprecated
public static class KeyValueConfig {
private KeyValue[] keyValues;
public KeyValue[] getKeyValues() {
return keyValues;
}
public void setKeyValues(KeyValue[] keyValues) {
this.keyValues = keyValues;
}
}
/**
* @deprecated in favour of
* {@link org.springframework.cloud.gateway.support.config.KeyValue}
*/
@Deprecated
public static class KeyValue {
private final String key;
private final String value;
public KeyValue(String key, String value) {
this.key = key;
this.value = value;
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
@Override
public String toString() {
return new ToStringCreator(this).append("name", key).append("value", value).toString();
}
}
}

View File

@@ -73,11 +73,6 @@ public class RewriteResponseHeaderGatewayFilterFactory
};
}
@Deprecated
protected void rewriteHeader(ServerWebExchange exchange, Config config) {
rewriteHeaders(exchange, config);
}
protected void rewriteHeaders(ServerWebExchange exchange, Config config) {
final String name = config.getName();
final HttpHeaders responseHeaders = exchange.getResponse().getHeaders();

View File

@@ -40,13 +40,6 @@ public class GlobalLocalResponseCacheGatewayFilter implements GlobalFilter, Orde
private final ResponseCacheGatewayFilter responseCacheGatewayFilter;
@Deprecated
public GlobalLocalResponseCacheGatewayFilter(ResponseCacheManagerFactory cacheManagerFactory, Cache globalCache,
Duration configuredTimeToLive) {
responseCacheGatewayFilter = new ResponseCacheGatewayFilter(
cacheManagerFactory.create(globalCache, configuredTimeToLive));
}
public GlobalLocalResponseCacheGatewayFilter(ResponseCacheManagerFactory cacheManagerFactory, Cache globalCache,
Duration configuredTimeToLive, LocalResponseCacheProperties.RequestOptions requestOptions) {
responseCacheGatewayFilter = new ResponseCacheGatewayFilter(

View File

@@ -61,12 +61,6 @@ public class LocalResponseCacheGatewayFilterFactory
private final CaffeineCacheManager caffeineCacheManager;
@Deprecated
public LocalResponseCacheGatewayFilterFactory(ResponseCacheManagerFactory cacheManagerFactory,
Duration defaultTimeToLive, DataSize defaultSize) {
this(cacheManagerFactory, defaultTimeToLive, defaultSize, new RequestOptions());
}
public LocalResponseCacheGatewayFilterFactory(ResponseCacheManagerFactory cacheManagerFactory,
Duration defaultTimeToLive, DataSize defaultSize, RequestOptions requestOptions) {
this(cacheManagerFactory, defaultTimeToLive, defaultSize, requestOptions, new CaffeineCacheManager());

View File

@@ -69,11 +69,6 @@ public class ResponseCacheManager {
private final boolean ignoreNoCacheUpdate;
@Deprecated
public ResponseCacheManager(CacheKeyGenerator cacheKeyGenerator, Cache cache, Duration configuredTimeToLive) {
this(cacheKeyGenerator, cache, configuredTimeToLive, new RequestOptions());
}
public ResponseCacheManager(CacheKeyGenerator cacheKeyGenerator, Cache cache, Duration configuredTimeToLive,
RequestOptions requestOptions) {
this.cacheKeyGenerator = cacheKeyGenerator;

View File

@@ -33,11 +33,6 @@ public class ResponseCacheManagerFactory {
this.cacheKeyGenerator = cacheKeyGenerator;
}
@Deprecated
public ResponseCacheManager create(Cache cache, Duration timeToLive) {
return new ResponseCacheManager(cacheKeyGenerator, cache, timeToLive);
}
public ResponseCacheManager create(Cache cache, Duration timeToLive,
LocalResponseCacheProperties.RequestOptions requestOptions) {
return new ResponseCacheManager(cacheKeyGenerator, cache, timeToLive, requestOptions);

View File

@@ -62,11 +62,6 @@ public class FilteringWebHandler implements WebHandler, ApplicationListener<Refr
private final boolean routeFilterCacheEnabled;
@Deprecated
public FilteringWebHandler(List<GlobalFilter> globalFilters) {
this(globalFilters, false);
}
public FilteringWebHandler(List<GlobalFilter> globalFilters, boolean routeFilterCacheEnabled) {
this.globalFilters = loadFilters(globalFilters);
this.routeFilterCacheEnabled = routeFilterCacheEnabled;

View File

@@ -55,15 +55,6 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<Pat
private final WebFluxProperties webFluxProperties;
/**
* @deprecated {@link #PathRoutePredicateFactory(WebFluxProperties)}
*/
@Deprecated
public PathRoutePredicateFactory() {
super(Config.class);
this.webFluxProperties = new WebFluxProperties();
}
public PathRoutePredicateFactory(WebFluxProperties webFluxProperties) {
super(Config.class);
this.webFluxProperties = webFluxProperties;
@@ -173,23 +164,6 @@ public class PathRoutePredicateFactory extends AbstractRoutePredicateFactory<Pat
return this;
}
/**
* @deprecated use {@link #isMatchTrailingSlash()}
*/
@Deprecated
public boolean isMatchOptionalTrailingSeparator() {
return isMatchTrailingSlash();
}
/**
* @deprecated use {@link #setMatchTrailingSlash(boolean)}
*/
@Deprecated
public Config setMatchOptionalTrailingSeparator(boolean matchOptionalTrailingSeparator) {
setMatchTrailingSlash(matchOptionalTrailingSeparator);
return this;
}
public boolean isMatchTrailingSlash() {
return matchTrailingSlash;
}

View File

@@ -40,7 +40,6 @@ import org.springframework.cloud.gateway.filter.OrderedGatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractChangeRequestUriGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeadersIfNotPresentGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeadersIfNotPresentGatewayFilterFactory.KeyValue;
import org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.AddResponseHeaderGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.factory.CacheRequestBodyGatewayFilterFactory;
@@ -83,6 +82,7 @@ import org.springframework.cloud.gateway.filter.factory.rewrite.ModifyResponseBo
import org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction;
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
import org.springframework.cloud.gateway.route.Route;
import org.springframework.cloud.gateway.support.config.KeyValue;
import org.springframework.core.Ordered;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpStatus;

View File

@@ -1,45 +0,0 @@
/*
* Copyright 2013-2022 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
*
* https://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.gateway.support;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeadersIfNotPresentGatewayFilterFactory.KeyValue;
import org.springframework.core.convert.converter.Converter;
/**
* @deprecated in favour of
* {@link org.springframework.cloud.gateway.support.config.KeyValueConverter}
*/
@Deprecated
public class KeyValueConverter implements Converter<String, KeyValue> {
private static final String INVALID_CONFIGURATION_MESSAGE = "Invalid configuration, expected format is: 'key:value', received: ";
@Override
public KeyValue convert(String source) throws IllegalArgumentException {
try {
String[] split = source.split(":");
if (split.length == 2) {
return new KeyValue(split[0], split.length == 1 ? "" : split[1]);
}
throw new IllegalArgumentException(INVALID_CONFIGURATION_MESSAGE + source);
}
catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalArgumentException(INVALID_CONFIGURATION_MESSAGE + source);
}
}
}

View File

@@ -3,8 +3,4 @@ org.springframework.cloud.gateway.config.GatewayEnvironmentPostProcessor
# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.cloud.gateway.support.MvcFoundOnClasspathFailureAnalyzer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.cloud.gateway.config.GatewayServerWebfluxPropertiesMigrationListener
org.springframework.cloud.gateway.support.MvcFoundOnClasspathFailureAnalyzer

View File

@@ -133,7 +133,7 @@ public class GatewayMetricsAutoConfigurationTests {
@Nested
@SpringBootTest(classes = CustomTagsProviderConfig.class,
properties = "spring.cloud.gateway.metrics.prefix=myprefix.")
properties = "spring.cloud.gateway.server.webflux.metrics.prefix=myprefix.")
public class AddCustomTagsProvider {
@Autowired(required = false)

View File

@@ -1,85 +0,0 @@
/*
* Copyright 2013-2025 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
*
* https://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.gateway.config;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.gateway.filter.factory.AddRequestParameterGatewayFilterFactory;
import org.springframework.cloud.gateway.filter.headers.ForwardedHeadersFilter;
import org.springframework.cloud.gateway.filter.headers.XForwardedHeadersFilter;
import org.springframework.cloud.gateway.handler.predicate.AfterRoutePredicateFactory;
import org.springframework.cloud.gateway.route.RouteRefreshListener;
import org.springframework.context.ApplicationContext;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("unchecked")
@SpringBootTest(properties = { "debug=true" }, webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("propertiesmigrationtests")
public class GatewayPropertiesMigrationTests {
@Autowired
ApplicationContext context;
@Autowired
GatewayProperties properties;
@Test
public void deprecatedPropertiesWork() {
assertBeanDoesNotExist(AddRequestParameterGatewayFilterFactory.class);
assertBeanDoesNotExist(AfterRoutePredicateFactory.class);
assertBeanDoesNotExist(ForwardedHeadersFilter.class);
assertBeanDoesNotExist(RouteRefreshListener.class);
assertBeanDoesNotExist(XForwardedHeadersFilter.class);
}
@Test
public void deprecatedRoutePropertiesWork() {
assertThat(properties.getRoutes()).hasSize(2);
}
@Test
public void deprecatedDefaultFiltersPropertiesWork() {
assertThat(properties.getDefaultFilters()).hasSize(2);
assertThat(properties.getDefaultFilters().get(0).getName()).isEqualTo("AddRequestHeader");
assertThat(properties.getDefaultFilters().get(1).getName()).isEqualTo("AddRequestHeader");
}
@Test
public void deprecatedStreamingMediaTypesWork() {
assertThat(properties.getStreamingMediaTypes()).hasSize(1)
.containsOnly(new MediaType("application", "activemessage"));
}
private void assertBeanDoesNotExist(Class<?> type) {
assertThat(context.getBeanNamesForType(type)).isEmpty();
}
@SpringBootConfiguration
@EnableAutoConfiguration
protected static class TestConfiguration {
}
}

View File

@@ -26,10 +26,10 @@ import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeadersIfNotPresentGatewayFilterFactory.KeyValue;
import org.springframework.cloud.gateway.filter.factory.AddRequestHeadersIfNotPresentGatewayFilterFactory.KeyValueConfig;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.cloud.gateway.support.config.KeyValue;
import org.springframework.cloud.gateway.support.config.KeyValueConfig;
import org.springframework.cloud.gateway.test.BaseWebClientTests;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;

View File

@@ -30,7 +30,7 @@ import java.util.stream.Collectors;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;
import org.springframework.cloud.gateway.webflux.config.ProxyProperties;
import org.springframework.cloud.gateway.webflux.config.ProxyExchangeWebfluxProperties;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
@@ -115,9 +115,9 @@ public class ProxyExchange<T> {
/**
* Contains headers that are considered case-sensitive by default.
* @deprecated {@link ProxyProperties#DEFAULT_SENSITIVE}
* @deprecated {@link ProxyExchangeWebfluxProperties#DEFAULT_SENSITIVE}
*/
public static Set<String> DEFAULT_SENSITIVE = ProxyProperties.DEFAULT_SENSITIVE;
public static Set<String> DEFAULT_SENSITIVE = ProxyExchangeWebfluxProperties.DEFAULT_SENSITIVE;
private HttpMethod httpMethod;
@@ -198,17 +198,6 @@ public class ProxyExchange<T> {
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
* @deprecated {@link #excluded(String...)}
*/
public ProxyExchange<T> sensitive(String... names) {
return excluded(names);
}
/**
* Sets the names of excluded headers that are not passed downstream to the backend
* service.

View File

@@ -58,11 +58,6 @@ public class ProxyExchangeArgumentResolver implements HandlerMethodArgumentResol
this.autoForwardedHeaders = autoForwardedHeaders;
}
@Deprecated
public void setSensitive(Set<String> excluded) {
setExcluded(excluded);
}
public void setExcluded(Set<String> excluded) {
this.excluded = excluded;
}

View File

@@ -1,120 +0,0 @@
/*
* Copyright 2016-2019 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
*
* https://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.gateway.webflux.config;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
import org.springframework.cloud.gateway.webflux.ProxyExchange;
import org.springframework.http.HttpHeaders;
/**
* Configuration properties for the {@link ProxyExchange} argument handler in
* <code>@RequestMapping</code> methods.
*
* @author Dave Syer
* @author Tim Ysewyn
* @author Joris Kuipers
* @deprecated {@link ProxyExchangeWebfluxProperties}
*
*/
@Deprecated
@ConfigurationProperties("spring.cloud.gateway.proxy")
public class ProxyProperties {
/**
* Contains headers that are considered case-sensitive by default.
*/
public static Set<String> DEFAULT_SENSITIVE = Set.of("cookie", "authorization");
/**
* Contains headers that are skipped by default.
*/
public static Set<String> DEFAULT_SKIPPED = Set.of("content-length", "host");
/**
* Fixed header values that will be added to all downstream requests.
*/
private Map<String, String> headers = new LinkedHashMap<>();
/**
* A set of header names that should be sent downstream by default.
*/
private Set<String> autoForward = new HashSet<>();
/**
* A set of sensitive header names that will not be sent downstream by default.
*/
private Set<String> sensitive = DEFAULT_SENSITIVE;
/**
* A set of header names that will not be sent downstream because they could be
* problematic.
*/
private Set<String> skipped = DEFAULT_SKIPPED;
@DeprecatedConfigurationProperty(replacement = ProxyExchangeWebfluxProperties.PREFIX + ".headers", since = "4.3.0")
public Map<String, String> getHeaders() {
return headers;
}
public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}
@DeprecatedConfigurationProperty(replacement = ProxyExchangeWebfluxProperties.PREFIX + ".auto-forward",
since = "4.3.0")
public Set<String> getAutoForward() {
return autoForward;
}
public void setAutoForward(Set<String> autoForward) {
this.autoForward = autoForward;
}
@DeprecatedConfigurationProperty(replacement = ProxyExchangeWebfluxProperties.PREFIX + ".sensitive",
since = "4.3.0")
public Set<String> getSensitive() {
return sensitive;
}
public void setSensitive(Set<String> sensitive) {
this.sensitive = sensitive;
}
@DeprecatedConfigurationProperty(replacement = ProxyExchangeWebfluxProperties.PREFIX + ".skipped", since = "4.3.0")
public Set<String> getSkipped() {
return skipped;
}
public void setSkipped(Set<String> skipped) {
this.skipped = skipped;
}
public HttpHeaders convertHeaders() {
HttpHeaders headers = new HttpHeaders();
for (String key : this.headers.keySet()) {
headers.set(key, this.headers.get(key));
}
return headers;
}
}

View File

@@ -48,7 +48,7 @@ import org.springframework.web.reactive.result.method.annotation.ArgumentResolve
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@ConditionalOnClass({ HandlerMethodReturnValueHandler.class, WebClient.class })
@EnableConfigurationProperties({ ProxyExchangeWebfluxProperties.class, ProxyProperties.class })
@EnableConfigurationProperties({ ProxyExchangeWebfluxProperties.class })
public class ProxyResponseAutoConfiguration implements WebFluxConfigurer {
@Autowired

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2013-2025 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
*
* https://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.gateway.webflux.config;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.ActiveProfiles;
import static org.assertj.core.api.Assertions.assertThat;
@SuppressWarnings("unchecked")
@SpringBootTest(properties = {}, webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("propertiesmigrationtests")
public class ProxyExchangeWebfluxPropertiesMigrationTests {
@Autowired
ProxyExchangeWebfluxProperties properties;
@Test
public void deprecatedRoutePropertiesWork() {
assertThat(properties.getHeaders()).hasSize(2);
assertThat(properties.getAutoForward()).hasSize(2);
assertThat(properties.getSensitive()).hasSize(2);
assertThat(properties.getSkipped()).hasSize(3);
}
@SpringBootConfiguration
@EnableAutoConfiguration
protected static class TestConfiguration {
}
}