From ebead68e0ad3246121326b6119bbe134bfbdfeef Mon Sep 17 00:00:00 2001 From: Zhang Yuhan Date: Fri, 17 Oct 2014 23:44:50 -0700 Subject: [PATCH 1/5] To define threadPoolProperties from @HystrixCommand annotation --- .../javanica/annotation/HystrixCommand.java | 7 ++++ .../AbstractHystrixCommandFactory.java | 36 +++++++++++++++++++ .../command/CommandSetterBuilder.java | 11 +++++- .../command/CommandPropertiesTest.java | 9 +++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/annotation/HystrixCommand.java b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/annotation/HystrixCommand.java index 83386b9d2..92f3231be 100644 --- a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/annotation/HystrixCommand.java +++ b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/annotation/HystrixCommand.java @@ -100,6 +100,13 @@ */ HystrixProperty[] commandProperties() default {}; + /** + * Specifies thread pool properties. + * + * @return thread pool properties + */ + HystrixProperty[] threadPoolProperties() default {}; + /** * Defines exceptions which should be ignored and wrapped to throw in HystrixBadRequestException. * diff --git a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java index d1413901e..3bf7f6ed7 100644 --- a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java +++ b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java @@ -19,6 +19,7 @@ import com.google.common.base.Throwables; import com.google.common.collect.Maps; import com.netflix.hystrix.HystrixCollapser; +import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; import org.apache.commons.lang3.StringUtils; @@ -51,10 +52,15 @@ public T create(MetaHolder metaHolder, metaHolder.getHystrixCommand().commandKey() : metaHolder.getDefaultCommandKey(); + HystrixThreadPoolProperties.Setter threadPoolProperties = getThreadPoolProperties(metaHolder.getHystrixCommand()); + CommandSetterBuilder setterBuilder = new CommandSetterBuilder(); setterBuilder.commandKey(commandKey); setterBuilder.groupKey(groupKey); setterBuilder.threadPoolKey(metaHolder.getHystrixCommand().threadPoolKey()); + if(threadPoolProperties != null) { + setterBuilder.threadPoolProperties(threadPoolProperties); + } Map commandProperties = getCommandProperties(metaHolder.getHystrixCommand()); CommandAction commandAction = new MethodExecutionAction(metaHolder.getObj(), metaHolder.getMethod(), metaHolder.getArgs()); CommandAction fallbackAction = createFallbackAction(metaHolder, collapsedRequests); @@ -122,4 +128,34 @@ private Map getCommandProperties(HystrixCommand hystrixCommand) return commandProperties; } + public HystrixThreadPoolProperties.Setter getThreadPoolProperties(HystrixCommand hystrixCommand) { + if(hystrixCommand.threadPoolProperties() == null || hystrixCommand.threadPoolProperties().length == 0) { + return null; + } + + HystrixThreadPoolProperties.Setter setter = HystrixThreadPoolProperties.Setter(); + HystrixProperty[] properties = hystrixCommand.threadPoolProperties(); + for(HystrixProperty property : properties) { + Integer value = Integer.parseInt(property.value()); + String name = property.name(); + if("coreSize".equals(name)) { + setter.withCoreSize(value); + } else if("maxQueueSize".equals(name)) { + setter.withMaxQueueSize(value); + } else if("keepAliveTimeMinutes".equals(name)) { + setter.withKeepAliveTimeMinutes(value); + } else if("metricsRollingStatisticalWindowBuckets".equals(name)) { + setter.withMetricsRollingStatisticalWindowBuckets(value); + } else if("queueSizeRejectionThreshold".equals(name)) { + setter.withQueueSizeRejectionThreshold(value); + } else if("metricsRollingStatisticalWindowInMilliseconds".equals(name)) { + setter.withMetricsRollingStatisticalWindowInMilliseconds(value); + } else { + throw new IllegalArgumentException("unsupported threadPoolPropery: " + name); + } + } + + return setter; + } + } diff --git a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/CommandSetterBuilder.java b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/CommandSetterBuilder.java index d7b49f46b..264ce4606 100644 --- a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/CommandSetterBuilder.java +++ b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/CommandSetterBuilder.java @@ -19,6 +19,7 @@ import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixThreadPoolKey; +import com.netflix.hystrix.HystrixThreadPoolProperties; import org.apache.commons.lang3.StringUtils; /** @@ -29,6 +30,7 @@ public class CommandSetterBuilder { private String groupKey; private String commandKey; private String threadPoolKey; + private HystrixThreadPoolProperties.Setter threadPoolProperties = null; public CommandSetterBuilder groupKey(String pGroupKey) { this.groupKey = pGroupKey; @@ -50,11 +52,15 @@ public CommandSetterBuilder commandKey(String pCommandKey, String def) { return this; } + public CommandSetterBuilder threadPoolProperties(HystrixThreadPoolProperties.Setter threadPoolProperties) { + this.threadPoolProperties = threadPoolProperties; + return this; + } + public CommandSetterBuilder threadPoolKey(String pThreadPoolKey) { this.threadPoolKey = pThreadPoolKey; return this; } - /** * Creates instance of {@link HystrixCommand.Setter}. * @@ -67,6 +73,9 @@ public HystrixCommand.Setter build() { if (StringUtils.isNotBlank(threadPoolKey)) { setter.andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(threadPoolKey)); } + if (threadPoolProperties != null) { + setter.andThreadPoolPropertiesDefaults(threadPoolProperties); + } return setter; } diff --git a/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java b/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java index 68c4002bf..52d13e0af 100644 --- a/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java +++ b/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java @@ -4,6 +4,7 @@ import com.netflix.hystrix.HystrixRequestLog; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; +import com.netflix.hystrix.contrib.javanica.command.AbstractHystrixCommand; import com.netflix.hystrix.contrib.javanica.test.spring.conf.AopCglibConfig; import com.netflix.hystrix.contrib.javanica.test.spring.domain.User; import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; @@ -70,6 +71,14 @@ public static class UserService { commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "110"), @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "false") + }, + threadPoolProperties = { + @HystrixProperty(name = "coreSize", value = "30"), + @HystrixProperty(name = "maxQueueSize", value = "101"), + @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), + @HystrixProperty(name = "metricsRollingStatisticalWindowBuckets", value = "12"), + @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), + @HystrixProperty(name = "metricsRollingStatisticalWindowInMilliseconds", value = "1440") }) public User getUser(String id, String name) { return new User(id, name + id); // it should be network call From fc952f5abfe5eb0f7d13daa46b1c80cbc882cee6 Mon Sep 17 00:00:00 2001 From: Zhang Yuhan Date: Fri, 17 Oct 2014 23:55:35 -0700 Subject: [PATCH 2/5] Added an example of threadPoolProperties usage into README --- hystrix-contrib/hystrix-javanica/README.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/hystrix-contrib/hystrix-javanica/README.md b/hystrix-contrib/hystrix-javanica/README.md index 494adcdd5..e4e0488d7 100644 --- a/hystrix-contrib/hystrix-javanica/README.md +++ b/hystrix-contrib/hystrix-javanica/README.md @@ -198,6 +198,25 @@ ConfigurationManager.getConfigInstance().setProperty("hystrix.command.getUserByI ``` More about Hystrix command properties [command](https://github.com/Netflix/Hystrix/wiki/Configuration#wiki-CommandExecution) and [fallback](https://github.com/Netflix/Hystrix/wiki/Configuration#wiki-CommandFallback) +ThreadPoolProperties can be set using @HystrixCommand's 'threadPoolProperties' like below: + +```java + @HystrixCommand(commandProperties = { + @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "500") + }, + threadPoolProperties = { + @HystrixProperty(name = "coreSize", value = "30"), + @HystrixProperty(name = "maxQueueSize", value = "101"), + @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), + @HystrixProperty(name = "metricsRollingStatisticalWindowBuckets", value = "12"), + @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), + @HystrixProperty(name = "metricsRollingStatisticalWindowInMilliseconds", value = "1440") + }) + public User getUserById(String id) { + return userResource.getUserById(id); + } +``` + ## Hystrix collapser Suppose you have some command which calls should be collapsed in one backend call. For this goal you can use ```@HystrixCollapser``` annotation. From d7d29823f2178f2023c49de2d846ed2f30cac9da Mon Sep 17 00:00:00 2001 From: Zhang Yuhan Date: Mon, 20 Oct 2014 18:15:02 -0700 Subject: [PATCH 3/5] Use ConfigurationManager to initialize ThreadPoolProperties instead of passing ThreadPoolPropertiesSetter into the constructor --- .../AbstractHystrixCommandFactory.java | 35 +++++++------------ .../command/CommandPropertiesTest.java | 12 +++---- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java index 3bf7f6ed7..93cb05b6d 100644 --- a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java +++ b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java @@ -18,6 +18,7 @@ import com.google.common.base.Throwables; import com.google.common.collect.Maps; +import com.netflix.config.ConfigurationManager; import com.netflix.hystrix.HystrixCollapser; import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; @@ -52,15 +53,12 @@ public T create(MetaHolder metaHolder, metaHolder.getHystrixCommand().commandKey() : metaHolder.getDefaultCommandKey(); - HystrixThreadPoolProperties.Setter threadPoolProperties = getThreadPoolProperties(metaHolder.getHystrixCommand()); + initializeThreadPoolProperties(metaHolder.getHystrixCommand()); CommandSetterBuilder setterBuilder = new CommandSetterBuilder(); setterBuilder.commandKey(commandKey); setterBuilder.groupKey(groupKey); setterBuilder.threadPoolKey(metaHolder.getHystrixCommand().threadPoolKey()); - if(threadPoolProperties != null) { - setterBuilder.threadPoolProperties(threadPoolProperties); - } Map commandProperties = getCommandProperties(metaHolder.getHystrixCommand()); CommandAction commandAction = new MethodExecutionAction(metaHolder.getObj(), metaHolder.getMethod(), metaHolder.getArgs()); CommandAction fallbackAction = createFallbackAction(metaHolder, collapsedRequests); @@ -128,34 +126,25 @@ private Map getCommandProperties(HystrixCommand hystrixCommand) return commandProperties; } - public HystrixThreadPoolProperties.Setter getThreadPoolProperties(HystrixCommand hystrixCommand) { + public void initializeThreadPoolProperties(HystrixCommand hystrixCommand) { if(hystrixCommand.threadPoolProperties() == null || hystrixCommand.threadPoolProperties().length == 0) { - return null; + return; } HystrixThreadPoolProperties.Setter setter = HystrixThreadPoolProperties.Setter(); + String threadPoolKey = hystrixCommand.threadPoolKey(); + if(threadPoolKey == null || "".equals(threadPoolKey)) { + threadPoolKey = "default"; + } + HystrixProperty[] properties = hystrixCommand.threadPoolProperties(); for(HystrixProperty property : properties) { Integer value = Integer.parseInt(property.value()); String name = property.name(); - if("coreSize".equals(name)) { - setter.withCoreSize(value); - } else if("maxQueueSize".equals(name)) { - setter.withMaxQueueSize(value); - } else if("keepAliveTimeMinutes".equals(name)) { - setter.withKeepAliveTimeMinutes(value); - } else if("metricsRollingStatisticalWindowBuckets".equals(name)) { - setter.withMetricsRollingStatisticalWindowBuckets(value); - } else if("queueSizeRejectionThreshold".equals(name)) { - setter.withQueueSizeRejectionThreshold(value); - } else if("metricsRollingStatisticalWindowInMilliseconds".equals(name)) { - setter.withMetricsRollingStatisticalWindowInMilliseconds(value); - } else { - throw new IllegalArgumentException("unsupported threadPoolPropery: " + name); - } - } + name = name.replace("{}", threadPoolKey); - return setter; + ConfigurationManager.getConfigInstance().setProperty(name, property.value()); + } } } diff --git a/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java b/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java index 52d13e0af..e66825f3e 100644 --- a/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java +++ b/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java @@ -73,12 +73,12 @@ public static class UserService { @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "false") }, threadPoolProperties = { - @HystrixProperty(name = "coreSize", value = "30"), - @HystrixProperty(name = "maxQueueSize", value = "101"), - @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), - @HystrixProperty(name = "metricsRollingStatisticalWindowBuckets", value = "12"), - @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), - @HystrixProperty(name = "metricsRollingStatisticalWindowInMilliseconds", value = "1440") + @HystrixProperty(name = "hystrix.threadpool.{}.coreSize", value = "30"), + @HystrixProperty(name = "hystrix.threadpool.{}.maxQueueSize", value = "101"), + @HystrixProperty(name = "hystrix.threadpool.{}.keepAliveTimeMinutes", value = "2"), + @HystrixProperty(name = "hystrix.threadpool.{}.metricsRollingStatisticalWindowBuckets", value = "12"), + @HystrixProperty(name = "hystrix.threadpool.{}.queueSizeRejectionThreshold", value = "15"), + @HystrixProperty(name = "hystrix.threadpool.{}.metricsRollingStatisticalWindowInMilliseconds", value = "1440") }) public User getUser(String id, String name) { return new User(id, name + id); // it should be network call From 3d9ef196c659df2dc8fb970ac2557f74aa0406f7 Mon Sep 17 00:00:00 2001 From: Zhang Yuhan Date: Tue, 21 Oct 2014 19:05:29 -0700 Subject: [PATCH 4/5] refactor, and added test case for verifying the thread pool properties. problem: metricsRollingStatisticalWindowInMilliseconds, and metricsRollingStatisticalWindowBuckets wouldn't be set correctly --- .../AbstractHystrixCommandFactory.java | 24 ++----------- .../conf/HystrixPropertiesManager.java | 20 +++++++++++ .../command/CommandPropertiesTest.java | 35 +++++++++++++++---- 3 files changed, 50 insertions(+), 29 deletions(-) diff --git a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java index 93cb05b6d..4716232d7 100644 --- a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java +++ b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/command/AbstractHystrixCommandFactory.java @@ -23,6 +23,7 @@ import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; +import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; @@ -53,7 +54,7 @@ public T create(MetaHolder metaHolder, metaHolder.getHystrixCommand().commandKey() : metaHolder.getDefaultCommandKey(); - initializeThreadPoolProperties(metaHolder.getHystrixCommand()); + HystrixPropertiesManager.initializeThreadPoolProperties(metaHolder.getHystrixCommand()); CommandSetterBuilder setterBuilder = new CommandSetterBuilder(); setterBuilder.commandKey(commandKey); @@ -126,25 +127,4 @@ private Map getCommandProperties(HystrixCommand hystrixCommand) return commandProperties; } - public void initializeThreadPoolProperties(HystrixCommand hystrixCommand) { - if(hystrixCommand.threadPoolProperties() == null || hystrixCommand.threadPoolProperties().length == 0) { - return; - } - - HystrixThreadPoolProperties.Setter setter = HystrixThreadPoolProperties.Setter(); - String threadPoolKey = hystrixCommand.threadPoolKey(); - if(threadPoolKey == null || "".equals(threadPoolKey)) { - threadPoolKey = "default"; - } - - HystrixProperty[] properties = hystrixCommand.threadPoolProperties(); - for(HystrixProperty property : properties) { - Integer value = Integer.parseInt(property.value()); - String name = property.name(); - name = name.replace("{}", threadPoolKey); - - ConfigurationManager.getConfigInstance().setProperty(name, property.value()); - } - } - } diff --git a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/conf/HystrixPropertiesManager.java b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/conf/HystrixPropertiesManager.java index 3d8a5e0d5..b64017ec4 100644 --- a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/conf/HystrixPropertiesManager.java +++ b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/conf/HystrixPropertiesManager.java @@ -17,6 +17,7 @@ import com.google.common.collect.Maps; import com.netflix.config.ConfigurationManager; +import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; @@ -96,4 +97,23 @@ private static void validate(HystrixProperty hystrixProperty) throws IllegalArgu Validate.notBlank(hystrixProperty.name(), "hystrix property name cannot be null"); } + public static void initializeThreadPoolProperties(HystrixCommand hystrixCommand) { + if(hystrixCommand.threadPoolProperties() == null || hystrixCommand.threadPoolProperties().length == 0) { + return; + } + + HystrixThreadPoolProperties.Setter setter = HystrixThreadPoolProperties.Setter(); + String threadPoolKey = hystrixCommand.threadPoolKey(); + if(threadPoolKey == null || "".equals(threadPoolKey)) { + threadPoolKey = "default"; + } + + HystrixProperty[] properties = hystrixCommand.threadPoolProperties(); + for(HystrixProperty property : properties) { + Integer value = Integer.parseInt(property.value()); + String name = String.format("hystrix.threadpool.%s.%s", threadPoolKey, property.name()); + ConfigurationManager.getConfigInstance().setProperty(name, property.value()); + } + } + } diff --git a/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java b/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java index e66825f3e..cb436c1ea 100644 --- a/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java +++ b/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java @@ -2,12 +2,15 @@ import com.netflix.hystrix.HystrixEventType; import com.netflix.hystrix.HystrixRequestLog; +import com.netflix.hystrix.HystrixThreadPool; +import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; import com.netflix.hystrix.contrib.javanica.command.AbstractHystrixCommand; import com.netflix.hystrix.contrib.javanica.test.spring.conf.AopCglibConfig; import com.netflix.hystrix.contrib.javanica.test.spring.domain.User; import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; +import com.netflix.hystrix.strategy.properties.HystrixPropertiesThreadPoolDefault; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -16,6 +19,9 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import java.lang.reflect.Field; +import java.util.concurrent.TimeUnit; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -27,7 +33,7 @@ public class CommandPropertiesTest { private UserService userService; @Test - public void testGetUser() { + public void testGetUser() throws NoSuchFieldException, IllegalAccessException { HystrixRequestContext context = HystrixRequestContext.initializeContext(); try { User u1 = userService.getUser("1", "name: "); @@ -42,6 +48,21 @@ public void testGetUser() { // assert properties assertEquals(110, command.getProperties().executionIsolationThreadTimeoutInMilliseconds().get().intValue()); assertEquals(false, command.getProperties().executionIsolationThreadInterruptOnTimeout().get()); + + Field field = command.getClass().getSuperclass().getSuperclass().getSuperclass().getDeclaredField("threadPool"); + field.setAccessible(true); + HystrixThreadPool threadPool = (HystrixThreadPool) field.get(command); + + Field field2 = HystrixThreadPool.HystrixThreadPoolDefault.class.getDeclaredField("properties"); + field2.setAccessible(true); + HystrixThreadPoolProperties properties = (HystrixThreadPoolProperties) field2.get(threadPool); + + assertEquals(30, (int) properties.coreSize().get()); + assertEquals(101, (int) properties.maxQueueSize().get()); + assertEquals(2, (int) properties.keepAliveTimeMinutes().get()); + assertEquals(15, (int) properties.queueSizeRejectionThreshold().get()); + //assertEquals(1440, (int) properties.metricsRollingStatisticalWindowInMilliseconds().get()); // TODO: won't be set. make this work. + //assertEquals(12, (int) properties.metricsRollingStatisticalWindowBuckets().get()); } finally { context.shutdown(); } @@ -73,12 +94,12 @@ public static class UserService { @HystrixProperty(name = "execution.isolation.thread.interruptOnTimeout", value = "false") }, threadPoolProperties = { - @HystrixProperty(name = "hystrix.threadpool.{}.coreSize", value = "30"), - @HystrixProperty(name = "hystrix.threadpool.{}.maxQueueSize", value = "101"), - @HystrixProperty(name = "hystrix.threadpool.{}.keepAliveTimeMinutes", value = "2"), - @HystrixProperty(name = "hystrix.threadpool.{}.metricsRollingStatisticalWindowBuckets", value = "12"), - @HystrixProperty(name = "hystrix.threadpool.{}.queueSizeRejectionThreshold", value = "15"), - @HystrixProperty(name = "hystrix.threadpool.{}.metricsRollingStatisticalWindowInMilliseconds", value = "1440") + @HystrixProperty(name = "coreSize", value = "30"), + @HystrixProperty(name = "maxQueueSize", value = "101"), + @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), + @HystrixProperty(name = "metricsRollingStatisticalWindowBuckets", value = "12"), + @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), + @HystrixProperty(name = "metricsRollingStatisticalWindowInMilliseconds", value = "1440") }) public User getUser(String id, String name) { return new User(id, name + id); // it should be network call From 9acbd362f0a4e0fcfe849d99f9594a54ea374aef Mon Sep 17 00:00:00 2001 From: Zhang Yuhan Date: Wed, 22 Oct 2014 10:10:02 -0700 Subject: [PATCH 5/5] added test case for setting metrics.rollingStats; updated README; removed unused code --- hystrix-contrib/hystrix-javanica/README.md | 4 ++-- .../javanica/conf/HystrixPropertiesManager.java | 1 - .../configuration/command/CommandPropertiesTest.java | 11 +++++------ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/hystrix-contrib/hystrix-javanica/README.md b/hystrix-contrib/hystrix-javanica/README.md index e4e0488d7..b87744305 100644 --- a/hystrix-contrib/hystrix-javanica/README.md +++ b/hystrix-contrib/hystrix-javanica/README.md @@ -208,9 +208,9 @@ ThreadPoolProperties can be set using @HystrixCommand's 'threadPoolProperties' l @HystrixProperty(name = "coreSize", value = "30"), @HystrixProperty(name = "maxQueueSize", value = "101"), @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), - @HystrixProperty(name = "metricsRollingStatisticalWindowBuckets", value = "12"), @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), - @HystrixProperty(name = "metricsRollingStatisticalWindowInMilliseconds", value = "1440") + @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"), + @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440") }) public User getUserById(String id) { return userResource.getUserById(id); diff --git a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/conf/HystrixPropertiesManager.java b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/conf/HystrixPropertiesManager.java index b64017ec4..585029698 100644 --- a/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/conf/HystrixPropertiesManager.java +++ b/hystrix-contrib/hystrix-javanica/src/main/java/com/netflix/hystrix/contrib/javanica/conf/HystrixPropertiesManager.java @@ -110,7 +110,6 @@ public static void initializeThreadPoolProperties(HystrixCommand hystrixCommand) HystrixProperty[] properties = hystrixCommand.threadPoolProperties(); for(HystrixProperty property : properties) { - Integer value = Integer.parseInt(property.value()); String name = String.format("hystrix.threadpool.%s.%s", threadPoolKey, property.name()); ConfigurationManager.getConfigInstance().setProperty(name, property.value()); } diff --git a/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java b/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java index cb436c1ea..11ab9dcd3 100644 --- a/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java +++ b/hystrix-contrib/hystrix-javanica/src/test/java/com/netflix/hystrix/contrib/javanica/test/spring/configuration/command/CommandPropertiesTest.java @@ -6,11 +6,10 @@ import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand; import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty; -import com.netflix.hystrix.contrib.javanica.command.AbstractHystrixCommand; import com.netflix.hystrix.contrib.javanica.test.spring.conf.AopCglibConfig; import com.netflix.hystrix.contrib.javanica.test.spring.domain.User; import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext; -import com.netflix.hystrix.strategy.properties.HystrixPropertiesThreadPoolDefault; + import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -61,8 +60,8 @@ public void testGetUser() throws NoSuchFieldException, IllegalAccessException { assertEquals(101, (int) properties.maxQueueSize().get()); assertEquals(2, (int) properties.keepAliveTimeMinutes().get()); assertEquals(15, (int) properties.queueSizeRejectionThreshold().get()); - //assertEquals(1440, (int) properties.metricsRollingStatisticalWindowInMilliseconds().get()); // TODO: won't be set. make this work. - //assertEquals(12, (int) properties.metricsRollingStatisticalWindowBuckets().get()); + assertEquals(1440, (int) properties.metricsRollingStatisticalWindowInMilliseconds().get()); + assertEquals(12, (int) properties.metricsRollingStatisticalWindowBuckets().get()); } finally { context.shutdown(); } @@ -97,9 +96,9 @@ public static class UserService { @HystrixProperty(name = "coreSize", value = "30"), @HystrixProperty(name = "maxQueueSize", value = "101"), @HystrixProperty(name = "keepAliveTimeMinutes", value = "2"), - @HystrixProperty(name = "metricsRollingStatisticalWindowBuckets", value = "12"), + @HystrixProperty(name = "metrics.rollingStats.numBuckets", value = "12"), @HystrixProperty(name = "queueSizeRejectionThreshold", value = "15"), - @HystrixProperty(name = "metricsRollingStatisticalWindowInMilliseconds", value = "1440") + @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "1440") }) public User getUser(String id, String name) { return new User(id, name + id); // it should be network call