http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixProcessorFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixProcessorFactory.java b/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixProcessorFactory.java index a996d56..909f6da 100644 --- a/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixProcessorFactory.java +++ b/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixProcessorFactory.java @@ -16,126 +16,103 @@ */ package org.apache.camel.component.hystrix.processor; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + import com.netflix.hystrix.HystrixCommand; 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 org.apache.camel.CamelContext; import org.apache.camel.Processor; +import org.apache.camel.impl.TypedProcessorFactory; import org.apache.camel.model.HystrixConfigurationDefinition; import org.apache.camel.model.HystrixDefinition; -import org.apache.camel.model.ProcessorDefinition; -import org.apache.camel.spi.ProcessorFactory; import org.apache.camel.spi.RouteContext; -import org.apache.camel.util.CamelContextHelper; +import org.apache.camel.util.IntrospectionSupport; +import org.apache.camel.util.function.Suppliers; + +import static org.apache.camel.util.CamelContextHelper.lookup; +import static org.apache.camel.util.CamelContextHelper.mandatoryLookup; /** * To integrate camel-hystrix with the Camel routes using the Hystrix EIP. */ -public class HystrixProcessorFactory implements ProcessorFactory { - - @Override - public Processor createChildProcessor(RouteContext routeContext, ProcessorDefinition<?> definition, boolean mandatory) throws Exception { - // not in use - return null; +public class HystrixProcessorFactory extends TypedProcessorFactory<HystrixDefinition> { + public HystrixProcessorFactory() { + super(HystrixDefinition.class); } @Override - public Processor createProcessor(RouteContext routeContext, ProcessorDefinition<?> definition) throws Exception { - if (definition instanceof HystrixDefinition) { - HystrixDefinition cb = (HystrixDefinition) definition; - - // create the regular and fallback processors - Processor processor = cb.createChildProcessor(routeContext, true); - Processor fallback = null; - if (cb.getOnFallback() != null) { - fallback = cb.getOnFallback().createProcessor(routeContext); - } - - HystrixConfigurationDefinition config = cb.getHystrixConfiguration(); - HystrixConfigurationDefinition configRef = null; - if (cb.getHystrixConfigurationRef() != null) { - configRef = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), cb.getHystrixConfigurationRef(), HystrixConfigurationDefinition.class); - } - - String id = cb.idOrCreate(routeContext.getCamelContext().getNodeIdFactory()); - - // group and thread pool keys to use they can be configured on configRef and config, so look there first, and if none then use default - String groupKey = null; - String threadPoolKey = null; - if (configRef != null) { - groupKey = configRef.getGroupKey(); - threadPoolKey = configRef.getThreadPoolKey(); - } - if (config != null && config.getGroupKey() != null) { - groupKey = config.getGroupKey(); - threadPoolKey = config.getThreadPoolKey(); - } - if (groupKey == null) { - groupKey = HystrixConfigurationDefinition.DEFAULT_GROUP_KEY; - } - if (threadPoolKey == null) { - // by default use the thread pool from the group - threadPoolKey = groupKey; - } - - // use the node id as the command key - HystrixCommandKey hcCommandKey = HystrixCommandKey.Factory.asKey(id); - HystrixCommandKey hcFallbackCommandKey = HystrixCommandKey.Factory.asKey(id + "-fallback"); - // use the configured group key - HystrixCommandGroupKey hcGroupKey = HystrixCommandGroupKey.Factory.asKey(groupKey); - HystrixThreadPoolKey tpKey = HystrixThreadPoolKey.Factory.asKey(threadPoolKey); - - // create setter using the default options - HystrixCommand.Setter setter = HystrixCommand.Setter - .withGroupKey(hcGroupKey) - .andCommandKey(hcCommandKey) - .andThreadPoolKey(tpKey); - HystrixCommandProperties.Setter commandSetter = HystrixCommandProperties.Setter(); - setter.andCommandPropertiesDefaults(commandSetter); - HystrixThreadPoolProperties.Setter threadPoolSetter = HystrixThreadPoolProperties.Setter(); - setter.andThreadPoolPropertiesDefaults(threadPoolSetter); + public Processor doCreateProcessor(RouteContext routeContext, HystrixDefinition definition) throws Exception { + // create the regular and fallback processors + Processor processor = definition.createChildProcessor(routeContext, true); + Processor fallback = null; + if (definition.getOnFallback() != null) { + fallback = definition.getOnFallback().createProcessor(routeContext); + } + + final HystrixConfigurationDefinition config = buildHystrixConfiguration(routeContext.getCamelContext(), definition); + final String id = definition.idOrCreate(routeContext.getCamelContext().getNodeIdFactory()); + + // group and thread pool keys to use they can be configured on configRef and config, so look there first, and if none then use default + String groupKey = config.getGroupKey(); + String threadPoolKey = config.getThreadPoolKey(); + + if (groupKey == null) { + groupKey = HystrixConfigurationDefinition.DEFAULT_GROUP_KEY; + } + if (threadPoolKey == null) { + // by default use the thread pool from the group + threadPoolKey = groupKey; + } + + // use the node id as the command key + HystrixCommandKey hcCommandKey = HystrixCommandKey.Factory.asKey(id); + HystrixCommandKey hcFallbackCommandKey = HystrixCommandKey.Factory.asKey(id + "-fallback"); + + // use the configured group key + HystrixCommandGroupKey hcGroupKey = HystrixCommandGroupKey.Factory.asKey(groupKey); + HystrixThreadPoolKey tpKey = HystrixThreadPoolKey.Factory.asKey(threadPoolKey); + + // create setter using the default options + HystrixCommand.Setter setter = HystrixCommand.Setter.withGroupKey(hcGroupKey) + .andCommandKey(hcCommandKey) + .andThreadPoolKey(tpKey); + + HystrixCommandProperties.Setter commandSetter = HystrixCommandProperties.Setter(); + setter.andCommandPropertiesDefaults(commandSetter); + + HystrixThreadPoolProperties.Setter threadPoolSetter = HystrixThreadPoolProperties.Setter(); + setter.andThreadPoolPropertiesDefaults(threadPoolSetter); + + configureHystrix(commandSetter, threadPoolSetter, config); + + // create setter for fallback via network + HystrixCommand.Setter fallbackSetter = null; + boolean fallbackViaNetwork = definition.getOnFallback() != null && definition.getOnFallback().isFallbackViaNetwork(); + if (fallbackViaNetwork) { + // use a different thread pool that is for fallback (should never use the same thread pool as the regular command) + HystrixThreadPoolKey tpFallbackKey = HystrixThreadPoolKey.Factory.asKey(threadPoolKey + "-fallback"); + + fallbackSetter = HystrixCommand.Setter.withGroupKey(hcGroupKey) + .andCommandKey(hcFallbackCommandKey) + .andThreadPoolKey(tpFallbackKey); + + HystrixCommandProperties.Setter commandFallbackSetter = HystrixCommandProperties.Setter(); + fallbackSetter.andCommandPropertiesDefaults(commandFallbackSetter); + + HystrixThreadPoolProperties.Setter fallbackThreadPoolSetter = HystrixThreadPoolProperties.Setter(); + fallbackSetter.andThreadPoolPropertiesDefaults(fallbackThreadPoolSetter); // at first configure any shared options - if (configRef != null) { - configureHystrix(commandSetter, threadPoolSetter, configRef); - } - // then any local configured can override - if (config != null) { - configureHystrix(commandSetter, threadPoolSetter, config); - } - - // create setter for fallback via network - HystrixCommand.Setter fallbackSetter = null; - boolean fallbackViaNetwork = cb.getOnFallback() != null && cb.getOnFallback().isFallbackViaNetwork(); - if (fallbackViaNetwork) { - // use a different thread pool that is for fallback (should never use the same thread pool as the regular command) - HystrixThreadPoolKey tpFallbackKey = HystrixThreadPoolKey.Factory.asKey(threadPoolKey + "-fallback"); - - fallbackSetter = HystrixCommand.Setter - .withGroupKey(hcGroupKey) - .andCommandKey(hcFallbackCommandKey) - .andThreadPoolKey(tpFallbackKey); - HystrixCommandProperties.Setter commandFallbackSetter = HystrixCommandProperties.Setter(); - fallbackSetter.andCommandPropertiesDefaults(commandFallbackSetter); - HystrixThreadPoolProperties.Setter fallbackThreadPoolSetter = HystrixThreadPoolProperties.Setter(); - fallbackSetter.andThreadPoolPropertiesDefaults(fallbackThreadPoolSetter); - - // at first configure any shared options - if (configRef != null) { - configureHystrix(commandFallbackSetter, fallbackThreadPoolSetter, configRef); - } - // then any local configured can override - if (config != null) { - configureHystrix(commandFallbackSetter, fallbackThreadPoolSetter, config); - } - } - - return new HystrixProcessor(hcGroupKey, hcCommandKey, hcFallbackCommandKey, setter, fallbackSetter, processor, fallback, fallbackViaNetwork); - } else { - return null; + configureHystrix(commandFallbackSetter, fallbackThreadPoolSetter, config); } + + return new HystrixProcessor(hcGroupKey, hcCommandKey, hcFallbackCommandKey, setter, fallbackSetter, processor, fallback, fallbackViaNetwork); } private void configureHystrix(HystrixCommandProperties.Setter command, HystrixThreadPoolProperties.Setter threadPool, HystrixConfigurationDefinition config) { @@ -228,4 +205,47 @@ public class HystrixProcessorFactory implements ProcessorFactory { threadPool.withAllowMaximumSizeToDivergeFromCoreSize(config.getAllowMaximumSizeToDivergeFromCoreSize()); } } + + // ******************************* + // Helpers + // ******************************* + + HystrixConfigurationDefinition buildHystrixConfiguration(CamelContext camelContext, HystrixDefinition definition) throws Exception { + Map<String, Object> properties = new HashMap<>(); + + // Extract properties from default configuration, the one configured on + // camel context takes the precedence over those in the registry + loadProperties(properties, Suppliers.firstNotNull( + () -> camelContext.getHystrixConfiguration(null), + () -> lookup(camelContext, HystrixConstants.DEFAULT_HYSTRIX_CONFIGURATION_ID, HystrixConfigurationDefinition.class)) + ); + + // Extract properties from referenced configuration, the one configured + // on camel context takes the precedence over those in the registry + if (definition.getHystrixConfigurationRef() != null) { + final String ref = definition.getHystrixConfigurationRef(); + + loadProperties(properties, Suppliers.firstNotNull( + () -> camelContext.getHystrixConfiguration(ref), + () -> mandatoryLookup(camelContext, ref, HystrixConfigurationDefinition.class)) + ); + } + + // Extract properties from local configuration + loadProperties(properties, Optional.ofNullable(definition.getHystrixConfiguration())); + + // Extract properties from definition + IntrospectionSupport.getProperties(definition, properties, null, false); + + HystrixConfigurationDefinition config = new HystrixConfigurationDefinition(); + + // Apply properties to a new configuration + IntrospectionSupport.setProperties(camelContext, camelContext.getTypeConverter(), config, properties); + + return config; + } + + private void loadProperties(Map<String, Object> properties, Optional<?> optional) { + optional.ifPresent(bean -> IntrospectionSupport.getProperties(bean, properties, null, false)); + } }
http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfigTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfigTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfigTest.java new file mode 100644 index 0000000..1b09566 --- /dev/null +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfigTest.java @@ -0,0 +1,134 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.component.hystrix.processor; + +import org.apache.camel.CamelContext; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.impl.SimpleRegistry; +import org.apache.camel.model.HystrixConfigurationDefinition; +import org.apache.camel.model.HystrixDefinition; +import org.junit.Assert; +import org.junit.Test; + +public class HystrixHierarchicalConfigTest { + + @Test + public void testRegistryConfiguration() throws Exception { + final SimpleRegistry registry = new SimpleRegistry(); + final CamelContext context = new DefaultCamelContext(registry); + + HystrixConfigurationDefinition def = new HystrixConfigurationDefinition(); + def.setGroupKey("global-group-key"); + def.setThreadPoolKey("global-thread-key"); + def.setCorePoolSize(10); + + HystrixConfigurationDefinition ref = new HystrixConfigurationDefinition(); + ref.setGroupKey("ref-group-key"); + ref.setCorePoolSize(5); + + registry.put(HystrixConstants.DEFAULT_HYSTRIX_CONFIGURATION_ID, def); + registry.put("ref-hystrix", ref); + + final HystrixProcessorFactory factory = new HystrixProcessorFactory(); + final HystrixConfigurationDefinition config = factory.buildHystrixConfiguration( + context, + new HystrixDefinition() + .hystrixConfiguration("ref-hystrix") + .hystrixConfiguration() + .groupKey("local-conf-group-key") + .requestLogEnabled(false) + .end() + ); + + Assert.assertEquals("local-conf-group-key", config.getGroupKey()); + Assert.assertEquals("global-thread-key", config.getThreadPoolKey()); + Assert.assertEquals(new Integer(5), config.getCorePoolSize()); + } + + @Test + public void testContextConfiguration() throws Exception { + final CamelContext context = new DefaultCamelContext(); + + HystrixConfigurationDefinition def = new HystrixConfigurationDefinition(); + def.setGroupKey("global-group-key"); + def.setThreadPoolKey("global-thread-key"); + def.setCorePoolSize(10); + + HystrixConfigurationDefinition ref = new HystrixConfigurationDefinition(); + ref.setGroupKey("ref-group-key"); + ref.setCorePoolSize(5); + + context.setHystrixConfiguration(def); + context.addHystrixConfiguration("ref-hystrix", ref); + + final HystrixProcessorFactory factory = new HystrixProcessorFactory(); + final HystrixConfigurationDefinition config = factory.buildHystrixConfiguration( + context, + new HystrixDefinition() + .hystrixConfiguration("ref-hystrix") + .hystrixConfiguration() + .groupKey("local-conf-group-key") + .requestLogEnabled(false) + .end() + ); + + Assert.assertEquals("local-conf-group-key", config.getGroupKey()); + Assert.assertEquals("global-thread-key", config.getThreadPoolKey()); + Assert.assertEquals(new Integer(5), config.getCorePoolSize()); + } + + @Test + public void testMixedConfiguration() throws Exception { + final SimpleRegistry registry = new SimpleRegistry(); + final CamelContext context = new DefaultCamelContext(registry); + + HystrixConfigurationDefinition def = new HystrixConfigurationDefinition(); + def.setGroupKey("global-group-key"); + def.setThreadPoolKey("global-thread-key"); + def.setCorePoolSize(10); + + HystrixConfigurationDefinition ref = new HystrixConfigurationDefinition(); + ref.setGroupKey("ref-group-key"); + ref.setCorePoolSize(5); + + // this should be ignored + HystrixConfigurationDefinition defReg = new HystrixConfigurationDefinition(); + defReg.setGroupKey("global-reg-group-key"); + defReg.setThreadPoolKey("global-reg-thread-key"); + defReg.setCorePoolSize(20); + + context.setHystrixConfiguration(def); + + registry.put(HystrixConstants.DEFAULT_HYSTRIX_CONFIGURATION_ID, defReg); + registry.put("ref-hystrix", ref); + + final HystrixProcessorFactory factory = new HystrixProcessorFactory(); + final HystrixConfigurationDefinition config = factory.buildHystrixConfiguration( + context, + new HystrixDefinition() + .hystrixConfiguration("ref-hystrix") + .hystrixConfiguration() + .groupKey("local-conf-group-key") + .requestLogEnabled(false) + .end() + ); + + Assert.assertEquals("local-conf-group-key", config.getGroupKey()); + Assert.assertEquals("global-thread-key", config.getThreadPoolKey()); + Assert.assertEquals(new Integer(5), config.getCorePoolSize()); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteConfigTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteConfigTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteConfigTest.java index b9bfc1c..e1f4ea4 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteConfigTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/HystrixRouteConfigTest.java @@ -61,6 +61,7 @@ public class HystrixRouteConfigTest extends CamelTestSupport { assertEquals("test2", config.getGroupKey()); assertEquals(99999, config.getMetricsHealthSnapshotIntervalInMilliseconds().intValue()); } + @Override protected RouteBuilder createRouteBuilder() throws Exception { http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigMaximumSizeTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigMaximumSizeTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigMaximumSizeTest.java index 0a88b8f..ba69a73 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigMaximumSizeTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigMaximumSizeTest.java @@ -20,7 +20,9 @@ import org.apache.camel.test.spring.CamelSpringTestSupport; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.annotation.DirtiesContext; +@DirtiesContext public class SpringHystrixRouteConfigMaximumSizeTest extends CamelSpringTestSupport { @Override http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigRefTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigRefTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigRefTest.java index dcf9dc0..17e620c 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigRefTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigRefTest.java @@ -20,7 +20,9 @@ import org.apache.camel.test.spring.CamelSpringTestSupport; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.annotation.DirtiesContext; +@DirtiesContext public class SpringHystrixRouteConfigRefTest extends CamelSpringTestSupport { @Override http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigTest.java index d0a52b1..4c9574d 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteConfigTest.java @@ -20,7 +20,9 @@ import org.apache.camel.test.spring.CamelSpringTestSupport; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.annotation.DirtiesContext; +@DirtiesContext public class SpringHystrixRouteConfigTest extends CamelSpringTestSupport { @Override http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteFallbackTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteFallbackTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteFallbackTest.java index 2857b27..c32606c 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteFallbackTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteFallbackTest.java @@ -20,7 +20,9 @@ import org.apache.camel.test.spring.CamelSpringTestSupport; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.annotation.DirtiesContext; +@DirtiesContext public class SpringHystrixRouteFallbackTest extends CamelSpringTestSupport { @Override http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.java new file mode 100644 index 0000000..ae4a5f1 --- /dev/null +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.java @@ -0,0 +1,68 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.component.hystrix.processor; + +import org.apache.camel.model.HystrixConfigurationDefinition; +import org.apache.camel.model.HystrixDefinition; +import org.apache.camel.model.RouteDefinition; +import org.apache.camel.test.spring.CamelSpringTestSupport; +import org.junit.Assert; +import org.junit.Test; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.annotation.DirtiesContext; + +@DirtiesContext +public class SpringHystrixRouteHierarchicalConfigTest extends CamelSpringTestSupport { + @Override + protected AbstractApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.xml"); + } + + @Test + public void testHystrix() throws Exception { + RouteDefinition routeDefinition = context.getRouteDefinition("hystrix-route"); + HystrixDefinition hystrixDefinition = findHystrixDefinition(routeDefinition); + + Assert.assertNotNull(hystrixDefinition); + + HystrixProcessorFactory factory = new HystrixProcessorFactory(); + HystrixConfigurationDefinition config = factory.buildHystrixConfiguration(context, hystrixDefinition); + + Assert.assertEquals("local-conf-group-key", config.getGroupKey()); + Assert.assertEquals("global-thread-key", config.getThreadPoolKey()); + Assert.assertEquals(new Integer(5), config.getCorePoolSize()); + + getMockEndpoint("mock:result").expectedBodiesReceived("Bye World"); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + // ********************************************** + // Helper + // ********************************************** + + private HystrixDefinition findHystrixDefinition(RouteDefinition routeDefinition) throws Exception { + return routeDefinition.getOutputs().stream() + .filter(HystrixDefinition.class::isInstance) + .map(HystrixDefinition.class::cast) + .findFirst() + .orElseThrow(() -> new IllegalStateException("Unable to find a HystrixDefinition")); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteOkTest.java ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteOkTest.java b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteOkTest.java index 18622bb..21b50ac 100644 --- a/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteOkTest.java +++ b/components/camel-hystrix/src/test/java/org/apache/camel/component/hystrix/processor/SpringHystrixRouteOkTest.java @@ -20,7 +20,9 @@ import org.apache.camel.test.spring.CamelSpringTestSupport; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; +import org.springframework.test.annotation.DirtiesContext; +@DirtiesContext public class SpringHystrixRouteOkTest extends CamelSpringTestSupport { @Override http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/test/resources/org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-hystrix/src/test/resources/org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.xml b/components/camel-hystrix/src/test/resources/org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.xml new file mode 100644 index 0000000..3917248 --- /dev/null +++ b/components/camel-hystrix/src/test/resources/org/apache/camel/component/hystrix/processor/SpringHystrixRouteHierarchicalConfigTest.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You 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. +--> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd "> + + <camelContext xmlns="http://camel.apache.org/schema/spring"> + + <defaultHystrixConfiguration id="global" groupKey="global-group-key" threadPoolKey="global-thread-key" corePoolSize="10"/> + <hystrixConfiguration id="ref-hystrix" groupKey="ref-group-key" corePoolSize="5"/> + + <route id="hystrix-route"> + <from uri="direct:start"/> + <hystrix hystrixConfigurationRef="ref-hystrix"> + <hystrixConfiguration groupKey="local-conf-group-key" requestLogEnabled="false"/> + <to uri="direct:foo"/> + <onFallback> + <transform> + <constant>Fallback message</constant> + </transform> + </onFallback> + </hystrix> + <to uri="mock:result"/> + </route> + + <route> + <from uri="direct:foo"/> + <transform> + <constant>Bye World</constant> + </transform> + </route> + </camelContext> + +</beans> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java index 514985e..70a319e 100644 --- a/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java +++ b/components/camel-spring/src/main/java/org/apache/camel/spring/CamelContextFactoryBean.java @@ -171,6 +171,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr private ServiceCallConfigurationDefinition defaultServiceCallConfiguration; @XmlElement(name = "serviceCallConfiguration", type = ServiceCallConfigurationDefinition.class) private List<ServiceCallConfigurationDefinition> serviceCallConfigurations; + @XmlElement(name = "defaultHystrixConfiguration") + private HystrixConfigurationDefinition defaultHystrixConfiguration; @XmlElement(name = "hystrixConfiguration", type = HystrixConfigurationDefinition.class) private List<HystrixConfigurationDefinition> hystrixConfigurations; @XmlElement(name = "routeBuilder") @@ -980,6 +982,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr return hystrixConfigurations; } + @Override + public HystrixConfigurationDefinition getDefaultHystrixConfiguration() { + return defaultHystrixConfiguration; + } + + public void setDefaultHystrixConfiguration(HystrixConfigurationDefinition defaultHystrixConfiguration) { + this.defaultHystrixConfiguration = defaultHystrixConfiguration; + } + /** * hystrix configurations */ http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java ---------------------------------------------------------------------- diff --git a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java index 072e904..2b89d44 100644 --- a/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java +++ b/components/camel-spring/src/main/java/org/apache/camel/spring/handler/CamelNamespaceHandler.java @@ -37,7 +37,6 @@ import org.apache.camel.core.xml.CamelPropertyPlaceholderDefinition; import org.apache.camel.core.xml.CamelStreamCachingStrategyDefinition; import org.apache.camel.impl.DefaultCamelContextNameStrategy; import org.apache.camel.model.FromDefinition; -import org.apache.camel.model.HystrixConfigurationDefinition; import org.apache.camel.model.SendDefinition; import org.apache.camel.spi.CamelContextNameStrategy; import org.apache.camel.spi.NamespaceAware; @@ -148,9 +147,8 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport { addBeanDefinitionParser("jmxAgent", CamelJMXAgentDefinition.class, false, false); addBeanDefinitionParser("streamCaching", CamelStreamCachingStrategyDefinition.class, false, false); addBeanDefinitionParser("propertyPlaceholder", CamelPropertyPlaceholderDefinition.class, false, false); - addBeanDefinitionParser("hystrixConfiguration", HystrixConfigurationDefinition.class, false, false); - // errorhandler could be the sub element of camelContext or defined outside camelContext + // error handler could be the sub element of camelContext or defined outside camelContext BeanDefinitionParser errorHandlerParser = new ErrorHandlerDefinitionParser(); registerParser("errorHandler", errorHandlerParser); parserMap.put("errorHandler", errorHandlerParser); @@ -405,6 +403,7 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport { builder.addPropertyValue("beans", factoryBean.getBeans()); builder.addPropertyValue("defaultServiceCallConfiguration", factoryBean.getDefaultServiceCallConfiguration()); builder.addPropertyValue("serviceCallConfigurations", factoryBean.getServiceCallConfigurations()); + builder.addPropertyValue("defaultHystrixConfiguration", factoryBean.getDefaultHystrixConfiguration()); builder.addPropertyValue("hystrixConfigurations", factoryBean.getHystrixConfigurations()); // add any depends-on addDependsOn(factoryBean, builder); http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/java/org/apache/camel/component/hystrix/springboot/HystrixAutoConfiguration.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/java/org/apache/camel/component/hystrix/springboot/HystrixAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/java/org/apache/camel/component/hystrix/springboot/HystrixAutoConfiguration.java new file mode 100644 index 0000000..def622c --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/java/org/apache/camel/component/hystrix/springboot/HystrixAutoConfiguration.java @@ -0,0 +1,59 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.component.hystrix.springboot; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.CamelContext; +import org.apache.camel.component.hystrix.processor.HystrixConstants; +import org.apache.camel.model.HystrixConfigurationDefinition; +import org.apache.camel.spring.boot.CamelAutoConfiguration; +import org.apache.camel.util.IntrospectionSupport; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +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.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Hystrix auto configuration. + */ +@Configuration +@ConditionalOnProperty(name = "camel.hystrix.enabled", matchIfMissing = true) +@ConditionalOnBean(value = CamelAutoConfiguration.class) +@AutoConfigureAfter(value = CamelAutoConfiguration.class) +@EnableConfigurationProperties(HystrixConfiguration.class) +public class HystrixAutoConfiguration { + + @Bean(name = HystrixConstants.DEFAULT_HYSTRIX_CONFIGURATION_ID) + @ConditionalOnClass(CamelContext.class) + @ConditionalOnMissingBean(name = HystrixConstants.DEFAULT_HYSTRIX_CONFIGURATION_ID) + HystrixConfigurationDefinition defaultHystrixConfigurationDefinition(CamelContext camelContext, HystrixConfiguration config) throws Exception { + Map<String, Object> properties = new HashMap<>(); + + IntrospectionSupport.getProperties(config, properties, null, false); + + HystrixConfigurationDefinition definition = new HystrixConfigurationDefinition(); + IntrospectionSupport.setProperties(camelContext, camelContext.getTypeConverter(), definition, properties); + + return definition; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/java/org/apache/camel/component/hystrix/springboot/HystrixConfiguration.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/java/org/apache/camel/component/hystrix/springboot/HystrixConfiguration.java b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/java/org/apache/camel/component/hystrix/springboot/HystrixConfiguration.java new file mode 100644 index 0000000..063f94a --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/java/org/apache/camel/component/hystrix/springboot/HystrixConfiguration.java @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.component.hystrix.springboot; + +import org.apache.camel.model.HystrixConfigurationCommon; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Hystrix component. + */ +@ConfigurationProperties(prefix = "camel.hystrix") +public class HystrixConfiguration extends HystrixConfigurationCommon { +} http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/resources/META-INF/spring.factories ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/resources/META-INF/spring.factories index 331a5e4..50c8d3d 100644 --- a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/resources/META-INF/spring.factories +++ b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/main/resources/META-INF/spring.factories @@ -16,4 +16,5 @@ # org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.apache.camel.component.hystrix.springboot.HystrixAutoConfiguration,\ org.apache.camel.component.hystrix.springboot.HystrixMappingAutoConfiguration http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfiguration.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfiguration.java b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfiguration.java new file mode 100644 index 0000000..39bbb22 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfiguration.java @@ -0,0 +1,54 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.component.hystrix.processor; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.HystrixConfigurationDefinition; +import org.springframework.context.annotation.Bean; + +public class HystrixHierarchicalConfiguration { + @Bean(name = "ref-hystrix") + public HystrixConfigurationDefinition hystrixConfiguration() { + return new HystrixConfigurationDefinition() + .groupKey("ref-group-key") + .corePoolSize(5); + } + + @Bean + public RouteBuilder routeBuilder() { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("direct:start") + .routeId("hystrix-route") + .hystrix() + .hystrixConfiguration("ref-hystrix") + .hystrixConfiguration() + .groupKey("local-conf-group-key") + .end() + .to("direct:foo") + .onFallback() + .transform().constant("Fallback message") + .end(); + + from("direct:foo") + .transform().body(b -> "Bye World"); + + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfigurationTest.java ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfigurationTest.java b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfigurationTest.java new file mode 100644 index 0000000..948b6f7 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/java/org/apache/camel/component/hystrix/processor/HystrixHierarchicalConfigurationTest.java @@ -0,0 +1,78 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.apache.camel.component.hystrix.processor; + +import org.apache.camel.CamelContext; +import org.apache.camel.model.HystrixConfigurationDefinition; +import org.apache.camel.model.HystrixDefinition; +import org.apache.camel.model.RouteDefinition; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Testing the Hystrix configuration hierarchy + */ +@RunWith(SpringRunner.class) +@SpringBootApplication +@DirtiesContext +@ContextConfiguration(classes = HystrixHierarchicalConfiguration.class) +@SpringBootTest(properties = { + "debug=false", + "camel.hystrix.enabled=true", + "camel.hystrix.group-key=global-group-key", + "camel.hystrix.thread-pool-key=global-thread-key", + "camel.hystrix.core-pool-size=10" +}) +public class HystrixHierarchicalConfigurationTest { + @Autowired + CamelContext camelContext; + + @Test + public void testConfiguration() throws Exception { + RouteDefinition routeDefinition = camelContext.getRouteDefinition("hystrix-route"); + HystrixDefinition hystrixDefinition = findHystrixDefinition(routeDefinition); + + Assert.assertNotNull(hystrixDefinition); + + HystrixProcessorFactory factory = new HystrixProcessorFactory(); + HystrixConfigurationDefinition config = factory.buildHystrixConfiguration(camelContext, hystrixDefinition); + + Assert.assertEquals("local-conf-group-key", config.getGroupKey()); + Assert.assertEquals("global-thread-key", config.getThreadPoolKey()); + Assert.assertEquals(new Integer(5), config.getCorePoolSize()); + } + + // ********************************************** + // Helper + // ********************************************** + + private HystrixDefinition findHystrixDefinition(RouteDefinition routeDefinition) throws Exception { + return routeDefinition.getOutputs().stream() + .filter(HystrixDefinition.class::isInstance) + .map(HystrixDefinition.class::cast) + .findFirst() + .orElseThrow(() -> new IllegalStateException("Unable to find a HystrixDefinition")); + } +} + http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/resources/logback.xml ---------------------------------------------------------------------- diff --git a/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/resources/logback.xml b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/resources/logback.xml new file mode 100644 index 0000000..bd20d85 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-hystrix-starter/src/test/resources/logback.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Licensed to the Apache Software Foundation (ASF) under one or more + ~ contributor license agreements. See the NOTICE file distributed with + ~ this work for additional information regarding copyright ownership. + ~ The ASF licenses this file to You 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. + --> +<configuration> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <!-- encoders are assigned the type + ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%-15.15thread] %-5level %-30.30logger - %msg%n</pattern> + </encoder> + </appender> + + <appender name="FILE" class="ch.qos.logback.core.FileAppender"> + <encoder> + <pattern>%d{HH:mm:ss.SSS} [%-15.15thread] %-5level %-30.30logger - %msg%n</pattern> + </encoder> + <file>target/camel-hystrix-starter-test.log</file> + </appender> + + <root level="INFO"> + <appender-ref ref="FILE"/> + </root> + +</configuration> \ No newline at end of file