Merge remote-tracking branch 'origin/1.4.x'
This commit is contained in:
@@ -84,18 +84,21 @@ NOTE: Because of a limitation in Eureka, it is not possible to support per-serve
|
||||
=== Status Page and Health Indicator
|
||||
|
||||
The status page and health indicators for a Eureka instance default to `/info` and `/health` respectively, which are the default locations of useful endpoints in a Spring Boot Actuator application.
|
||||
You need to change these, even for an Actuator application if you use a non-default context path or servlet path (such as `server.servletPath=/custom`) or management endpoint path (such as `management.contextPath=/admin`). The following example shows the default values for the two settings:
|
||||
You need to change these, even for an Actuator application if you use a non-default context path or servlet path (such as `server.servletPath=/custom`). The following example shows the default values for the two settings:
|
||||
|
||||
.application.yml
|
||||
----
|
||||
eureka:
|
||||
instance:
|
||||
statusPageUrlPath: ${management.server.servlet.context-path}/info
|
||||
healthCheckUrlPath: ${management.server.servlet.context-path}/health
|
||||
statusPageUrlPath: ${server.servletPath}/info
|
||||
healthCheckUrlPath: ${server.servletPath}/health
|
||||
----
|
||||
|
||||
These links show up in the metadata that is consumed by clients and are used in some scenarios to decide whether to send requests to your application, so it is helpful if they are accurate.
|
||||
|
||||
NOTE: In Dalston it was also required to set the status and health check URLs when changing
|
||||
that management context path. This requirement was removed beginning in Edgware.
|
||||
|
||||
=== Registering a Secure Application
|
||||
|
||||
If your app wants to be contacted over HTTPS, you can set two flags in the `EurekaInstanceConfig`:
|
||||
@@ -747,6 +750,24 @@ Circuits are prefixed by their respective `serviceId`, followed by a dot (`.`),
|
||||
Spring Cloud provides a `spring-cloud-starter-netflix-turbine-stream` that has all the dependencies you need to get a Turbine Stream server running.
|
||||
You can then add the Stream binder of your choice -- such as `spring-cloud-starter-stream-rabbit`.
|
||||
|
||||
Turbine Stream server also supports the `cluster` parameter.
|
||||
Unlike Turbine server, Turbine Stream uses eureka serviceIds as cluster names and these are not configurable.
|
||||
|
||||
If Turbine Stream server is running on port 8989 on `my.turbine.server` and you have two eureka serviceIds `customers` and `products` in your environment, the following URLs will be available on your Turbine Stream server. `default` and empty cluster name will provide all metrics that Turbine Stream server receives.
|
||||
|
||||
----
|
||||
http://my.turbine.sever:8989/turbine.stream?cluster=customers
|
||||
http://my.turbine.sever:8989/turbine.stream?cluster=products
|
||||
http://my.turbine.sever:8989/turbine.stream?cluster=default
|
||||
http://my.turbine.sever:8989/turbine.stream
|
||||
----
|
||||
|
||||
So, you can use eureka serviceIds as cluster names for your Turbine dashboard (or any compatible dashboard).
|
||||
You don’t need to configure any properties like `turbine.appConfig`, `turbine.clusterNameExpression` and `turbine.aggregator.clusterConfig` for your Turbine Stream server.
|
||||
|
||||
NOTE: Turbine Stream server gathers all metrics from the configured input channel with Spring Cloud Stream. It means that it doesn’t gather Hystrix metrics actively from each instance. It just can provide metrics that were already gathered into the input channel by each instance.
|
||||
|
||||
|
||||
[[spring-cloud-ribbon]]
|
||||
== Client Side Load Balancer: Ribbon
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
|
||||
@@ -206,21 +204,22 @@ public class EurekaClientAutoConfiguration {
|
||||
return new EurekaServiceRegistry();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient, CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager, ObjectProvider<HealthCheckHandler> healthCheckHandler) {
|
||||
return EurekaRegistration.builder(instanceConfig)
|
||||
.with(applicationInfoManager)
|
||||
.with(eurekaClient)
|
||||
.with(healthCheckHandler)
|
||||
.build();
|
||||
}
|
||||
// @Bean
|
||||
// @ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
// @ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
// public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient, CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager, ObjectProvider<HealthCheckHandler> healthCheckHandler) {
|
||||
// return EurekaRegistration.builder(instanceConfig)
|
||||
// .with(applicationInfoManager)
|
||||
// .with(eurekaClient)
|
||||
// .with(healthCheckHandler)
|
||||
// .build();
|
||||
// }
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry registry, EurekaRegistration registration) {
|
||||
public EurekaAutoServiceRegistration eurekaAutoServiceRegistration(ApplicationContext context, EurekaServiceRegistry registry,
|
||||
EurekaRegistration registration) {
|
||||
return new EurekaAutoServiceRegistration(context, registry, registration);
|
||||
}
|
||||
|
||||
@@ -248,6 +247,20 @@ public class EurekaClientAutoConfiguration {
|
||||
InstanceInfo instanceInfo = new InstanceInfoFactory().create(config);
|
||||
return new ApplicationInfoManager(config, instanceInfo);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient,
|
||||
CloudEurekaInstanceConfig instanceConfig,
|
||||
ApplicationInfoManager applicationInfoManager,
|
||||
@Autowired(required = false) ObjectProvider<HealthCheckHandler> healthCheckHandler) {
|
||||
return EurekaRegistration.builder(instanceConfig)
|
||||
.with(applicationInfoManager)
|
||||
.with(eurekaClient)
|
||||
.with(healthCheckHandler)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -279,6 +292,21 @@ public class EurekaClientAutoConfiguration {
|
||||
return new ApplicationInfoManager(config, instanceInfo);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@org.springframework.cloud.context.config.annotation.RefreshScope
|
||||
@ConditionalOnBean(AutoServiceRegistrationProperties.class)
|
||||
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
|
||||
public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient,
|
||||
CloudEurekaInstanceConfig instanceConfig,
|
||||
ApplicationInfoManager applicationInfoManager,
|
||||
@Autowired(required = false) ObjectProvider<HealthCheckHandler> healthCheckHandler) {
|
||||
return EurekaRegistration.builder(instanceConfig)
|
||||
.with(applicationInfoManager)
|
||||
.with(eurekaClient)
|
||||
.with(healthCheckHandler)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
|
||||
@@ -19,8 +19,10 @@ package org.springframework.cloud.netflix.eureka.http;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.client.support.BasicAuthorizationInterceptor;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.web.client.DefaultResponseErrorHandler;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.fasterxml.jackson.databind.BeanDescription;
|
||||
@@ -74,6 +76,7 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
|
||||
}
|
||||
|
||||
restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter());
|
||||
restTemplate.setErrorHandler(new ErrorHanlder());
|
||||
|
||||
return restTemplate;
|
||||
}
|
||||
@@ -134,4 +137,20 @@ public class RestTemplateTransportClientFactory implements TransportClientFactor
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
class ErrorHanlder extends DefaultResponseErrorHandler {
|
||||
@Override
|
||||
protected boolean hasError(HttpStatus statusCode) {
|
||||
/**
|
||||
* When the Eureka server restarts and a client tries to sent a heartbeat the server
|
||||
* will respond with a 404. By default RestTemplate will throw an exception in this case.
|
||||
* What we want is to return the 404 to the upstream code so it will send another registration
|
||||
* request to the server.
|
||||
*/
|
||||
if(statusCode.is4xxClientError()) {
|
||||
return false;
|
||||
}
|
||||
return super.hasError(statusCode);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ public class DefaultManagementMetadataProvider implements ManagementMetadataProv
|
||||
return port != null && port == RANDOM_PORT;
|
||||
}
|
||||
|
||||
private String getHealthCheckUrl(EurekaInstanceConfigBean instance, int serverPort, String serverContextPath,
|
||||
protected String getHealthCheckUrl(EurekaInstanceConfigBean instance, int serverPort, String serverContextPath,
|
||||
String managementContextPath, Integer managementPort, boolean isSecure) {
|
||||
String healthCheckUrlPath = instance.getHealthCheckUrlPath();
|
||||
String healthCheckUrl = getUrl(instance, serverPort, serverContextPath, managementContextPath,
|
||||
|
||||
@@ -45,7 +45,7 @@ import com.netflix.discovery.EurekaClientConfig;
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class EurekaRegistration implements Registration, Closeable {
|
||||
public class EurekaRegistration implements Registration {
|
||||
private static final Log log = LogFactory.getLog(EurekaRegistration.class);
|
||||
|
||||
private final EurekaClient eurekaClient;
|
||||
@@ -202,8 +202,4 @@ public class EurekaRegistration implements Registration, Closeable {
|
||||
return this.instanceConfig.getSecurePort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.eurekaClient.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,14 +16,14 @@
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
@@ -31,9 +31,10 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
|
||||
import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationProperties;
|
||||
import org.springframework.cloud.commons.util.UtilAutoConfiguration;
|
||||
import org.springframework.cloud.context.refresh.ContextRefresher;
|
||||
import org.springframework.cloud.context.scope.GenericScope;
|
||||
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
@@ -42,8 +43,9 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.SystemEnvironmentPropertySource;
|
||||
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.appinfo.HealthCheckHandler;
|
||||
import com.netflix.discovery.EurekaClient;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.discovery.shared.transport.jersey.EurekaJerseyClient;
|
||||
@@ -52,8 +54,6 @@ import com.sun.jersey.client.apache4.ApacheHttpClient4;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.springframework.boot.test.util.EnvironmentTestUtils.addEnvironment;
|
||||
|
||||
/**
|
||||
@@ -377,6 +377,43 @@ public class EurekaClientAutoConfigurationTests {
|
||||
.startsWith(GenericScope.class.getName()+"$LockedScopedProxyFactoryBean");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReregisterHealthCheckHandlerAfterRefresh() throws Exception {
|
||||
addEnvironment(this.context, "eureka.client.healthcheck.enabled=true");
|
||||
setupContext(RefreshAutoConfiguration.class, AutoServiceRegistrationConfiguration.class);
|
||||
|
||||
EurekaClient oldEurekaClient = getLazyInitEurekaClient();
|
||||
|
||||
HealthCheckHandler healthCheckHandler = this.context.getBean("eurekaHealthCheckHandler", HealthCheckHandler.class);
|
||||
|
||||
assertThat(healthCheckHandler).isInstanceOf(EurekaHealthCheckHandler.class);
|
||||
assertThat(oldEurekaClient.getHealthCheckHandler()).isSameAs(healthCheckHandler);
|
||||
|
||||
ContextRefresher refresher = this.context.getBean("contextRefresher", ContextRefresher.class);
|
||||
refresher.refresh();
|
||||
|
||||
EurekaClient newEurekaClient = getLazyInitEurekaClient();
|
||||
HealthCheckHandler newHealthCheckHandler = this.context.getBean("eurekaHealthCheckHandler", HealthCheckHandler.class);
|
||||
|
||||
assertThat(healthCheckHandler).isSameAs(newHealthCheckHandler);
|
||||
assertThat(oldEurekaClient).isNotSameAs(newEurekaClient);
|
||||
assertThat(newEurekaClient.getHealthCheckHandler()).isSameAs(healthCheckHandler);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCloseDiscoveryClient() throws Exception {
|
||||
addEnvironment(this.context, "eureka.client.healthcheck.enabled=true");
|
||||
setupContext(RefreshAutoConfiguration.class, AutoServiceRegistrationConfiguration.class);
|
||||
|
||||
AtomicBoolean isShutdown = (AtomicBoolean) ReflectionTestUtils.getField(getLazyInitEurekaClient(), "isShutdown");
|
||||
|
||||
assertThat(isShutdown.get()).isFalse();
|
||||
|
||||
this.context.close();
|
||||
|
||||
assertThat(isShutdown.get()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicAuth() {
|
||||
TestPropertyValues.of( "server.port=8989",
|
||||
@@ -470,16 +507,6 @@ public class EurekaClientAutoConfigurationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eurekaRegistrationClosed() throws IOException {
|
||||
setupContext(TestEurekaRegistrationConfiguration.class);
|
||||
if (this.context != null) {
|
||||
EurekaRegistration registration = this.context.getBean(EurekaRegistration.class);
|
||||
this.context.close();
|
||||
verify(registration).close();
|
||||
}
|
||||
}
|
||||
|
||||
private void testNonSecurePortSystemProp(String propName) {
|
||||
addSystemEnvironment(this.context.getEnvironment(), propName + ":8888");
|
||||
setupContext();
|
||||
@@ -502,6 +529,10 @@ public class EurekaClientAutoConfigurationTests {
|
||||
return this.context.getBean(EurekaInstanceConfigBean.class);
|
||||
}
|
||||
|
||||
private EurekaClient getLazyInitEurekaClient() throws Exception {
|
||||
return (EurekaClient)((Advised) this.context.getBean("eurekaClient", EurekaClient.class)).getTargetSource().getTarget();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@Import({ UtilAutoConfiguration.class, EurekaClientAutoConfiguration.class })
|
||||
@@ -531,18 +562,6 @@ public class EurekaClientAutoConfigurationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class TestEurekaRegistrationConfiguration {
|
||||
|
||||
@Bean
|
||||
public EurekaRegistration eurekaRegistration(EurekaClient eurekaClient, CloudEurekaInstanceConfig instanceConfig, ApplicationInfoManager applicationInfoManager) {
|
||||
return spy(EurekaRegistration.builder(instanceConfig)
|
||||
.with(applicationInfoManager)
|
||||
.with(eurekaClient)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class MockClientConfiguration {
|
||||
|
||||
@@ -565,4 +584,10 @@ public class EurekaClientAutoConfigurationTests {
|
||||
return Mockito.mock(ApacheHttpClient4.class);
|
||||
}
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(AutoServiceRegistrationProperties.class)
|
||||
public static class AutoServiceRegistrationConfiguration {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
@@ -132,13 +133,16 @@ public class EurekaServerMockApplication {
|
||||
@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,
|
||||
public ResponseEntity sendHeartBeat(@PathVariable String appName,
|
||||
@PathVariable String id, @RequestParam String status,
|
||||
@RequestParam String lastDirtyTimestamp,
|
||||
@RequestParam(required = false) String overriddenstatus) {
|
||||
if("fourOFour".equals(appName)) {
|
||||
return new ResponseEntity(HttpStatus.NOT_FOUND);
|
||||
}
|
||||
return new ResponseEntity<InstanceInfo>(new InstanceInfo(null, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, 0, null, null, null, null, null, null, null, new HashMap<String, String>(), 0l,
|
||||
0l, null, null);
|
||||
0l, null, null), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
|
||||
@@ -92,6 +92,12 @@ public class RestTemplateEurekaHttpClientTest {
|
||||
.sendHeartBeat("test", "test", info, null).getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendHeartBeatFourOFour() {
|
||||
Assert.assertEquals(HttpStatus.NOT_FOUND.value(), eurekaHttpClient
|
||||
.sendHeartBeat("fourOFour", "test", info, null).getStatusCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStatusUpdate() {
|
||||
Assert.assertEquals(HttpStatus.OK.value(), eurekaHttpClient
|
||||
|
||||
@@ -20,13 +20,16 @@ import static org.springframework.cloud.commons.util.IdUtils.getDefaultInstanceI
|
||||
|
||||
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.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.actuator.HasFeatures;
|
||||
import org.springframework.cloud.commons.util.InetUtils;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadata;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
@@ -35,8 +38,7 @@ import org.springframework.util.StringUtils;
|
||||
import com.netflix.appinfo.HealthCheckHandler;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Sidecar Configuration that setting up {@link com.netflix.appinfo.EurekaInstanceConfig}.
|
||||
@@ -79,8 +81,17 @@ public class SidecarConfiguration {
|
||||
@Autowired
|
||||
private InetUtils inetUtils;
|
||||
|
||||
@Value("${management.port:${MANAGEMENT_PORT:${server.port:${SERVER_PORT:${PORT:8080}}}}}")
|
||||
private int managementPort = 8080;
|
||||
@Value(value = "${management.port:${MANAGEMENT_PORT:#{null}}}")
|
||||
private Integer managementPort;
|
||||
|
||||
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
|
||||
private int serverPort = 8080;
|
||||
|
||||
@Value("${management.context-path:${MANAGEMENT_CONTEXT_PATH:#{null}}}")
|
||||
private String managementContextPath;
|
||||
|
||||
@Value("${server.context-path:${SERVER_CONTEXT_PATH:/}}")
|
||||
private String serverContextPath = "/";
|
||||
|
||||
@Value("${eureka.instance.hostname:${EUREKA_INSTANCE_HOSTNAME:}}")
|
||||
private String hostname;
|
||||
@@ -89,7 +100,13 @@ public class SidecarConfiguration {
|
||||
private ConfigurableEnvironment env;
|
||||
|
||||
@Bean
|
||||
public EurekaInstanceConfigBean eurekaInstanceConfigBean() {
|
||||
@ConditionalOnMissingBean
|
||||
public ManagementMetadataProvider serviceManagementMetadataProvider() {
|
||||
return new DefaultManagementMetadataProvider();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public EurekaInstanceConfigBean eurekaInstanceConfigBean(ManagementMetadataProvider managementMetadataProvider) {
|
||||
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
|
||||
String springAppName = this.env.getProperty("spring.application.name", "");
|
||||
int port = this.sidecarProperties.getPort();
|
||||
@@ -112,10 +129,20 @@ public class SidecarConfiguration {
|
||||
config.setIpAddress(ipAddress);
|
||||
}
|
||||
String scheme = config.getSecurePortEnabled() ? "https" : "http";
|
||||
config.setStatusPageUrl(scheme + "://" + config.getHostname() + ":"
|
||||
+ this.managementPort + config.getStatusPageUrlPath());
|
||||
config.setHealthCheckUrl(scheme + "://" + config.getHostname() + ":"
|
||||
+ this.managementPort + config.getHealthCheckUrlPath());
|
||||
ManagementMetadata metadata = managementMetadataProvider.get(config, serverPort,
|
||||
serverContextPath, managementContextPath, managementPort);
|
||||
|
||||
if(metadata != null) {
|
||||
config.setStatusPageUrl(metadata.getStatusPageUrl());
|
||||
config.setHealthCheckUrl(metadata.getHealthCheckUrl());
|
||||
if(config.isSecurePortEnabled()) {
|
||||
config.setSecureHealthCheckUrl(metadata.getSecureHealthCheckUrl());
|
||||
}
|
||||
Map<String, String> metadataMap = config.getMetadataMap();
|
||||
if (metadataMap.get("management.port") == null) {
|
||||
metadataMap.put("management.port", String.valueOf(metadata.getManagementPort()));
|
||||
}
|
||||
}
|
||||
config.setHomePageUrl(scheme + "://" + config.getHostname() + ":" + port
|
||||
+ config.getHomePageUrlPath());
|
||||
return config;
|
||||
|
||||
@@ -18,6 +18,11 @@ package org.springframework.cloud.netflix.sidecar;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.DefaultManagementMetadataProvider;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadata;
|
||||
import org.springframework.cloud.netflix.eureka.metadata.ManagementMetadataProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@SpringBootApplication
|
||||
@@ -29,4 +34,25 @@ public class SidecarApplication {
|
||||
SpringApplication.run(SidecarApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ManagementMetadataProvider managementMetadataProvider() {
|
||||
//The default management metadata provider checks for random ports, we dont care about this in tests
|
||||
return new DefaultManagementMetadataProvider() {
|
||||
@Override
|
||||
public ManagementMetadata get(EurekaInstanceConfigBean instance, int serverPort, String serverContextPath, String managementContextPath, Integer managementPort) {
|
||||
String healthCheckUrl = getHealthCheckUrl(instance, serverPort, serverContextPath,
|
||||
managementContextPath, managementPort, false);
|
||||
String statusPageUrl = getStatusPageUrl(instance, serverPort, serverContextPath,
|
||||
managementContextPath, managementPort);
|
||||
|
||||
ManagementMetadata metadata = new ManagementMetadata(healthCheckUrl, statusPageUrl, managementPort == null ? serverPort : managementPort);
|
||||
if(instance.isSecurePortEnabled()) {
|
||||
metadata.setSecureHealthCheckUrl(getHealthCheckUrl(instance, serverPort, serverContextPath,
|
||||
managementContextPath, managementPort, true));
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,4 +98,34 @@ public class SidecarApplicationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"spring.application.name=mytest", "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1",
|
||||
"eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", "sidecar.port=7000", "sidecar.ipAddress=127.0.0.1",
|
||||
"management.context-path=/foo"})
|
||||
public static class ManagementContextPathStatusAndHealthCheckUrls {
|
||||
@Autowired
|
||||
EurekaInstanceConfigBean config;
|
||||
|
||||
public void testStatusAndHealthCheckUrls() {
|
||||
assertThat(this.config.getStatusPageUrl(), equalTo("http://mhhost2:0/foo/info"));
|
||||
assertThat(this.config.getHealthCheckUrl(), equalTo("http://mhhost2:0/foo/health"));
|
||||
}
|
||||
}
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = SidecarApplication.class, webEnvironment = RANDOM_PORT, value = {
|
||||
"spring.application.name=mytest", "spring.cloud.client.hostname=mhhost", "spring.application.instance_id=1",
|
||||
"eureka.instance.hostname=mhhost1", "sidecar.hostname=mhhost2", "sidecar.port=7000", "sidecar.ipAddress=127.0.0.1",
|
||||
"server.context-path=/foo"})
|
||||
public static class ServerContextPathStatusAndHealthCheckUrls {
|
||||
@Autowired
|
||||
EurekaInstanceConfigBean config;
|
||||
|
||||
@Test
|
||||
public void testStatusAndHealthCheckUrls() {
|
||||
assertThat(this.config.getStatusPageUrl(), equalTo("http://mhhost2:0/foo/info"));
|
||||
assertThat(this.config.getHealthCheckUrl(), equalTo("http://mhhost2:0/foo/health"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
spring-cloud-netflix-turbine-stream/.jdk8
Normal file
0
spring-cloud-netflix-turbine-stream/.jdk8
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2013-2018 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.turbine.stream;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import rx.Observable;
|
||||
import rx.functions.Func1;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Yongsung Yoon
|
||||
*/
|
||||
public class TurbineStreamConfigurationTest {
|
||||
TurbineStreamConfiguration turbineStreamConfiguration;
|
||||
List<Map<String, Object>> testMetricList;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
turbineStreamConfiguration = new TurbineStreamConfiguration();
|
||||
testMetricList = createBasicTestMetricList();
|
||||
}
|
||||
|
||||
private List<Map<String,Object>> createBasicTestMetricList() {
|
||||
List<Map<String, Object>> testDataList = new ArrayList<>();
|
||||
HashMap<String, Object> map = new HashMap<>();
|
||||
map.put("instanceId", "abc:127.0.0.1:8080");
|
||||
map.put("type", "HystrixCommand");
|
||||
testDataList.add(map);
|
||||
|
||||
map = new HashMap<>();
|
||||
map.put("instanceId", "def:127.0.0.1:8080");
|
||||
map.put("type", "HystrixCommand");
|
||||
testDataList.add(map);
|
||||
|
||||
map = new HashMap<>();
|
||||
map.put("instanceId", "xyz:127.0.0.1:8080");
|
||||
map.put("type", "HystrixThreadPool");
|
||||
testDataList.add(map);
|
||||
|
||||
map = new HashMap<>();
|
||||
map.put("type", "ping");
|
||||
testDataList.add(map);
|
||||
|
||||
map = new HashMap<>();
|
||||
map.put("dummy", "data");
|
||||
testDataList.add(map);
|
||||
|
||||
return testDataList;
|
||||
}
|
||||
}
|
||||
@@ -145,7 +145,9 @@ public class ProxyRequestHelper {
|
||||
for (String header : zuulRequestHeaders.keySet()) {
|
||||
headers.set(header, zuulRequestHeaders.get(header));
|
||||
}
|
||||
headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
|
||||
if(!headers.containsKey(HttpHeaders.ACCEPT_ENCODING)) {
|
||||
headers.set(HttpHeaders.ACCEPT_ENCODING, "gzip");
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
|
||||
@@ -210,6 +210,20 @@ public class ProxyRequestHelperTests {
|
||||
assertThat(acceptEncodings, contains("gzip"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void buildZuulRequestHeadersRequestsAcceptEncoding() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("", "/");
|
||||
request.addHeader("accept-encoding", "identity");
|
||||
|
||||
ProxyRequestHelper helper = new ProxyRequestHelper();
|
||||
|
||||
MultiValueMap<String, String> headers = helper.buildZuulRequestHeaders(request);
|
||||
|
||||
List<String> acceptEncodings = headers.get("accept-encoding");
|
||||
assertThat(acceptEncodings, hasSize(1));
|
||||
assertThat(acceptEncodings, contains("identity"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setResponseLowercase() throws IOException {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
|
||||
|
||||
Reference in New Issue
Block a user