Merge remote-tracking branch 'Upstream/master' into http-client-centralization

This commit is contained in:
Ryan Baxter
2017-08-01 16:46:07 -04:00
147 changed files with 4821 additions and 1015 deletions

View File

@@ -12,7 +12,7 @@ dependencies:
- ./mvnw -s .settings.xml -U --fail-never dependency:go-offline || true
test:
override:
- ./mvnw -s .settings.xml clean install org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
- ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
post:
- find . -type f -regex ".*/spring-cloud-*.*/target/*.*" | cpio -pdm $CIRCLE_ARTIFACTS
- mkdir -p $CIRCLE_TEST_REPORTS/junit/

View File

@@ -20,7 +20,7 @@ Service Discovery is one of the key tenets of a microservice based architecture.
=== How to Include Eureka Client
To include Eureka Client in your project use the starter with group `org.springframework.cloud`
and artifact id `spring-cloud-starter-eureka`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
and artifact id `spring-cloud-starter-netflix-eureka-client`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
for details on setting up your build system with the current Spring Cloud Release Train.
=== Registering with Eureka
@@ -265,6 +265,34 @@ not be started yet). It is initialized in a `SmartLifecycle` (with
another `SmartLifecycle` with higher phase.
====
==== EurekaClient without Jersey
By default, EurekaClient uses Jersey for HTTP communication. If you wish
to avoid dependencies from Jersey, you can exclude it from your dependencies.
Spring Cloud will auto configure a transport client based on Spring
`RestTemplate`.
----
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-apache-client4</artifactId>
</exclusion>
</exclusions>
</dependency>
----
=== Alternatives to the native Netflix EurekaClient
You don't have to use the raw Netflix `EurekaClient` and usually it
@@ -341,7 +369,7 @@ eureka.client.preferSameZoneEureka = true
=== How to Include Eureka Server
To include Eureka Server in your project use the starter with group `org.springframework.cloud`
and artifact id `spring-cloud-starter-eureka-server`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
and artifact id `spring-cloud-starter-netflix-eureka-server`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
for details on setting up your build system with the current Spring Cloud Release Train.
[[spring-cloud-running-eureka-server]]
@@ -370,7 +398,7 @@ Eureka background reading: see https://github.com/cfregly/fluxcapacitor/wiki/Net
[TIP]
====
Due to Gradle's dependency resolution rules and the lack of a parent bom feature, simply depending on spring-cloud-starter-eureka-server can cause failures on application startup. To remedy this the Spring Boot Gradle plugin must be added and the Spring cloud starter parent bom must be imported like so:
Due to Gradle's dependency resolution rules and the lack of a parent bom feature, simply depending on spring-cloud-starter-netflix-eureka-server can cause failures on application startup. To remedy this the Spring Boot Gradle plugin must be added and the Spring cloud starter parent bom must be imported like so:
.build.gradle
[source,java,indent=0]
@@ -488,6 +516,14 @@ of services rather than the hostname. Set `eureka.instance.preferIpAddress`
to `true` and when the application registers with eureka, it will use its
IP Address rather than its hostname.
[TIP]
====
If hostname can't be determined by Java, then IP address is sent to Eureka.
Only explict way of setting hostname is by using `eureka.instance.hostname`.
You can set your hostname at the run time using environment variable, for
example `eureka.instance.hostname=${HOST_NAME}`.
====
== Circuit Breaker: Hystrix Clients
Netflix has created a library called https://github.com/Netflix/Hystrix[Hystrix] that implements the http://martinfowler.com/bliki/CircuitBreaker.html[circuit breaker pattern]. In a microservice architecture it is common to have multiple layers of service calls.
@@ -495,7 +531,7 @@ Netflix has created a library called https://github.com/Netflix/Hystrix[Hystrix]
.Microservice Graph
image::HystrixGraph.png[]
A service failure in the lower level of services can cause cascading failure all the way up to the user. When calls to a particular service reach a certain threshold (20 failures in 5 seconds is the default in Hystrix), the circuit opens and the call is not made. In cases of error and an open circuit a fallback can be provided by the developer.
A service failure in the lower level of services can cause cascading failure all the way up to the user. When calls to a particular service is greater than `circuitBreaker.requestVolumeThreshold` (default: 20 requests) and failue percentage is greater than `circuitBreaker.errorThresholdPercentage` (default: >50%) in a rolling window defined by `metrics.rollingStats.timeInMilliseconds` (default: 10 seconds), the circuit opens and the call is not made. In cases of error and an open circuit a fallback can be provided by the developer.
.Hystrix fallback prevents cascading failures
image::HystrixFallback.png[]
@@ -507,7 +543,7 @@ Having an open circuit stops cascading failures and allows overwhelmed or failin
=== How to Include Hystrix
To include Hystrix in your project use the starter with group `org.springframework.cloud`
and artifact id `spring-cloud-starter-hystrix`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
and artifact id `spring-cloud-starter-netflix-hystrix`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
for details on setting up your build system with the current Spring Cloud Release Train.
Example boot app:
@@ -619,14 +655,14 @@ be slightly more than three seconds.
=== How to Include Hystrix Dashboard
To include the Hystrix Dashboard in your project use the starter with group `org.springframework.cloud`
and artifact id `spring-cloud-starter-hystrix-dashboard`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
and artifact id `spring-cloud-starter-hystrix-netflix-dashboard`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
for details on setting up your build system with the current Spring Cloud Release Train.
To run the Hystrix Dashboard annotate your Spring Boot main class with `@EnableHystrixDashboard`. You then visit `/hystrix` and point the dashboard to an individual instances `/hystrix.stream` endpoint in a Hystrix client application.
=== Turbine
Looking at an individual instances Hystrix data is not very useful in terms of the overall health of the system. https://github.com/Netflix/Turbine[Turbine] is an application that aggregates all of the relevant `/hystrix.stream` endpoints into a combined `/turbine.stream` for use in the Hystrix Dashboard. Individual instances are located via Eureka. Running Turbine is as simple as annotating your main class with the `@EnableTurbine` annotation (e.g. using spring-cloud-starter-turbine to set up the classpath). All of the documented configuration properties from https://github.com/Netflix/Turbine/wiki/Configuration-(1.x)[the Turbine 1 wiki] apply. The only difference is that the `turbine.instanceUrlSuffix` does not need the port prepended as this is handled automatically unless `turbine.instanceInsertPort=false`.
Looking at an individual instances Hystrix data is not very useful in terms of the overall health of the system. https://github.com/Netflix/Turbine[Turbine] is an application that aggregates all of the relevant `/hystrix.stream` endpoints into a combined `/turbine.stream` for use in the Hystrix Dashboard. Individual instances are located via Eureka. Running Turbine is as simple as annotating your main class with the `@EnableTurbine` annotation (e.g. using spring-cloud-starter-netflix-turbine to set up the classpath). All of the documented configuration properties from https://github.com/Netflix/Turbine/wiki/Configuration-(1.x)[the Turbine 1 wiki] apply. The only difference is that the `turbine.instanceUrlSuffix` does not need the port prepended as this is handled automatically unless `turbine.instanceInsertPort=false`.
NOTE: By default, Turbine looks for the `/hystrix.stream` endpoint on a registered instance by looking up its `homePageUrl` entry in Eureka, then appending `/hystrix.stream` to it. This means that if `spring-boot-actuator` is running on its own port (which is the default), the call to `/hystrix.stream` will fail.
To make turbine find the Hystrix stream at the correct port, you need to add `management.port` to the instances' metadata:
@@ -667,7 +703,7 @@ turbine:
clusterNameExpression: "'default'"
----
Spring Cloud provides a `spring-cloud-starter-turbine` that has all the dependencies you need to get a Turbine server running. Just create a Spring Boot application and annotate it with `@EnableTurbine`.
Spring Cloud provides a `spring-cloud-starter-netflix-turbine` that has all the dependencies you need to get a Turbine server running. Just create a Spring Boot application and annotate it with `@EnableTurbine`.
NOTE: by default Spring Cloud allows Turbine to use the host and port to allow multiple processes per host, per cluster. If you want the native Netflix behaviour built into Turbine that does _not_ allow multiple processes per host, per cluster (the key to the instance id is the hostname), then set the property `turbine.combineHostPort=false`.
@@ -679,7 +715,7 @@ On the server side Just create a Spring Boot application and annotate it with `@
You can then point the Hystrix Dashboard to the Turbine Stream Server instead of individual Hystrix streams. If Turbine Stream is running on port 8989 on myhost, then put `http://myhost:8989` in the stream input field in the Hystrix Dashboard. Circuits will be prefixed by their respective serviceId, followed by a dot, then the circuit name.
Spring Cloud provides a `spring-cloud-starter-turbine-stream` that has all the dependencies you need to get a Turbine Stream server running - just add the Stream binder of your choice, e.g. `spring-cloud-starter-stream-rabbit`. You need Java 8 to run the app because it is Netty-based.
Spring Cloud provides a `spring-cloud-starter-netflix-turbine-stream` that has all the dependencies you need to get a Turbine Stream server running - just add the Stream binder of your choice, e.g. `spring-cloud-starter-stream-rabbit`. You need Java 8 to run the app because it is Netty-based.
[[spring-cloud-ribbon]]
== Client Side Load Balancer: Ribbon
@@ -701,7 +737,7 @@ annotation). Spring Cloud creates a new ensemble as an
=== How to Include Ribbon
To include Ribbon in your project use the starter with group `org.springframework.cloud`
and artifact id `spring-cloud-starter-ribbon`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
and artifact id `spring-cloud-starter-netflix-ribbon`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
for details on setting up your build system with the current Spring Cloud Release Train.
=== Customizing the Ribbon Client
@@ -710,7 +746,7 @@ You can configure some bits of a Ribbon client using external
properties in `<client>.ribbon.*`, which is no different than using
the Netflix APIs natively, except that you can use Spring Boot
configuration files. The native options can
be inspected as static fields in `CommonClientConfigKey` (part of
be inspected as static fields in https://github.com/Netflix/ribbon/blob/master/ribbon-core/src/main/java/com/netflix/client/config/CommonClientConfigKey.java[`CommonClientConfigKey`] (part of
ribbon-core).
Spring Cloud also lets you take full control of the client by
@@ -742,7 +778,7 @@ Spring Cloud Netflix provides the following beans by default for ribbon
* `IClientConfig` ribbonClientConfig: `DefaultClientConfigImpl`
* `IRule` ribbonRule: `ZoneAvoidanceRule`
* `IPing` ribbonPing: `NoOpPing`
* `IPing` ribbonPing: `DummyPing`
* `ServerList<Server>` ribbonServerList: `ConfigurationBasedServerList`
* `ServerListFilter<Server>` ribbonServerListFilter: `ZonePreferenceServerListFilter`
* `ILoadBalancer` ribbonLoadBalancer: `ZoneAwareLoadBalancer`
@@ -754,16 +790,18 @@ one of the beans described. Example:
[source,java,indent=0]
----
@Configuration
public class FooConfiguration {
@Bean
public IPing ribbonPing(IClientConfig config) {
return new PingUrl();
}
}
include::../../../../spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientsPreprocessorIntegrationTests.java[tags=sample_override_ribbon_config,indent=0]
----
This replaces the `NoOpPing` with `PingUrl`.
This replaces the `NoOpPing` with `PingUrl` and provides a custom `serverListFilter`
=== Customizing default for all Ribbon Clients
A default configuration can be provided for all Ribbon Clients using the `@RibbonClients` annotation and registering a default configuration as shown in the following example:
[source,java,indent=0]
----
include::../../../../spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/test/RibbonClientDefaultConfigurationTestsConfig.java[tags=sample_default_ribbon_config,indent=0]
----
=== Customizing the Ribbon Client using properties
@@ -919,7 +957,7 @@ https://github.com/Netflix/feign[Feign] is a declarative web service client. It
=== How to Include Feign
To include Feign in your project use the starter with group `org.springframework.cloud`
and artifact id `spring-cloud-starter-feign`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
and artifact id `spring-cloud-starter-openfeign`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
for details on setting up your build system with the current Spring Cloud Release Train.
Example spring boot app
@@ -1366,7 +1404,7 @@ NOTE: Default Hystrix isolation pattern (ExecutionIsolationStrategy) for all rou
=== How to Include Zuul
To include Zuul in your project use the starter with group `org.springframework.cloud`
and artifact id `spring-cloud-starter-zuul`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
and artifact id `spring-cloud-starter-netflix-zuul`. See the http://projects.spring.io/spring-cloud/[Spring Cloud Project page]
for details on setting up your build system with the current Spring Cloud Release Train.
[[netflix-zuul-reverse-proxy]]
@@ -1660,7 +1698,37 @@ To not discard these well known security headers in case Spring Security is on t
If you are using `@EnableZuulProxy` with tha Spring Boot Actuator you
will enable (by default) an additional endpoint, available via HTTP as
`/routes`. A GET to this endpoint will return a list of the mapped
routes. A POST will force a refresh of the existing routes (e.g. in
routes:
.GET /routes
[source,json]
----
{
/stores/**: "http://localhost:8081"
}
----
Additional route details can be requested by adding the `?format=details` query
string to `/routes`. This will produce the following output:
.GET /routes?format=details
[source,json]
----
{
"/stores/**": {
"id": "stores",
"fullPath": "/stores/**",
"location": "http://localhost:8081",
"path": "/**",
"prefix": "/stores",
"retryable": false,
"customSensitiveHeaders": false,
"prefixStripped": true
}
}
----
A POST will force a refresh of the existing routes (e.g. in
case there have been changes in the service catalog). You can disable
this endpoint by setting `endpoints.routes.enabled` to `false`.
@@ -2386,7 +2454,7 @@ To enable Spectator metrics, include a dependency on `spring-boot-starter-specta
----
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-spectator</artifactId>
<artifactId>spring-cloud-starter-netflix-spectator</artifactId>
</dependency>
----
@@ -2490,7 +2558,7 @@ Atlas was developed by Netflix to manage dimensional time series data for near r
Atlas captures operational intelligence. Whereas business intelligence is data gathered for analyzing trends over time, operational intelligence provides a picture of what is currently happening within a system.
Spring Cloud provides a `spring-cloud-starter-atlas` that has all the dependencies you need. Then just annotate your Spring Boot application with `@EnableAtlas` and provide a location for your running Atlas server with the `netflix.atlas.uri` property.
Spring Cloud provides a `spring-cloud-starter-netflix-atlas` that has all the dependencies you need. Then just annotate your Spring Boot application with `@EnableAtlas` and provide a location for your running Atlas server with the `netflix.atlas.uri` property.
==== Global tags

View File

@@ -28,6 +28,9 @@
<spring-cloud-config.version>1.4.0.BUILD-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-stream.version>Ditmars.BUILD-SNAPSHOT</spring-cloud-stream.version>
<!-- Plugin versions -->
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
<!-- Sonar -->
<surefire.plugin.version>2.19.1</surefire.plugin.version>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
@@ -40,6 +43,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>${maven-eclipse-plugin.version}</version>
<configuration>
<useProjectReferences>false</useProjectReferences>
<additionalConfig>
@@ -56,6 +60,7 @@
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
@@ -129,6 +134,7 @@
<module>spring-cloud-netflix-turbine</module>
<module>spring-cloud-netflix-turbine-stream</module>
<module>spring-cloud-netflix-sidecar</module>
<module>spring-cloud-starter-netflix</module>
<module>spring-cloud-starter-archaius</module>
<module>spring-cloud-starter-atlas</module>
<module>spring-cloud-starter-eureka</module>

View File

@@ -38,6 +38,8 @@ import org.apache.commons.configuration.SystemConfiguration;
import org.apache.commons.configuration.event.ConfigurationEvent;
import org.apache.commons.configuration.event.ConfigurationListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
@@ -60,18 +62,17 @@ import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME;
import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
import lombok.extern.apachecommons.CommonsLog;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnClass({ ConcurrentCompositeConfiguration.class,
ConfigurationBuilder.class })
@CommonsLog
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
public class ArchaiusAutoConfiguration {
private static final Log log = LogFactory.getLog(ArchaiusAutoConfiguration.class);
private static final AtomicBoolean initialized = new AtomicBoolean(false);
@Autowired

View File

@@ -214,7 +214,7 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
}
throw new IllegalStateException(
"No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-ribbon?");
"No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?");
}
@Override

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.netflix.feign.ribbon;
import feign.Client;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
*/
@Configuration
class DefaultFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory) {
return new LoadBalancerFeignClient(new Client.Default(null, null),
cachingFactory, clientFactory);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,43 +16,24 @@
package org.springframework.cloud.netflix.feign.ribbon;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;
import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import com.netflix.loadbalancer.ILoadBalancer;
import feign.Client;
import feign.Feign;
import feign.Request;
import feign.httpclient.ApacheHttpClient;
import feign.okhttp.OkHttpClient;
import okhttp3.ConnectionPool;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
/**
* Autoconfiguration to be activated if Feign is in use and needs to be use Ribbon as a
@@ -64,6 +45,11 @@ import javax.annotation.PreDestroy;
@Configuration
@AutoConfigureBefore(FeignAutoConfiguration.class)
@EnableConfigurationProperties({ FeignHttpClientProperties.class })
//Order is important here, last should be the default, first should be optional
// see https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({ HttpClientFeignLoadBalancedConfiguration.class,
OkHttpFeignLoadBalancedConfiguration.class,
DefaultFeignLoadBalancedConfiguration.class })
public class FeignRibbonClientAutoConfiguration {
@Bean
@@ -83,139 +69,9 @@ public class FeignRibbonClientAutoConfiguration {
return new CachingSpringLoadBalancerFactory(factory, retryPolicyFactory, true);
}
@Bean
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory) {
return new LoadBalancerFeignClient(new Client.Default(null, null), cachingFactory,
clientFactory);
}
@Bean
@ConditionalOnMissingBean
public Request.Options feignRequestOptions() {
return LoadBalancerFeignClient.DEFAULT_OPTIONS;
}
@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
@ConditionalOnMissingBean(CloseableHttpClient.class)
protected static class HttpClientFeignConfiguration {
private final Timer connectionManagerTimer = new Timer(
"FeignApacheHttpClientConfiguration.connectionManagerTimer", true);
private CloseableHttpClient httpClient;
@Autowired(required = false)
private RegistryBuilder registryBuilder;
@Bean
@ConditionalOnMissingBean(HttpClientConnectionManager.class)
public HttpClientConnectionManager connectionManager(
ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
FeignHttpClientProperties httpClientProperties) {
final HttpClientConnectionManager connectionManager = connectionManagerFactory
.newConnectionManager(false, httpClientProperties.getMaxConnections(),
httpClientProperties.getMaxConnectionsPerRoute(),
httpClientProperties.getTimeToLive(),
httpClientProperties.getTimeToLiveUnit(), registryBuilder);
this.connectionManagerTimer.schedule(new TimerTask() {
@Override
public void run() {
connectionManager.closeExpiredConnections();
}
}, 30000, httpClientProperties.getConnectionTimerRepeat());
return connectionManager;
}
@Bean
public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory,
HttpClientConnectionManager httpClientConnectionManager,
FeignHttpClientProperties httpClientProperties) {
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(httpClientProperties.getConnectionTimeout())
.setRedirectsEnabled(httpClientProperties.isFollowRedirects())
.build();
this.httpClient = httpClientFactory.createBuilder().
setDefaultRequestConfig(defaultRequestConfig).
setConnectionManager(httpClientConnectionManager).build();
return this.httpClient;
}
@PreDestroy
public void destroy() throws Exception {
connectionManagerTimer.cancel();
if(httpClient != null) {
httpClient.close();
}
}
}
@Configuration
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
@ConditionalOnClass(ApacheHttpClient.class)
protected static class HttpClientFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, HttpClient httpClient) {
ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}
@Configuration
@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty(value = "feign.okhttp.enabled")
protected static class OkHttpFeignConfiguration {
private okhttp3.OkHttpClient okHttpClient;
@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties,
OkHttpClientConnectionPoolFactory connectionPoolFactory) {
Integer maxTotalConnections = httpClientProperties.getMaxConnections();
Long timeToLive = httpClientProperties.getTimeToLive();
TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
}
@Bean
public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory,
ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {
Boolean followRedirects = httpClientProperties.isFollowRedirects();
Integer connectTimeout = httpClientProperties.getConnectionTimeout();
this.okHttpClient = httpClientFactory.createBuilder(false).
connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).
followRedirects(followRedirects).
connectionPool(connectionPool).build();
return this.okHttpClient;
}
@PreDestroy
public void destroy() {
if(okHttpClient != null) {
okHttpClient.dispatcher().executorService().shutdown();
okHttpClient.connectionPool().evictAll();
}
}
}
@Configuration
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty(value = "feign.okhttp.enabled")
protected static class OkHttpFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {
OkHttpClient delegate = new OkHttpClient(okHttpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.netflix.feign.ribbon;
import feign.Client;
import feign.httpclient.ApacheHttpClient;
import java.util.Timer;
import java.util.TimerTask;
import javax.annotation.PreDestroy;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
class HttpClientFeignLoadBalancedConfiguration {
@Configuration
@ConditionalOnMissingBean(CloseableHttpClient.class)
protected static class HttpClientFeignConfiguration {
private final Timer connectionManagerTimer = new Timer(
"FeignApacheHttpClientConfiguration.connectionManagerTimer", true);
private CloseableHttpClient httpClient;
@Autowired(required = false)
private RegistryBuilder registryBuilder;
@Bean
@ConditionalOnMissingBean(HttpClientConnectionManager.class)
public HttpClientConnectionManager connectionManager(
ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
FeignHttpClientProperties httpClientProperties) {
final HttpClientConnectionManager connectionManager = connectionManagerFactory
.newConnectionManager(false, httpClientProperties.getMaxConnections(),
httpClientProperties.getMaxConnectionsPerRoute(),
httpClientProperties.getTimeToLive(),
httpClientProperties.getTimeToLiveUnit(), registryBuilder);
this.connectionManagerTimer.schedule(new TimerTask() {
@Override
public void run() {
connectionManager.closeExpiredConnections();
}
}, 30000, httpClientProperties.getConnectionTimerRepeat());
return connectionManager;
}
@Bean
public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory,
HttpClientConnectionManager httpClientConnectionManager,
FeignHttpClientProperties httpClientProperties) {
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(httpClientProperties.getConnectionTimeout())
.setRedirectsEnabled(httpClientProperties.isFollowRedirects())
.build();
this.httpClient = httpClientFactory.createBuilder().
setDefaultRequestConfig(defaultRequestConfig).
setConnectionManager(httpClientConnectionManager).build();
return this.httpClient;
}
@PreDestroy
public void destroy() throws Exception {
connectionManagerTimer.cancel();
if(httpClient != null) {
httpClient.close();
}
}
}
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, HttpClient httpClient) {
ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}

View File

@@ -0,0 +1,88 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.netflix.feign.ribbon;
import feign.Client;
import feign.okhttp.OkHttpClient;
import okhttp3.ConnectionPool;
import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty(value = "feign.okhttp.enabled")
class OkHttpFeignLoadBalancedConfiguration {
@Configuration
@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
protected static class OkHttpFeignConfiguration {
private okhttp3.OkHttpClient okHttpClient;
@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties,
OkHttpClientConnectionPoolFactory connectionPoolFactory) {
Integer maxTotalConnections = httpClientProperties.getMaxConnections();
Long timeToLive = httpClientProperties.getTimeToLive();
TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
}
@Bean
public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory,
ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {
Boolean followRedirects = httpClientProperties.isFollowRedirects();
Integer connectTimeout = httpClientProperties.getConnectionTimeout();
this.okHttpClient = httpClientFactory.createBuilder(false).
connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).
followRedirects(followRedirects).
connectionPool(connectionPool).build();
return this.okHttpClient;
}
@PreDestroy
public void destroy() {
if(okHttpClient != null) {
okHttpClient.dispatcher().executorService().shutdown();
okHttpClient.connectionPool().evictAll();
}
}
}
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {
OkHttpClient delegate = new OkHttpClient(okHttpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}

View File

@@ -14,14 +14,12 @@ import org.springframework.util.MultiValueMap;
import feign.FeignException;
import feign.Response;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;
/**
* Decoder adds compatibility for Spring MVC's ResponseEntity to any other decoder via
* composition.
* @author chadjaros
*/
@Slf4j
public class ResponseEntityDecoder implements Decoder {
private Decoder decoder;

View File

@@ -23,6 +23,8 @@ import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.Collection;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.http.HttpHeaders;
@@ -34,7 +36,6 @@ import org.springframework.http.converter.HttpMessageConverter;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import lombok.extern.apachecommons.CommonsLog;
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHeaders;
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
@@ -42,9 +43,10 @@ import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttp
/**
* @author Spencer Gibb
*/
@CommonsLog
public class SpringEncoder implements Encoder {
private static final Log log = LogFactory.getLog(SpringEncoder.class);
private ObjectFactory<HttpMessageConverters> messageConverters;
public SpringEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {

View File

@@ -19,16 +19,18 @@ import java.util.Map;
import com.netflix.servo.MonitorRegistry;
import com.netflix.servo.monitor.BasicTimer;
import com.netflix.servo.monitor.MonitorConfig;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Servo does not provide a mechanism to retrieve an existing monitor by name + tags.
*
* @author Jon Schneider
*/
@CommonsLog
public class ServoMonitorCache {
private static final Log log = LogFactory.getLog(ServoMonitorCache.class);
private final Map<MonitorConfig, BasicTimer> timerCache = new HashMap<>();
private final MonitorRegistry monitorRegistry;
private final ServoMetricsConfigBean config;

View File

@@ -0,0 +1,64 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.netflix.ribbon;
import com.netflix.client.AbstractLoadBalancerAwareClient;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.niws.client.http.RestClient;
import com.netflix.servo.monitor.Monitors;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
/**
* @author Spencer Gibb
*/
@SuppressWarnings("deprecation")
@Configuration
@RibbonAutoConfiguration.ConditionalOnRibbonRestClient
class RestClientRibbonConfiguration {
@Value("${ribbon.client.name}")
private String name = "client";
/**
* Create a Netflix {@link RestClient} integrated with Ribbon if none already exists
* in the application context. It is not required for Ribbon to work properly and is
* therefore created lazily if ever another component requires it.
*
* @param config the configuration to use by the underlying Ribbon instance
* @param loadBalancer the load balancer to use by the underlying Ribbon instance
* @param serverIntrospector server introspector to use by the underlying Ribbon instance
* @param retryHandler retry handler to use by the underlying Ribbon instance
* @return a {@link RestClient} instances backed by Ribbon
*/
@Bean
@Lazy
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer,
ServerIntrospector serverIntrospector, RetryHandler retryHandler) {
RestClient client = new RibbonClientConfiguration.OverrideRestClient(config, serverIntrospector);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
}

View File

@@ -16,51 +16,25 @@
package org.springframework.cloud.netflix.ribbon;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import java.net.URI;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.params.CookiePolicy;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
import org.springframework.cloud.netflix.ribbon.apache.RetryableRibbonLoadBalancingHttpClient;
import org.springframework.cloud.netflix.ribbon.apache.RibbonLoadBalancingHttpClient;
import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpLoadBalancingClient;
import org.springframework.cloud.netflix.ribbon.okhttp.RetryableOkHttpLoadBalancingClient;
import org.springframework.cloud.netflix.ribbon.apache.HttpClientRibbonConfiguration;
import org.springframework.cloud.netflix.ribbon.okhttp.OkHttpRibbonConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import com.netflix.client.AbstractLoadBalancerAwareClient;
import com.netflix.client.DefaultLoadBalancerRetryHandler;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ConfigurationBasedServerList;
@@ -76,7 +50,6 @@ import com.netflix.loadbalancer.ServerListUpdater;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import com.netflix.niws.client.http.RestClient;
import com.netflix.servo.monitor.Monitors;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.client.apache4.ApacheHttpClient4;
@@ -90,7 +63,9 @@ import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttps
@SuppressWarnings("deprecation")
@Configuration
@EnableConfigurationProperties
@Import(HttpClientConfiguration.class)
//Order is important here, last should be the default, first should be optional
// see https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({HttpClientConfiguration.class, OkHttpRibbonConfiguration.class, RestClientRibbonConfiguration.class, HttpClientRibbonConfiguration.class})
public class RibbonClientConfiguration {
@Value("${ribbon.client.name}")
@@ -142,248 +117,6 @@ public class RibbonClientConfiguration {
return serverList;
}
@Configuration
@ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true)
protected static class ApacheHttpClientConfiguration {
private final Timer connectionManagerTimer = new Timer(
"RibbonApacheHttpClientConfiguration.connectionManagerTimer", true);
private CloseableHttpClient httpClient;
@Autowired(required = false)
private RegistryBuilder registryBuilder;
@Bean
@ConditionalOnMissingBean(HttpClientConnectionManager.class)
public HttpClientConnectionManager httpClientConnectionManager(
IClientConfig config,
ApacheHttpClientConnectionManagerFactory connectionManagerFactory) {
Integer maxTotalConnections = config.getPropertyAsInteger(
CommonClientConfigKey.MaxTotalConnections,
DefaultClientConfigImpl.DEFAULT_MAX_TOTAL_CONNECTIONS);
Integer maxConnectionsPerHost = config.getPropertyAsInteger(
CommonClientConfigKey.MaxConnectionsPerHost,
DefaultClientConfigImpl.DEFAULT_MAX_CONNECTIONS_PER_HOST);
Integer timerRepeat = config.getPropertyAsInteger(
CommonClientConfigKey.ConnectionCleanerRepeatInterval,
DefaultClientConfigImpl.DEFAULT_CONNECTION_IDLE_TIMERTASK_REPEAT_IN_MSECS);
Object timeToLiveObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTime);
Long timeToLive = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME;
Object ttlUnitObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTimeUnits);
TimeUnit ttlUnit = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS;
if (timeToLiveObj instanceof Long) {
timeToLive = (Long) timeToLiveObj;
}
if (ttlUnitObj instanceof TimeUnit) {
ttlUnit = (TimeUnit) ttlUnitObj;
}
final HttpClientConnectionManager connectionManager = connectionManagerFactory
.newConnectionManager(false, maxTotalConnections,
maxConnectionsPerHost, timeToLive, ttlUnit, registryBuilder);
this.connectionManagerTimer.schedule(new TimerTask() {
@Override
public void run() {
connectionManager.closeExpiredConnections();
}
}, 30000, timerRepeat);
return connectionManager;
}
@Bean
@ConditionalOnMissingBean(CloseableHttpClient.class)
public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory,
HttpClientConnectionManager connectionManager, IClientConfig config) {
Boolean followRedirects = config.getPropertyAsBoolean(
CommonClientConfigKey.FollowRedirects,
DefaultClientConfigImpl.DEFAULT_FOLLOW_REDIRECTS);
Integer connectTimeout = config.getPropertyAsInteger(
CommonClientConfigKey.ConnectTimeout,
DefaultClientConfigImpl.DEFAULT_CONNECT_TIMEOUT);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setRedirectsEnabled(followRedirects).build();
this.httpClient = httpClientFactory.createBuilder().
setDefaultRequestConfig(defaultRequestConfig).
setConnectionManager(connectionManager).build();
return httpClient;
}
@PreDestroy
public void destroy() throws Exception {
connectionManagerTimer.cancel();
if(httpClient != null) {
httpClient.close();
}
}
}
@Configuration
@ConditionalOnProperty(value = {"ribbon.okhttp.enabled"})
@ConditionalOnClass(name = "okhttp3.OkHttpClient")
protected static class OkHttpClientConfiguration {
private OkHttpClient httpClient;
@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(IClientConfig config,
OkHttpClientConnectionPoolFactory connectionPoolFactory) {
Integer maxTotalConnections = config.getPropertyAsInteger(
CommonClientConfigKey.MaxTotalConnections,
DefaultClientConfigImpl.DEFAULT_MAX_TOTAL_CONNECTIONS);
Object timeToLiveObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTime);
Long timeToLive = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME;
Object ttlUnitObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTimeUnits);
TimeUnit ttlUnit = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS;
if (timeToLiveObj instanceof Long) {
timeToLive = (Long) timeToLiveObj;
}
if (ttlUnitObj instanceof TimeUnit) {
ttlUnit = (TimeUnit) ttlUnitObj;
}
return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
}
@Bean
@ConditionalOnMissingBean(OkHttpClient.class)
public OkHttpClient client(OkHttpClientFactory httpClientFactory,
ConnectionPool connectionPool, IClientConfig config) {
Boolean followRedirects = config.getPropertyAsBoolean(
CommonClientConfigKey.FollowRedirects,
DefaultClientConfigImpl.DEFAULT_FOLLOW_REDIRECTS);
Integer connectTimeout = config.getPropertyAsInteger(
CommonClientConfigKey.ConnectTimeout,
DefaultClientConfigImpl.DEFAULT_CONNECT_TIMEOUT);
Integer readTimeout = config.getPropertyAsInteger(CommonClientConfigKey.ReadTimeout,
DefaultClientConfigImpl.DEFAULT_READ_TIMEOUT);
this.httpClient = httpClientFactory.createBuilder(false).
connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).
readTimeout(readTimeout, TimeUnit.MILLISECONDS).
followRedirects(followRedirects).
connectionPool(connectionPool).build();
return this.httpClient;
}
@PreDestroy
public void destroy() {
if(httpClient != null) {
httpClient.dispatcher().executorService().shutdown();
httpClient.connectionPool().evictAll();
}
}
}
@Configuration
@ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true)
protected static class HttpClientRibbonConfiguration {
@Value("${ribbon.client.name}")
private String name = "client";
@Bean
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
@ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate")
public RibbonLoadBalancingHttpClient ribbonLoadBalancingHttpClient(
IClientConfig config, ServerIntrospector serverIntrospector,
ILoadBalancer loadBalancer, RetryHandler retryHandler,
CloseableHttpClient httpClient) {
RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(
httpClient, config, serverIntrospector);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
@Bean
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
public RetryableRibbonLoadBalancingHttpClient retryableRibbonLoadBalancingHttpClient(
IClientConfig config, ServerIntrospector serverIntrospector,
ILoadBalancer loadBalancer, RetryHandler retryHandler,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
CloseableHttpClient httpClient) {
RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient(
httpClient, config, serverIntrospector,
loadBalancedRetryPolicyFactory);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
}
@Configuration
@ConditionalOnProperty(value = {"ribbon.okhttp.enabled"})
@ConditionalOnClass(name = "okhttp3.OkHttpClient")
protected static class OkHttpRibbonConfiguration {
@Value("${ribbon.client.name}")
private String name = "client";
@Bean
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
public RetryableOkHttpLoadBalancingClient okHttpLoadBalancingClient(
IClientConfig config, ServerIntrospector serverIntrospector,
ILoadBalancer loadBalancer, RetryHandler retryHandler,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
OkHttpClient delegate) {
RetryableOkHttpLoadBalancingClient client = new RetryableOkHttpLoadBalancingClient(
delegate, config, serverIntrospector, loadBalancedRetryPolicyFactory);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
@Bean
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
@ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate")
public OkHttpLoadBalancingClient retryableOkHttpLoadBalancingClient(
IClientConfig config, ServerIntrospector serverIntrospector,
ILoadBalancer loadBalancer, RetryHandler retryHandler, OkHttpClient delegate) {
OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(delegate, config,
serverIntrospector);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
}
@Configuration
@RibbonAutoConfiguration.ConditionalOnRibbonRestClient
protected static class RestClientRibbonConfiguration {
@Value("${ribbon.client.name}")
private String name = "client";
/**
* Create a Netflix {@link RestClient} integrated with Ribbon if none already
* exists in the application context. It is not required for Ribbon to work
* properly and is therefore created lazily if ever another component requires it.
*
* @param config the configuration to use by the underlying Ribbon instance
* @param loadBalancer the load balancer to use by the underlying Ribbon instance
* @param serverIntrospector server introspector to use by the underlying Ribbon
* instance
* @param retryHandler retry handler to use by the underlying Ribbon instance
* @return a {@link RestClient} instances backed by Ribbon
*/
@Bean
@Lazy
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
public RestClient ribbonRestClient(IClientConfig config,
ILoadBalancer loadBalancer, ServerIntrospector serverIntrospector,
RetryHandler retryHandler) {
RestClient client = new OverrideRestClient(config, serverIntrospector);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
}
@Bean
@ConditionalOnMissingBean
public ServerListUpdater ribbonServerListUpdater(IClientConfig config) {

View File

@@ -0,0 +1,162 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.netflix.ribbon.apache;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.client.AbstractLoadBalancerAwareClient;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.servo.monitor.Monitors;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnClass(name = "org.apache.http.client.HttpClient")
@ConditionalOnProperty(name = "ribbon.httpclient.enabled", matchIfMissing = true)
public class HttpClientRibbonConfiguration {
@Value("${ribbon.client.name}")
private String name = "client";
@Configuration
protected static class ApacheHttpClientConfiguration {
private final Timer connectionManagerTimer = new Timer(
"RibbonApacheHttpClientConfiguration.connectionManagerTimer", true);
private CloseableHttpClient httpClient;
@Autowired(required = false)
private RegistryBuilder registryBuilder;
@Bean
@ConditionalOnMissingBean(HttpClientConnectionManager.class)
public HttpClientConnectionManager httpClientConnectionManager(
IClientConfig config,
ApacheHttpClientConnectionManagerFactory connectionManagerFactory) {
Integer maxTotalConnections = config.getPropertyAsInteger(
CommonClientConfigKey.MaxTotalConnections,
DefaultClientConfigImpl.DEFAULT_MAX_TOTAL_CONNECTIONS);
Integer maxConnectionsPerHost = config.getPropertyAsInteger(
CommonClientConfigKey.MaxConnectionsPerHost,
DefaultClientConfigImpl.DEFAULT_MAX_CONNECTIONS_PER_HOST);
Integer timerRepeat = config.getPropertyAsInteger(
CommonClientConfigKey.ConnectionCleanerRepeatInterval,
DefaultClientConfigImpl.DEFAULT_CONNECTION_IDLE_TIMERTASK_REPEAT_IN_MSECS);
Object timeToLiveObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTime);
Long timeToLive = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME;
Object ttlUnitObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTimeUnits);
TimeUnit ttlUnit = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS;
if (timeToLiveObj instanceof Long) {
timeToLive = (Long) timeToLiveObj;
}
if (ttlUnitObj instanceof TimeUnit) {
ttlUnit = (TimeUnit) ttlUnitObj;
}
final HttpClientConnectionManager connectionManager = connectionManagerFactory
.newConnectionManager(false, maxTotalConnections,
maxConnectionsPerHost, timeToLive, ttlUnit, registryBuilder);
this.connectionManagerTimer.schedule(new TimerTask() {
@Override
public void run() {
connectionManager.closeExpiredConnections();
}
}, 30000, timerRepeat);
return connectionManager;
}
@Bean
@ConditionalOnMissingBean(CloseableHttpClient.class)
public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory,
HttpClientConnectionManager connectionManager, IClientConfig config) {
Boolean followRedirects = config.getPropertyAsBoolean(
CommonClientConfigKey.FollowRedirects,
DefaultClientConfigImpl.DEFAULT_FOLLOW_REDIRECTS);
Integer connectTimeout = config.getPropertyAsInteger(
CommonClientConfigKey.ConnectTimeout,
DefaultClientConfigImpl.DEFAULT_CONNECT_TIMEOUT);
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(connectTimeout)
.setRedirectsEnabled(followRedirects).build();
this.httpClient = httpClientFactory.createBuilder().
setDefaultRequestConfig(defaultRequestConfig).
setConnectionManager(connectionManager).build();
return httpClient;
}
@PreDestroy
public void destroy() throws Exception {
connectionManagerTimer.cancel();
if(httpClient != null) {
httpClient.close();
}
}
}
@Bean
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
@ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate")
public RibbonLoadBalancingHttpClient ribbonLoadBalancingHttpClient(
IClientConfig config, ServerIntrospector serverIntrospector,
ILoadBalancer loadBalancer, RetryHandler retryHandler, CloseableHttpClient httpClient) {
RibbonLoadBalancingHttpClient client = new RibbonLoadBalancingHttpClient(
httpClient, config, serverIntrospector);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
@Bean
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
public RetryableRibbonLoadBalancingHttpClient retryableRibbonLoadBalancingHttpClient(
IClientConfig config, ServerIntrospector serverIntrospector,
ILoadBalancer loadBalancer, RetryHandler retryHandler,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, CloseableHttpClient httpClient) {
RetryableRibbonLoadBalancingHttpClient client = new RetryableRibbonLoadBalancingHttpClient(
httpClient, config, serverIntrospector, loadBalancedRetryPolicyFactory);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.springframework.cloud.netflix.ribbon.okhttp;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
import com.netflix.client.AbstractLoadBalancerAwareClient;
import com.netflix.client.RetryHandler;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.servo.monitor.Monitors;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnProperty("ribbon.okhttp.enabled")
@ConditionalOnClass(name = "okhttp3.OkHttpClient")
public class OkHttpRibbonConfiguration {
@Value("${ribbon.client.name}")
private String name = "client";
@Configuration
protected static class OkHttpClientConfiguration {
private OkHttpClient httpClient;
@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(IClientConfig config,
OkHttpClientConnectionPoolFactory connectionPoolFactory) {
Integer maxTotalConnections = config.getPropertyAsInteger(
CommonClientConfigKey.MaxTotalConnections,
DefaultClientConfigImpl.DEFAULT_MAX_TOTAL_CONNECTIONS);
Object timeToLiveObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTime);
Long timeToLive = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME;
Object ttlUnitObj = config
.getProperty(CommonClientConfigKey.PoolKeepAliveTimeUnits);
TimeUnit ttlUnit = DefaultClientConfigImpl.DEFAULT_POOL_KEEP_ALIVE_TIME_UNITS;
if (timeToLiveObj instanceof Long) {
timeToLive = (Long) timeToLiveObj;
}
if (ttlUnitObj instanceof TimeUnit) {
ttlUnit = (TimeUnit) ttlUnitObj;
}
return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
}
@Bean
@ConditionalOnMissingBean(OkHttpClient.class)
public OkHttpClient client(OkHttpClientFactory httpClientFactory,
ConnectionPool connectionPool, IClientConfig config) {
Boolean followRedirects = config.getPropertyAsBoolean(
CommonClientConfigKey.FollowRedirects,
DefaultClientConfigImpl.DEFAULT_FOLLOW_REDIRECTS);
Integer connectTimeout = config.getPropertyAsInteger(
CommonClientConfigKey.ConnectTimeout,
DefaultClientConfigImpl.DEFAULT_CONNECT_TIMEOUT);
Integer readTimeout = config.getPropertyAsInteger(CommonClientConfigKey.ReadTimeout,
DefaultClientConfigImpl.DEFAULT_READ_TIMEOUT);
this.httpClient = httpClientFactory.createBuilder(false).
connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).
readTimeout(readTimeout, TimeUnit.MILLISECONDS).
followRedirects(followRedirects).
connectionPool(connectionPool).build();
return this.httpClient;
}
@PreDestroy
public void destroy() {
if(httpClient != null) {
httpClient.dispatcher().executorService().shutdown();
httpClient.connectionPool().evictAll();
}
}
}
@Bean
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
public RetryableOkHttpLoadBalancingClient okHttpLoadBalancingClient(IClientConfig config,
ServerIntrospector serverIntrospector,
ILoadBalancer loadBalancer,
RetryHandler retryHandler,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
OkHttpClient delegate) {
RetryableOkHttpLoadBalancingClient client = new RetryableOkHttpLoadBalancingClient(delegate, config,
serverIntrospector, loadBalancedRetryPolicyFactory);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
@Bean
@ConditionalOnMissingBean(AbstractLoadBalancerAwareClient.class)
@ConditionalOnMissingClass(value = "org.springframework.retry.support.RetryTemplate")
public OkHttpLoadBalancingClient retryableOkHttpLoadBalancingClient(IClientConfig config,
ServerIntrospector serverIntrospector, ILoadBalancer loadBalancer,
RetryHandler retryHandler, OkHttpClient delegate) {
OkHttpLoadBalancingClient client = new OkHttpLoadBalancingClient(delegate, config,
serverIntrospector);
client.setLoadBalancer(loadBalancer);
client.setRetryHandler(retryHandler);
Monitors.registerObject("Client_" + this.name, client);
return client;
}
}

View File

@@ -18,7 +18,11 @@ package org.springframework.cloud.netflix.zuul;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -34,6 +38,7 @@ import org.springframework.jmx.export.annotation.ManagedResource;
* @author Spencer Gibb
* @author Dave Syer
* @author Ryan Baxter
* @author Gregor Zurowski
*/
@ManagedResource(description = "Can be used to list the reverse proxy routes")
@ConfigurationProperties(prefix = "endpoints.routes")
@@ -59,4 +64,112 @@ public class RoutesEndpoint extends AbstractEndpoint<Map<String, String>> {
}
return map;
}
Map<String, RouteDetails> invokeRouteDetails() {
Map<String, RouteDetails> map = new LinkedHashMap<>();
for (Route route : this.routes.getRoutes()) {
map.put(route.getFullPath(), new RouteDetails(route));
}
return map;
}
/**
* Container for exposing Zuul {@link Route} details as JSON.
*/
@JsonPropertyOrder({ "id", "fullPath", "location" })
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public static class RouteDetails {
private String id;
private String fullPath;
private String path;
private String location;
private String prefix;
private Boolean retryable;
private Set<String> sensitiveHeaders;
private boolean customSensitiveHeaders;
private boolean prefixStripped;
public RouteDetails() {
}
RouteDetails(final Route route) {
this.id = route.getId();
this.fullPath = route.getFullPath();
this.path = route.getPath();
this.location = route.getLocation();
this.prefix = route.getPrefix();
this.retryable = route.getRetryable();
this.sensitiveHeaders = route.getSensitiveHeaders();
this.customSensitiveHeaders = route.isCustomSensitiveHeaders();
this.prefixStripped = route.isPrefixStripped();
}
public String getId() {
return id;
}
public String getFullPath() {
return fullPath;
}
public String getPath() {
return path;
}
public String getLocation() {
return location;
}
public String getPrefix() {
return prefix;
}
public Boolean getRetryable() {
return retryable;
}
public Set<String> getSensitiveHeaders() {
return sensitiveHeaders;
}
public boolean isCustomSensitiveHeaders() {
return customSensitiveHeaders;
}
public boolean isPrefixStripped() {
return prefixStripped;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RouteDetails that = (RouteDetails) o;
return Objects.equals(id, that.id) &&
Objects.equals(fullPath, that.fullPath) &&
Objects.equals(path, that.path) &&
Objects.equals(location, that.location) &&
Objects.equals(prefix, that.prefix) &&
Objects.equals(retryable, that.retryable) &&
Objects.equals(sensitiveHeaders, that.sensitiveHeaders) &&
customSensitiveHeaders == that.customSensitiveHeaders &&
prefixStripped == that.prefixStripped;
}
@Override
public int hashCode() {
return Objects.hash(id, fullPath, path, location, prefix, retryable,
sensitiveHeaders, customSensitiveHeaders, prefixStripped);
}
}
}

View File

@@ -18,28 +18,38 @@
package org.springframework.cloud.netflix.zuul;
import org.springframework.boot.actuate.endpoint.mvc.ActuatorMediaTypes;
import org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.RouteLocator;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.http.MediaType;
import org.springframework.jmx.export.annotation.ManagedOperation;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Endpoint used to reset the reverse proxy routes
* @author Ryan Baxter
* @author Gregor Zurowski
*/
@ManagedResource(description = "Can be used to reset the reverse proxy routes")
public class RoutesMvcEndpoint extends EndpointMvcAdapter implements ApplicationEventPublisherAware {
static final String FORMAT_DETAILS = "details";
private final RoutesEndpoint endpoint;
private RouteLocator routes;
private ApplicationEventPublisher publisher;
public RoutesMvcEndpoint(RoutesEndpoint endpoint, RouteLocator routes) {
super(endpoint);
this.endpoint = endpoint;
this.routes = routes;
}
@@ -55,4 +65,18 @@ public class RoutesMvcEndpoint extends EndpointMvcAdapter implements Application
this.publisher.publishEvent(new RoutesRefreshedEvent(this.routes));
return super.invoke();
}
}
/**
* Expose Zuul {@link Route} information with details.
*/
@GetMapping(params = "format", produces = { ActuatorMediaTypes.APPLICATION_ACTUATOR_V1_JSON_VALUE,
MediaType.APPLICATION_JSON_VALUE })
@ResponseBody
public Object invokeRouteDetails(@RequestParam String format) {
if (FORMAT_DETAILS.equalsIgnoreCase(format)) {
return endpoint.invokeRouteDetails();
} else {
return super.invoke();
}
}
}

View File

@@ -22,6 +22,8 @@ import java.util.Map;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.ReflectionUtils;
import com.netflix.zuul.FilterLoader;
@@ -30,17 +32,16 @@ import com.netflix.zuul.filters.FilterRegistry;
import com.netflix.zuul.monitoring.CounterFactory;
import com.netflix.zuul.monitoring.TracerFactory;
import lombok.extern.apachecommons.CommonsLog;
/**
* Initializes various Zuul components including {@link ZuulFilter}.
*
* @author Spencer Gibb
*
*/
@CommonsLog
public class ZuulFilterInitializer {
private static final Log log = LogFactory.getLog(ZuulFilterInitializer.class);
private final Map<String, ZuulFilter> filters;
private final CounterFactory counterFactory;
private final TracerFactory tracerFactory;

View File

@@ -31,6 +31,8 @@ import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.netflix.zuul.util.RequestUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.util.LinkedMultiValueMap;
@@ -46,16 +48,15 @@ import static org.springframework.cloud.netflix.zuul.filters.support.FilterConst
import static org.springframework.http.HttpHeaders.CONTENT_ENCODING;
import static org.springframework.http.HttpHeaders.CONTENT_LENGTH;
import lombok.extern.apachecommons.CommonsLog;
/**
* @author Dave Syer
* @author Marcos Barbero
* @author Spencer Gibb
*/
@CommonsLog
public class ProxyRequestHelper {
private static final Log log = LogFactory.getLog(ProxyRequestHelper.class);
/**
* Zuul context key for a collection of ignored headers for the current request.
* Pre-filters can set this up as a set of lowercase strings.

View File

@@ -24,6 +24,8 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.cloud.netflix.zuul.util.RequestUtils;
import org.springframework.core.Ordered;
@@ -31,15 +33,15 @@ import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;
import lombok.extern.apachecommons.CommonsLog;
/**
* Simple {@link RouteLocator} based on configuration data held in {@link ZuulProperties}.
*
* @author Dave Syer
*/
@CommonsLog
public class SimpleRouteLocator implements RouteLocator, Ordered {
private static final Log log = LogFactory.getLog(SimpleRouteLocator.class);
private static final int DEFAULT_ORDER = 0;
private ZuulProperties properties;

View File

@@ -32,12 +32,9 @@ import org.springframework.util.MultiValueMap;
import com.netflix.zuul.context.RequestContext;
import lombok.extern.apachecommons.CommonsLog;
/**
* @author Spencer Gibb
*/
@CommonsLog
public class TraceProxyRequestHelper extends ProxyRequestHelper {
private TraceRepository traces;

View File

@@ -21,6 +21,8 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
@@ -31,8 +33,6 @@ import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;
import lombok.extern.apachecommons.CommonsLog;
/**
* A {@link RouteLocator} that combines static, configured routes with those from a
* {@link DiscoveryClient}. The discovery client takes precedence.
@@ -40,10 +40,11 @@ import lombok.extern.apachecommons.CommonsLog;
* @author Spencer Gibb
* @author Dave Syer
*/
@CommonsLog
public class DiscoveryClientRouteLocator extends SimpleRouteLocator
implements RefreshableRouteLocator {
private static final Log log = LogFactory.getLog(DiscoveryClientRouteLocator.class);
public static final String DEFAULT_ROUTE = "/**";
private DiscoveryClient discovery;

View File

@@ -62,7 +62,8 @@ import static org.mockito.Mockito.mockingDetails;
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = OkHttpClientConfigurationTestApp.class, value = {"feign.okhttp.enabled: true",
"spring.cloud.httpclientfactories.ok.enabled: true", "ribbon.eureka.enabled = false", "ribbon.okhttp.enabled: true"})
"spring.cloud.httpclientfactories.ok.enabled: true", "ribbon.eureka.enabled = false", "ribbon.okhttp.enabled: true",
"feign.okhttp.enabled: true", "ribbon.httpclient.enabled: false", "feign.httpclient.enabled: false"})
@DirtiesContext
public class OkHttpClientConfigurationTests {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ package org.springframework.cloud.netflix.feign;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import static org.junit.Assert.assertNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;

View File

@@ -28,7 +28,7 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.ClassPathExclusions;
import org.springframework.cloud.FilteredClassPathRunner;

View File

@@ -63,7 +63,8 @@ import lombok.NoArgsConstructor;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = FeignOkHttpTests.Application.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"spring.application.name=feignclienttest", "feign.hystrix.enabled=false",
"feign.okhttp.enabled=true", "spring.cloud.httpclientfactories.ok.enabled=true" })
"feign.httpclient.enabled=false", "feign.okhttp.enabled=true",
"spring.cloud.httpclientfactories.ok.enabled=true" })
@DirtiesContext
public class FeignOkHttpTests {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
@@ -22,8 +22,8 @@ import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.aop.AopAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.cloud.netflix.metrics.servo.ServoMetricsAutoConfiguration;
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
import org.springframework.context.annotation.Bean;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
@@ -25,7 +25,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.cloud.netflix.metrics.servo.ServoMetricsAutoConfiguration;
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
import org.springframework.context.annotation.Bean;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ package org.springframework.cloud.netflix.ribbon;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.PlainRibbonClientPreprocessorIntegrationTests.TestConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfigurationIntegrationTests.TestConfiguration;

View File

@@ -149,18 +149,21 @@ public class RibbonClientConfigurationTests {
return clients;
}
@SuppressWarnings("deprecation")
@Test
public void testDefaultsToApacheHttpClient() {
testClient(RibbonLoadBalancingHttpClient.class, null, RestClient.class, OkHttpLoadBalancingClient.class);
testClient(RibbonLoadBalancingHttpClient.class, new String[]{"ribbon.httpclient.enabled"}, RestClient.class, OkHttpLoadBalancingClient.class);
}
@SuppressWarnings("deprecation")
@Test
public void testEnableRestClient() {
testClient(RestClient.class, new String[]{"ribbon.restclient.enabled"}, RibbonLoadBalancingHttpClient.class,
OkHttpLoadBalancingClient.class);
}
@SuppressWarnings("deprecation")
@Test
public void testEnableOkHttpClient() {
testClient(OkHttpLoadBalancingClient.class, new String[]{"ribbon.okhttp.enabled"}, RibbonLoadBalancingHttpClient.class,

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ package org.springframework.cloud.netflix.ribbon;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonClientPreprocessorIntegrationTests.PlainConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,7 +26,7 @@ import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.context.annotation.Bean;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ import static org.junit.Assume.assumeThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;

View File

@@ -16,12 +16,15 @@
package org.springframework.cloud.netflix.ribbon;
import static org.junit.Assert.assertEquals;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.PingUrl;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
@@ -33,9 +36,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.netflix.loadbalancer.Server;
import com.netflix.loadbalancer.ZoneAvoidanceRule;
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Dave Syer
@@ -60,8 +61,13 @@ public class RibbonClientsPreprocessorIntegrationTests {
@Test
public void serverListFilterOverride() throws Exception {
assertEquals("myTestZone", ZonePreferenceServerListFilter.class
.cast(getLoadBalancer().getFilter()).getZone());
assertThat(ZonePreferenceServerListFilter.class
.cast(getLoadBalancer().getFilter()).getZone()).isEqualTo("myTestZone");
}
@Test
public void pingOverride() throws Exception {
assertThat(getLoadBalancer().getPing()).isInstanceOf(PingUrl.class);
}
@Configuration
@@ -71,6 +77,7 @@ public class RibbonClientsPreprocessorIntegrationTests {
protected static class TestConfiguration {
}
// tag::sample_override_ribbon_config[]
@Configuration
protected static class FooConfiguration {
@Bean
@@ -79,6 +86,12 @@ public class RibbonClientsPreprocessorIntegrationTests {
filter.setZone("myTestZone");
return filter;
}
@Bean
public IPing ribbonPing() {
return new PingUrl();
}
}
// end::sample_override_ribbon_config[]
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,8 @@
package org.springframework.cloud.netflix.ribbon.test;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.cloud.commons.httpclient.HttpClientConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
@@ -41,7 +41,8 @@ import com.netflix.loadbalancer.ServerListSubsetFilter;
*/
@Configuration
@Import({ PropertyPlaceholderAutoConfiguration.class, ArchaiusAutoConfiguration.class,
UtilAutoConfiguration.class, RibbonAutoConfiguration.class, HttpClientConfiguration.class})
UtilAutoConfiguration.class, RibbonAutoConfiguration.class, HttpClientConfiguration.class })
// tag::sample_default_ribbon_config[]
@RibbonClients(defaultConfiguration = DefaultRibbonConfig.class)
public class RibbonClientDefaultConfigurationTestsConfig {
@@ -76,4 +77,5 @@ class DefaultRibbonConfig {
return filter;
}
}
}
// end::sample_default_ribbon_config[]

View File

@@ -66,8 +66,6 @@ import static org.junit.Assert.assertEquals;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.util.StreamUtils.copyToString;
import lombok.extern.slf4j.Slf4j;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = FormZuulProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = {
"zuul.routes.simple:/simple/**" })
@@ -228,7 +226,6 @@ public class FormZuulProxyApplicationTests {
@RibbonClients({
@RibbonClient(name = "simple", configuration = FormRibbonClientConfiguration.class),
@RibbonClient(name = "psimple", configuration = FormRibbonClientConfiguration.class) })
@Slf4j
class FormZuulProxyApplication {
@RequestMapping(value = "/form", method = RequestMethod.POST)

View File

@@ -25,6 +25,8 @@ import com.netflix.loadbalancer.ServerList;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -63,8 +65,6 @@ import org.springframework.web.multipart.MultipartFile;
import static org.junit.Assert.assertEquals;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import lombok.extern.slf4j.Slf4j;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = FormZuulServletProxyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT, value = "zuul.routes.simple:/simple/**")
@DirtiesContext
@@ -145,9 +145,10 @@ public class FormZuulServletProxyApplicationTests {
@RestController
@EnableZuulProxy
@RibbonClients(@RibbonClient(name = "simple", configuration = ServletFormRibbonClientConfiguration.class))
@Slf4j
class FormZuulServletProxyApplication {
private static final Log log = LogFactory.getLog(FormZuulServletProxyApplication.class);
@RequestMapping(value = "/form", method = RequestMethod.POST)
public String accept(@RequestParam MultiValueMap<String, String> form)
throws IOException {

View File

@@ -27,16 +27,23 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.web.bind.annotation.RestController;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
/**
* @author Ryan Baxter
* @author Gregor Zurowski
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(
@@ -64,6 +71,22 @@ public class RoutesEndpointIntegrationTests {
assertTrue(refreshListener.wasCalled());
}
@Test
public void getRouteDetailsTest() {
ResponseEntity<Map<String, RoutesEndpoint.RouteDetails>> responseEntity = restTemplate.exchange(
"/admin/routes?format=details", HttpMethod.GET, null, new ParameterizedTypeReference<Map<String, RoutesEndpoint.RouteDetails>>() {
});
assertThat(responseEntity.getStatusCode(), is(HttpStatus.OK));
RoutesEndpoint.RouteDetails details = responseEntity.getBody().get("/sslservice/**");
assertThat(details.getPath(), is("/**"));
assertThat(details.getFullPath(), is("/sslservice/**"));
assertThat(details.getLocation(), is("https://localhost:8443"));
assertThat(details.getPrefix(), is("/sslservice"));
assertTrue(details.isPrefixStripped());
}
@Configuration
@EnableAutoConfiguration
@RestController

View File

@@ -34,6 +34,7 @@ import static org.junit.Assert.assertTrue;
/**
* @author Ryan Baxter
* @author Gregor Zurowski
*/
public class RoutesEndpointTests {
@@ -51,7 +52,7 @@ public class RoutesEndpointTests {
public List<Route> getRoutes() {
List<Route> routes = new ArrayList<>();
routes.add(new Route("foo", "foopath", "foolocation", null, true, Collections.EMPTY_SET));
routes.add(new Route("bar", "barpath", "barlocation", null, true, Collections.EMPTY_SET));
routes.add(new Route("bar", "barpath", "barlocation", "/bar-prefix", true, Collections.EMPTY_SET));
return routes;
}
@@ -72,6 +73,16 @@ public class RoutesEndpointTests {
assertEquals(result , endpoint.invoke());
}
@Test
public void testInvokeRouteDetails() {
RoutesEndpoint endpoint = new RoutesEndpoint(locator);
Map<String, RoutesEndpoint.RouteDetails> results = new HashMap<>();
for (Route route : locator.getRoutes()) {
results.put(route.getFullPath(), new RoutesEndpoint.RouteDetails(route));
}
assertEquals(results, endpoint.invokeRouteDetails());
}
@Test
public void testId() {
RoutesEndpoint endpoint = new RoutesEndpoint(locator);

View File

@@ -42,6 +42,7 @@ import static org.mockito.Mockito.verify;
/**
* @author Ryan Baxter
* @author Gregor Zurowski
*/
@SpringBootTest
@RunWith(MockitoJUnitRunner.class)
@@ -63,7 +64,7 @@ public class RoutesMvcEndpointTests {
public List<Route> getRoutes() {
List<Route> routes = new ArrayList<>();
routes.add(new Route("foo", "foopath", "foolocation", null, true, Collections.EMPTY_SET));
routes.add(new Route("bar", "barpath", "barlocation", null, true, Collections.EMPTY_SET));
routes.add(new Route("bar", "barpath", "barlocation", "bar-prefix", true, Collections.EMPTY_SET));
return routes;
}
@@ -88,4 +89,15 @@ public class RoutesMvcEndpointTests {
verify(publisher, times(1)).publishEvent(isA(RoutesRefreshedEvent.class));
}
@Test
public void routeDetails() throws Exception {
RoutesMvcEndpoint mvcEndpoint = new RoutesMvcEndpoint(endpoint, locator);
Map<String, RoutesEndpoint.RouteDetails> results = new HashMap<>();
for (Route route : locator.getRoutes()) {
results.put(route.getFullPath(), new RoutesEndpoint.RouteDetails(route));
}
assertEquals(results, mvcEndpoint.invokeRouteDetails(RoutesMvcEndpoint.FORMAT_DETAILS));
verify(endpoint, times(1)).invokeRouteDetails();
}
}

View File

@@ -118,7 +118,6 @@ public class SimpleZuulProxyApplicationTests {
}
@Test
@Ignore
public void getOnSelfWithComplexQueryParam() throws URISyntaxException {
String encodedQueryString = "foo=%7B%22project%22%3A%22stream%22%2C%22logger%22%3A%22javascript%22%2C%22platform%22%3A%22javascript%22%2C%22request%22%3A%7B%22url%22%3A%22https%3A%2F%2Ffoo%2Fadmin";
ResponseEntity<String> result = testRestTemplate.exchange(

View File

@@ -5,7 +5,7 @@
<parent>
<artifactId>spring-cloud-dependencies-parent</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>1.3.1.BUILD-SNAPSHOT</version>
<version>1.3.3.BUILD-SNAPSHOT</version>
<relativePath/>
</parent>
<artifactId>spring-cloud-netflix-dependencies</artifactId>
@@ -70,6 +70,71 @@
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-archaius</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-atlas</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-spectator</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine-amqp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-turbine-stream</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>

View File

@@ -112,17 +112,21 @@
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- Only needed at compile time -->
<scope>compile</scope>
<optional>true</optional>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>

View File

@@ -29,6 +29,7 @@ import org.springframework.util.ReflectionUtils;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
import com.netflix.discovery.DiscoveryClient;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
@@ -55,7 +56,7 @@ public class CloudEurekaClient extends DiscoveryClient {
public CloudEurekaClient(ApplicationInfoManager applicationInfoManager,
EurekaClientConfig config,
DiscoveryClientOptionalArgs args,
AbstractDiscoveryClientOptionalArgs<?> args,
ApplicationEventPublisher publisher) {
super(applicationInfoManager, config, args);
this.applicationInfoManager = applicationInfoManager;

View File

@@ -18,12 +18,12 @@ package org.springframework.cloud.netflix.eureka;
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
import lombok.Data;
import java.util.Objects;
/**
* @author Spencer Gibb
* @author Gregor Zurowski
*/
@Data
public class CloudEurekaTransportConfig implements EurekaTransportConfig {
private int sessionedClientReconnectIntervalSeconds = 20 * 60;
@@ -59,4 +59,153 @@ public class CloudEurekaTransportConfig implements EurekaTransportConfig {
public boolean applicationsResolverUseIp() {
return this.applicationsResolverUseIp;
}
public int getSessionedClientReconnectIntervalSeconds() {
return sessionedClientReconnectIntervalSeconds;
}
public void setSessionedClientReconnectIntervalSeconds(
int sessionedClientReconnectIntervalSeconds) {
this.sessionedClientReconnectIntervalSeconds = sessionedClientReconnectIntervalSeconds;
}
public double getRetryableClientQuarantineRefreshPercentage() {
return retryableClientQuarantineRefreshPercentage;
}
public void setRetryableClientQuarantineRefreshPercentage(
double retryableClientQuarantineRefreshPercentage) {
this.retryableClientQuarantineRefreshPercentage = retryableClientQuarantineRefreshPercentage;
}
public int getBootstrapResolverRefreshIntervalSeconds() {
return bootstrapResolverRefreshIntervalSeconds;
}
public void setBootstrapResolverRefreshIntervalSeconds(
int bootstrapResolverRefreshIntervalSeconds) {
this.bootstrapResolverRefreshIntervalSeconds = bootstrapResolverRefreshIntervalSeconds;
}
public int getApplicationsResolverDataStalenessThresholdSeconds() {
return applicationsResolverDataStalenessThresholdSeconds;
}
public void setApplicationsResolverDataStalenessThresholdSeconds(
int applicationsResolverDataStalenessThresholdSeconds) {
this.applicationsResolverDataStalenessThresholdSeconds = applicationsResolverDataStalenessThresholdSeconds;
}
public int getAsyncResolverRefreshIntervalMs() {
return asyncResolverRefreshIntervalMs;
}
public void setAsyncResolverRefreshIntervalMs(int asyncResolverRefreshIntervalMs) {
this.asyncResolverRefreshIntervalMs = asyncResolverRefreshIntervalMs;
}
public int getAsyncResolverWarmUpTimeoutMs() {
return asyncResolverWarmUpTimeoutMs;
}
public void setAsyncResolverWarmUpTimeoutMs(int asyncResolverWarmUpTimeoutMs) {
this.asyncResolverWarmUpTimeoutMs = asyncResolverWarmUpTimeoutMs;
}
public int getAsyncExecutorThreadPoolSize() {
return asyncExecutorThreadPoolSize;
}
public void setAsyncExecutorThreadPoolSize(int asyncExecutorThreadPoolSize) {
this.asyncExecutorThreadPoolSize = asyncExecutorThreadPoolSize;
}
public String getReadClusterVip() {
return readClusterVip;
}
public void setReadClusterVip(String readClusterVip) {
this.readClusterVip = readClusterVip;
}
public String getWriteClusterVip() {
return writeClusterVip;
}
public void setWriteClusterVip(String writeClusterVip) {
this.writeClusterVip = writeClusterVip;
}
public boolean isBootstrapResolverForQuery() {
return bootstrapResolverForQuery;
}
public void setBootstrapResolverForQuery(boolean bootstrapResolverForQuery) {
this.bootstrapResolverForQuery = bootstrapResolverForQuery;
}
public String getBootstrapResolverStrategy() {
return bootstrapResolverStrategy;
}
public void setBootstrapResolverStrategy(String bootstrapResolverStrategy) {
this.bootstrapResolverStrategy = bootstrapResolverStrategy;
}
public boolean isApplicationsResolverUseIp() {
return applicationsResolverUseIp;
}
public void setApplicationsResolverUseIp(boolean applicationsResolverUseIp) {
this.applicationsResolverUseIp = applicationsResolverUseIp;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CloudEurekaTransportConfig that = (CloudEurekaTransportConfig) o;
return sessionedClientReconnectIntervalSeconds == that.sessionedClientReconnectIntervalSeconds &&
Double.compare(retryableClientQuarantineRefreshPercentage, that.retryableClientQuarantineRefreshPercentage) == 0 &&
bootstrapResolverRefreshIntervalSeconds == that.bootstrapResolverRefreshIntervalSeconds &&
applicationsResolverDataStalenessThresholdSeconds == that.applicationsResolverDataStalenessThresholdSeconds &&
asyncResolverRefreshIntervalMs == that.asyncResolverRefreshIntervalMs &&
asyncResolverWarmUpTimeoutMs == that.asyncResolverWarmUpTimeoutMs &&
asyncExecutorThreadPoolSize == that.asyncExecutorThreadPoolSize &&
Objects.equals(readClusterVip, that.readClusterVip) &&
Objects.equals(writeClusterVip, that.writeClusterVip) &&
bootstrapResolverForQuery == that.bootstrapResolverForQuery &&
Objects.equals(bootstrapResolverStrategy, that.bootstrapResolverStrategy) &&
applicationsResolverUseIp == that.applicationsResolverUseIp;
}
@Override
public int hashCode() {
return Objects.hash(sessionedClientReconnectIntervalSeconds,
retryableClientQuarantineRefreshPercentage,
bootstrapResolverRefreshIntervalSeconds,
applicationsResolverDataStalenessThresholdSeconds,
asyncResolverRefreshIntervalMs, asyncResolverWarmUpTimeoutMs,
asyncExecutorThreadPoolSize, readClusterVip, writeClusterVip,
bootstrapResolverForQuery, bootstrapResolverStrategy,
applicationsResolverUseIp);
}
@Override
public String toString() {
return new StringBuilder("CloudEurekaTransportConfig{")
.append("sessionedClientReconnectIntervalSeconds=").append(sessionedClientReconnectIntervalSeconds).append(", ")
.append("retryableClientQuarantineRefreshPercentage=").append(retryableClientQuarantineRefreshPercentage).append(", ")
.append("bootstrapResolverRefreshIntervalSeconds=").append(bootstrapResolverRefreshIntervalSeconds).append(", ")
.append("applicationsResolverDataStalenessThresholdSeconds=").append(applicationsResolverDataStalenessThresholdSeconds).append(", ")
.append("asyncResolverRefreshIntervalMs=").append(asyncResolverRefreshIntervalMs).append(", ")
.append("asyncResolverWarmUpTimeoutMs=").append(asyncResolverWarmUpTimeoutMs).append(", ")
.append("asyncExecutorThreadPoolSize=").append(asyncExecutorThreadPoolSize).append(", ")
.append("readClusterVip='").append(readClusterVip).append("', ")
.append("writeClusterVip='").append(writeClusterVip).append("', ")
.append("bootstrapResolverForQuery=").append(bootstrapResolverForQuery).append(", ")
.append("bootstrapResolverStrategy='").append(bootstrapResolverStrategy).append("', ")
.append("applicationsResolverUseIp=").append(applicationsResolverUseIp).append(", ").append("}")
.toString();
}
}

View File

@@ -17,6 +17,8 @@
package org.springframework.cloud.netflix.eureka;
import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceId;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -47,6 +49,7 @@ import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationP
import org.springframework.cloud.client.serviceregistry.ServiceRegistryAutoConfiguration;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration;
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration;
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry;
@@ -54,6 +57,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertyResolver;
@@ -63,9 +67,10 @@ import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient.DiscoveryClientOptionalArgs;
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceId;
/**
@@ -74,10 +79,12 @@ import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceI
* @author Jon Schneider
* @author Matt Jenkins
* @author Ryan Baxter
* @author Daniel Lavoie
*/
@Configuration
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@Import(DiscoveryClientOptionalArgsConfiguration.class)
@ConditionalOnBean(EurekaDiscoveryClientConfiguration.Marker.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@AutoConfigureBefore({ NoopDiscoveryClientAutoConfiguration.class,
@@ -177,12 +184,6 @@ public class EurekaClientAutoConfiguration {
return new EurekaAutoServiceRegistration(context, registry, registration);
}
@Bean
@ConditionalOnMissingBean(value = DiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT)
public MutableDiscoveryClientOptionalArgs discoveryClientOptionalArgs() {
return new MutableDiscoveryClientOptionalArgs();
}
@Configuration
@ConditionalOnMissingRefreshScope
protected static class EurekaClientConfiguration {
@@ -190,8 +191,8 @@ public class EurekaClientAutoConfiguration {
@Autowired
private ApplicationContext context;
@Autowired(required = false)
private DiscoveryClientOptionalArgs optionalArgs;
@Autowired
private AbstractDiscoveryClientOptionalArgs<?> optionalArgs;
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)
@@ -216,8 +217,8 @@ public class EurekaClientAutoConfiguration {
@Autowired
private ApplicationContext context;
@Autowired(required = false)
private DiscoveryClientOptionalArgs optionalArgs;
@Autowired
private AbstractDiscoveryClientOptionalArgs<?> optionalArgs;
@Bean(destroyMethod = "shutdown")
@ConditionalOnMissingBean(value = EurekaClient.class, search = SearchStrategy.CURRENT)

View File

@@ -17,13 +17,14 @@
package org.springframework.cloud.netflix.eureka;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.core.env.PropertyResolver;
import org.springframework.util.StringUtils;
@@ -31,14 +32,12 @@ import com.netflix.appinfo.EurekaAccept;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.shared.transport.EurekaTransportConfig;
import lombok.Data;
import static org.springframework.cloud.netflix.eureka.EurekaConstants.DEFAULT_PREFIX;
/**
* @author Dave Syer
* @author Gregor Zurowski
*/
@Data
@ConfigurationProperties(EurekaClientConfigBean.PREFIX)
public class EurekaClientConfigBean implements EurekaClientConfig {
@@ -59,6 +58,7 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
*/
private boolean enabled = true;
@NestedConfigurationProperty
private EurekaTransportConfig transport = new CloudEurekaTransportConfig();
/**
@@ -485,4 +485,517 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
public EurekaTransportConfig getTransportConfig() {
return getTransport();
}
public PropertyResolver getPropertyResolver() {
return propertyResolver;
}
public void setPropertyResolver(PropertyResolver propertyResolver) {
this.propertyResolver = propertyResolver;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public EurekaTransportConfig getTransport() {
return transport;
}
public void setTransport(EurekaTransportConfig transport) {
this.transport = transport;
}
@Override
public int getRegistryFetchIntervalSeconds() {
return registryFetchIntervalSeconds;
}
public void setRegistryFetchIntervalSeconds(int registryFetchIntervalSeconds) {
this.registryFetchIntervalSeconds = registryFetchIntervalSeconds;
}
@Override
public int getInstanceInfoReplicationIntervalSeconds() {
return instanceInfoReplicationIntervalSeconds;
}
public void setInstanceInfoReplicationIntervalSeconds(
int instanceInfoReplicationIntervalSeconds) {
this.instanceInfoReplicationIntervalSeconds = instanceInfoReplicationIntervalSeconds;
}
@Override
public int getInitialInstanceInfoReplicationIntervalSeconds() {
return initialInstanceInfoReplicationIntervalSeconds;
}
public void setInitialInstanceInfoReplicationIntervalSeconds(
int initialInstanceInfoReplicationIntervalSeconds) {
this.initialInstanceInfoReplicationIntervalSeconds = initialInstanceInfoReplicationIntervalSeconds;
}
@Override
public int getEurekaServiceUrlPollIntervalSeconds() {
return eurekaServiceUrlPollIntervalSeconds;
}
public void setEurekaServiceUrlPollIntervalSeconds(
int eurekaServiceUrlPollIntervalSeconds) {
this.eurekaServiceUrlPollIntervalSeconds = eurekaServiceUrlPollIntervalSeconds;
}
@Override
public String getProxyPort() {
return proxyPort;
}
public void setProxyPort(String proxyPort) {
this.proxyPort = proxyPort;
}
@Override
public String getProxyHost() {
return proxyHost;
}
public void setProxyHost(String proxyHost) {
this.proxyHost = proxyHost;
}
@Override
public String getProxyUserName() {
return proxyUserName;
}
public void setProxyUserName(String proxyUserName) {
this.proxyUserName = proxyUserName;
}
@Override
public String getProxyPassword() {
return proxyPassword;
}
public void setProxyPassword(String proxyPassword) {
this.proxyPassword = proxyPassword;
}
@Override
public int getEurekaServerReadTimeoutSeconds() {
return eurekaServerReadTimeoutSeconds;
}
public void setEurekaServerReadTimeoutSeconds(int eurekaServerReadTimeoutSeconds) {
this.eurekaServerReadTimeoutSeconds = eurekaServerReadTimeoutSeconds;
}
@Override
public int getEurekaServerConnectTimeoutSeconds() {
return eurekaServerConnectTimeoutSeconds;
}
public void setEurekaServerConnectTimeoutSeconds(
int eurekaServerConnectTimeoutSeconds) {
this.eurekaServerConnectTimeoutSeconds = eurekaServerConnectTimeoutSeconds;
}
@Override
public String getBackupRegistryImpl() {
return backupRegistryImpl;
}
public void setBackupRegistryImpl(String backupRegistryImpl) {
this.backupRegistryImpl = backupRegistryImpl;
}
@Override
public int getEurekaServerTotalConnections() {
return eurekaServerTotalConnections;
}
public void setEurekaServerTotalConnections(int eurekaServerTotalConnections) {
this.eurekaServerTotalConnections = eurekaServerTotalConnections;
}
@Override
public int getEurekaServerTotalConnectionsPerHost() {
return eurekaServerTotalConnectionsPerHost;
}
public void setEurekaServerTotalConnectionsPerHost(
int eurekaServerTotalConnectionsPerHost) {
this.eurekaServerTotalConnectionsPerHost = eurekaServerTotalConnectionsPerHost;
}
@Override
public String getEurekaServerURLContext() {
return eurekaServerURLContext;
}
public void setEurekaServerURLContext(String eurekaServerURLContext) {
this.eurekaServerURLContext = eurekaServerURLContext;
}
@Override
public String getEurekaServerPort() {
return eurekaServerPort;
}
public void setEurekaServerPort(String eurekaServerPort) {
this.eurekaServerPort = eurekaServerPort;
}
@Override
public String getEurekaServerDNSName() {
return eurekaServerDNSName;
}
public void setEurekaServerDNSName(String eurekaServerDNSName) {
this.eurekaServerDNSName = eurekaServerDNSName;
}
@Override
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
@Override
public int getEurekaConnectionIdleTimeoutSeconds() {
return eurekaConnectionIdleTimeoutSeconds;
}
public void setEurekaConnectionIdleTimeoutSeconds(
int eurekaConnectionIdleTimeoutSeconds) {
this.eurekaConnectionIdleTimeoutSeconds = eurekaConnectionIdleTimeoutSeconds;
}
@Override
public String getRegistryRefreshSingleVipAddress() {
return registryRefreshSingleVipAddress;
}
public void setRegistryRefreshSingleVipAddress(
String registryRefreshSingleVipAddress) {
this.registryRefreshSingleVipAddress = registryRefreshSingleVipAddress;
}
@Override
public int getHeartbeatExecutorThreadPoolSize() {
return heartbeatExecutorThreadPoolSize;
}
public void setHeartbeatExecutorThreadPoolSize(int heartbeatExecutorThreadPoolSize) {
this.heartbeatExecutorThreadPoolSize = heartbeatExecutorThreadPoolSize;
}
@Override
public int getHeartbeatExecutorExponentialBackOffBound() {
return heartbeatExecutorExponentialBackOffBound;
}
public void setHeartbeatExecutorExponentialBackOffBound(
int heartbeatExecutorExponentialBackOffBound) {
this.heartbeatExecutorExponentialBackOffBound = heartbeatExecutorExponentialBackOffBound;
}
@Override
public int getCacheRefreshExecutorThreadPoolSize() {
return cacheRefreshExecutorThreadPoolSize;
}
public void setCacheRefreshExecutorThreadPoolSize(
int cacheRefreshExecutorThreadPoolSize) {
this.cacheRefreshExecutorThreadPoolSize = cacheRefreshExecutorThreadPoolSize;
}
@Override
public int getCacheRefreshExecutorExponentialBackOffBound() {
return cacheRefreshExecutorExponentialBackOffBound;
}
public void setCacheRefreshExecutorExponentialBackOffBound(
int cacheRefreshExecutorExponentialBackOffBound) {
this.cacheRefreshExecutorExponentialBackOffBound = cacheRefreshExecutorExponentialBackOffBound;
}
public Map<String, String> getServiceUrl() {
return serviceUrl;
}
public void setServiceUrl(Map<String, String> serviceUrl) {
this.serviceUrl = serviceUrl;
}
public boolean isgZipContent() {
return gZipContent;
}
public void setgZipContent(boolean gZipContent) {
this.gZipContent = gZipContent;
}
public boolean isUseDnsForFetchingServiceUrls() {
return useDnsForFetchingServiceUrls;
}
public void setUseDnsForFetchingServiceUrls(boolean useDnsForFetchingServiceUrls) {
this.useDnsForFetchingServiceUrls = useDnsForFetchingServiceUrls;
}
public boolean isRegisterWithEureka() {
return registerWithEureka;
}
public void setRegisterWithEureka(boolean registerWithEureka) {
this.registerWithEureka = registerWithEureka;
}
public boolean isPreferSameZoneEureka() {
return preferSameZoneEureka;
}
public void setPreferSameZoneEureka(boolean preferSameZoneEureka) {
this.preferSameZoneEureka = preferSameZoneEureka;
}
public boolean isLogDeltaDiff() {
return logDeltaDiff;
}
public void setLogDeltaDiff(boolean logDeltaDiff) {
this.logDeltaDiff = logDeltaDiff;
}
public boolean isDisableDelta() {
return disableDelta;
}
public void setDisableDelta(boolean disableDelta) {
this.disableDelta = disableDelta;
}
public String getFetchRemoteRegionsRegistry() {
return fetchRemoteRegionsRegistry;
}
public void setFetchRemoteRegionsRegistry(String fetchRemoteRegionsRegistry) {
this.fetchRemoteRegionsRegistry = fetchRemoteRegionsRegistry;
}
public Map<String, String> getAvailabilityZones() {
return availabilityZones;
}
public void setAvailabilityZones(Map<String, String> availabilityZones) {
this.availabilityZones = availabilityZones;
}
public boolean isFilterOnlyUpInstances() {
return filterOnlyUpInstances;
}
public void setFilterOnlyUpInstances(boolean filterOnlyUpInstances) {
this.filterOnlyUpInstances = filterOnlyUpInstances;
}
public boolean isFetchRegistry() {
return fetchRegistry;
}
public void setFetchRegistry(boolean fetchRegistry) {
this.fetchRegistry = fetchRegistry;
}
@Override
public String getDollarReplacement() {
return dollarReplacement;
}
public void setDollarReplacement(String dollarReplacement) {
this.dollarReplacement = dollarReplacement;
}
@Override
public String getEscapeCharReplacement() {
return escapeCharReplacement;
}
public void setEscapeCharReplacement(String escapeCharReplacement) {
this.escapeCharReplacement = escapeCharReplacement;
}
public boolean isAllowRedirects() {
return allowRedirects;
}
public void setAllowRedirects(boolean allowRedirects) {
this.allowRedirects = allowRedirects;
}
public boolean isOnDemandUpdateStatusChange() {
return onDemandUpdateStatusChange;
}
public void setOnDemandUpdateStatusChange(boolean onDemandUpdateStatusChange) {
this.onDemandUpdateStatusChange = onDemandUpdateStatusChange;
}
@Override
public String getEncoderName() {
return encoderName;
}
public void setEncoderName(String encoderName) {
this.encoderName = encoderName;
}
@Override
public String getDecoderName() {
return decoderName;
}
public void setDecoderName(String decoderName) {
this.decoderName = decoderName;
}
@Override
public String getClientDataAccept() {
return clientDataAccept;
}
public void setClientDataAccept(String clientDataAccept) {
this.clientDataAccept = clientDataAccept;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EurekaClientConfigBean that = (EurekaClientConfigBean) o;
return Objects.equals(propertyResolver, that.propertyResolver) &&
enabled == that.enabled &&
Objects.equals(transport, that.transport) &&
registryFetchIntervalSeconds == that.registryFetchIntervalSeconds &&
instanceInfoReplicationIntervalSeconds == that.instanceInfoReplicationIntervalSeconds &&
initialInstanceInfoReplicationIntervalSeconds == that.initialInstanceInfoReplicationIntervalSeconds &&
eurekaServiceUrlPollIntervalSeconds == that.eurekaServiceUrlPollIntervalSeconds &&
eurekaServerReadTimeoutSeconds == that.eurekaServerReadTimeoutSeconds &&
eurekaServerConnectTimeoutSeconds == that.eurekaServerConnectTimeoutSeconds &&
eurekaServerTotalConnections == that.eurekaServerTotalConnections &&
eurekaServerTotalConnectionsPerHost == that.eurekaServerTotalConnectionsPerHost &&
eurekaConnectionIdleTimeoutSeconds == that.eurekaConnectionIdleTimeoutSeconds &&
heartbeatExecutorThreadPoolSize == that.heartbeatExecutorThreadPoolSize &&
heartbeatExecutorExponentialBackOffBound == that.heartbeatExecutorExponentialBackOffBound &&
cacheRefreshExecutorThreadPoolSize == that.cacheRefreshExecutorThreadPoolSize &&
cacheRefreshExecutorExponentialBackOffBound == that.cacheRefreshExecutorExponentialBackOffBound &&
gZipContent == that.gZipContent &&
useDnsForFetchingServiceUrls == that.useDnsForFetchingServiceUrls &&
registerWithEureka == that.registerWithEureka &&
preferSameZoneEureka == that.preferSameZoneEureka &&
logDeltaDiff == that.logDeltaDiff &&
disableDelta == that.disableDelta &&
filterOnlyUpInstances == that.filterOnlyUpInstances &&
fetchRegistry == that.fetchRegistry &&
allowRedirects == that.allowRedirects &&
onDemandUpdateStatusChange == that.onDemandUpdateStatusChange &&
Objects.equals(proxyPort, that.proxyPort) &&
Objects.equals(proxyHost, that.proxyHost) &&
Objects.equals(proxyUserName, that.proxyUserName) &&
Objects.equals(proxyPassword, that.proxyPassword) &&
Objects.equals(backupRegistryImpl, that.backupRegistryImpl) &&
Objects.equals(eurekaServerURLContext, that.eurekaServerURLContext) &&
Objects.equals(eurekaServerPort, that.eurekaServerPort) &&
Objects.equals(eurekaServerDNSName, that.eurekaServerDNSName) &&
Objects.equals(region, that.region) &&
Objects.equals(registryRefreshSingleVipAddress, that.registryRefreshSingleVipAddress) &&
Objects.equals(serviceUrl, that.serviceUrl) &&
Objects.equals(fetchRemoteRegionsRegistry, that.fetchRemoteRegionsRegistry) &&
Objects.equals(availabilityZones, that.availabilityZones) &&
Objects.equals(dollarReplacement, that.dollarReplacement) &&
Objects.equals(escapeCharReplacement, that.escapeCharReplacement) &&
Objects.equals(encoderName, that.encoderName) &&
Objects.equals(decoderName, that.decoderName) &&
Objects.equals(clientDataAccept, that.clientDataAccept);
}
@Override
public int hashCode() {
return Objects.hash(propertyResolver, enabled, transport,
registryFetchIntervalSeconds, instanceInfoReplicationIntervalSeconds,
initialInstanceInfoReplicationIntervalSeconds,
eurekaServiceUrlPollIntervalSeconds, proxyPort, proxyHost, proxyUserName,
proxyPassword, eurekaServerReadTimeoutSeconds,
eurekaServerConnectTimeoutSeconds, backupRegistryImpl,
eurekaServerTotalConnections, eurekaServerTotalConnectionsPerHost,
eurekaServerURLContext, eurekaServerPort, eurekaServerDNSName, region,
eurekaConnectionIdleTimeoutSeconds, registryRefreshSingleVipAddress,
heartbeatExecutorThreadPoolSize, heartbeatExecutorExponentialBackOffBound,
cacheRefreshExecutorThreadPoolSize,
cacheRefreshExecutorExponentialBackOffBound, serviceUrl, gZipContent,
useDnsForFetchingServiceUrls, registerWithEureka, preferSameZoneEureka,
logDeltaDiff, disableDelta, fetchRemoteRegionsRegistry, availabilityZones,
filterOnlyUpInstances, fetchRegistry, dollarReplacement,
escapeCharReplacement, allowRedirects, onDemandUpdateStatusChange,
encoderName, decoderName, clientDataAccept);
}
@Override
public String toString() {
return new StringBuilder("EurekaClientConfigBean{")
.append("propertyResolver=").append(propertyResolver).append(", ")
.append("enabled=").append(enabled).append(", ")
.append("transport=").append(transport).append(", ")
.append("registryFetchIntervalSeconds=").append(registryFetchIntervalSeconds).append(", ")
.append("instanceInfoReplicationIntervalSeconds=").append(instanceInfoReplicationIntervalSeconds).append(", ")
.append("initialInstanceInfoReplicationIntervalSeconds=").append(initialInstanceInfoReplicationIntervalSeconds).append(", ")
.append("eurekaServiceUrlPollIntervalSeconds=").append(eurekaServiceUrlPollIntervalSeconds).append(", ")
.append("proxyPort='").append(proxyPort).append("', ")
.append("proxyHost='").append(proxyHost).append("', ")
.append("proxyUserName='").append(proxyUserName).append("', ")
.append("proxyPassword='").append(proxyPassword).append("', ")
.append("eurekaServerReadTimeoutSeconds=").append(eurekaServerReadTimeoutSeconds).append(", ")
.append("eurekaServerConnectTimeoutSeconds=").append(eurekaServerConnectTimeoutSeconds).append(", ")
.append("backupRegistryImpl='").append(backupRegistryImpl).append("', ")
.append("eurekaServerTotalConnections=").append(eurekaServerTotalConnections).append(", ")
.append("eurekaServerTotalConnectionsPerHost=").append(eurekaServerTotalConnectionsPerHost).append(", ")
.append("eurekaServerURLContext='").append(eurekaServerURLContext).append("', ")
.append("eurekaServerPort='").append(eurekaServerPort).append("', ")
.append("eurekaServerDNSName='").append(eurekaServerDNSName).append("', ")
.append("region='").append(region).append("', ")
.append("eurekaConnectionIdleTimeoutSeconds=").append(eurekaConnectionIdleTimeoutSeconds).append(", ")
.append("registryRefreshSingleVipAddress='").append(registryRefreshSingleVipAddress).append("', ")
.append("heartbeatExecutorThreadPoolSize=").append(heartbeatExecutorThreadPoolSize).append(", ")
.append("heartbeatExecutorExponentialBackOffBound=").append(heartbeatExecutorExponentialBackOffBound).append(", ")
.append("cacheRefreshExecutorThreadPoolSize=").append(cacheRefreshExecutorThreadPoolSize).append(", ")
.append("cacheRefreshExecutorExponentialBackOffBound=").append(cacheRefreshExecutorExponentialBackOffBound).append(", ")
.append("serviceUrl=").append(serviceUrl).append(", ")
.append("gZipContent=").append(gZipContent).append(", ")
.append("useDnsForFetchingServiceUrls=").append(useDnsForFetchingServiceUrls).append(", ")
.append("registerWithEureka=").append(registerWithEureka).append(", ")
.append("preferSameZoneEureka=").append(preferSameZoneEureka).append(", ")
.append("logDeltaDiff=").append(logDeltaDiff).append(", ")
.append("disableDelta=").append(disableDelta).append(", ")
.append("fetchRemoteRegionsRegistry='").append(fetchRemoteRegionsRegistry).append("', ")
.append("availabilityZones=").append(availabilityZones).append(", ")
.append("filterOnlyUpInstances=").append(filterOnlyUpInstances).append(", ")
.append("fetchRegistry=").append(fetchRegistry).append(", ")
.append("dollarReplacement='").append(dollarReplacement).append("', ")
.append("escapeCharReplacement='").append(escapeCharReplacement).append("', ")
.append("allowRedirects=").append(allowRedirects).append(", ")
.append("onDemandUpdateStatusChange=").append(onDemandUpdateStatusChange).append(", ")
.append("encoderName='").append(encoderName).append("', ")
.append("decoderName='").append(decoderName).append("', ")
.append("clientDataAccept='").append(clientDataAccept).append("'").append("}")
.toString();
}
}

View File

@@ -35,12 +35,9 @@ import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import lombok.RequiredArgsConstructor;
/**
* @author Spencer Gibb
*/
@RequiredArgsConstructor
public class EurekaDiscoveryClient implements DiscoveryClient {
public static final String DESCRIPTION = "Spring Cloud Eureka Discovery Client";
@@ -49,6 +46,11 @@ public class EurekaDiscoveryClient implements DiscoveryClient {
private final EurekaClient eurekaClient;
public EurekaDiscoveryClient(EurekaInstanceConfig config, EurekaClient eurekaClient) {
this.config = config;
this.eurekaClient = eurekaClient;
}
@Override
public String description() {
return DESCRIPTION;

View File

@@ -34,8 +34,6 @@ import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
import lombok.extern.apachecommons.CommonsLog;
/**
* @author Dave Syer
* @author Spencer Gibb
@@ -46,7 +44,6 @@ import lombok.extern.apachecommons.CommonsLog;
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@CommonsLog
public class EurekaDiscoveryClientConfiguration {
class Marker {}

View File

@@ -16,8 +16,10 @@
package org.springframework.cloud.netflix.eureka;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -31,28 +33,19 @@ import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.appinfo.MyDataCenterInfo;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
/**
* @author Dave Syer
* @author Spencer Gibb
* @author Ryan Baxter
* @author Gregor Zurowski
*/
@Data
@ConfigurationProperties("eureka.instance")
public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, EnvironmentAware {
private static final String UNKNOWN = "unknown";
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private HostInfo hostInfo;
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private InetUtils inetUtils;
/**
@@ -339,4 +332,321 @@ public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, Envi
setSecureVirtualHostName(springAppName);
}
}
private HostInfo getHostInfo() {
return hostInfo;
}
private void setHostInfo(HostInfo hostInfo) {
this.hostInfo = hostInfo;
}
private InetUtils getInetUtils() {
return inetUtils;
}
private void setInetUtils(InetUtils inetUtils) {
this.inetUtils = inetUtils;
}
public String getAppname() {
return appname;
}
public void setAppname(String appname) {
this.appname = appname;
}
public String getAppGroupName() {
return appGroupName;
}
public void setAppGroupName(String appGroupName) {
this.appGroupName = appGroupName;
}
public boolean isInstanceEnabledOnit() {
return instanceEnabledOnit;
}
public void setInstanceEnabledOnit(boolean instanceEnabledOnit) {
this.instanceEnabledOnit = instanceEnabledOnit;
}
public int getNonSecurePort() {
return nonSecurePort;
}
public void setNonSecurePort(int nonSecurePort) {
this.nonSecurePort = nonSecurePort;
}
public int getSecurePort() {
return securePort;
}
public void setSecurePort(int securePort) {
this.securePort = securePort;
}
public boolean isNonSecurePortEnabled() {
return nonSecurePortEnabled;
}
public void setNonSecurePortEnabled(boolean nonSecurePortEnabled) {
this.nonSecurePortEnabled = nonSecurePortEnabled;
}
public boolean isSecurePortEnabled() {
return securePortEnabled;
}
public void setSecurePortEnabled(boolean securePortEnabled) {
this.securePortEnabled = securePortEnabled;
}
public int getLeaseRenewalIntervalInSeconds() {
return leaseRenewalIntervalInSeconds;
}
public void setLeaseRenewalIntervalInSeconds(int leaseRenewalIntervalInSeconds) {
this.leaseRenewalIntervalInSeconds = leaseRenewalIntervalInSeconds;
}
public int getLeaseExpirationDurationInSeconds() {
return leaseExpirationDurationInSeconds;
}
public void setLeaseExpirationDurationInSeconds(
int leaseExpirationDurationInSeconds) {
this.leaseExpirationDurationInSeconds = leaseExpirationDurationInSeconds;
}
public String getVirtualHostName() {
return virtualHostName;
}
public void setVirtualHostName(String virtualHostName) {
this.virtualHostName = virtualHostName;
}
public void setInstanceId(String instanceId) {
this.instanceId = instanceId;
}
public String getSecureVirtualHostName() {
return secureVirtualHostName;
}
public void setSecureVirtualHostName(String secureVirtualHostName) {
this.secureVirtualHostName = secureVirtualHostName;
}
public String getASGName() {
return aSGName;
}
public void setASGName(String aSGName) {
this.aSGName = aSGName;
}
public Map<String, String> getMetadataMap() {
return metadataMap;
}
public void setMetadataMap(Map<String, String> metadataMap) {
this.metadataMap = metadataMap;
}
public DataCenterInfo getDataCenterInfo() {
return dataCenterInfo;
}
public void setDataCenterInfo(DataCenterInfo dataCenterInfo) {
this.dataCenterInfo = dataCenterInfo;
}
public String getIpAddress() {
return ipAddress;
}
public String getStatusPageUrlPath() {
return statusPageUrlPath;
}
public void setStatusPageUrlPath(String statusPageUrlPath) {
this.statusPageUrlPath = statusPageUrlPath;
}
public String getStatusPageUrl() {
return statusPageUrl;
}
public void setStatusPageUrl(String statusPageUrl) {
this.statusPageUrl = statusPageUrl;
}
public String getHomePageUrlPath() {
return homePageUrlPath;
}
public void setHomePageUrlPath(String homePageUrlPath) {
this.homePageUrlPath = homePageUrlPath;
}
public String getHomePageUrl() {
return homePageUrl;
}
public void setHomePageUrl(String homePageUrl) {
this.homePageUrl = homePageUrl;
}
public String getHealthCheckUrlPath() {
return healthCheckUrlPath;
}
public void setHealthCheckUrlPath(String healthCheckUrlPath) {
this.healthCheckUrlPath = healthCheckUrlPath;
}
public String getHealthCheckUrl() {
return healthCheckUrl;
}
public void setHealthCheckUrl(String healthCheckUrl) {
this.healthCheckUrl = healthCheckUrl;
}
public String getSecureHealthCheckUrl() {
return secureHealthCheckUrl;
}
public void setSecureHealthCheckUrl(String secureHealthCheckUrl) {
this.secureHealthCheckUrl = secureHealthCheckUrl;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public boolean isPreferIpAddress() {
return preferIpAddress;
}
public void setPreferIpAddress(boolean preferIpAddress) {
this.preferIpAddress = preferIpAddress;
}
public InstanceStatus getInitialStatus() {
return initialStatus;
}
public void setInitialStatus(InstanceStatus initialStatus) {
this.initialStatus = initialStatus;
}
public String[] getDefaultAddressResolutionOrder() {
return defaultAddressResolutionOrder;
}
public void setDefaultAddressResolutionOrder(String[] defaultAddressResolutionOrder) {
this.defaultAddressResolutionOrder = defaultAddressResolutionOrder;
}
public Environment getEnvironment() {
return environment;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EurekaInstanceConfigBean that = (EurekaInstanceConfigBean) o;
return Objects.equals(hostInfo, that.hostInfo) &&
Objects.equals(inetUtils, that.inetUtils) &&
Objects.equals(appname, that.appname) &&
Objects.equals(appGroupName, that.appGroupName) &&
instanceEnabledOnit == that.instanceEnabledOnit &&
nonSecurePort == that.nonSecurePort &&
securePort == that.securePort &&
nonSecurePortEnabled == that.nonSecurePortEnabled &&
securePortEnabled == that.securePortEnabled &&
leaseRenewalIntervalInSeconds == that.leaseRenewalIntervalInSeconds &&
leaseExpirationDurationInSeconds == that.leaseExpirationDurationInSeconds &&
Objects.equals(virtualHostName, that.virtualHostName) &&
Objects.equals(instanceId, that.instanceId) &&
Objects.equals(secureVirtualHostName, that.secureVirtualHostName) &&
Objects.equals(aSGName, that.aSGName) &&
Objects.equals(metadataMap, that.metadataMap) &&
Objects.equals(dataCenterInfo, that.dataCenterInfo) &&
Objects.equals(ipAddress, that.ipAddress) &&
Objects.equals(statusPageUrlPath, that.statusPageUrlPath) &&
Objects.equals(statusPageUrl, that.statusPageUrl) &&
Objects.equals(homePageUrlPath, that.homePageUrlPath) &&
Objects.equals(homePageUrl, that.homePageUrl) &&
Objects.equals(healthCheckUrlPath, that.healthCheckUrlPath) &&
Objects.equals(healthCheckUrl, that.healthCheckUrl) &&
Objects.equals(secureHealthCheckUrl, that.secureHealthCheckUrl) &&
Objects.equals(namespace, that.namespace) &&
Objects.equals(hostname, that.hostname) &&
preferIpAddress == that.preferIpAddress &&
Objects.equals(initialStatus, that.initialStatus) &&
Arrays.equals(defaultAddressResolutionOrder, that.defaultAddressResolutionOrder) &&
Objects.equals(environment, that.environment);
}
@Override
public int hashCode() {
return Objects.hash(hostInfo, inetUtils, appname, appGroupName,
instanceEnabledOnit, nonSecurePort, securePort, nonSecurePortEnabled,
securePortEnabled, leaseRenewalIntervalInSeconds,
leaseExpirationDurationInSeconds, virtualHostName, instanceId,
secureVirtualHostName, aSGName, metadataMap, dataCenterInfo, ipAddress,
statusPageUrlPath, statusPageUrl, homePageUrlPath, homePageUrl,
healthCheckUrlPath, healthCheckUrl, secureHealthCheckUrl, namespace,
hostname, preferIpAddress, initialStatus, defaultAddressResolutionOrder, environment);
}
@Override
public String toString() {
return new StringBuilder("EurekaInstanceConfigBean{")
.append("hostInfo=").append(hostInfo).append(", ")
.append("inetUtils=").append(inetUtils).append(", ")
.append("appname='").append(appname).append("', ")
.append("appGroupName='").append(appGroupName).append("', ")
.append("instanceEnabledOnit=").append(instanceEnabledOnit).append(", ")
.append("nonSecurePort=").append(nonSecurePort).append(", ")
.append("securePort=").append(securePort).append(", ")
.append("nonSecurePortEnabled=").append(nonSecurePortEnabled).append(", ")
.append("securePortEnabled=").append(securePortEnabled).append(", ")
.append("leaseRenewalIntervalInSeconds=").append(leaseRenewalIntervalInSeconds).append(", ")
.append("leaseExpirationDurationInSeconds=").append(leaseExpirationDurationInSeconds).append(", ")
.append("virtualHostName='").append(virtualHostName).append("', ")
.append("instanceId='").append(instanceId).append("', ")
.append("secureVirtualHostName='").append(secureVirtualHostName).append("', ")
.append("aSGName='").append(aSGName).append("', ")
.append("metadataMap=").append(metadataMap).append(", ")
.append("dataCenterInfo=").append(dataCenterInfo).append(", ")
.append("ipAddress='").append(ipAddress).append("', ")
.append("statusPageUrlPath='").append(statusPageUrlPath).append("', ")
.append("statusPageUrl='").append(statusPageUrl).append("', ")
.append("homePageUrlPath='").append(homePageUrlPath).append("', ")
.append("homePageUrl='").append(homePageUrl).append("', ")
.append("healthCheckUrlPath='").append(healthCheckUrlPath).append("', ")
.append("healthCheckUrl='").append(healthCheckUrl).append("', ")
.append("secureHealthCheckUrl='").append(secureHealthCheckUrl).append("', ")
.append("namespace='").append(namespace).append("', ")
.append("hostname='").append(hostname).append("', ")
.append("preferIpAddress=").append(preferIpAddress).append(", ")
.append("initialStatus=").append(initialStatus).append(", ")
.append("defaultAddressResolutionOrder=").append(Arrays.toString(defaultAddressResolutionOrder)).append(", ")
.append("environment=").append(environment).append(", ").append("}")
.toString();
}
}

View File

@@ -21,16 +21,17 @@ import java.util.Map;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.LeaseInfo;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* See com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider
* @author Spencer Gibb
*/
@CommonsLog
public class InstanceInfoFactory {
private static final Log log = LogFactory.getLog(InstanceInfoFactory.class);
public InstanceInfo create(EurekaInstanceConfig config) {
LeaseInfo.Builder leaseInfoBuilder = LeaseInfo.Builder.newBuilder()
.setRenewalIntervalInSecs(config.getLeaseRenewalIntervalInSeconds())

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.cloud.netflix.eureka.MutableDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
/**
* @author Daniel Lavoie
*/
@Configuration
public class DiscoveryClientOptionalArgsConfiguration {
@Bean
@ConditionalOnMissingClass("com.sun.jersey.api.client.filter.ClientFilter")
@ConditionalOnMissingBean(value = AbstractDiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT)
public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs() {
return new RestTemplateDiscoveryClientOptionalArgs();
}
@Bean
@ConditionalOnClass(name = "com.sun.jersey.api.client.filter.ClientFilter")
@ConditionalOnMissingBean(value = AbstractDiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT)
public MutableDiscoveryClientOptionalArgs discoveryClientOptionalArgs() {
return new MutableDiscoveryClientOptionalArgs();
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
/**
* A simple wrapper class for {@link Applications} that insure proprer Jackson
* serialization through the JsonPropert overwrites.
*
* @author Daniel Lavoie
*/
public class EurekaApplications extends com.netflix.discovery.shared.Applications {
@JsonCreator
public EurekaApplications(@JsonProperty("apps__hashcode") String appsHashCode,
@JsonProperty("versions__delta") Long versionDelta,
@JsonProperty("application") List<Application> registeredApplications) {
super(appsHashCode, versionDelta, registeredApplications);
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
/**
* @author Daniel Lavoie
*/
public class RestTemplateDiscoveryClientOptionalArgs
extends AbstractDiscoveryClientOptionalArgs<Void> {
public RestTemplateDiscoveryClientOptionalArgs() {
setTransportClientFactories(new RestTemplateTransportClientFactories());
}
}

View File

@@ -0,0 +1,227 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import static com.netflix.discovery.shared.transport.EurekaHttpResponse.anEurekaHttpResponse;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
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.RestTemplate;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import com.netflix.discovery.shared.transport.EurekaHttpResponse;
import com.netflix.discovery.shared.transport.EurekaHttpResponse.EurekaHttpResponseBuilder;
import com.netflix.discovery.util.StringUtil;
/**
* @author Daniel Lavoie
*/
public class RestTemplateEurekaHttpClient implements EurekaHttpClient {
protected final Log logger = LogFactory.getLog(getClass());
private RestTemplate restTemplate;
private String serviceUrl;
public RestTemplateEurekaHttpClient(RestTemplate restTemplate, String serviceUrl) {
this.restTemplate = restTemplate;
this.serviceUrl = serviceUrl;
}
@Override
public EurekaHttpResponse<Void> register(InstanceInfo info) {
String urlPath = serviceUrl + "apps/" + info.getAppName();
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT_ENCODING, "gzip");
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.POST,
new HttpEntity<InstanceInfo>(info, headers), Void.class);
return anEurekaHttpResponse(response.getStatusCodeValue())
.headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<Void> cancel(String appName, String id) {
String urlPath = serviceUrl + "apps/" + appName + '/' + id;
ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.DELETE,
null, Void.class);
return anEurekaHttpResponse(response.getStatusCodeValue())
.headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<InstanceInfo> sendHeartBeat(String appName, String id,
InstanceInfo info, InstanceStatus overriddenStatus) {
String urlPath = serviceUrl + "apps/" + appName + '/' + id + "?status="
+ info.getStatus().toString() + "&lastDirtyTimestamp="
+ info.getLastDirtyTimestamp().toString() + (overriddenStatus != null
? "&overriddenstatus=" + overriddenStatus.name() : "");
ResponseEntity<InstanceInfo> response = restTemplate.exchange(urlPath,
HttpMethod.PUT, null, InstanceInfo.class);
EurekaHttpResponseBuilder<InstanceInfo> eurekaResponseBuilder = anEurekaHttpResponse(
response.getStatusCodeValue(), InstanceInfo.class)
.headers(headersOf(response));
if (response.hasBody())
eurekaResponseBuilder.entity(response.getBody());
return eurekaResponseBuilder.build();
}
@Override
public EurekaHttpResponse<Void> statusUpdate(String appName, String id,
InstanceStatus newStatus, InstanceInfo info) {
String urlPath = serviceUrl + "apps/" + appName + '/' + id + "?status="
+ newStatus.name() + "&lastDirtyTimestamp="
+ info.getLastDirtyTimestamp().toString();
ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.PUT,
null, Void.class);
return anEurekaHttpResponse(response.getStatusCodeValue())
.headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<Void> deleteStatusOverride(String appName, String id,
InstanceInfo info) {
String urlPath = serviceUrl + "apps/" + appName + '/' + id
+ "/status?lastDirtyTimestamp=" + info.getLastDirtyTimestamp().toString();
ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.DELETE,
null, Void.class);
return anEurekaHttpResponse(response.getStatusCodeValue())
.headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<Applications> getApplications(String... regions) {
return getApplicationsInternal("apps/", regions);
}
private EurekaHttpResponse<Applications> getApplicationsInternal(String urlPath,
String[] regions) {
String url = serviceUrl + urlPath;
if (regions != null && regions.length > 0)
urlPath = (urlPath.contains("?") ? "&" : "?") + "regions="
+ StringUtil.join(regions);
ResponseEntity<EurekaApplications> response = restTemplate.exchange(url,
HttpMethod.GET, null, EurekaApplications.class);
return anEurekaHttpResponse(response.getStatusCodeValue(),
response.getStatusCode().value() == HttpStatus.OK.value()
&& response.hasBody() ? (Applications) response.getBody() : null)
.headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<Applications> getDelta(String... regions) {
return getApplicationsInternal("apps/delta", regions);
}
@Override
public EurekaHttpResponse<Applications> getVip(String vipAddress, String... regions) {
return getApplicationsInternal("vips/" + vipAddress, regions);
}
@Override
public EurekaHttpResponse<Applications> getSecureVip(String secureVipAddress,
String... regions) {
return getApplicationsInternal("svips/" + secureVipAddress, regions);
}
@Override
public EurekaHttpResponse<Application> getApplication(String appName) {
String urlPath = serviceUrl + "apps/" + appName;
ResponseEntity<Application> response = restTemplate.exchange(urlPath,
HttpMethod.GET, null, Application.class);
Application application = response.getStatusCodeValue() == HttpStatus.OK.value()
&& response.hasBody() ? response.getBody() : null;
return anEurekaHttpResponse(response.getStatusCodeValue(), application)
.headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<InstanceInfo> getInstance(String appName, String id) {
return getInstanceInternal("apps/" + appName + '/' + id);
}
@Override
public EurekaHttpResponse<InstanceInfo> getInstance(String id) {
return getInstanceInternal("instances/" + id);
}
private EurekaHttpResponse<InstanceInfo> getInstanceInternal(String urlPath) {
urlPath = serviceUrl + urlPath;
ResponseEntity<InstanceInfo> response = restTemplate.exchange(urlPath,
HttpMethod.GET, null, InstanceInfo.class);
return anEurekaHttpResponse(response.getStatusCodeValue(),
response.getStatusCodeValue() == HttpStatus.OK.value()
&& response.hasBody() ? response.getBody() : null)
.headers(headersOf(response)).build();
}
@Override
public void shutdown() {
// Nothing to do
}
private static Map<String, String> headersOf(ResponseEntity<?> response) {
HttpHeaders httpHeaders = response.getHeaders();
if (httpHeaders == null || httpHeaders.isEmpty()) {
return Collections.emptyMap();
}
Map<String, String> headers = new HashMap<>();
for (Entry<String, List<String>> entry : httpHeaders.entrySet()) {
if (!entry.getValue().isEmpty()) {
headers.put(entry.getKey(), entry.getValue().get(0));
}
}
return headers;
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.util.Collection;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.shared.transport.TransportClientFactory;
import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClient;
import com.netflix.discovery.shared.transport.jersey.TransportClientFactories;
/**
* @author Daniel Lavoie
*/
public class RestTemplateTransportClientFactories
implements TransportClientFactories<Void> {
@Override
public TransportClientFactory newTransportClientFactory(
Collection<Void> additionalFilters, EurekaJerseyClient providedJerseyClient) {
throw new UnsupportedOperationException();
}
@Override
public TransportClientFactory newTransportClientFactory(
EurekaClientConfig clientConfig, Collection<Void> additionalFilters,
InstanceInfo myInstanceInfo) {
return new RestTemplateTransportClientFactory();
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.net.URI;
import java.net.URISyntaxException;
import org.springframework.http.client.support.BasicAuthorizationInterceptor;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.netflix.discovery.shared.resolver.EurekaEndpoint;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import com.netflix.discovery.shared.transport.TransportClientFactory;
/**
* Provides the custom {@link RestTemplate} required by the
* {@link RestTemplateEurekaHttpClient}. Relies on Jackson for serialization and
* deserialization.
*
* @author Daniel Lavoie
*/
public class RestTemplateTransportClientFactory implements TransportClientFactory {
@Override
public EurekaHttpClient newClient(EurekaEndpoint serviceUrl) {
return new RestTemplateEurekaHttpClient(restTemplate(serviceUrl.getServiceUrl()),
serviceUrl.getServiceUrl());
}
private RestTemplate restTemplate(String serviceUrl) {
RestTemplate restTemplate = new RestTemplate();
try {
URI serviceURI = new URI(serviceUrl);
if (serviceURI.getUserInfo() != null) {
String[] credentials = serviceURI.getUserInfo().split(":");
if (credentials.length == 2) {
restTemplate.getInterceptors().add(new BasicAuthorizationInterceptor(
credentials[0], credentials[1]));
}
}
}
catch (URISyntaxException ignore) {
}
restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter());
return restTemplate;
}
/**
* Provides the serialization configurations required by the Eureka Server. JSON
* content exchanged with eureka requires a root node matching the entity being
* serialized or deserialized. Achived with
* {@link SerializationFeature.WRAP_ROOT_VALUE} and
* {@link DeserializationFeature.UNWRAP_ROOT_VALUE}.
* {@link PropertyNamingStrategy.SnakeCaseStrategy} is applied to the underlying
* {@link ObjectMapper}.
*
*
* @return
*/
public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE));
converter.getObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true);
converter.getObjectMapper().configure(DeserializationFeature.UNWRAP_ROOT_VALUE,
true);
return converter;
}
@Override
public void shutdown() {
}
}

View File

@@ -19,9 +19,6 @@ package org.springframework.cloud.netflix.ribbon.eureka;
import java.util.ArrayList;
import java.util.List;
import lombok.Getter;
import lombok.Setter;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
@@ -78,10 +75,18 @@ public class DomainExtractingServerList implements ServerList<DiscoveryEnabledSe
class DomainExtractingServer extends DiscoveryEnabledServer {
@Getter
@Setter
private String id;
@Override
public String getId() {
return id;
}
@Override
public void setId(String id) {
this.id = id;
}
public DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort,
boolean useIpAddr, boolean approximateZoneFromHostname) {
// host and port are set in super()

View File

@@ -20,6 +20,8 @@ import javax.annotation.PostConstruct;
import javax.inject.Provider;
import com.netflix.discovery.EurekaClient;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -43,8 +45,6 @@ import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextB
import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity;
import static org.springframework.cloud.netflix.ribbon.RibbonUtils.setRibbonProperty;
import lombok.extern.apachecommons.CommonsLog;
/**
* Preprocessor that configures defaults for eureka-discovered ribbon clients. Such as:
* <code>@zone</code>, NIWSServerListClassName, DeploymentContextBasedVipAddresses,
@@ -55,9 +55,10 @@ import lombok.extern.apachecommons.CommonsLog;
* @author Ryan Baxter
*/
@Configuration
@CommonsLog
public class EurekaRibbonClientConfiguration {
private static final Log log = LogFactory.getLog(EurekaRibbonClientConfiguration.class);
@Value("${ribbon.eureka.approximateZoneFromHostname:false}")
private boolean approximateZoneFromHostname = false;

View File

@@ -21,7 +21,7 @@ import org.junit.After;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.aop.scope.ScopedProxyFactoryBean;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import java.util.Collections;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

View File

@@ -1,5 +1,5 @@
/*
Copyright 2013-2014 the original author or authors.
Copyright 2013-2017 the original author or authors.
*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.commons.util.InetUtils;

View File

@@ -3,7 +3,7 @@ package org.springframework.cloud.netflix.eureka;
import java.io.IOException;
import org.junit.Test;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import java.util.Arrays;
import org.junit.After;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.util.EnvironmentTestUtils;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.config.client.ConfigClientProperties;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package org.springframework.cloud.netflix.eureka.config;
import org.junit.After;
import org.junit.Test;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.config.server.config.ConfigServerProperties;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.config;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.eureka.sample.EurekaSampleApplication;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.netflix.discovery.DiscoveryClient.DiscoveryClientOptionalArgs;
/**
* @author Daniel Lavoie
*/
@DirtiesContext
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = EurekaSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class JerseyOptionalArgsConfigurationTest {
@Autowired
private DiscoveryClientOptionalArgs optionalArgs;
@Test
public void contextLoads() {
Assert.assertNotNull(optionalArgs);
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.config;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.ClassPathExclusions;
import org.springframework.cloud.FilteredClassPathRunner;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.sample.EurekaSampleApplication;
import org.springframework.context.ConfigurableApplicationContext;
/**
* @author Daniel Lavoie
*/
@RunWith(FilteredClassPathRunner.class)
@ClassPathExclusions({ "jersey-client-*", "jersey-core-*", "jersey-apache-client4-*" })
@SpringBootTest(classes = EurekaSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class RestTemplateOptionalArgsConfigurationTest {
@Test
public void contextLoads() {
try (ConfigurableApplicationContext context = new SpringApplicationBuilder()
.web(false).sources(EurekaSampleApplication.class).run()) {
Assert.assertNotNull(
context.getBean(RestTemplateDiscoveryClientOptionalArgs.class));
}
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
/**
* Mocked Eureka Server
*
* @author Daniel Lavoie
*/
@Configuration
@RestController
@SpringBootApplication
public class EurekaServerMockApplication {
private static final InstanceInfo INFO = new InstanceInfo(null, null, null, null,
null, null, null, null, null, null, null, null, null, 0, null, null, null,
null, null, null, null, 0l, 0l, null, null);
/**
* Simulates Eureka Server own's serialization.
* @return
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
return new RestTemplateTransportClientFactory()
.mappingJacksonHttpMessageConverter();
}
@ResponseStatus(HttpStatus.OK)
@PostMapping("/apps/{appName}")
public void register(@PathVariable String appName,
@RequestBody InstanceInfo instanceInfo) {
// Nothing to do
}
@ResponseStatus(HttpStatus.OK)
@DeleteMapping("/apps/{appName}/{id}")
public void cancel(@PathVariable String appName, @PathVariable String id) {
}
@ResponseStatus(HttpStatus.OK)
@PutMapping(value = "/apps/{appName}/{id}", params = { "status",
"lastDirtyTimestamp" })
public InstanceInfo sendHeartBeat(@PathVariable String appName,
@PathVariable String id, @RequestParam String status,
@RequestParam String lastDirtyTimestamp,
@RequestParam(required = false) String overriddenstatus) {
return new InstanceInfo(null, null, null, null, null, null, null, null, null,
null, null, null, null, 0, null, null, null, null, null, null, null, 0l,
0l, null, null);
}
@ResponseStatus(HttpStatus.OK)
@PutMapping(value = "/apps/{appName}/{id}/status", params = { "value",
"lastDirtyTimestamp" })
public void statusUpdate(@PathVariable String appName, @PathVariable String id,
@RequestParam String value, @RequestParam String lastDirtyTimestamp) {
}
@ResponseStatus(HttpStatus.OK)
@DeleteMapping(value = "/apps/{appName}/{id}/status", params = "lastDirtyTimestamp")
public void deleteStatusOverride(@PathVariable String appName,
@PathVariable String id, @RequestParam String lastDirtyTimestamp) {
}
@GetMapping(value = { "/apps", "/apps/delta", "/vips/{address}", "/svips/{address}" })
public Applications getApplications(@PathVariable(required = false) String address,
@RequestParam(required = false) String regions) {
return new Applications();
}
@GetMapping(value = "/apps/{appName}")
public Application getApplication(@PathVariable String appName) {
return new Application();
}
@GetMapping(value = { "/apps/{appName}/{id}", "/instances/{id}" })
public InstanceInfo getInstance(@PathVariable(required = false) String appName,
@PathVariable String id) {
return INFO;
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.http.HttpStatus;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider;
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
/**
* @author Daniel Lavoie
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = EurekaServerMockApplication.class, properties = { "debug=true",
"security.basic.enabled=true" }, webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
public class RestTemplateEurekaHttpClientTest {
@Autowired
private InetUtils inetUtils;
@Value("http://${security.user.name}:${security.user.password}@localhost:${local.server.port}")
private String serviceUrl;
private EurekaHttpClient eurekaHttpClient;
private InstanceInfo info;
@Before
public void setup() {
eurekaHttpClient = new RestTemplateTransportClientFactory()
.newClient(new DefaultEndpoint(serviceUrl));
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
String appname = "customapp";
config.setIpAddress("127.0.0.1");
config.setHostname("localhost");
config.setAppname(appname);
config.setVirtualHostName(appname);
config.setSecureVirtualHostName(appname);
config.setNonSecurePort(4444);
config.setInstanceId("127.0.0.1:customapp:4444");
info = new EurekaConfigBasedInstanceInfoProvider(config).get();
}
@Test
public void testRegister() {
Assert.assertEquals(HttpStatus.OK.value(),
eurekaHttpClient.register(info).getStatusCode());
}
@Test
public void testCancel() {
Assert.assertEquals(HttpStatus.OK.value(),
eurekaHttpClient.cancel("test", "test").getStatusCode());
}
@Test
public void testSendHeartBeat() {
Assert.assertEquals(HttpStatus.OK.value(), eurekaHttpClient
.sendHeartBeat("test", "test", info, null).getStatusCode());
}
@Test
public void testStatusUpdate() {
Assert.assertEquals(HttpStatus.OK.value(), eurekaHttpClient
.statusUpdate("test", "test", InstanceStatus.UP, info).getStatusCode());
}
@Test
public void testDeleteStatusOverride() {
Assert.assertEquals(HttpStatus.OK.value(), eurekaHttpClient
.deleteStatusOverride("test", "test", info).getStatusCode());
}
@Test
public void testGetApplications() {
Assert.assertNotNull(eurekaHttpClient.getApplications().getEntity());
Assert.assertNotNull(eurekaHttpClient.getApplications("us", "eu").getEntity());
}
@Test
public void testGetDelta() {
eurekaHttpClient.getDelta().getEntity();
eurekaHttpClient.getDelta("us", "eu").getEntity();
}
@Test
public void testGetVips() {
eurekaHttpClient.getVip("test");
eurekaHttpClient.getVip("test", "us", "eu");
}
@Test
public void testGetSecureVip() {
eurekaHttpClient.getSecureVip("test");
eurekaHttpClient.getSecureVip("test", "us", "eu");
}
@Test
public void testGetApplication() {
eurekaHttpClient.getApplication("test");
}
@Test
public void testGetInstance() {
eurekaHttpClient.getInstance("test");
eurekaHttpClient.getInstance("test", "test");
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import org.junit.Test;
/**
* @author Daniel Lavoie
*/
public class RestTemplateTransportClientFactoriesTest {
@Test(expected = UnsupportedOperationException.class)
public void testJerseyIsUnsuported() {
new RestTemplateTransportClientFactories().newTransportClientFactory(null, null);
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
/**
* @author Daniel Lavoie
*/
public class RestTemplateTransportClientFactoryTest {
private RestTemplateTransportClientFactory transportClientFatory;
@Before
public void setup() {
transportClientFatory = new RestTemplateTransportClientFactory();
}
@Test
public void testWithoutUserInfo() {
transportClientFatory.newClient(new DefaultEndpoint("http://localhost:8761"));
}
@Test
public void testInvalidUserInfo() {
transportClientFatory
.newClient(new DefaultEndpoint("http://test@localhost:8761"));
}
@Test
public void testUserInfo() {
transportClientFatory
.newClient(new DefaultEndpoint("http://test:test@localhost:8761"));
}
@After
public void shutdown() {
transportClientFatory.shutdown();
}
}

View File

@@ -23,7 +23,7 @@ import com.netflix.niws.loadbalancer.NIWSDiscoveryPing;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ package org.springframework.cloud.netflix.ribbon.eureka;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2016 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.commons.util.InetUtilsProperties;

View File

@@ -2,4 +2,11 @@
foo3:
ribbon:
NFLoadBalancerPingClassName: com.netflix.loadbalancer.DummyPing
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
security:
basic:
enabled: false
user:
name: test
password: test

View File

@@ -96,13 +96,6 @@
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- Only needed at compile time -->
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -16,17 +16,16 @@
package org.springframework.cloud.netflix.eureka.server;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Objects;
/**
* Configuration properties for the Eureka dashboard (UI).
*
* @author Dave Syer
*/
@ConfigurationProperties("eureka.dashboard")
@Data
public class EurekaDashboardProperties {
/**
@@ -39,4 +38,42 @@ public class EurekaDashboardProperties {
*/
private boolean enabled = true;
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EurekaDashboardProperties that = (EurekaDashboardProperties) o;
return enabled == that.enabled &&
Objects.equals(path, that.path);
}
@Override
public int hashCode() {
return Objects.hash(path, enabled);
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer("EurekaDashboardProperties{");
sb.append("path='").append(path).append('\'');
sb.append(", enabled=").append(enabled);
sb.append('}');
return sb.toString();
}
}

View File

@@ -34,14 +34,16 @@ import com.netflix.eureka.aws.AwsBinderDelegate;
import com.netflix.eureka.registry.PeerAwareInstanceRegistry;
import com.netflix.eureka.util.EurekaMonitors;
import com.thoughtworks.xstream.XStream;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* @author Spencer Gibb
*/
@CommonsLog
public class EurekaServerBootstrap {
private static final Log log = LogFactory.getLog(EurekaServerBootstrap.class);
private static final String TEST = "test";
private static final String ARCHAIUS_DEPLOYMENT_ENVIRONMENT = "archaius.deployment.environment";

View File

@@ -21,6 +21,9 @@ import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.PropertyResolver;
@@ -28,12 +31,9 @@ import org.springframework.core.env.PropertyResolver;
import com.netflix.eureka.EurekaServerConfig;
import com.netflix.eureka.aws.AwsBindingStrategy;
import lombok.Data;
/**
* @author Dave Syer
*/
@Data
@ConfigurationProperties(EurekaServerConfigBean.PREFIX)
public class EurekaServerConfigBean implements EurekaServerConfig {
@@ -89,7 +89,7 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
private long aSGUpdateIntervalMs = 5 * MINUTES;
private long aSGCacheExpiryTimeoutMs = 10 * MINUTES; // defaults to longer than the
// asg update interval
// asg update interval
private long responseCacheAutoExpirationInSeconds = 180;
@@ -273,4 +273,665 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
public int getHealthStatusMinNumberOfAvailablePeers() {
return this.minAvailableInstancesForPeerReplication;
}
public PropertyResolver getPropertyResolver() {
return propertyResolver;
}
public void setPropertyResolver(PropertyResolver propertyResolver) {
this.propertyResolver = propertyResolver;
}
public String getAWSAccessId() {
return aWSAccessId;
}
public void setAWSAccessId(String aWSAccessId) {
this.aWSAccessId = aWSAccessId;
}
public String getAWSSecretKey() {
return aWSSecretKey;
}
public void setAWSSecretKey(String aWSSecretKey) {
this.aWSSecretKey = aWSSecretKey;
}
public int getEIPBindRebindRetries() {
return eIPBindRebindRetries;
}
public void setEIPBindRebindRetries(int eIPBindRebindRetries) {
this.eIPBindRebindRetries = eIPBindRebindRetries;
}
public int getEIPBindingRetryIntervalMs() {
return eIPBindingRetryIntervalMs;
}
public void setEIPBindingRetryIntervalMs(int eIPBindingRetryIntervalMs) {
this.eIPBindingRetryIntervalMs = eIPBindingRetryIntervalMs;
}
public int getEIPBindingRetryIntervalMsWhenUnbound() {
return eIPBindingRetryIntervalMsWhenUnbound;
}
public void setEIPBindingRetryIntervalMsWhenUnbound(
int eIPBindingRetryIntervalMsWhenUnbound) {
this.eIPBindingRetryIntervalMsWhenUnbound = eIPBindingRetryIntervalMsWhenUnbound;
}
public boolean isEnableSelfPreservation() {
return enableSelfPreservation;
}
public void setEnableSelfPreservation(boolean enableSelfPreservation) {
this.enableSelfPreservation = enableSelfPreservation;
}
@Override
public double getRenewalPercentThreshold() {
return renewalPercentThreshold;
}
public void setRenewalPercentThreshold(double renewalPercentThreshold) {
this.renewalPercentThreshold = renewalPercentThreshold;
}
@Override
public int getRenewalThresholdUpdateIntervalMs() {
return renewalThresholdUpdateIntervalMs;
}
public void setRenewalThresholdUpdateIntervalMs(
int renewalThresholdUpdateIntervalMs) {
this.renewalThresholdUpdateIntervalMs = renewalThresholdUpdateIntervalMs;
}
@Override
public int getPeerEurekaNodesUpdateIntervalMs() {
return peerEurekaNodesUpdateIntervalMs;
}
public void setPeerEurekaNodesUpdateIntervalMs(int peerEurekaNodesUpdateIntervalMs) {
this.peerEurekaNodesUpdateIntervalMs = peerEurekaNodesUpdateIntervalMs;
}
@Override
public int getNumberOfReplicationRetries() {
return numberOfReplicationRetries;
}
public void setNumberOfReplicationRetries(int numberOfReplicationRetries) {
this.numberOfReplicationRetries = numberOfReplicationRetries;
}
@Override
public int getPeerEurekaStatusRefreshTimeIntervalMs() {
return peerEurekaStatusRefreshTimeIntervalMs;
}
public void setPeerEurekaStatusRefreshTimeIntervalMs(
int peerEurekaStatusRefreshTimeIntervalMs) {
this.peerEurekaStatusRefreshTimeIntervalMs = peerEurekaStatusRefreshTimeIntervalMs;
}
@Override
public int getWaitTimeInMsWhenSyncEmpty() {
return waitTimeInMsWhenSyncEmpty;
}
public void setWaitTimeInMsWhenSyncEmpty(int waitTimeInMsWhenSyncEmpty) {
this.waitTimeInMsWhenSyncEmpty = waitTimeInMsWhenSyncEmpty;
}
@Override
public int getPeerNodeConnectTimeoutMs() {
return peerNodeConnectTimeoutMs;
}
public void setPeerNodeConnectTimeoutMs(int peerNodeConnectTimeoutMs) {
this.peerNodeConnectTimeoutMs = peerNodeConnectTimeoutMs;
}
@Override
public int getPeerNodeReadTimeoutMs() {
return peerNodeReadTimeoutMs;
}
public void setPeerNodeReadTimeoutMs(int peerNodeReadTimeoutMs) {
this.peerNodeReadTimeoutMs = peerNodeReadTimeoutMs;
}
@Override
public int getPeerNodeTotalConnections() {
return peerNodeTotalConnections;
}
public void setPeerNodeTotalConnections(int peerNodeTotalConnections) {
this.peerNodeTotalConnections = peerNodeTotalConnections;
}
@Override
public int getPeerNodeTotalConnectionsPerHost() {
return peerNodeTotalConnectionsPerHost;
}
public void setPeerNodeTotalConnectionsPerHost(int peerNodeTotalConnectionsPerHost) {
this.peerNodeTotalConnectionsPerHost = peerNodeTotalConnectionsPerHost;
}
@Override
public int getPeerNodeConnectionIdleTimeoutSeconds() {
return peerNodeConnectionIdleTimeoutSeconds;
}
public void setPeerNodeConnectionIdleTimeoutSeconds(
int peerNodeConnectionIdleTimeoutSeconds) {
this.peerNodeConnectionIdleTimeoutSeconds = peerNodeConnectionIdleTimeoutSeconds;
}
@Override
public long getRetentionTimeInMSInDeltaQueue() {
return retentionTimeInMSInDeltaQueue;
}
public void setRetentionTimeInMSInDeltaQueue(long retentionTimeInMSInDeltaQueue) {
this.retentionTimeInMSInDeltaQueue = retentionTimeInMSInDeltaQueue;
}
@Override
public long getDeltaRetentionTimerIntervalInMs() {
return deltaRetentionTimerIntervalInMs;
}
public void setDeltaRetentionTimerIntervalInMs(long deltaRetentionTimerIntervalInMs) {
this.deltaRetentionTimerIntervalInMs = deltaRetentionTimerIntervalInMs;
}
@Override
public long getEvictionIntervalTimerInMs() {
return evictionIntervalTimerInMs;
}
public void setEvictionIntervalTimerInMs(long evictionIntervalTimerInMs) {
this.evictionIntervalTimerInMs = evictionIntervalTimerInMs;
}
public int getASGQueryTimeoutMs() {
return aSGQueryTimeoutMs;
}
public void setASGQueryTimeoutMs(int aSGQueryTimeoutMs) {
this.aSGQueryTimeoutMs = aSGQueryTimeoutMs;
}
public long getASGUpdateIntervalMs() {
return aSGUpdateIntervalMs;
}
public void setASGUpdateIntervalMs(long aSGUpdateIntervalMs) {
this.aSGUpdateIntervalMs = aSGUpdateIntervalMs;
}
public long getASGCacheExpiryTimeoutMs() {
return aSGCacheExpiryTimeoutMs;
}
public void setASGCacheExpiryTimeoutMs(long aSGCacheExpiryTimeoutMs) {
this.aSGCacheExpiryTimeoutMs = aSGCacheExpiryTimeoutMs;
}
@Override
public long getResponseCacheAutoExpirationInSeconds() {
return responseCacheAutoExpirationInSeconds;
}
public void setResponseCacheAutoExpirationInSeconds(
long responseCacheAutoExpirationInSeconds) {
this.responseCacheAutoExpirationInSeconds = responseCacheAutoExpirationInSeconds;
}
@Override
public long getResponseCacheUpdateIntervalMs() {
return responseCacheUpdateIntervalMs;
}
public void setResponseCacheUpdateIntervalMs(long responseCacheUpdateIntervalMs) {
this.responseCacheUpdateIntervalMs = responseCacheUpdateIntervalMs;
}
public boolean isUseReadOnlyResponseCache() {
return useReadOnlyResponseCache;
}
public void setUseReadOnlyResponseCache(boolean useReadOnlyResponseCache) {
this.useReadOnlyResponseCache = useReadOnlyResponseCache;
}
public boolean isDisableDelta() {
return disableDelta;
}
public void setDisableDelta(boolean disableDelta) {
this.disableDelta = disableDelta;
}
@Override
public long getMaxIdleThreadInMinutesAgeForStatusReplication() {
return maxIdleThreadInMinutesAgeForStatusReplication;
}
public void setMaxIdleThreadInMinutesAgeForStatusReplication(
long maxIdleThreadInMinutesAgeForStatusReplication) {
this.maxIdleThreadInMinutesAgeForStatusReplication = maxIdleThreadInMinutesAgeForStatusReplication;
}
@Override
public int getMinThreadsForStatusReplication() {
return minThreadsForStatusReplication;
}
public void setMinThreadsForStatusReplication(int minThreadsForStatusReplication) {
this.minThreadsForStatusReplication = minThreadsForStatusReplication;
}
@Override
public int getMaxThreadsForStatusReplication() {
return maxThreadsForStatusReplication;
}
public void setMaxThreadsForStatusReplication(int maxThreadsForStatusReplication) {
this.maxThreadsForStatusReplication = maxThreadsForStatusReplication;
}
@Override
public int getMaxElementsInStatusReplicationPool() {
return maxElementsInStatusReplicationPool;
}
public void setMaxElementsInStatusReplicationPool(
int maxElementsInStatusReplicationPool) {
this.maxElementsInStatusReplicationPool = maxElementsInStatusReplicationPool;
}
public boolean isSyncWhenTimestampDiffers() {
return syncWhenTimestampDiffers;
}
public void setSyncWhenTimestampDiffers(boolean syncWhenTimestampDiffers) {
this.syncWhenTimestampDiffers = syncWhenTimestampDiffers;
}
@Override
public int getRegistrySyncRetries() {
return registrySyncRetries;
}
public void setRegistrySyncRetries(int registrySyncRetries) {
this.registrySyncRetries = registrySyncRetries;
}
@Override
public long getRegistrySyncRetryWaitMs() {
return registrySyncRetryWaitMs;
}
public void setRegistrySyncRetryWaitMs(long registrySyncRetryWaitMs) {
this.registrySyncRetryWaitMs = registrySyncRetryWaitMs;
}
@Override
public int getMaxElementsInPeerReplicationPool() {
return maxElementsInPeerReplicationPool;
}
public void setMaxElementsInPeerReplicationPool(
int maxElementsInPeerReplicationPool) {
this.maxElementsInPeerReplicationPool = maxElementsInPeerReplicationPool;
}
@Override
public long getMaxIdleThreadAgeInMinutesForPeerReplication() {
return maxIdleThreadAgeInMinutesForPeerReplication;
}
public void setMaxIdleThreadAgeInMinutesForPeerReplication(
long maxIdleThreadAgeInMinutesForPeerReplication) {
this.maxIdleThreadAgeInMinutesForPeerReplication = maxIdleThreadAgeInMinutesForPeerReplication;
}
@Override
public int getMinThreadsForPeerReplication() {
return minThreadsForPeerReplication;
}
public void setMinThreadsForPeerReplication(int minThreadsForPeerReplication) {
this.minThreadsForPeerReplication = minThreadsForPeerReplication;
}
@Override
public int getMaxThreadsForPeerReplication() {
return maxThreadsForPeerReplication;
}
public void setMaxThreadsForPeerReplication(int maxThreadsForPeerReplication) {
this.maxThreadsForPeerReplication = maxThreadsForPeerReplication;
}
@Override
public int getMaxTimeForReplication() {
return maxTimeForReplication;
}
public void setMaxTimeForReplication(int maxTimeForReplication) {
this.maxTimeForReplication = maxTimeForReplication;
}
public boolean isPrimeAwsReplicaConnections() {
return primeAwsReplicaConnections;
}
public void setPrimeAwsReplicaConnections(boolean primeAwsReplicaConnections) {
this.primeAwsReplicaConnections = primeAwsReplicaConnections;
}
public boolean isDisableDeltaForRemoteRegions() {
return disableDeltaForRemoteRegions;
}
public void setDisableDeltaForRemoteRegions(boolean disableDeltaForRemoteRegions) {
this.disableDeltaForRemoteRegions = disableDeltaForRemoteRegions;
}
@Override
public int getRemoteRegionConnectTimeoutMs() {
return remoteRegionConnectTimeoutMs;
}
public void setRemoteRegionConnectTimeoutMs(int remoteRegionConnectTimeoutMs) {
this.remoteRegionConnectTimeoutMs = remoteRegionConnectTimeoutMs;
}
@Override
public int getRemoteRegionReadTimeoutMs() {
return remoteRegionReadTimeoutMs;
}
public void setRemoteRegionReadTimeoutMs(int remoteRegionReadTimeoutMs) {
this.remoteRegionReadTimeoutMs = remoteRegionReadTimeoutMs;
}
@Override
public int getRemoteRegionTotalConnections() {
return remoteRegionTotalConnections;
}
public void setRemoteRegionTotalConnections(int remoteRegionTotalConnections) {
this.remoteRegionTotalConnections = remoteRegionTotalConnections;
}
@Override
public int getRemoteRegionTotalConnectionsPerHost() {
return remoteRegionTotalConnectionsPerHost;
}
public void setRemoteRegionTotalConnectionsPerHost(
int remoteRegionTotalConnectionsPerHost) {
this.remoteRegionTotalConnectionsPerHost = remoteRegionTotalConnectionsPerHost;
}
@Override
public int getRemoteRegionConnectionIdleTimeoutSeconds() {
return remoteRegionConnectionIdleTimeoutSeconds;
}
public void setRemoteRegionConnectionIdleTimeoutSeconds(
int remoteRegionConnectionIdleTimeoutSeconds) {
this.remoteRegionConnectionIdleTimeoutSeconds = remoteRegionConnectionIdleTimeoutSeconds;
}
public boolean isgZipContentFromRemoteRegion() {
return gZipContentFromRemoteRegion;
}
public void setgZipContentFromRemoteRegion(boolean gZipContentFromRemoteRegion) {
this.gZipContentFromRemoteRegion = gZipContentFromRemoteRegion;
}
@Override
public Map<String, String> getRemoteRegionUrlsWithName() {
return remoteRegionUrlsWithName;
}
public void setRemoteRegionUrlsWithName(
Map<String, String> remoteRegionUrlsWithName) {
this.remoteRegionUrlsWithName = remoteRegionUrlsWithName;
}
@Override
public String[] getRemoteRegionUrls() {
return remoteRegionUrls;
}
public void setRemoteRegionUrls(String[] remoteRegionUrls) {
this.remoteRegionUrls = remoteRegionUrls;
}
public Map<String, Set<String>> getRemoteRegionAppWhitelist() {
return remoteRegionAppWhitelist;
}
public void setRemoteRegionAppWhitelist(
Map<String, Set<String>> remoteRegionAppWhitelist) {
this.remoteRegionAppWhitelist = remoteRegionAppWhitelist;
}
@Override
public int getRemoteRegionRegistryFetchInterval() {
return remoteRegionRegistryFetchInterval;
}
public void setRemoteRegionRegistryFetchInterval(
int remoteRegionRegistryFetchInterval) {
this.remoteRegionRegistryFetchInterval = remoteRegionRegistryFetchInterval;
}
@Override
public int getRemoteRegionFetchThreadPoolSize() {
return remoteRegionFetchThreadPoolSize;
}
public void setRemoteRegionFetchThreadPoolSize(int remoteRegionFetchThreadPoolSize) {
this.remoteRegionFetchThreadPoolSize = remoteRegionFetchThreadPoolSize;
}
@Override
public String getRemoteRegionTrustStore() {
return remoteRegionTrustStore;
}
public void setRemoteRegionTrustStore(String remoteRegionTrustStore) {
this.remoteRegionTrustStore = remoteRegionTrustStore;
}
@Override
public String getRemoteRegionTrustStorePassword() {
return remoteRegionTrustStorePassword;
}
public void setRemoteRegionTrustStorePassword(String remoteRegionTrustStorePassword) {
this.remoteRegionTrustStorePassword = remoteRegionTrustStorePassword;
}
public boolean isDisableTransparentFallbackToOtherRegion() {
return disableTransparentFallbackToOtherRegion;
}
public void setDisableTransparentFallbackToOtherRegion(
boolean disableTransparentFallbackToOtherRegion) {
this.disableTransparentFallbackToOtherRegion = disableTransparentFallbackToOtherRegion;
}
public boolean isBatchReplication() {
return batchReplication;
}
public void setBatchReplication(boolean batchReplication) {
this.batchReplication = batchReplication;
}
@Override
public boolean isRateLimiterEnabled() {
return rateLimiterEnabled;
}
public void setRateLimiterEnabled(boolean rateLimiterEnabled) {
this.rateLimiterEnabled = rateLimiterEnabled;
}
@Override
public boolean isRateLimiterThrottleStandardClients() {
return rateLimiterThrottleStandardClients;
}
public void setRateLimiterThrottleStandardClients(
boolean rateLimiterThrottleStandardClients) {
this.rateLimiterThrottleStandardClients = rateLimiterThrottleStandardClients;
}
@Override
public Set<String> getRateLimiterPrivilegedClients() {
return rateLimiterPrivilegedClients;
}
public void setRateLimiterPrivilegedClients(
Set<String> rateLimiterPrivilegedClients) {
this.rateLimiterPrivilegedClients = rateLimiterPrivilegedClients;
}
@Override
public int getRateLimiterBurstSize() {
return rateLimiterBurstSize;
}
public void setRateLimiterBurstSize(int rateLimiterBurstSize) {
this.rateLimiterBurstSize = rateLimiterBurstSize;
}
@Override
public int getRateLimiterRegistryFetchAverageRate() {
return rateLimiterRegistryFetchAverageRate;
}
public void setRateLimiterRegistryFetchAverageRate(
int rateLimiterRegistryFetchAverageRate) {
this.rateLimiterRegistryFetchAverageRate = rateLimiterRegistryFetchAverageRate;
}
@Override
public int getRateLimiterFullFetchAverageRate() {
return rateLimiterFullFetchAverageRate;
}
public void setRateLimiterFullFetchAverageRate(int rateLimiterFullFetchAverageRate) {
this.rateLimiterFullFetchAverageRate = rateLimiterFullFetchAverageRate;
}
public boolean isLogIdentityHeaders() {
return logIdentityHeaders;
}
public void setLogIdentityHeaders(boolean logIdentityHeaders) {
this.logIdentityHeaders = logIdentityHeaders;
}
@Override
public String getListAutoScalingGroupsRoleName() {
return listAutoScalingGroupsRoleName;
}
public void setListAutoScalingGroupsRoleName(String listAutoScalingGroupsRoleName) {
this.listAutoScalingGroupsRoleName = listAutoScalingGroupsRoleName;
}
public boolean isEnableReplicatedRequestCompression() {
return enableReplicatedRequestCompression;
}
public void setEnableReplicatedRequestCompression(
boolean enableReplicatedRequestCompression) {
this.enableReplicatedRequestCompression = enableReplicatedRequestCompression;
}
public void setJsonCodecName(String jsonCodecName) {
this.jsonCodecName = jsonCodecName;
}
public void setXmlCodecName(String xmlCodecName) {
this.xmlCodecName = xmlCodecName;
}
@Override
public int getRoute53BindRebindRetries() {
return route53BindRebindRetries;
}
public void setRoute53BindRebindRetries(int route53BindRebindRetries) {
this.route53BindRebindRetries = route53BindRebindRetries;
}
@Override
public int getRoute53BindingRetryIntervalMs() {
return route53BindingRetryIntervalMs;
}
public void setRoute53BindingRetryIntervalMs(int route53BindingRetryIntervalMs) {
this.route53BindingRetryIntervalMs = route53BindingRetryIntervalMs;
}
@Override
public long getRoute53DomainTTL() {
return route53DomainTTL;
}
public void setRoute53DomainTTL(long route53DomainTTL) {
this.route53DomainTTL = route53DomainTTL;
}
@Override
public AwsBindingStrategy getBindingStrategy() {
return bindingStrategy;
}
public void setBindingStrategy(AwsBindingStrategy bindingStrategy) {
this.bindingStrategy = bindingStrategy;
}
public int getMinAvailableInstancesForPeerReplication() {
return minAvailableInstancesForPeerReplication;
}
public void setMinAvailableInstancesForPeerReplication(
int minAvailableInstancesForPeerReplication) {
this.minAvailableInstancesForPeerReplication = minAvailableInstancesForPeerReplication;
}
@Override
public boolean equals(Object o) {
return EqualsBuilder.reflectionEquals(this, o);
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}

View File

@@ -18,6 +18,8 @@ package org.springframework.cloud.netflix.eureka.server;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.eureka.server.event.EurekaRegistryAvailableEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaServerStartedEvent;
@@ -30,16 +32,15 @@ import org.springframework.web.context.ServletContextAware;
import com.netflix.eureka.EurekaServerConfig;
import lombok.extern.apachecommons.CommonsLog;
/**
* @author Dave Syer
*/
@Configuration
@CommonsLog
public class EurekaServerInitializerConfiguration
implements ServletContextAware, SmartLifecycle, Ordered {
private static final Log log = LogFactory.getLog(EurekaServerInitializerConfiguration.class);
@Autowired
private EurekaServerConfig eurekaServerConfig;

View File

@@ -19,6 +19,8 @@ package org.springframework.cloud.netflix.eureka.server;
import java.util.List;
import com.netflix.eureka.lease.Lease;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent;
@@ -35,16 +37,16 @@ import com.netflix.eureka.EurekaServerConfig;
import com.netflix.eureka.registry.PeerAwareInstanceRegistryImpl;
import com.netflix.eureka.resources.ServerCodecs;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.context.ApplicationEvent;
/**
* @author Spencer Gibb
*/
@CommonsLog
public class InstanceRegistry extends PeerAwareInstanceRegistryImpl
implements ApplicationContextAware {
private static final Log log = LogFactory.getLog(InstanceRegistry.class);
private ApplicationContext ctxt;
private int defaultOpenForTrafficCount;

View File

@@ -16,16 +16,14 @@
package org.springframework.cloud.netflix.eureka.server.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.context.ApplicationEvent;
import java.util.Objects;
/**
* @author Spencer Gibb
* @author Gregor Zurowski
*/
@Data
@EqualsAndHashCode(callSuper = false)
@SuppressWarnings("serial")
public class EurekaInstanceCanceledEvent extends ApplicationEvent {
@@ -43,4 +41,52 @@ public class EurekaInstanceCanceledEvent extends ApplicationEvent {
this.replication = replication;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getServerId() {
return serverId;
}
public void setServerId(String serverId) {
this.serverId = serverId;
}
public boolean isReplication() {
return replication;
}
public void setReplication(boolean replication) {
this.replication = replication;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EurekaInstanceCanceledEvent that = (EurekaInstanceCanceledEvent) o;
return Objects.equals(appName, that.appName) &&
Objects.equals(serverId, that.serverId) &&
replication == replication;
}
@Override
public int hashCode() {
return Objects.hash(appName, serverId, replication);
}
@Override
public String toString() {
return new StringBuilder("EurekaInstanceCanceledEvent{")
.append("appName='").append(appName).append("', ")
.append("serverId='").append(serverId).append("', ")
.append("replication=").append(replication).append("}")
.toString();
}
}

View File

@@ -16,18 +16,16 @@
package org.springframework.cloud.netflix.eureka.server.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.context.ApplicationEvent;
import com.netflix.appinfo.InstanceInfo;
import java.util.Objects;
/**
* @author Spencer Gibb
* @author Gregor Zurowski
*/
@Data
@EqualsAndHashCode(callSuper = false)
@SuppressWarnings("serial")
public class EurekaInstanceRegisteredEvent extends ApplicationEvent {
@@ -45,4 +43,51 @@ public class EurekaInstanceRegisteredEvent extends ApplicationEvent {
this.replication = replication;
}
public InstanceInfo getInstanceInfo() {
return instanceInfo;
}
public void setInstanceInfo(InstanceInfo instanceInfo) {
this.instanceInfo = instanceInfo;
}
public int getLeaseDuration() {
return leaseDuration;
}
public void setLeaseDuration(int leaseDuration) {
this.leaseDuration = leaseDuration;
}
public boolean isReplication() {
return replication;
}
public void setReplication(boolean replication) {
this.replication = replication;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EurekaInstanceRegisteredEvent that = (EurekaInstanceRegisteredEvent) o;
return Objects.equals(instanceInfo, that.instanceInfo) &&
leaseDuration == leaseDuration &&
replication == replication;
}
@Override
public int hashCode() {
return Objects.hash(instanceInfo, leaseDuration, replication);
}
@Override
public String toString() {
return new StringBuilder("EurekaInstanceRegisteredEvent{")
.append("instanceInfo=").append(instanceInfo).append(", ")
.append("leaseDuration=").append(leaseDuration).append(", ")
.append("replication=").append(replication).append("}")
.toString();
}
}

View File

@@ -16,18 +16,16 @@
package org.springframework.cloud.netflix.eureka.server.event;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.context.ApplicationEvent;
import com.netflix.appinfo.InstanceInfo;
import java.util.Objects;
/**
* @author Spencer Gibb
* @author Gregor Zurowski
*/
@Data
@EqualsAndHashCode(callSuper = false)
@SuppressWarnings("serial")
public class EurekaInstanceRenewedEvent extends ApplicationEvent {
@@ -48,4 +46,62 @@ public class EurekaInstanceRenewedEvent extends ApplicationEvent {
this.replication = replication;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getServerId() {
return serverId;
}
public void setServerId(String serverId) {
this.serverId = serverId;
}
public InstanceInfo getInstanceInfo() {
return instanceInfo;
}
public void setInstanceInfo(InstanceInfo instanceInfo) {
this.instanceInfo = instanceInfo;
}
public boolean isReplication() {
return replication;
}
public void setReplication(boolean replication) {
this.replication = replication;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EurekaInstanceRenewedEvent that = (EurekaInstanceRenewedEvent) o;
return Objects.equals(appName, that.appName) &&
Objects.equals(serverId, that.serverId) &&
Objects.equals(instanceInfo, that.instanceInfo) &&
replication == that.replication;
}
@Override
public int hashCode() {
return Objects.hash(appName, serverId, instanceInfo, replication);
}
@Override
public String toString() {
return new StringBuilder("EurekaInstanceRenewedEvent{")
.append("appName='").append(appName).append("', ")
.append("serverId='").append(serverId).append("', ")
.append("instanceInfo=").append(instanceInfo).append(", ")
.append("replication=").append(replication).append("}")
.toString();
}
}

View File

@@ -56,13 +56,6 @@
<groupId>org.webjars</groupId>
<artifactId>d3js</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- Only needed at compile time -->
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -26,8 +26,8 @@ import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
@@ -103,9 +103,10 @@ public class HystrixDashboardConfiguration {
* not yet support CORS (https://bugs.webkit.org/show_bug.cgi?id=61862) so that a UI
* can request a stream from a different server.
*/
@CommonsLog
public static class ProxyStreamServlet extends HttpServlet {
private static final Log log = LogFactory.getLog(ProxyStreamServlet.class);
private static final long serialVersionUID = 1L;
private static final String CONNECTION_CLOSE_VALUE = "close";
@@ -134,6 +135,7 @@ public class HystrixDashboardConfiguration {
response.getWriter()
.println(
"Required parameter 'origin' missing. Example: 107.20.175.135:7001");
return;
}
origin = origin.trim();

View File

@@ -89,13 +89,6 @@
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- Only needed at compile time -->
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -17,18 +17,17 @@
package org.springframework.cloud.netflix.sidecar;
import java.net.URI;
import java.util.Objects;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Spencer Gibb
* @author Gregor Zurowski
*/
@Data
@ConfigurationProperties("sidecar")
public class SidecarProperties {
@@ -44,4 +43,72 @@ public class SidecarProperties {
private String ipAddress;
public URI getHealthUri() {
return healthUri;
}
public void setHealthUri(URI healthUri) {
this.healthUri = healthUri;
}
public URI getHomePageUri() {
return homePageUri;
}
public void setHomePageUri(URI homePageUri) {
this.homePageUri = homePageUri;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getHostname() {
return hostname;
}
public void setHostname(String hostname) {
this.hostname = hostname;
}
public String getIpAddress() {
return ipAddress;
}
public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SidecarProperties that = (SidecarProperties) o;
return Objects.equals(healthUri, that.healthUri) &&
Objects.equals(homePageUri, that.homePageUri) &&
port == that.port &&
Objects.equals(hostname, that.hostname) &&
Objects.equals(ipAddress, that.ipAddress);
}
@Override
public int hashCode() {
return Objects.hash(healthUri, homePageUri, port, hostname, ipAddress);
}
@Override
public String toString() {
return new StringBuilder("SidecarProperties{")
.append("healthUri=").append(healthUri).append(", ")
.append("homePageUri=").append(homePageUri).append(", ")
.append("port=").append(port).append(", ")
.append("hostname='").append(hostname).append("', ")
.append("ipAddress='").append(ipAddress).append("'}")
.toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
@@ -25,7 +25,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
import org.springframework.cloud.netflix.metrics.MetricsHandlerInterceptor;
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
import org.springframework.context.annotation.Bean;

View File

@@ -78,13 +78,6 @@
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- Only needed at compile time -->
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>

View File

@@ -20,6 +20,8 @@ import java.io.IOException;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.handler.annotation.Payload;
@@ -28,16 +30,16 @@ import org.springframework.util.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.apachecommons.CommonsLog;
import rx.subjects.PublishSubject;
/**
* @author Spencer Gibb
*/
@CommonsLog
@Component // needed for ServiceActivator to be picked up
public class HystrixStreamAggregator {
private static final Log log = LogFactory.getLog(HystrixStreamAggregator.class);
private ObjectMapper objectMapper;
private PublishSubject<Map<String, Object>> subject;

View File

@@ -21,6 +21,8 @@ import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.actuator.HasFeatures;
@@ -39,7 +41,6 @@ import io.netty.buffer.ByteBuf;
import io.reactivex.netty.RxNetty;
import io.reactivex.netty.protocol.http.server.HttpServer;
import io.reactivex.netty.protocol.text.sse.ServerSentEvent;
import lombok.extern.apachecommons.CommonsLog;
import rx.Observable;
import rx.subjects.PublishSubject;
@@ -47,10 +48,11 @@ import rx.subjects.PublishSubject;
* @author Spencer Gibb
*/
@Configuration
@CommonsLog
@EnableConfigurationProperties(TurbineStreamProperties.class)
public class TurbineStreamConfiguration implements SmartLifecycle {
private static final Log log = LogFactory.getLog(TurbineStreamConfiguration.class);
private AtomicBoolean running = new AtomicBoolean(false);
@Autowired

View File

@@ -21,13 +21,13 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.netflix.hystrix.HystrixConstants;
import org.springframework.http.MediaType;
import lombok.Data;
import java.util.Objects;
/**
* @author Dave Syer
* @author Gregor Zurowski
*/
@ConfigurationProperties("turbine.stream")
@Data
public class TurbineStreamProperties {
@Value("${server.port:8989}")
@@ -36,4 +36,53 @@ public class TurbineStreamProperties {
private String destination = HystrixConstants.HYSTRIX_STREAM_DESTINATION;
private String contentType = MediaType.APPLICATION_JSON_VALUE;
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getDestination() {
return destination;
}
public void setDestination(String destination) {
this.destination = destination;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TurbineStreamProperties that = (TurbineStreamProperties) o;
return port == that.port &&
Objects.equals(destination, that.destination) &&
Objects.equals(contentType, that.contentType);
}
@Override
public int hashCode() {
return Objects.hash(port, destination, contentType);
}
@Override
public String toString() {
return new StringBuilder("TurbineStreamProperties{")
.append("port=").append(port).append(", ")
.append("destination='").append(destination).append("', ")
.append("contentType='").append(contentType).append("'}")
.toString();
}
}

View File

@@ -89,13 +89,6 @@
<groupId>com.netflix.turbine</groupId>
<artifactId>turbine-core</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- Only needed at compile time -->
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>

View File

@@ -21,6 +21,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.expression.Expression;
@@ -30,8 +32,6 @@ import org.springframework.expression.spel.support.StandardEvaluationContext;
import com.netflix.turbine.discovery.Instance;
import com.netflix.turbine.discovery.InstanceDiscovery;
import lombok.extern.apachecommons.CommonsLog;
/**
* Class that encapsulates an {@link InstanceDiscovery}
* implementation that uses Spring Cloud Commons (see https://github.com/spring-cloud/spring-cloud-commons)
@@ -45,9 +45,10 @@ import lombok.extern.apachecommons.CommonsLog;
*
* @author Spencer Gibb
*/
@CommonsLog
public class CommonsInstanceDiscovery implements InstanceDiscovery {
private static final Log log = LogFactory.getLog(CommonsInstanceDiscovery.class);
private static final String DEFAULT_CLUSTER_NAME_EXPRESSION = "serviceId";
protected static final String PORT_KEY = "port";
protected static final String SECURE_PORT_KEY = "securePort";

Some files were not shown because too many files have changed in this diff Show More