Commit 02ec9bb9 by Ryan Baxter

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

parents b2f608b8 a496dc81
...@@ -886,6 +886,28 @@ ribbon: ...@@ -886,6 +886,28 @@ ribbon:
clients: client1, client2, client3 clients: client1, client2, client3
---- ----
[[how-to-configure-hystrix-thread-pools]]
=== How to Configure Hystrix thread pools
If you change `zuul.ribbonIsolationStrategy` to THREAD, the thread isolation strategy for Hystrix will be used for all routes. In this case, the HystrixThreadPoolKey is set to "RibbonCommand" as default. It means that HystrixCommands for all routes will be executed in the same Hystrix thread pool. This behavior can be changed using the following configuration and it will result in HystrixCommands being executed in the Hystrix thread pool for each route.
.application.yml
----
zuul:
threadPool:
useSeparateThreadPools: true
----
The default HystrixThreadPoolKey in this case is same with service ID for each route. To add a prefix to HystrixThreadPoolKey, set `zuul.threadPool.threadPoolKeyPrefix` to a value that you want to add. For example:
.application.yml
----
zuul:
threadPool:
useSeparateThreadPools: true
threadPoolKeyPrefix: zuulgw
----
[[spring-cloud-feign]] [[spring-cloud-feign]]
== Declarative REST Client: Feign == Declarative REST Client: Feign
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<main.basedir>${basedir}</main.basedir> <main.basedir>${basedir}</main.basedir>
<netty.version>4.0.27.Final</netty.version> <netty.version>4.0.27.Final</netty.version>
<jackson.version>2.7.3</jackson.version> <jackson.version>2.7.3</jackson.version>
<spring-cloud-commons.version>1.2.3.BUILD-SNAPSHOT</spring-cloud-commons.version> <spring-cloud-commons.version>1.3.0.BUILD-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-config.version>1.4.0.BUILD-SNAPSHOT</spring-cloud-config.version> <spring-cloud-config.version>1.4.0.BUILD-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-stream.version>Ditmars.BUILD-SNAPSHOT</spring-cloud-stream.version> <spring-cloud-stream.version>Ditmars.BUILD-SNAPSHOT</spring-cloud-stream.version>
......
...@@ -19,8 +19,12 @@ package org.springframework.cloud.netflix.hystrix; ...@@ -19,8 +19,12 @@ package org.springframework.cloud.netflix.hystrix;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
*/ */
public interface HystrixConstants { public class HystrixConstants {
String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream"; public static final String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream";
private HystrixConstants() {
throw new AssertionError("Must not instantiate constant utility class");
}
} }
...@@ -26,7 +26,7 @@ import org.aspectj.lang.annotation.Aspect; ...@@ -26,7 +26,7 @@ import org.aspectj.lang.annotation.Aspect;
@Aspect @Aspect
public class RestTemplateUrlTemplateCapturingAspect { public class RestTemplateUrlTemplateCapturingAspect {
@Around("execution(* org.springframework.web.client.RestOperations+.*(String, ..))") @Around("execution(* org.springframework.web.client.RestOperations+.*(String, ..))")
Object captureUrlTemplate(ProceedingJoinPoint joinPoint) throws Throwable { public Object captureUrlTemplate(ProceedingJoinPoint joinPoint) throws Throwable {
try { try {
String urlTemplate = (String) joinPoint.getArgs()[0]; String urlTemplate = (String) joinPoint.getArgs()[0];
RestTemplateUrlTemplateHolder.setRestTemplateUrlTemplate(urlTemplate); RestTemplateUrlTemplateHolder.setRestTemplateUrlTemplate(urlTemplate);
......
...@@ -160,6 +160,8 @@ public class ZuulProperties { ...@@ -160,6 +160,8 @@ public class ZuulProperties {
private ExecutionIsolationStrategy ribbonIsolationStrategy = SEMAPHORE; private ExecutionIsolationStrategy ribbonIsolationStrategy = SEMAPHORE;
private HystrixSemaphore semaphore = new HystrixSemaphore(); private HystrixSemaphore semaphore = new HystrixSemaphore();
private HystrixThreadPool threadPool = new HystrixThreadPool();
public Set<String> getIgnoredHeaders() { public Set<String> getIgnoredHeaders() {
Set<String> ignoredHeaders = new LinkedHashSet<>(this.ignoredHeaders); Set<String> ignoredHeaders = new LinkedHashSet<>(this.ignoredHeaders);
...@@ -357,6 +359,39 @@ public class ZuulProperties { ...@@ -357,6 +359,39 @@ public class ZuulProperties {
} }
public static class HystrixThreadPool {
/**
* Flag to determine whether RibbonCommands should use separate thread pools for hystrix.
* By setting to true, RibbonCommands will be executed in a hystrix's thread pool that it is associated with.
* Each RibbonCommand will be associated with a thread pool according to its commandKey (serviceId).
* As default, all commands will be executed in a single thread pool whose threadPoolKey is "RibbonCommand".
* This property is only applicable when using THREAD as ribbonIsolationStrategy
*/
private boolean useSeparateThreadPools = false;
/**
* A prefix for HystrixThreadPoolKey of hystrix's thread pool that is allocated to each service Id.
* This property is only applicable when using THREAD as ribbonIsolationStrategy and useSeparateThreadPools = true
*/
private String threadPoolKeyPrefix = "";
public boolean isUseSeparateThreadPools() {
return useSeparateThreadPools;
}
public void setUseSeparateThreadPools(boolean useSeparateThreadPools) {
this.useSeparateThreadPools = useSeparateThreadPools;
}
public String getThreadPoolKeyPrefix() {
return threadPoolKeyPrefix;
}
public void setThreadPoolKeyPrefix(String threadPoolKeyPrefix) {
this.threadPoolKeyPrefix = threadPoolKeyPrefix;
}
}
public String getServletPattern() { public String getServletPattern() {
String path = this.servletPath; String path = this.servletPath;
if (!path.startsWith("/")) { if (!path.startsWith("/")) {
......
...@@ -34,6 +34,7 @@ import com.netflix.hystrix.HystrixCommandGroupKey; ...@@ -34,6 +34,7 @@ import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandKey;
import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixCommandProperties;
import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy; import com.netflix.hystrix.HystrixCommandProperties.ExecutionIsolationStrategy;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.zuul.constants.ZuulConstants; import com.netflix.zuul.constants.ZuulConstants;
import com.netflix.zuul.context.RequestContext; import com.netflix.zuul.context.RequestContext;
...@@ -78,6 +79,9 @@ public abstract class AbstractRibbonCommand<LBC extends AbstractLoadBalancerAwar ...@@ -78,6 +79,9 @@ public abstract class AbstractRibbonCommand<LBC extends AbstractLoadBalancerAwar
ZuulProperties zuulProperties) { ZuulProperties zuulProperties) {
// @formatter:off // @formatter:off
Setter commandSetter = Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RibbonCommand"))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey));
final HystrixCommandProperties.Setter setter = HystrixCommandProperties.Setter() final HystrixCommandProperties.Setter setter = HystrixCommandProperties.Setter()
.withExecutionIsolationStrategy(zuulProperties.getRibbonIsolationStrategy()); .withExecutionIsolationStrategy(zuulProperties.getRibbonIsolationStrategy());
if (zuulProperties.getRibbonIsolationStrategy() == ExecutionIsolationStrategy.SEMAPHORE){ if (zuulProperties.getRibbonIsolationStrategy() == ExecutionIsolationStrategy.SEMAPHORE){
...@@ -87,13 +91,12 @@ public abstract class AbstractRibbonCommand<LBC extends AbstractLoadBalancerAwar ...@@ -87,13 +91,12 @@ public abstract class AbstractRibbonCommand<LBC extends AbstractLoadBalancerAwar
final DynamicIntProperty value = DynamicPropertyFactory.getInstance() final DynamicIntProperty value = DynamicPropertyFactory.getInstance()
.getIntProperty(name, zuulProperties.getSemaphore().getMaxSemaphores()); .getIntProperty(name, zuulProperties.getSemaphore().getMaxSemaphores());
setter.withExecutionIsolationSemaphoreMaxConcurrentRequests(value.get()); setter.withExecutionIsolationSemaphoreMaxConcurrentRequests(value.get());
} else { } else if (zuulProperties.getThreadPool().isUseSeparateThreadPools()) {
// TODO Find out is some parameters can be set here final String threadPoolKey = zuulProperties.getThreadPool().getThreadPoolKeyPrefix() + commandKey;
commandSetter.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(threadPoolKey));
} }
return Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("RibbonCommand")) return commandSetter.andCommandPropertiesDefaults(setter);
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey))
.andCommandPropertiesDefaults(setter);
// @formatter:on // @formatter:on
} }
......
...@@ -26,190 +26,195 @@ import com.netflix.zuul.ZuulFilter; ...@@ -26,190 +26,195 @@ import com.netflix.zuul.ZuulFilter;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
*/ */
public interface FilterConstants { public class FilterConstants {
// KEY constants ----------------------------------- // KEY constants -----------------------------------
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter} * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter}
*/ */
String IS_DISPATCHER_SERVLET_REQUEST_KEY = "isDispatcherServletRequest"; public static final String IS_DISPATCHER_SERVLET_REQUEST_KEY = "isDispatcherServletRequest";
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter} * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter}
*/ */
String FORWARD_TO_KEY = "forward.to"; public static final String FORWARD_TO_KEY = "forward.to";
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in TODO: determine use * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in TODO: determine use
*/ */
String PROXY_KEY = "proxy"; public static final String PROXY_KEY = "proxy";
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter} * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}
*/ */
String REQUEST_ENTITY_KEY = "requestEntity"; public static final String REQUEST_ENTITY_KEY = "requestEntity";
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in to override the path of the request. * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in to override the path of the request.
*/ */
String REQUEST_URI_KEY = "requestURI"; public static final String REQUEST_URI_KEY = "requestURI";
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter} * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}
*/ */
String RETRYABLE_KEY = "retryable"; public static final String RETRYABLE_KEY = "retryable";
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter} * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter}
*/ */
String ROUTING_DEBUG_KEY = "routingDebug"; public static final String ROUTING_DEBUG_KEY = "routingDebug";
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter} * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter}
*/ */
String SERVICE_ID_KEY = "serviceId"; public static final String SERVICE_ID_KEY = "serviceId";
// ORDER constants ----------------------------------- // ORDER constants -----------------------------------
/** /**
* Filter Order for {@link DebugFilter#filterOrder()} * Filter Order for {@link DebugFilter#filterOrder()}
*/ */
int DEBUG_FILTER_ORDER = 1; public static final int DEBUG_FILTER_ORDER = 1;
/** /**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter#filterOrder()} * Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter#filterOrder()}
*/ */
int FORM_BODY_WRAPPER_FILTER_ORDER = -1; public static final int FORM_BODY_WRAPPER_FILTER_ORDER = -1;
/** /**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter} * Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter}
*/ */
int PRE_DECORATION_FILTER_ORDER = 5; public static final int PRE_DECORATION_FILTER_ORDER = 5;
/** /**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter#filterOrder()} * Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.route.RibbonRoutingFilter#filterOrder()}
*/ */
int RIBBON_ROUTING_FILTER_ORDER = 10; public static final int RIBBON_ROUTING_FILTER_ORDER = 10;
/** /**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter#filterOrder()} * Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter#filterOrder()}
*/ */
int SEND_ERROR_FILTER_ORDER = 0; public static final int SEND_ERROR_FILTER_ORDER = 0;
/** /**
* Filter Order for {@link SendForwardFilter#filterOrder()} * Filter Order for {@link SendForwardFilter#filterOrder()}
*/ */
int SEND_FORWARD_FILTER_ORDER = 500; public static final int SEND_FORWARD_FILTER_ORDER = 500;
/** /**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter#filterOrder()} * Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter#filterOrder()}
*/ */
int SEND_RESPONSE_FILTER_ORDER = 1000; public static final int SEND_RESPONSE_FILTER_ORDER = 1000;
/** /**
* Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter#filterOrder()} * Filter Order for {@link org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter#filterOrder()}
*/ */
int SIMPLE_HOST_ROUTING_FILTER_ORDER = 100; public static final int SIMPLE_HOST_ROUTING_FILTER_ORDER = 100;
/** /**
* filter order for {@link Servlet30WrapperFilter#filterOrder()} * filter order for {@link Servlet30WrapperFilter#filterOrder()}
*/ */
int SERVLET_30_WRAPPER_FILTER_ORDER = -2; public static final int SERVLET_30_WRAPPER_FILTER_ORDER = -2;
/** /**
* filter order for {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter#filterOrder()} * filter order for {@link org.springframework.cloud.netflix.zuul.filters.pre.ServletDetectionFilter#filterOrder()}
*/ */
int SERVLET_DETECTION_FILTER_ORDER = -3; public static final int SERVLET_DETECTION_FILTER_ORDER = -3;
// Zuul Filter TYPE constants ----------------------------------- // Zuul Filter TYPE constants -----------------------------------
/** /**
* {@link ZuulFilter#filterType()} error type. * {@link ZuulFilter#filterType()} error type.
*/ */
String ERROR_TYPE = "error"; public static final String ERROR_TYPE = "error";
/** /**
* {@link ZuulFilter#filterType()} post type. * {@link ZuulFilter#filterType()} post type.
*/ */
String POST_TYPE = "post"; public static final String POST_TYPE = "post";
/** /**
* {@link ZuulFilter#filterType()} pre type. * {@link ZuulFilter#filterType()} pre type.
*/ */
String PRE_TYPE = "pre"; public static final String PRE_TYPE = "pre";
/** /**
* {@link ZuulFilter#filterType()} route type. * {@link ZuulFilter#filterType()} route type.
*/ */
String ROUTE_TYPE = "route"; public static final String ROUTE_TYPE = "route";
// OTHER constants ----------------------------------- // OTHER constants -----------------------------------
/** /**
* Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter} * Zuul {@link com.netflix.zuul.context.RequestContext} key for use in {@link org.springframework.cloud.netflix.zuul.filters.route.SendForwardFilter}
*/ */
String FORWARD_LOCATION_PREFIX = "forward:"; public static final String FORWARD_LOCATION_PREFIX = "forward:";
/** /**
* default http port * default http port
*/ */
int HTTP_PORT = 80; public static final int HTTP_PORT = 80;
/** /**
* default https port * default https port
*/ */
int HTTPS_PORT = 443; public static final int HTTPS_PORT = 443;
/** /**
* http url scheme * http url scheme
*/ */
String HTTP_SCHEME = "http"; public static final String HTTP_SCHEME = "http";
/** /**
* https url scheme * https url scheme
*/ */
String HTTPS_SCHEME = "https"; public static final String HTTPS_SCHEME = "https";
// HEADER constants ----------------------------------- // HEADER constants -----------------------------------
/** /**
* X-* Header for the matching url. Used when routes use a url rather than serviceId * X-* Header for the matching url. Used when routes use a url rather than serviceId
*/ */
String SERVICE_HEADER = "X-Zuul-Service"; public static final String SERVICE_HEADER = "X-Zuul-Service";
/** /**
* X-* Header for the matching serviceId * X-* Header for the matching serviceId
*/ */
String SERVICE_ID_HEADER = "X-Zuul-ServiceId"; public static final String SERVICE_ID_HEADER = "X-Zuul-ServiceId";
/** /**
* X-Forwarded-For Header * X-Forwarded-For Header
*/ */
String X_FORWARDED_FOR_HEADER = "X-Forwarded-For"; public static final String X_FORWARDED_FOR_HEADER = "X-Forwarded-For";
/** /**
* X-Forwarded-Host Header * X-Forwarded-Host Header
*/ */
String X_FORWARDED_HOST_HEADER = "X-Forwarded-Host"; public static final String X_FORWARDED_HOST_HEADER = "X-Forwarded-Host";
/** /**
* X-Forwarded-Prefix Header * X-Forwarded-Prefix Header
*/ */
String X_FORWARDED_PREFIX_HEADER = "X-Forwarded-Prefix"; public static final String X_FORWARDED_PREFIX_HEADER = "X-Forwarded-Prefix";
/** /**
* X-Forwarded-Port Header * X-Forwarded-Port Header
*/ */
String X_FORWARDED_PORT_HEADER = "X-Forwarded-Port"; public static final String X_FORWARDED_PORT_HEADER = "X-Forwarded-Port";
/** /**
* X-Forwarded-Proto Header * X-Forwarded-Proto Header
*/ */
String X_FORWARDED_PROTO_HEADER = "X-Forwarded-Proto"; public static final String X_FORWARDED_PROTO_HEADER = "X-Forwarded-Proto";
/** /**
* X-Zuul-Debug Header * X-Zuul-Debug Header
*/ */
String X_ZUUL_DEBUG_HEADER = "X-Zuul-Debug-Header"; public static final String X_ZUUL_DEBUG_HEADER = "X-Zuul-Debug-Header";
private FilterConstants() {
throw new AssertionError("Must not instantiate constant utility class");
}
} }
...@@ -24,6 +24,7 @@ import org.junit.Before; ...@@ -24,6 +24,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute; import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
...@@ -103,4 +104,9 @@ public class ZuulPropertiesTests { ...@@ -103,4 +104,9 @@ public class ZuulPropertiesTests {
assertFalse(this.zuul.getSensitiveHeaders().contains("Cookie")); assertFalse(this.zuul.getSensitiveHeaders().contains("Cookie"));
} }
@Test
public void defaultHystrixThreadPool() {
assertFalse(this.zuul.getThreadPool().isUseSeparateThreadPools());
assertEquals("", this.zuul.getThreadPool().getThreadPoolKeyPrefix());
}
} }
/*
* 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.zuul.filters.route.support;
import com.netflix.client.ClientRequest;
import com.netflix.hystrix.HystrixCommandProperties;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Yongsung Yoon
*/
public class RibbonCommandHystrixThreadPoolKeyTests {
private ZuulProperties zuulProperties;
@Before
public void setUp() throws Exception {
zuulProperties = new ZuulProperties();
}
@Test
public void testDefaultHystrixThreadPoolKey() throws Exception {
zuulProperties.setRibbonIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);
TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", zuulProperties);
TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", zuulProperties);
// CommandGroupKey should be used as ThreadPoolKey as default.
assertThat(ribbonCommand1.getThreadPoolKey().name()).isEqualTo(ribbonCommand1.getCommandGroup().name());
assertThat(ribbonCommand2.getThreadPoolKey().name()).isEqualTo(ribbonCommand2.getCommandGroup().name());
}
@Test
public void testUseSeparateThreadPools() throws Exception {
zuulProperties.setRibbonIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);
zuulProperties.getThreadPool().setUseSeparateThreadPools(true);
TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", zuulProperties);
TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", zuulProperties);
assertThat(ribbonCommand1.getThreadPoolKey().name()).isEqualTo("testCommand1");
assertThat(ribbonCommand2.getThreadPoolKey().name()).isEqualTo("testCommand2");
}
@Test
public void testThreadPoolKeyPrefix() throws Exception {
final String prefix = "zuulgw-";
zuulProperties.setRibbonIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.THREAD);
zuulProperties.getThreadPool().setUseSeparateThreadPools(true);
zuulProperties.getThreadPool().setThreadPoolKeyPrefix(prefix);
TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", zuulProperties);
TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", zuulProperties);
assertThat(ribbonCommand1.getThreadPoolKey().name()).isEqualTo(prefix + "testCommand1");
assertThat(ribbonCommand2.getThreadPoolKey().name()).isEqualTo(prefix + "testCommand2");
}
@Test
public void testNoSideEffectOnSemaphoreIsolation() throws Exception {
final String prefix = "zuulgw-";
zuulProperties.setRibbonIsolationStrategy(HystrixCommandProperties.ExecutionIsolationStrategy.SEMAPHORE);
zuulProperties.getThreadPool().setUseSeparateThreadPools(true);
zuulProperties.getThreadPool().setThreadPoolKeyPrefix(prefix);
TestRibbonCommand ribbonCommand1 = new TestRibbonCommand("testCommand1", zuulProperties);
TestRibbonCommand ribbonCommand2 = new TestRibbonCommand("testCommand2", zuulProperties);
// There should be no side effect on semaphore isolation
assertThat(ribbonCommand1.getThreadPoolKey().name()).isEqualTo(ribbonCommand1.getCommandGroup().name());
assertThat(ribbonCommand2.getThreadPoolKey().name()).isEqualTo(ribbonCommand2.getCommandGroup().name());
}
public static class TestRibbonCommand extends AbstractRibbonCommand {
public TestRibbonCommand(String commandKey, ZuulProperties zuulProperties) {
super(commandKey, null, null, zuulProperties);
}
@Override
protected ClientRequest createRequest() throws Exception {
return null;
}
}
}
\ No newline at end of file
...@@ -38,14 +38,14 @@ import lombok.Data; ...@@ -38,14 +38,14 @@ import lombok.Data;
*/ */
@Data @Data
@ConfigurationProperties(EurekaClientConfigBean.PREFIX) @ConfigurationProperties(EurekaClientConfigBean.PREFIX)
public class EurekaClientConfigBean implements EurekaClientConfig, EurekaConstants { public class EurekaClientConfigBean implements EurekaClientConfig {
public static final String PREFIX = "eureka.client"; public static final String PREFIX = "eureka.client";
@Autowired(required = false) @Autowired(required = false)
PropertyResolver propertyResolver; PropertyResolver propertyResolver;
public static final String DEFAULT_URL = "http://localhost:8761" + DEFAULT_PREFIX public static final String DEFAULT_URL = "http://localhost:8761" + EurekaConstants.DEFAULT_PREFIX
+ "/"; + "/";
public static final String DEFAULT_ZONE = "defaultZone"; public static final String DEFAULT_ZONE = "defaultZone";
......
...@@ -19,8 +19,12 @@ package org.springframework.cloud.netflix.eureka; ...@@ -19,8 +19,12 @@ package org.springframework.cloud.netflix.eureka;
/** /**
* @author Spencer Gibb * @author Spencer Gibb
*/ */
public interface EurekaConstants { public class EurekaConstants {
String DEFAULT_PREFIX = "/eureka"; public static final String DEFAULT_PREFIX = "/eureka";
private EurekaConstants() {
throw new AssertionError("Must not instantiate constant utility class");
}
} }
...@@ -23,7 +23,6 @@ import java.util.Set; ...@@ -23,7 +23,6 @@ import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.netflix.eureka.EurekaConstants;
import org.springframework.core.env.PropertyResolver; import org.springframework.core.env.PropertyResolver;
import com.netflix.eureka.EurekaServerConfig; import com.netflix.eureka.EurekaServerConfig;
...@@ -36,7 +35,7 @@ import lombok.Data; ...@@ -36,7 +35,7 @@ import lombok.Data;
*/ */
@Data @Data
@ConfigurationProperties(EurekaServerConfigBean.PREFIX) @ConfigurationProperties(EurekaServerConfigBean.PREFIX)
public class EurekaServerConfigBean implements EurekaServerConfig, EurekaConstants { public class EurekaServerConfigBean implements EurekaServerConfig {
public static final String PREFIX = "eureka.server"; public static final String PREFIX = "eureka.server";
......
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