/* * Copyright 2014 Avanza Bank AB * * 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 com.avanza.astrix.ft.hystrix; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import com.avanza.astrix.beans.core.AstrixBeanKey; import com.avanza.astrix.beans.core.AstrixBeanSettings; import com.avanza.astrix.beans.ft.BeanFaultToleranceFactorySpi; import com.avanza.astrix.context.AstrixApplicationContext; import com.avanza.astrix.context.AstrixContext; import com.avanza.astrix.context.TestAstrixConfigurer; import com.avanza.astrix.core.AstrixFaultToleranceProxy; import com.avanza.astrix.provider.core.AstrixApiProvider; import com.avanza.astrix.provider.core.DefaultBeanSettings; import com.avanza.astrix.provider.core.Library; import com.avanza.astrix.test.util.AutoCloseableRule; import com.netflix.hystrix.HystrixCommandGroupKey; import com.netflix.hystrix.HystrixCommandKey; import com.netflix.hystrix.HystrixCommandProperties; import com.netflix.hystrix.HystrixThreadPoolKey; import com.netflix.hystrix.HystrixThreadPoolProperties; import com.netflix.hystrix.strategy.HystrixPlugins; import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy; public class HystrixCommandConfigurationTest { @Rule public AutoCloseableRule autoClosables = new AutoCloseableRule(); private AstrixContext astrixContext; private TestAstrixConfigurer astrixConfigurer; @Before public void setup() { astrixConfigurer = new TestAstrixConfigurer(); astrixConfigurer.enableFaultTolerance(true); astrixConfigurer.registerApiProvider(PingApi.class); astrixContext = autoClosables.add(astrixConfigurer.configure()); } @Test public void differentContextCanHaveDifferentSettingsForSameApi() throws Throwable { astrixConfigurer.set(AstrixBeanSettings.TIMEOUT, AstrixBeanKey.create(Ping.class), 100); TestAstrixConfigurer astrixConfigurer2 = new TestAstrixConfigurer(); astrixConfigurer2.set(AstrixBeanSettings.TIMEOUT, AstrixBeanKey.create(Ping.class), 200); astrixConfigurer2.enableFaultTolerance(true); astrixConfigurer2.registerApiProvider(PingApi.class); AstrixContext astrixContext2 = autoClosables.add(astrixConfigurer2.configure()); astrixContext.getBean(Ping.class).ping("foo"); HystrixFaultToleranceFactory hystrixFaultTolerance = getFaultTolerance(astrixContext); HystrixFaultToleranceFactory hystrixFaultTolerance2 = getFaultTolerance(astrixContext2); HystrixCommandProperties pingCommandPropertiesContext1 = getHystrixCommandProperties(hystrixFaultTolerance, Ping.class); HystrixCommandProperties pingCommandPropertiesContext2 = getHystrixCommandProperties(hystrixFaultTolerance2, Ping.class); assertEquals(100, pingCommandPropertiesContext1.executionTimeoutInMilliseconds().get().intValue()); assertEquals(200, pingCommandPropertiesContext2.executionTimeoutInMilliseconds().get().intValue()); } @Test public void readsDefaultBeanSettingsFromBeanConfiguration() throws Throwable { astrixConfigurer.set(AstrixBeanSettings.CORE_SIZE, AstrixBeanKey.create(Ping.class), 4); astrixConfigurer.set(AstrixBeanSettings.QUEUE_SIZE_REJECTION_THRESHOLD, AstrixBeanKey.create(Ping.class), 6); astrixConfigurer.set(AstrixBeanSettings.TIMEOUT, AstrixBeanKey.create(Ping.class), 100); astrixConfigurer.set(AstrixBeanSettings.MAX_CONCURRENT_REQUESTS, AstrixBeanKey.create(Ping.class), 21); astrixContext.getBean(Ping.class).ping("foo"); HystrixFaultToleranceFactory hystrixFaultTolerance = getFaultTolerance(astrixContext); HystrixCommandProperties pingCommandProperties = getHystrixCommandProperties(hystrixFaultTolerance, Ping.class); HystrixThreadPoolProperties pingThreadPoolProperties = getThreadPoolProperties(hystrixFaultTolerance, Ping.class); assertEquals(100, pingCommandProperties.executionTimeoutInMilliseconds().get().intValue()); assertEquals(21, pingCommandProperties.executionIsolationSemaphoreMaxConcurrentRequests().get().intValue()); assertEquals(4, pingThreadPoolProperties.coreSize().get().intValue()); assertEquals(6, pingThreadPoolProperties.queueSizeRejectionThreshold().get().intValue()); } @Test public void defaultBeanSettingsFromBeanConfiguration() throws Throwable { astrixContext.getBean(Ping.class).ping("foo"); HystrixFaultToleranceFactory hystrixFaultTolerance = getFaultTolerance(astrixContext); HystrixCommandProperties pingCommandProperties = getHystrixCommandProperties(hystrixFaultTolerance, Ping.class); HystrixThreadPoolProperties pingThreadPoolProperties = getThreadPoolProperties(hystrixFaultTolerance, Ping.class); assertEquals(DefaultBeanSettings.DEFAULT_CORE_SIZE, pingThreadPoolProperties.coreSize().get().intValue()); assertEquals(DefaultBeanSettings.DEFAULT_QUEUE_SIZE_REJECTION_THRESHOLD, pingThreadPoolProperties.queueSizeRejectionThreshold().get().intValue()); assertEquals(DefaultBeanSettings.DEFAULT_TIMEOUT, pingCommandProperties.executionTimeoutInMilliseconds().get().intValue()); assertEquals(DefaultBeanSettings.DEFAULT_MAX_CONCURRENT_REQUESTS, pingCommandProperties.executionIsolationSemaphoreMaxConcurrentRequests().get().intValue()); } private static HystrixCommandProperties getHystrixCommandProperties(HystrixFaultToleranceFactory hystrixFaultTolerance, Class<?> api) { HystrixPropertiesStrategy hystrixPropertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy(); HystrixCommandKey commandKey = hystrixFaultTolerance.getCommandKey(AstrixBeanKey.create(api)); return hystrixPropertiesStrategy.getCommandProperties(commandKey, HystrixCommandProperties.Setter()); } private static HystrixFaultToleranceFactory getFaultTolerance(AstrixContext astrixContext) { BeanFaultToleranceFactorySpi ftStrategy = AstrixApplicationContext.class.cast(astrixContext).getInstance(BeanFaultToleranceFactorySpi.class); assertEquals(HystrixFaultToleranceFactory.class, ftStrategy.getClass()); return (HystrixFaultToleranceFactory) ftStrategy; } private static HystrixThreadPoolProperties getThreadPoolProperties(HystrixFaultToleranceFactory hystrixFaultTolerance, Class<?> api) { HystrixPropertiesStrategy hystrixPropertiesStrategy = HystrixPlugins.getInstance().getPropertiesStrategy(); HystrixCommandGroupKey groupKey = hystrixFaultTolerance.getGroupKey(AstrixBeanKey.create(api)); return hystrixPropertiesStrategy.getThreadPoolProperties(HystrixThreadPoolKey.Factory.asKey(groupKey.name()), HystrixThreadPoolProperties.Setter()); } @AstrixApiProvider public static class PingApi { @AstrixFaultToleranceProxy @Library public Ping ping() { return new PingImpl(); } } private static class PingImpl implements Ping { @Override public String ping(String msg) { return msg; } } public interface Ping { String ping(String msg); } }