Merge remote-tracking branch 'origin/main'
This commit is contained in:
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@@ -17,7 +17,7 @@ given the ability to merge pull requests.
|
||||
|
||||
## Code of Conduct
|
||||
This project adheres to the Contributor Covenant [code of
|
||||
conduct](https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/src/main/asciidoc/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
|
||||
conduct](https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/modules/ROOT/partials/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
|
||||
unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
## Code Conventions and Housekeeping
|
||||
|
||||
2
.github/workflows/maven.yml
vendored
2
.github/workflows/maven.yml
vendored
@@ -28,6 +28,6 @@ jobs:
|
||||
cache: 'maven'
|
||||
- name: Build with Maven
|
||||
run: ./mvnw clean install -B -U -P sonar
|
||||
- uses: codecov/codecov-action@v4
|
||||
- uses: codecov/codecov-action@v5
|
||||
with:
|
||||
fail_ci_if_error: false
|
||||
|
||||
@@ -98,13 +98,18 @@ NOTE: Because of a limitation in Eureka, it is not possible to support per-serve
|
||||
|
||||
If you want to customize the RestTemplate used by the Eureka HTTP Client you may want to create a bean of `EurekaClientHttpRequestFactorySupplier` and provide your own logic for generating a `ClientHttpRequestFactory` instance.
|
||||
|
||||
All default timeout-related properties for RestTemplate used by the Eureka HTTP Client are set to 3 minutes (in keeping with Apache HC5 default `RequestConfig` and `SocketConfig`). Therefore, to specify the timeout values, you must specify the value directly with the properties in `eureka.client.rest-template-timeout`. (All timeout properties are in milliseconds.)
|
||||
All default timeout-related properties for RestTemplate and RestClient used by the Eureka HTTP Client are set to 3 minutes (in keeping with Apache HC5 default `RequestConfig` and `SocketConfig`). Therefore, to specify the timeout values, you must specify the value directly with the properties in `eureka.client.rest-template-timeout` or `eureka.client.restclient.timeout`. All timeout properties are in milliseconds.
|
||||
|
||||
.application.yml
|
||||
[source,yaml]
|
||||
----
|
||||
eureka:
|
||||
client:
|
||||
restclient:
|
||||
timeout:
|
||||
connect-timeout: 5000
|
||||
connect-request-timeout: 8000
|
||||
socket-timeout: 10000
|
||||
rest-template-timeout:
|
||||
connect-timeout: 5000
|
||||
connect-request-timeout: 8000
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
|eureka.client.rest-template-timeout.connect-timeout | `+++180000+++` | Default values are set to 180000, in keeping with {@link RequestConfig} and {@link SocketConfig} defaults.
|
||||
|eureka.client.rest-template-timeout.socket-timeout | `+++180000+++` |
|
||||
|eureka.client.restclient.enabled | `+++false+++` | Enables the use of RestClient for Eureka HTTP Client.
|
||||
|eureka.client.restclient.timeout.connect-request-timeout | `+++180000+++` |
|
||||
|eureka.client.restclient.timeout.connect-timeout | `+++180000+++` | Default values are set to 180000, in keeping with {@link RequestConfig} and {@link SocketConfig} defaults.
|
||||
|eureka.client.restclient.timeout.socket-timeout | `+++180000+++` |
|
||||
|eureka.client.service-url | | Map of availability zone to list of fully qualified URLs to communicate with eureka server. Each value can be a single URL or a comma separated list of alternative locations. Typically the eureka server URLs carry protocol,host,port,context and version information if any. Example: https://ec2-256-156-243-129.compute-1.amazonaws.com:7001/eureka/ The changes are effective at runtime at the next service url refresh cycle as specified by eurekaServiceUrlPollIntervalSeconds.
|
||||
|eureka.client.should-enforce-registration-at-init | `+++false+++` | Indicates whether the client should enforce registration during initialization. Defaults to false.
|
||||
|eureka.client.should-unregister-on-shutdown | `+++true+++` | Indicates whether the client should explicitly unregister itself from the remote server on client shutdown.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"dependencies": {
|
||||
"antora": "3.2.0-alpha.6",
|
||||
"@antora/atlas-extension": "1.0.0-alpha.2",
|
||||
"@antora/collector-extension": "1.0.0-beta.4",
|
||||
"@antora/collector-extension": "1.0.0-beta.5",
|
||||
"@asciidoctor/tabs": "1.0.0-beta.6",
|
||||
"@springio/antora-extensions": "1.14.2",
|
||||
"@springio/asciidoctor-extensions": "1.0.0-alpha.14"
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactories;
|
||||
@@ -33,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class EurekaClientTests extends BaseCertTests {
|
||||
|
||||
private static final Log log = LogFactory.getLog(EurekaClientTests.class);
|
||||
private static final Log LOG = LogFactory.getLog(EurekaClientTests.class);
|
||||
|
||||
static EurekaServerRunner server;
|
||||
|
||||
@@ -44,7 +43,7 @@ public class EurekaClientTests extends BaseCertTests {
|
||||
server = startEurekaServer(EurekaClientTests.TestEurekaServer.class);
|
||||
service = startService(server, EurekaClientTests.TestApp.class);
|
||||
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
|
||||
log.info("Successfully asserted that Jersey will be used");
|
||||
LOG.info("Successfully asserted that Jersey will be used");
|
||||
waitForRegistration(() -> new EurekaClientTests().createEurekaClient());
|
||||
}
|
||||
|
||||
@@ -59,9 +58,8 @@ public class EurekaClientTests extends BaseCertTests {
|
||||
|
||||
@Bean
|
||||
public RestTemplateTransportClientFactories forceRestTemplateTransportClientFactories(
|
||||
DiscoveryClientOptionalArgsConfiguration configuration,
|
||||
RestTemplateDiscoveryClientOptionalArgs discoveryClientOptionalArgs) {
|
||||
return configuration.restTemplateTransportClientFactories(discoveryClientOptionalArgs);
|
||||
return new RestTemplateTransportClientFactories(discoveryClientOptionalArgs);
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2018-2024 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.netflix.eureka;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestClientDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestClientTransportClientFactories;
|
||||
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration.setupTLS;
|
||||
|
||||
/**
|
||||
* Tests for verifying TLS setup with {@link RestClientTransportClientFactories}.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
public class RestClientEurekaClientTests extends BaseCertTests {
|
||||
|
||||
private static final Log LOG = LogFactory.getLog(RestClientEurekaClientTests.class);
|
||||
|
||||
private static EurekaServerRunner server;
|
||||
|
||||
private static EurekaClientRunner service;
|
||||
|
||||
@BeforeAll
|
||||
public static void setupAll() {
|
||||
server = startEurekaServer(TestEurekaServer.class);
|
||||
service = startService(server, TestApp.class);
|
||||
// Will use RestClient
|
||||
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestClientDiscoveryClientOptionalArgs.class);
|
||||
LOG.info("Successfully asserted that RestClient will be used");
|
||||
waitForRegistration(() -> new RestClientEurekaClientTests().createEurekaClient());
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDownAll() {
|
||||
stopService(service);
|
||||
stopEurekaServer(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
EurekaClientRunner createEurekaClient() {
|
||||
return new EurekaClientRunner(TestApp.class, server);
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
public static class TestApp {
|
||||
|
||||
// Want to force reusing exactly the same bean as on production without excluding
|
||||
// jersey from the classpath
|
||||
@Bean
|
||||
public RestClientDiscoveryClientOptionalArgs forceRestClientDiscoveryClientOptionalArgs(
|
||||
TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier)
|
||||
throws GeneralSecurityException, IOException {
|
||||
RestClientDiscoveryClientOptionalArgs result = new RestClientDiscoveryClientOptionalArgs(
|
||||
eurekaClientHttpRequestFactorySupplier, RestClient::builder);
|
||||
setupTLS(result, tlsProperties);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestClientTransportClientFactories forceRestClientTransportClientFactories(
|
||||
RestClientDiscoveryClientOptionalArgs discoveryClientOptionalArgs) {
|
||||
return new RestClientTransportClientFactories(discoveryClientOptionalArgs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@EnableEurekaServer
|
||||
public static class TestEurekaServer {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,13 +24,11 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.SpringBootConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration;
|
||||
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactories;
|
||||
@@ -38,6 +36,7 @@ import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration.setupTLS;
|
||||
|
||||
public class RestTemplateEurekaClientTests extends BaseCertTests {
|
||||
|
||||
@@ -49,7 +48,7 @@ public class RestTemplateEurekaClientTests extends BaseCertTests {
|
||||
|
||||
@BeforeAll
|
||||
public static void setupAll() {
|
||||
server = startEurekaServer(RestTemplateEurekaClientTests.RestTemplateTestEurekaServer.class);
|
||||
server = startEurekaServer(TestEurekaServer.class);
|
||||
service = startService(server, RestTemplateEurekaClientTests.RestTemplateTestApp.class);
|
||||
// Will use RestTemplate
|
||||
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
|
||||
@@ -72,24 +71,27 @@ public class RestTemplateEurekaClientTests extends BaseCertTests {
|
||||
@EnableAutoConfiguration
|
||||
public static class RestTemplateTestApp {
|
||||
|
||||
// Want to force reusing exactly the same bean as on production without excluding
|
||||
// jersey from the classpath
|
||||
@Bean
|
||||
public RestTemplateDiscoveryClientOptionalArgs forceRestTemplateDiscoveryClientOptionalArgs(
|
||||
TlsProperties tlsProperties, DiscoveryClientOptionalArgsConfiguration configuration,
|
||||
TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier)
|
||||
throws GeneralSecurityException, IOException {
|
||||
return configuration.restTemplateDiscoveryClientOptionalArgs(tlsProperties,
|
||||
eurekaClientHttpRequestFactorySupplier, new RestTemplateBuilderObjectProvider());
|
||||
RestTemplateDiscoveryClientOptionalArgs result = new RestTemplateDiscoveryClientOptionalArgs(
|
||||
eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
|
||||
setupTLS(result, tlsProperties);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Want to force reusing exactly the same bean as on production without excluding
|
||||
// jersey from the classpath
|
||||
@Bean
|
||||
public RestTemplateTransportClientFactories forceRestTemplateTransportClientFactories(
|
||||
DiscoveryClientOptionalArgsConfiguration configuration,
|
||||
RestTemplateDiscoveryClientOptionalArgs discoveryClientOptionalArgs) {
|
||||
return configuration.restTemplateTransportClientFactories(discoveryClientOptionalArgs);
|
||||
return new RestTemplateTransportClientFactories(discoveryClientOptionalArgs);
|
||||
}
|
||||
|
||||
@Bean
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
|
||||
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -97,33 +99,7 @@ public class RestTemplateEurekaClientTests extends BaseCertTests {
|
||||
@SpringBootConfiguration
|
||||
@EnableAutoConfiguration
|
||||
@EnableEurekaServer
|
||||
public static class RestTemplateTestEurekaServer {
|
||||
|
||||
}
|
||||
|
||||
private static class RestTemplateBuilderObjectProvider implements ObjectProvider<RestTemplateBuilder> {
|
||||
|
||||
private final RestTemplateBuilder builder = new RestTemplateBuilder();
|
||||
|
||||
@Override
|
||||
public RestTemplateBuilder getObject(Object... args) throws BeansException {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTemplateBuilder getIfAvailable() throws BeansException {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTemplateBuilder getIfUnique() throws BeansException {
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestTemplateBuilder getObject() throws BeansException {
|
||||
return builder;
|
||||
}
|
||||
public static class TestEurekaServer {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2013-2024 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.netflix.eureka;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
/**
|
||||
* A {@link RestClient}-specific {@link TimeoutProperties} implementation.
|
||||
*
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 4.2.0
|
||||
*/
|
||||
@ConfigurationProperties("eureka.client.restclient.timeout")
|
||||
public class RestClientTimeoutProperties extends TimeoutProperties {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "RestClientTimeoutProperties{" + ", connectTimeout=" + connectTimeout + ", connectRequestTimeout="
|
||||
+ connectRequestTimeout + ", socketTimeout=" + socketTimeout + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,79 +16,23 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.core5.http.io.SocketConfig;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Properties for configuring timeouts used in {@link RestTemplate} required by
|
||||
* {@link RestTemplateEurekaHttpClient}.
|
||||
* A {@link RestTemplate}-specific {@link TimeoutProperties} implementation.
|
||||
*
|
||||
* @author Jiwon Jeon
|
||||
* @author Mooyong Lee
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 3.1.6
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
|
||||
* {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
@ConfigurationProperties("eureka.client.rest-template-timeout")
|
||||
public class RestTemplateTimeoutProperties {
|
||||
|
||||
/**
|
||||
* Default values are set to 180000, in keeping with {@link RequestConfig} and
|
||||
* {@link SocketConfig} defaults.
|
||||
*/
|
||||
private int connectTimeout = 180000; // 3 * MINUTES
|
||||
|
||||
private int connectRequestTimeout = 180000; // 3 * MINUTES
|
||||
|
||||
private int socketTimeout = 180000; // 3 * MINUTES
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
public int getConnectRequestTimeout() {
|
||||
return connectRequestTimeout;
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
return socketTimeout;
|
||||
}
|
||||
|
||||
public void setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
public void setConnectRequestTimeout(int connectRequestTimeout) {
|
||||
this.connectRequestTimeout = connectRequestTimeout;
|
||||
}
|
||||
|
||||
public void setSocketTimeout(int socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RestTemplateTimeoutProperties that = (RestTemplateTimeoutProperties) o;
|
||||
|
||||
return connectTimeout == that.connectTimeout && connectRequestTimeout == that.connectRequestTimeout
|
||||
&& socketTimeout == that.socketTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(connectTimeout, connectRequestTimeout, socketTimeout);
|
||||
}
|
||||
public class RestTemplateTimeoutProperties extends TimeoutProperties {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2013-2024 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.netflix.eureka;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.core5.http.io.SocketConfig;
|
||||
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Properties for configuring timeouts used in {@link RestTemplate} required by
|
||||
* {@link EurekaHttpClient}.
|
||||
*
|
||||
* @author Jiwon Jeon
|
||||
* @author Mooyong Lee
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public abstract class TimeoutProperties {
|
||||
|
||||
/**
|
||||
* Default values are set to 180000, in keeping with {@link RequestConfig} and
|
||||
* {@link SocketConfig} defaults.
|
||||
*/
|
||||
protected int connectTimeout = 180000; // 3 * MINUTES
|
||||
|
||||
protected int connectRequestTimeout = 180000; // 3 * MINUTES
|
||||
|
||||
protected int socketTimeout = 180000; // 3 * MINUTES
|
||||
|
||||
public int getConnectTimeout() {
|
||||
return connectTimeout;
|
||||
}
|
||||
|
||||
public int getConnectRequestTimeout() {
|
||||
return connectRequestTimeout;
|
||||
}
|
||||
|
||||
public int getSocketTimeout() {
|
||||
return socketTimeout;
|
||||
}
|
||||
|
||||
public void setConnectTimeout(int connectTimeout) {
|
||||
this.connectTimeout = connectTimeout;
|
||||
}
|
||||
|
||||
public void setConnectRequestTimeout(int connectRequestTimeout) {
|
||||
this.connectRequestTimeout = connectRequestTimeout;
|
||||
}
|
||||
|
||||
public void setSocketTimeout(int socketTimeout) {
|
||||
this.socketTimeout = socketTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RestTemplateTimeoutProperties that = (RestTemplateTimeoutProperties) o;
|
||||
|
||||
return connectTimeout == that.connectTimeout && connectRequestTimeout == that.connectRequestTimeout
|
||||
&& socketTimeout == that.socketTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(connectTimeout, connectRequestTimeout, socketTimeout);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,6 +38,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.cloud.configuration.SSLContextFactory;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
|
||||
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
|
||||
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
|
||||
@@ -51,6 +52,7 @@ import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
@@ -60,7 +62,7 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
* @author Wonchul Heo
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(RestTemplateTimeoutProperties.class)
|
||||
@EnableConfigurationProperties({ RestTemplateTimeoutProperties.class, RestClientTimeoutProperties.class })
|
||||
public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
protected static final Log logger = LogFactory.getLog(DiscoveryClientOptionalArgsConfiguration.class);
|
||||
@@ -71,40 +73,8 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
return new TlsProperties();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
|
||||
@Conditional(RestTemplateEnabledCondition.class)
|
||||
@ConditionalOnMissingBean(value = { AbstractDiscoveryClientOptionalArgs.class }, search = SearchStrategy.CURRENT)
|
||||
public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs(TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
ObjectProvider<RestTemplateBuilder> restTemplateBuilders) throws GeneralSecurityException, IOException {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Eureka HTTP Client uses RestTemplate.");
|
||||
}
|
||||
RestTemplateDiscoveryClientOptionalArgs result = new RestTemplateDiscoveryClientOptionalArgs(
|
||||
eurekaClientHttpRequestFactorySupplier, restTemplateBuilders::getIfAvailable);
|
||||
setupTLS(result, tlsProperties);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
|
||||
@Conditional(RestTemplateEnabledCondition.class)
|
||||
@ConditionalOnMissingBean(value = { TransportClientFactories.class }, search = SearchStrategy.CURRENT)
|
||||
public RestTemplateTransportClientFactories restTemplateTransportClientFactories(
|
||||
RestTemplateDiscoveryClientOptionalArgs optionalArgs) {
|
||||
return new RestTemplateTransportClientFactories(optionalArgs);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
|
||||
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties);
|
||||
}
|
||||
|
||||
private static void setupTLS(AbstractDiscoveryClientOptionalArgs<?> args, TlsProperties properties)
|
||||
// Visible for tests
|
||||
public static void setupTLS(AbstractDiscoveryClientOptionalArgs<?> args, TlsProperties properties)
|
||||
throws GeneralSecurityException, IOException {
|
||||
if (properties.isEnabled()) {
|
||||
SSLContextFactory factory = new SSLContextFactory(properties);
|
||||
@@ -112,8 +82,49 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
|
||||
* {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(JerseyClientPresentAndEnabledCondition.class)
|
||||
@Conditional(OnRestTemplatePresentAndEnabledCondition.class)
|
||||
@Deprecated
|
||||
static class RestTemplateConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
|
||||
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = { AbstractDiscoveryClientOptionalArgs.class },
|
||||
search = SearchStrategy.CURRENT)
|
||||
public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs(
|
||||
TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
ObjectProvider<RestTemplateBuilder> restTemplateBuilders) throws GeneralSecurityException, IOException {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Eureka HTTP Client uses RestTemplate.");
|
||||
}
|
||||
RestTemplateDiscoveryClientOptionalArgs result = new RestTemplateDiscoveryClientOptionalArgs(
|
||||
eurekaClientHttpRequestFactorySupplier, restTemplateBuilders::getIfAvailable);
|
||||
setupTLS(result, tlsProperties);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = { TransportClientFactories.class }, search = SearchStrategy.CURRENT)
|
||||
public RestTemplateTransportClientFactories restTemplateTransportClientFactories(
|
||||
RestTemplateDiscoveryClientOptionalArgs optionalArgs) {
|
||||
return new RestTemplateTransportClientFactories(optionalArgs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(OnJerseyClientPresentAndEnabledCondition.class)
|
||||
@ConditionalOnBean(value = AbstractDiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT)
|
||||
static class DiscoveryClientOptionalArgsTlsConfiguration {
|
||||
|
||||
@@ -127,7 +138,8 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Conditional(JerseyClientNotPresentOrNotEnabledCondition.class)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(OnJerseyClientNotPresentOrNotEnabledCondition.class)
|
||||
@ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient")
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", havingValue = "true")
|
||||
protected static class WebClientConfiguration {
|
||||
@@ -156,8 +168,8 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Conditional(JerseyClientNotPresentOrNotEnabledCondition.class)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(OnJerseyClientNotPresentOrNotEnabledCondition.class)
|
||||
@ConditionalOnMissingClass("org.springframework.web.reactive.function.client.WebClient")
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", havingValue = "true")
|
||||
protected static class WebClientNotFoundConfiguration {
|
||||
@@ -170,20 +182,30 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestClient")
|
||||
@Conditional(RestClientEnabledCondition.class)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(OnRestClientPresentAndEnabledCondition.class)
|
||||
protected static class RestClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
|
||||
RestClientTimeoutProperties restClientTimeoutProperties) {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier(restClientTimeoutProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = { AbstractDiscoveryClientOptionalArgs.class },
|
||||
search = SearchStrategy.CURRENT)
|
||||
public RestClientDiscoveryClientOptionalArgs restClientDiscoveryClientOptionalArgs(TlsProperties tlsProperties,
|
||||
ObjectProvider<RestClient.Builder> builder) throws GeneralSecurityException, IOException {
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
ObjectProvider<RestClient.Builder> restClientBuilderProvider)
|
||||
throws GeneralSecurityException, IOException {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Eureka HTTP Client uses RestClient.");
|
||||
}
|
||||
RestClientDiscoveryClientOptionalArgs result = new RestClientDiscoveryClientOptionalArgs(
|
||||
builder::getIfAvailable);
|
||||
eurekaClientHttpRequestFactorySupplier,
|
||||
() -> restClientBuilderProvider.getIfAvailable(RestClient::builder));
|
||||
setupTLS(result, tlsProperties);
|
||||
return result;
|
||||
}
|
||||
@@ -191,15 +213,15 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = TransportClientFactories.class, search = SearchStrategy.CURRENT)
|
||||
public RestClientTransportClientFactories restClientTransportClientFactories(
|
||||
ObjectProvider<RestClient.Builder> builder) {
|
||||
return new RestClientTransportClientFactories(builder::getIfAvailable);
|
||||
RestClientDiscoveryClientOptionalArgs args) {
|
||||
return new RestClientTransportClientFactories(args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class JerseyClientPresentAndEnabledCondition extends AllNestedConditions {
|
||||
static class OnJerseyClientPresentAndEnabledCondition extends AllNestedConditions {
|
||||
|
||||
JerseyClientPresentAndEnabledCondition() {
|
||||
OnJerseyClientPresentAndEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@@ -215,9 +237,9 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
}
|
||||
|
||||
static class JerseyClientNotPresentOrNotEnabledCondition extends AnyNestedCondition {
|
||||
static class OnJerseyClientNotPresentOrNotEnabledCondition extends AnyNestedCondition {
|
||||
|
||||
JerseyClientNotPresentOrNotEnabledCondition() {
|
||||
OnJerseyClientNotPresentOrNotEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@@ -233,13 +255,23 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
}
|
||||
|
||||
static class RestTemplateEnabledCondition extends AllNestedConditions {
|
||||
/**
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
|
||||
* {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
static class OnRestTemplatePresentAndEnabledCondition extends AllNestedConditions {
|
||||
|
||||
RestTemplateEnabledCondition() {
|
||||
OnRestTemplatePresentAndEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@Conditional(JerseyClientNotPresentOrNotEnabledCondition.class)
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
|
||||
static class OnRestTemplatePresent {
|
||||
|
||||
}
|
||||
|
||||
@Conditional(OnJerseyClientNotPresentOrNotEnabledCondition.class)
|
||||
static class OnJerseyClientNotPresentOrNotEnabled {
|
||||
|
||||
}
|
||||
@@ -257,13 +289,18 @@ public class DiscoveryClientOptionalArgsConfiguration {
|
||||
|
||||
}
|
||||
|
||||
static class RestClientEnabledCondition extends AllNestedConditions {
|
||||
static class OnRestClientPresentAndEnabledCondition extends AllNestedConditions {
|
||||
|
||||
RestClientEnabledCondition() {
|
||||
OnRestClientPresentAndEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@Conditional(JerseyClientNotPresentOrNotEnabledCondition.class)
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestClient")
|
||||
static class OnRestClientPresent {
|
||||
|
||||
}
|
||||
|
||||
@Conditional(OnJerseyClientNotPresentOrNotEnabledCondition.class)
|
||||
static class OnJerseyClientNotPresentOrNotEnabled {
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
@@ -35,6 +34,7 @@ import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
|
||||
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
|
||||
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
|
||||
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
|
||||
@@ -50,6 +50,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
/**
|
||||
@@ -59,11 +60,12 @@ import org.springframework.web.reactive.function.client.WebClient;
|
||||
* @author Dave Syer
|
||||
* @author Armin Krezovic
|
||||
* @author Wonchul Heo
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
@ConditionalOnClass(ConfigServicePropertySourceLocator.class)
|
||||
@Conditional(EurekaConfigServerBootstrapConfiguration.EurekaConfigServerBootstrapCondition.class)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(RestTemplateTimeoutProperties.class)
|
||||
@EnableConfigurationProperties({ RestTemplateTimeoutProperties.class, RestClientTimeoutProperties.class })
|
||||
public class EurekaConfigServerBootstrapConfiguration {
|
||||
|
||||
@Bean
|
||||
@@ -72,31 +74,70 @@ public class EurekaConfigServerBootstrapConfiguration {
|
||||
return new EurekaClientConfigBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(EurekaHttpClient.class)
|
||||
@Conditional(RestTemplateEnabledCondition.class)
|
||||
public RestTemplateEurekaHttpClient configDiscoveryRestTemplateEurekaHttpClient(EurekaClientConfigBean config,
|
||||
Environment env, @Nullable TlsProperties properties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
ObjectProvider<RestTemplateBuilder> restTemplateBuilders) {
|
||||
return (RestTemplateEurekaHttpClient) new RestTemplateTransportClientFactory(properties,
|
||||
eurekaClientHttpRequestFactorySupplier, restTemplateBuilders::getIfAvailable)
|
||||
.newClient(HostnameBasedUrlRandomizer.randomEndpoint(config, env));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
|
||||
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConfigServerInstanceProvider.Function eurekaConfigServerInstanceProvider(EurekaHttpClient client,
|
||||
EurekaClientConfig config) {
|
||||
return new EurekaConfigServerInstanceProvider(client, config)::getInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
|
||||
* {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Conditional(RestTemplateConfiguration.OnRestTemplatePresentAndEnabledCondition.class)
|
||||
@Deprecated
|
||||
static class RestTemplateConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(EurekaHttpClient.class)
|
||||
public RestTemplateEurekaHttpClient configDiscoveryRestTemplateEurekaHttpClient(EurekaClientConfigBean config,
|
||||
Environment env, @Nullable TlsProperties properties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
ObjectProvider<RestTemplateBuilder> restTemplateBuilders) {
|
||||
return (RestTemplateEurekaHttpClient) new RestTemplateTransportClientFactory(properties,
|
||||
eurekaClientHttpRequestFactorySupplier, restTemplateBuilders::getIfAvailable)
|
||||
.newClient(HostnameBasedUrlRandomizer.randomEndpoint(config, env));
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
|
||||
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour
|
||||
* of {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
static class OnRestTemplatePresentAndEnabledCondition extends AllNestedConditions {
|
||||
|
||||
OnRestTemplatePresentAndEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
|
||||
static class OnRestTemplatePresent {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
|
||||
havingValue = "false")
|
||||
static class OnWebClientDisabled {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "restclient.enabled", havingValue = "false")
|
||||
static class OnRestClientDisabled {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(name = "org.springframework.web.reactive.function.client.WebClient")
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", havingValue = "true")
|
||||
@@ -114,55 +155,50 @@ public class EurekaConfigServerBootstrapConfiguration {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestClient")
|
||||
@Conditional(RestClientEnabledCondition.class)
|
||||
@ImportAutoConfiguration(RestClientAutoConfiguration.class)
|
||||
protected static class RestClientConfiguration {
|
||||
@Conditional(RestClientConfiguration.OnRestClientPresentAndEnabledCondition.class)
|
||||
static class RestClientConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(EurekaHttpClient.class)
|
||||
public RestClientEurekaHttpClient configDiscoveryRestClientEurekaHttpClient(EurekaClientConfigBean config,
|
||||
ObjectProvider<RestClient.Builder> builder, Environment env) {
|
||||
return (RestClientEurekaHttpClient) new RestClientTransportClientFactory(builder::getIfAvailable)
|
||||
@Nullable TlsProperties properties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
ObjectProvider<RestClient.Builder> restClientBuilderProvider, Environment env) {
|
||||
return (RestClientEurekaHttpClient) new RestClientTransportClientFactory(properties,
|
||||
eurekaClientHttpRequestFactorySupplier,
|
||||
() -> restClientBuilderProvider.getIfAvailable(RestClient::builder))
|
||||
.newClient(HostnameBasedUrlRandomizer.randomEndpoint(config, env));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class RestTemplateEnabledCondition extends AllNestedConditions {
|
||||
|
||||
RestTemplateEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
|
||||
RestClientTimeoutProperties restClientTimeoutProperties) {
|
||||
return new DefaultEurekaClientHttpRequestFactorySupplier(restClientTimeoutProperties);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
|
||||
havingValue = "false")
|
||||
static class OnWebClientDisabled {
|
||||
static class OnRestClientPresentAndEnabledCondition extends AllNestedConditions {
|
||||
|
||||
}
|
||||
OnRestClientPresentAndEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "restclient.enabled", havingValue = "false")
|
||||
static class OnRestClientDisabled {
|
||||
@ConditionalOnClass(name = "org.springframework.web.client.RestClient")
|
||||
static class OnRestClientPresentCondition {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
|
||||
havingValue = "false")
|
||||
static class OnWebClientDisabled {
|
||||
|
||||
static class RestClientEnabledCondition extends AllNestedConditions {
|
||||
}
|
||||
|
||||
RestClientEnabledCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "restclient.enabled", matchIfMissing = true,
|
||||
havingValue = "true")
|
||||
static class OnRestClientEnabled {
|
||||
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
|
||||
havingValue = "false")
|
||||
static class OnWebClientDisabled {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(prefix = "eureka.client", name = "restclient.enabled", matchIfMissing = true,
|
||||
havingValue = "true")
|
||||
static class OnRestClientEnabled {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013-2022 the original author or authors.
|
||||
* Copyright 2013-2024 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.
|
||||
@@ -30,9 +30,10 @@ import org.springframework.cloud.config.client.ConfigServerConfigDataLocationRes
|
||||
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
|
||||
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactory;
|
||||
import org.springframework.cloud.netflix.eureka.http.RestClientTransportClientFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
public class EurekaConfigServerBootstrapper implements BootstrapRegistryInitializer {
|
||||
@@ -57,10 +58,10 @@ public class EurekaConfigServerBootstrapper implements BootstrapRegistryInitiali
|
||||
return (id) -> Collections.emptyList();
|
||||
}
|
||||
EurekaClientConfigBean config = context.get(EurekaClientConfigBean.class);
|
||||
EurekaHttpClient httpClient = new RestTemplateTransportClientFactory(
|
||||
EurekaHttpClient httpClient = new RestClientTransportClientFactory(
|
||||
context.getOrElse(TlsProperties.class, null),
|
||||
context.getOrElse(EurekaClientHttpRequestFactorySupplier.class,
|
||||
new DefaultEurekaClientHttpRequestFactorySupplier()))
|
||||
new DefaultEurekaClientHttpRequestFactorySupplier(new RestClientTimeoutProperties())))
|
||||
.newClient(HostnameBasedUrlRandomizer.randomEndpoint(config, getPropertyResolver(context)));
|
||||
return new EurekaConfigServerInstanceProvider(httpClient, config)::getInstances;
|
||||
});
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.apache.hc.core5.http.io.SocketConfig;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
|
||||
import org.springframework.cloud.netflix.eureka.TimeoutProperties;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -47,29 +48,38 @@ import org.springframework.lang.Nullable;
|
||||
*/
|
||||
public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClientHttpRequestFactorySupplier {
|
||||
|
||||
private final RestTemplateTimeoutProperties restTemplateTimeoutProperties;
|
||||
private final TimeoutProperties timeoutProperties;
|
||||
|
||||
/**
|
||||
* @deprecated in favour of
|
||||
* {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(RestTemplateTimeoutProperties)}
|
||||
* {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public DefaultEurekaClientHttpRequestFactorySupplier() {
|
||||
this.restTemplateTimeoutProperties = new RestTemplateTimeoutProperties();
|
||||
this.timeoutProperties = new RestTemplateTimeoutProperties();
|
||||
}
|
||||
|
||||
public DefaultEurekaClientHttpRequestFactorySupplier(RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
this.restTemplateTimeoutProperties = restTemplateTimeoutProperties;
|
||||
/**
|
||||
* @deprecated in favour of
|
||||
* {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties)}
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public DefaultEurekaClientHttpRequestFactorySupplier(RestTemplateTimeoutProperties timeoutProperties) {
|
||||
this.timeoutProperties = timeoutProperties;
|
||||
}
|
||||
|
||||
public DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties timeoutProperties) {
|
||||
this.timeoutProperties = timeoutProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpRequestFactory get(SSLContext sslContext, @Nullable HostnameVerifier hostnameVerifier) {
|
||||
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
|
||||
if (sslContext != null || hostnameVerifier != null || restTemplateTimeoutProperties != null) {
|
||||
httpClientBuilder.setConnectionManager(
|
||||
buildConnectionManager(sslContext, hostnameVerifier, restTemplateTimeoutProperties));
|
||||
if (sslContext != null || hostnameVerifier != null || timeoutProperties != null) {
|
||||
httpClientBuilder
|
||||
.setConnectionManager(buildConnectionManager(sslContext, hostnameVerifier, timeoutProperties));
|
||||
}
|
||||
if (restTemplateTimeoutProperties != null) {
|
||||
if (timeoutProperties != null) {
|
||||
httpClientBuilder.setDefaultRequestConfig(buildRequestConfig());
|
||||
}
|
||||
|
||||
@@ -80,7 +90,7 @@ public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClie
|
||||
}
|
||||
|
||||
private HttpClientConnectionManager buildConnectionManager(SSLContext sslContext, HostnameVerifier hostnameVerifier,
|
||||
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
|
||||
TimeoutProperties restTemplateTimeoutProperties) {
|
||||
PoolingHttpClientConnectionManagerBuilder connectionManagerBuilder = PoolingHttpClientConnectionManagerBuilder
|
||||
.create();
|
||||
SSLConnectionSocketFactoryBuilder sslConnectionSocketFactoryBuilder = SSLConnectionSocketFactoryBuilder
|
||||
@@ -102,9 +112,9 @@ public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClie
|
||||
|
||||
private RequestConfig buildRequestConfig() {
|
||||
return RequestConfig.custom()
|
||||
.setConnectTimeout(Timeout.of(restTemplateTimeoutProperties.getConnectTimeout(), TimeUnit.MILLISECONDS))
|
||||
.setConnectTimeout(Timeout.of(timeoutProperties.getConnectTimeout(), TimeUnit.MILLISECONDS))
|
||||
.setConnectionRequestTimeout(
|
||||
Timeout.of(restTemplateTimeoutProperties.getConnectRequestTimeout(), TimeUnit.MILLISECONDS))
|
||||
Timeout.of(timeoutProperties.getConnectRequestTimeout(), TimeUnit.MILLISECONDS))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ package org.springframework.cloud.netflix.eureka.http;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import com.fasterxml.jackson.databind.BeanDescription;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
@@ -36,6 +39,8 @@ import com.netflix.discovery.converters.jackson.serializer.InstanceInfoJsonBeanS
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
|
||||
import org.springframework.cloud.configuration.SSLContextFactory;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
@@ -44,6 +49,7 @@ import org.springframework.lang.Nullable;
|
||||
*
|
||||
* @author Daniel Lavoie
|
||||
* @author Wonchul Heo
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 4.2.0
|
||||
*/
|
||||
final class EurekaHttpClientUtils {
|
||||
@@ -123,6 +129,18 @@ final class EurekaHttpClientUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
static Optional<SSLContext> context(TlsProperties properties) {
|
||||
if (properties == null || !properties.isEnabled()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
return Optional.of(new SSLContextFactory(properties).createSSLContext());
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
record UserInfo(String username, String password) {
|
||||
}
|
||||
|
||||
|
||||
@@ -28,11 +28,28 @@ import org.springframework.web.client.RestClient;
|
||||
* supplying {@link ClientRequestFilter}.
|
||||
*
|
||||
* @author Wonchul Heo
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class RestClientDiscoveryClientOptionalArgs extends AbstractDiscoveryClientOptionalArgs<Void> {
|
||||
|
||||
public RestClientDiscoveryClientOptionalArgs(Supplier<RestClient.Builder> builder) {
|
||||
private final EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier;
|
||||
|
||||
private final Supplier<RestClient.Builder> restClientBuilderSupplier;
|
||||
|
||||
public RestClientDiscoveryClientOptionalArgs(
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
Supplier<RestClient.Builder> restClientBuilderSupplier) {
|
||||
this.eurekaClientHttpRequestFactorySupplier = eurekaClientHttpRequestFactorySupplier;
|
||||
this.restClientBuilderSupplier = restClientBuilderSupplier;
|
||||
}
|
||||
|
||||
EurekaClientHttpRequestFactorySupplier getEurekaClientHttpRequestFactorySupplier() {
|
||||
return eurekaClientHttpRequestFactorySupplier;
|
||||
}
|
||||
|
||||
Supplier<RestClient.Builder> getRestClientBuilderSupplier() {
|
||||
return restClientBuilderSupplier;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.springframework.cloud.netflix.eureka.http;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
@@ -28,31 +27,32 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.transport.TransportClientFactory;
|
||||
import com.netflix.discovery.shared.transport.jersey.TransportClientFactories;
|
||||
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
/**
|
||||
* @author Wonchul Heo
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class RestClientTransportClientFactories implements TransportClientFactories<Void> {
|
||||
|
||||
private final Supplier<RestClient.Builder> builder;
|
||||
private final RestClientDiscoveryClientOptionalArgs args;
|
||||
|
||||
public RestClientTransportClientFactories(Supplier<RestClient.Builder> builder) {
|
||||
this.builder = builder;
|
||||
public RestClientTransportClientFactories(RestClientDiscoveryClientOptionalArgs args) {
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportClientFactory newTransportClientFactory(EurekaClientConfig clientConfig,
|
||||
Collection<Void> additionalFilters, InstanceInfo myInstanceInfo) {
|
||||
return new RestClientTransportClientFactory(builder);
|
||||
return new RestClientTransportClientFactory(args.getSSLContext(), args.getHostnameVerifier(),
|
||||
args.getEurekaClientHttpRequestFactorySupplier(), args.getRestClientBuilderSupplier());
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportClientFactory newTransportClientFactory(final EurekaClientConfig clientConfig,
|
||||
final Collection<Void> additionalFilters, final InstanceInfo myInstanceInfo,
|
||||
final Optional<SSLContext> sslContext, final Optional<HostnameVerifier> hostnameVerifier) {
|
||||
return new RestClientTransportClientFactory(builder);
|
||||
return new RestClientTransportClientFactory(args.getSSLContext(), args.getHostnameVerifier(),
|
||||
args.getEurekaClientHttpRequestFactorySupplier(), args.getRestClientBuilderSupplier());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,19 +16,26 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.http;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import com.netflix.discovery.shared.resolver.EurekaEndpoint;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import com.netflix.discovery.shared.transport.TransportClientFactory;
|
||||
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.context;
|
||||
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.extractUserInfo;
|
||||
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.mappingJacksonHttpMessageConverter;
|
||||
|
||||
@@ -38,20 +45,49 @@ import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtil
|
||||
* deserialization.
|
||||
*
|
||||
* @author Wonchul Heo
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class RestClientTransportClientFactory implements TransportClientFactory {
|
||||
|
||||
private final Optional<SSLContext> sslContext;
|
||||
|
||||
private final Optional<HostnameVerifier> hostnameVerifier;
|
||||
|
||||
private final EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier;
|
||||
|
||||
private final Supplier<RestClient.Builder> builderSupplier;
|
||||
|
||||
public RestClientTransportClientFactory(Supplier<RestClient.Builder> builderSupplier) {
|
||||
public RestClientTransportClientFactory(Optional<SSLContext> sslContext,
|
||||
Optional<HostnameVerifier> hostnameVerifier,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
Supplier<RestClient.Builder> builderSupplier) {
|
||||
this.sslContext = sslContext;
|
||||
this.hostnameVerifier = hostnameVerifier;
|
||||
this.eurekaClientHttpRequestFactorySupplier = eurekaClientHttpRequestFactorySupplier;
|
||||
this.builderSupplier = builderSupplier;
|
||||
}
|
||||
|
||||
public RestClientTransportClientFactory(TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
Supplier<RestClient.Builder> builderSupplier) {
|
||||
this(context(tlsProperties), Optional.empty(), eurekaClientHttpRequestFactorySupplier, builderSupplier);
|
||||
}
|
||||
|
||||
public RestClientTransportClientFactory(TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
|
||||
this(tlsProperties, eurekaClientHttpRequestFactorySupplier, RestClient::builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EurekaHttpClient newClient(EurekaEndpoint endpoint) {
|
||||
// we want a copy to modify. Don't change the original
|
||||
final RestClient.Builder builder = builderSupplier.get().clone();
|
||||
|
||||
ClientHttpRequestFactory requestFactory = this.eurekaClientHttpRequestFactorySupplier
|
||||
.get(this.sslContext.orElse(null), this.hostnameVerifier.orElse(null));
|
||||
|
||||
builder.requestFactory(requestFactory);
|
||||
setUrl(builder, endpoint.getServiceUrl());
|
||||
builder.messageConverters(converters -> converters.add(0, mappingJacksonHttpMessageConverter()));
|
||||
|
||||
@@ -69,6 +105,10 @@ public class RestClientTransportClientFactory implements TransportClientFactory
|
||||
return new RestClientEurekaHttpClient(builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
private static void setUrl(RestClient.Builder builder, String serviceUrl) {
|
||||
final String url = UriComponentsBuilder.fromUriString(serviceUrl).userInfo(null).toUriString();
|
||||
|
||||
@@ -79,8 +119,4 @@ public class RestClientTransportClientFactory implements TransportClientFactory
|
||||
builder.baseUrl(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,11 +21,16 @@ import java.util.function.Supplier;
|
||||
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
|
||||
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
* @author Armin Krezovic
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
|
||||
* {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Deprecated
|
||||
public class RestTemplateDiscoveryClientOptionalArgs extends AbstractDiscoveryClientOptionalArgs<Void> {
|
||||
|
||||
protected final EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier;
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
@@ -46,7 +47,10 @@ import static com.netflix.discovery.shared.transport.EurekaHttpResponse.anEureka
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
* @author Václav Plic
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
|
||||
* {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class RestTemplateEurekaHttpClient implements EurekaHttpClient {
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
@@ -27,10 +27,16 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.transport.TransportClientFactory;
|
||||
import com.netflix.discovery.shared.transport.jersey.TransportClientFactories;
|
||||
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* @author Daniel Lavoie
|
||||
* @author Armin Krezovic
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
|
||||
* {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class RestTemplateTransportClientFactories implements TransportClientFactories<Void> {
|
||||
|
||||
private final RestTemplateDiscoveryClientOptionalArgs args;
|
||||
@@ -42,16 +48,16 @@ public class RestTemplateTransportClientFactories implements TransportClientFact
|
||||
@Override
|
||||
public TransportClientFactory newTransportClientFactory(EurekaClientConfig clientConfig,
|
||||
Collection<Void> additionalFilters, InstanceInfo myInstanceInfo) {
|
||||
return new RestTemplateTransportClientFactory(this.args.getSSLContext(), this.args.getHostnameVerifier(),
|
||||
this.args.eurekaClientHttpRequestFactorySupplier, this.args.restTemplateBuilderSupplier);
|
||||
return new RestTemplateTransportClientFactory(args.getSSLContext(), args.getHostnameVerifier(),
|
||||
args.eurekaClientHttpRequestFactorySupplier, args.restTemplateBuilderSupplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TransportClientFactory newTransportClientFactory(final EurekaClientConfig clientConfig,
|
||||
final Collection<Void> additionalFilters, final InstanceInfo myInstanceInfo,
|
||||
final Optional<SSLContext> sslContext, final Optional<HostnameVerifier> hostnameVerifier) {
|
||||
return new RestTemplateTransportClientFactory(this.args.getSSLContext(), this.args.getHostnameVerifier(),
|
||||
this.args.eurekaClientHttpRequestFactorySupplier, this.args.restTemplateBuilderSupplier);
|
||||
return new RestTemplateTransportClientFactory(args.getSSLContext(), args.getHostnameVerifier(),
|
||||
args.eurekaClientHttpRequestFactorySupplier, args.restTemplateBuilderSupplier);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import com.netflix.discovery.shared.transport.TransportClientFactory;
|
||||
|
||||
import org.springframework.boot.web.client.RestTemplateBuilder;
|
||||
import org.springframework.cloud.configuration.SSLContextFactory;
|
||||
import org.springframework.cloud.configuration.TlsProperties;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
@@ -35,9 +34,11 @@ import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
|
||||
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.context;
|
||||
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.extractUserInfo;
|
||||
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.mappingJacksonHttpMessageConverter;
|
||||
|
||||
@@ -49,7 +50,11 @@ import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtil
|
||||
* @author Daniel Lavoie
|
||||
* @author Armin Krezovic
|
||||
* @author Wonchul Heo
|
||||
* @author Olga Maciaszek-Sharma
|
||||
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
|
||||
* {@link RestClient}-based implementation.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public class RestTemplateTransportClientFactory implements TransportClientFactory {
|
||||
|
||||
private final Optional<SSLContext> sslContext;
|
||||
@@ -60,32 +65,6 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
|
||||
|
||||
private final Supplier<RestTemplateBuilder> restTemplateBuilderSupplier;
|
||||
|
||||
public RestTemplateTransportClientFactory(TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
Supplier<RestTemplateBuilder> restTemplateBuilderSupplier) {
|
||||
this.sslContext = context(tlsProperties);
|
||||
this.hostnameVerifier = Optional.empty();
|
||||
this.eurekaClientHttpRequestFactorySupplier = eurekaClientHttpRequestFactorySupplier;
|
||||
this.restTemplateBuilderSupplier = restTemplateBuilderSupplier;
|
||||
}
|
||||
|
||||
public RestTemplateTransportClientFactory(TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
|
||||
this(tlsProperties, eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
|
||||
}
|
||||
|
||||
private Optional<SSLContext> context(TlsProperties properties) {
|
||||
if (properties == null || !properties.isEnabled()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
try {
|
||||
return Optional.of(new SSLContextFactory(properties).createSSLContext());
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public RestTemplateTransportClientFactory(Optional<SSLContext> sslContext,
|
||||
Optional<HostnameVerifier> hostnameVerifier,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
@@ -96,6 +75,18 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
|
||||
this.restTemplateBuilderSupplier = restTemplateBuilderSupplier;
|
||||
}
|
||||
|
||||
public RestTemplateTransportClientFactory(TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
|
||||
Supplier<RestTemplateBuilder> restTemplateBuilderSupplier) {
|
||||
this(context(tlsProperties), Optional.empty(), eurekaClientHttpRequestFactorySupplier,
|
||||
restTemplateBuilderSupplier);
|
||||
}
|
||||
|
||||
public RestTemplateTransportClientFactory(TlsProperties tlsProperties,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
|
||||
this(tlsProperties, eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
|
||||
}
|
||||
|
||||
public RestTemplateTransportClientFactory(Optional<SSLContext> sslContext,
|
||||
Optional<HostnameVerifier> hostnameVerifier,
|
||||
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
|
||||
@@ -103,6 +94,11 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
|
||||
this(sslContext, hostnameVerifier, eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
/**
|
||||
* @deprecated pass the default values while initialising object in test classes.
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
public RestTemplateTransportClientFactory() {
|
||||
this(Optional.empty(), Optional.empty(), new DefaultEurekaClientHttpRequestFactorySupplier());
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.http;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider;
|
||||
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -26,11 +28,15 @@ import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
/**
|
||||
* Tests for {@link RestClientEurekaHttpClient}.
|
||||
*
|
||||
* @author Wonchul Heo
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
@SpringBootTest(classes = EurekaServerMockApplication.class,
|
||||
properties = { "debug=true", "security.basic.enabled=true", "eureka.client.fetch-registry=false",
|
||||
@@ -47,7 +53,9 @@ class RestClientEurekaHttpClientTests extends AbstractEurekaHttpClientTests {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
eurekaHttpClient = new RestClientTransportClientFactory(RestClient::builder)
|
||||
eurekaHttpClient = new RestClientTransportClientFactory(Optional.empty(), Optional.empty(),
|
||||
new DefaultEurekaClientHttpRequestFactorySupplier(new RestClientTimeoutProperties()),
|
||||
RestClient::builder)
|
||||
.newClient(new DefaultEndpoint(serviceUrl));
|
||||
|
||||
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
|
||||
|
||||
@@ -16,18 +16,24 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.http;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
|
||||
import com.netflix.discovery.shared.transport.EurekaHttpClient;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
|
||||
import org.springframework.web.client.RestClient;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link RestClientTransportClientFactory}.
|
||||
*
|
||||
* @author Wonchul Heo
|
||||
* @author Olga Maciaszek-Sharma
|
||||
*/
|
||||
class RestClientTransportClientFactoryTests {
|
||||
|
||||
@@ -35,7 +41,9 @@ class RestClientTransportClientFactoryTests {
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
transportClientFactory = new RestClientTransportClientFactory(RestClient::builder);
|
||||
transportClientFactory = new RestClientTransportClientFactory(Optional.empty(), Optional.empty(),
|
||||
new DefaultEurekaClientHttpRequestFactorySupplier(new RestClientTimeoutProperties()),
|
||||
RestClient::builder);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user