Commit 13c2500d by Ryan Baxter

Merge remote-tracking branch 'origin/1.4.x'

parents 02a0cacd c181163a
......@@ -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;
/**
......@@ -378,6 +378,43 @@ public class EurekaClientAutoConfigurationTests {
}
@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",
"eureka.client.serviceUrl.defaultZone=http://user:foo@example.com:80/eureka").applyTo(this.context);
......@@ -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 })
......@@ -532,18 +563,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 {
@Bean
......@@ -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)
......
......@@ -93,6 +93,12 @@ public class RestTemplateEurekaHttpClientTest {
}
@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
.statusUpdate("test", "test", InstanceStatus.UP, info).getStatusCode());
......
......@@ -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"));
}
}
}
/*
* 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;
}
......
......@@ -211,6 +211,20 @@ public class ProxyRequestHelperTests {
}
@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", "/");
MockHttpServletResponse response = new MockHttpServletResponse();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment