Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs/src/main/asciidoc/spring-cloud-netflix.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ 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 infinite. 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.)

.application.yml
[source,yaml]
----
eureka:
client:
rest-template-timeout:
connect-timeout: 5000
connect-request-timeout: 8000
socket-timeout: 10000
----

=== Status Page and Health Indicator

The status page and health indicators for a Eureka instance default to `/info` and `/health` respectively, which are the default locations of useful endpoints in a Spring Boot Actuator application.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* 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.netflix.eureka;

import java.util.Objects;

import org.apache.http.client.config.RequestConfig;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
import org.springframework.web.client.RestTemplate;

/**
* Properties for configuring timeouts used in {@link RestTemplate} required by
* {@link RestTemplateEurekaHttpClient}.
*
* @author Jiwon Jeon
* @since 4.0.0
*/
@ConfigurationProperties("eureka.client.rest-template-timeout")
public class RestTemplateTimeoutProperties {

/**
* Default values are set to -1 according to {@link RequestConfig .DEFAULT}.
*/
private int connectTimeout = -1;

private int connectRequestTimeout = -1;

private int socketTimeout = -1;

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);
}

@Override
public String toString() {
return "RestTemplateTimeoutProperties{" + ", connectTimeout=" + connectTimeout + ", connectRequestTimeout="
+ connectRequestTimeout + ", socketTimeout=" + socketTimeout + '}';
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.configuration.SSLContextFactory;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.cloud.netflix.eureka.MutableDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
Expand All @@ -46,6 +48,7 @@
* @author Daniel Lavoie
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(RestTemplateTimeoutProperties.class)
public class DiscoveryClientOptionalArgsConfiguration {

protected static final Log logger = LogFactory.getLog(DiscoveryClientOptionalArgsConfiguration.class);
Expand Down Expand Up @@ -75,8 +78,9 @@ public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOption
@Bean
@ConditionalOnMissingBean
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier() {
return new DefaultEurekaClientHttpRequestFactorySupplier();
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;

import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;

import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.lang.Nullable;
Expand All @@ -36,6 +38,16 @@
*/
public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClientHttpRequestFactorySupplier {

private final RestTemplateTimeoutProperties restTemplateTimeoutProperties;

public DefaultEurekaClientHttpRequestFactorySupplier() {
this.restTemplateTimeoutProperties = new RestTemplateTimeoutProperties();
}

public DefaultEurekaClientHttpRequestFactorySupplier(RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
this.restTemplateTimeoutProperties = restTemplateTimeoutProperties;
}

@Override
public ClientHttpRequestFactory get(SSLContext sslContext, @Nullable HostnameVerifier hostnameVerifier) {
HttpClientBuilder httpClientBuilder = HttpClients.custom();
Expand All @@ -45,10 +57,20 @@ public ClientHttpRequestFactory get(SSLContext sslContext, @Nullable HostnameVer
if (hostnameVerifier != null) {
httpClientBuilder = httpClientBuilder.setSSLHostnameVerifier(hostnameVerifier);
}
if (restTemplateTimeoutProperties != null) {
httpClientBuilder.setDefaultRequestConfig(buildRequestConfig());
}

CloseableHttpClient httpClient = httpClientBuilder.build();
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return requestFactory;
}

private RequestConfig buildRequestConfig() {
return RequestConfig.custom().setConnectTimeout(restTemplateTimeoutProperties.getConnectTimeout())
.setConnectionRequestTimeout(restTemplateTimeoutProperties.getConnectRequestTimeout())
.setSocketTimeout(restTemplateTimeoutProperties.getSocketTimeout()).build();
}

}