You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2017/03/14 20:19:10 UTC

[1/4] camel git commit: CAMEL-10991: ServiceCall - Allow to configure global configuration

Repository: camel
Updated Branches:
  refs/heads/master 32f39ea17 -> b4d0038a7


http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/platforms/spring-boot/components-starter/camel-kubernetes-starter/src/main/java/org/apache/camel/component/kubernetes/springboot/cloud/KubernetesCloudAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-kubernetes-starter/src/main/java/org/apache/camel/component/kubernetes/springboot/cloud/KubernetesCloudAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-kubernetes-starter/src/main/java/org/apache/camel/component/kubernetes/springboot/cloud/KubernetesCloudAutoConfiguration.java
index 6527ba4..921a34f 100644
--- a/platforms/spring-boot/components-starter/camel-kubernetes-starter/src/main/java/org/apache/camel/component/kubernetes/springboot/cloud/KubernetesCloudAutoConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-kubernetes-starter/src/main/java/org/apache/camel/component/kubernetes/springboot/cloud/KubernetesCloudAutoConfiguration.java
@@ -23,21 +23,16 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.cloud.ServiceDiscovery;
 import org.apache.camel.component.kubernetes.cloud.KubernetesServiceDiscoveryFactory;
 import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.util.GroupCondition;
 import org.apache.camel.util.IntrospectionSupport;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionMessage;
-import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
-import org.springframework.boot.bind.RelaxedPropertyResolver;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ConditionContext;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Lazy;
-import org.springframework.core.type.AnnotatedTypeMetadata;
 
 @Configuration
 @ConditionalOnBean(CamelAutoConfiguration.class)
@@ -58,22 +53,16 @@ public class KubernetesCloudAutoConfiguration {
         return factory.newInstance(camelContext);
     }
 
-    public static class Condition extends SpringBootCondition {
-        @Override
-        public ConditionOutcome getMatchOutcome(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
-            boolean groupEnabled = isEnabled(conditionContext, "camel.cloud.", true);
+    // *******************************
+    // Condition
+    // *******************************
 
-            ConditionMessage.Builder message = ConditionMessage.forCondition("camel.cloud.kubernetes");
-            if (isEnabled(conditionContext, "camel.cloud.kubernetes.", groupEnabled)) {
-                return ConditionOutcome.match(message.because("enabled"));
-            }
-
-            return ConditionOutcome.noMatch(message.because("not enabled"));
-        }
-
-        private boolean isEnabled(ConditionContext context, String prefix, boolean defaultValue) {
-            RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), prefix);
-            return resolver.getProperty("enabled", Boolean.class, defaultValue);
+    public static class Condition extends GroupCondition {
+        public Condition() {
+            super(
+                "camel.cloud",
+                "camel.cloud.kubernetes"
+            );
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java
index cfb7f88..fc6a4fd 100644
--- a/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-ribbon-starter/src/main/java/org/apache/camel/component/ribbon/springboot/cloud/RibbonCloudAutoConfiguration.java
@@ -23,21 +23,16 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.cloud.LoadBalancer;
 import org.apache.camel.component.ribbon.cloud.RibbonLoadBalancerFactory;
 import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.util.GroupCondition;
 import org.apache.camel.util.IntrospectionSupport;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionMessage;
-import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
-import org.springframework.boot.bind.RelaxedPropertyResolver;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ConditionContext;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Lazy;
-import org.springframework.core.type.AnnotatedTypeMetadata;
 
 @Configuration
 @ConditionalOnBean(CamelAutoConfiguration.class)
@@ -58,22 +53,16 @@ public class RibbonCloudAutoConfiguration {
         return factory.newInstance(camelContext);
     }
 
-    public static class Condition extends SpringBootCondition {
-        @Override
-        public ConditionOutcome getMatchOutcome(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
-            boolean groupEnabled = isEnabled(conditionContext, "camel.cloud.", true);
+    // *******************************
+    // Condition
+    // *******************************
 
-            ConditionMessage.Builder message = ConditionMessage.forCondition("camel.cloud.ribbon");
-            if (isEnabled(conditionContext, "camel.cloud.ribbon.", groupEnabled)) {
-                return ConditionOutcome.match(message.because("enabled"));
-            }
-
-            return ConditionOutcome.noMatch(message.because("not enabled"));
-        }
-
-        private boolean isEnabled(ConditionContext context, String prefix, boolean defaultValue) {
-            RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), prefix);
-            return resolver.getProperty("enabled", Boolean.class, defaultValue);
+    public static class Condition extends GroupCondition {
+        public Condition() {
+            super(
+                "camel.cloud",
+                "camel.cloud.ribbon"
+            );
         }
     }
 }


[3/4] camel git commit: CAMEL-10992: Hystrix - Allow to configure global configuration

Posted by lb...@apache.org.
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


[4/4] camel git commit: CAMEL-10992: Hystrix - Allow to configure global configuration

Posted by lb...@apache.org.
CAMEL-10992: Hystrix - Allow to configure global configuration


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b4d0038a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b4d0038a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b4d0038a

Branch: refs/heads/master
Commit: b4d0038a726525add4f032b6c3b45c030a3a760b
Parents: 9628b85
Author: lburgazzoli <lb...@gmail.com>
Authored: Mon Mar 13 18:21:25 2017 +0100
Committer: lburgazzoli <lb...@gmail.com>
Committed: Tue Mar 14 21:18:10 2017 +0100

----------------------------------------------------------------------
 camel-core/pom.xml                              |   5 +
 .../docs/eips/hystrixConfiguration-eip.adoc     |  62 +--
 .../java/org/apache/camel/CamelContext.java     |  32 ++
 .../apache/camel/impl/DefaultCamelContext.java  |  30 ++
 .../camel/impl/TypedProcessorFactory.java       |  57 +++
 .../camel/model/HystrixConfigurationCommon.java | 374 +++++++++++++++++
 .../model/HystrixConfigurationDefinition.java   | 410 ++-----------------
 .../model/cloud/ServiceCallDefinition.java      |  17 +-
 .../apache/camel/util/function/Suppliers.java   |   5 +-
 .../blueprint/CamelContextFactoryBean.java      |  11 +
 .../camel/cdi/xml/CamelContextFactoryBean.java  |  12 +
 .../xml/AbstractCamelContextFactoryBean.java    |  14 +-
 .../hystrix/processor/HystrixConstants.java     |   1 +
 .../processor/HystrixProcessorFactory.java      | 220 +++++-----
 .../HystrixHierarchicalConfigTest.java          | 134 ++++++
 .../processor/HystrixRouteConfigTest.java       |   1 +
 ...SpringHystrixRouteConfigMaximumSizeTest.java |   2 +
 .../SpringHystrixRouteConfigRefTest.java        |   2 +
 .../processor/SpringHystrixRouteConfigTest.java |   2 +
 .../SpringHystrixRouteFallbackTest.java         |   2 +
 ...pringHystrixRouteHierarchicalConfigTest.java |  68 +++
 .../processor/SpringHystrixRouteOkTest.java     |   2 +
 ...SpringHystrixRouteHierarchicalConfigTest.xml |  51 +++
 .../camel/spring/CamelContextFactoryBean.java   |  11 +
 .../spring/handler/CamelNamespaceHandler.java   |   5 +-
 .../springboot/HystrixAutoConfiguration.java    |  59 +++
 .../springboot/HystrixConfiguration.java        |  27 ++
 .../main/resources/META-INF/spring.factories    |   1 +
 .../HystrixHierarchicalConfiguration.java       |  54 +++
 .../HystrixHierarchicalConfigurationTest.java   |  78 ++++
 .../src/test/resources/logback.xml              |  39 ++
 31 files changed, 1268 insertions(+), 520 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/pom.xml
----------------------------------------------------------------------
diff --git a/camel-core/pom.xml b/camel-core/pom.xml
index b9f6430..2466dba 100644
--- a/camel-core/pom.xml
+++ b/camel-core/pom.xml
@@ -196,6 +196,11 @@
       <version>${xml-resolver-version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>com.bazaarvoice.jolt</groupId>
+      <artifactId>jolt-core</artifactId>
+      <version>0.0.23</version>
+    </dependency>
 
   </dependencies>
 

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc
----------------------------------------------------------------------
diff --git a/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc b/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc
index ca061db..69df9c6 100644
--- a/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc
+++ b/camel-core/src/main/docs/eips/hystrixConfiguration-eip.adoc
@@ -8,36 +8,36 @@ The Hystrix Configuration EIP supports 31 options which are listed below:
 [width="100%",cols="3,1m,6",options="header"]
 |=======================================================================
 | Name | Java Type | Description
-| groupKey | String | Sets the group key to use. The default value is CamelHystrix.
-| threadPoolKey | String | Sets the thread pool key to use. Will by default use the same value as groupKey has been configured to use.
-| circuitBreakerEnabled | Boolean | Whether to use a HystrixCircuitBreaker or not. If false no circuit-breaker logic will be used and all requests permitted. This is similar in effect to circuitBreakerForceClosed() except that continues tracking metrics and knowing whether it should be open/closed this property results in not even instantiating a circuit-breaker.
-| circuitBreakerErrorThresholdPercentage | Integer | Error percentage threshold (as whole number such as 50) at which point the circuit breaker will trip open and reject requests. It will stay tripped for the duration defined in circuitBreakerSleepWindowInMilliseconds; The error percentage this is compared against comes from HystrixCommandMetrics.getHealthCounts().
-| circuitBreakerForceClosed | Boolean | If true the HystrixCircuitBreakerallowRequest() will always return true to allow requests regardless of the error percentage from HystrixCommandMetrics.getHealthCounts(). The circuitBreakerForceOpen() property takes precedence so if it set to true this property does nothing.
-| circuitBreakerForceOpen | Boolean | If true the HystrixCircuitBreaker.allowRequest() will always return false causing the circuit to be open (tripped) and reject all requests. This property takes precedence over circuitBreakerForceClosed();
-| circuitBreakerRequestVolumeThreshold | Integer | Minimum number of requests in the metricsRollingStatisticalWindowInMilliseconds() that must exist before the HystrixCircuitBreaker will trip. If below this number the circuit will not trip regardless of error percentage.
-| circuitBreakerSleepWindowInMilliseconds | Integer | The time in milliseconds after a HystrixCircuitBreaker trips open that it should wait before trying requests again.
-| executionIsolationSemaphoreMaxConcurrentRequests | Integer | Number of concurrent requests permitted to HystrixCommand.run(). Requests beyond the concurrent limit will be rejected. Applicable only when executionIsolationStrategy == SEMAPHORE.
-| executionIsolationStrategy | String | What isolation strategy HystrixCommand.run() will be executed with. If THREAD then it will be executed on a separate thread and concurrent requests limited by the number of threads in the thread-pool. If SEMAPHORE then it will be executed on the calling thread and concurrent requests limited by the semaphore count.
-| executionIsolationThreadInterruptOnTimeout | Boolean | Whether the execution thread should attempt an interrupt (using link Futurecancel) when a thread times out. Applicable only when executionIsolationStrategy() == THREAD.
-| executionTimeoutInMilliseconds | Integer | Time in milliseconds at which point the command will timeout and halt execution. If link executionIsolationThreadInterruptOnTimeout == true and the command is thread-isolated the executing thread will be interrupted. If the command is semaphore-isolated and a HystrixObservableCommand that command will get unsubscribed.
-| executionTimeoutEnabled | Boolean | Whether the timeout mechanism is enabled for this command
-| fallbackIsolationSemaphoreMaxConcurrentRequests | Integer | Number of concurrent requests permitted to HystrixCommand.getFallback(). Requests beyond the concurrent limit will fail-fast and not attempt retrieving a fallback.
-| fallbackEnabled | Boolean | Whether HystrixCommand.getFallback() should be attempted when failure occurs.
-| metricsHealthSnapshotIntervalInMilliseconds | Integer | Time in milliseconds to wait between allowing health snapshots to be taken that calculate success and error percentages and affect HystrixCircuitBreaker.isOpen() status. On high-volume circuits the continual calculation of error percentage can become CPU intensive thus this controls how often it is calculated.
-| metricsRollingPercentileBucketSize | Integer | Maximum number of values stored in each bucket of the rolling percentile. This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
-| metricsRollingPercentileEnabled | Boolean | Whether percentile metrics should be captured using HystrixRollingPercentile inside HystrixCommandMetrics.
-| metricsRollingPercentileWindowInMilliseconds | Integer | Duration of percentile rolling window in milliseconds. This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
-| metricsRollingPercentileWindowBuckets | Integer | Number of buckets the rolling percentile window is broken into. This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
-| metricsRollingStatisticalWindowInMilliseconds | Integer | This property sets the duration of the statistical rolling window in milliseconds. This is how long metrics are kept for the thread pool. The window is divided into buckets and rolls by those increments.
-| metricsRollingStatisticalWindowBuckets | Integer | Number of buckets the rolling statistical window is broken into. This is passed into HystrixRollingNumber inside HystrixCommandMetrics.
-| requestLogEnabled | Boolean | Whether HystrixCommand execution and events should be logged to HystrixRequestLog.
-| corePoolSize | Integer | Core thread-pool size that gets passed to link java.util.concurrent.ThreadPoolExecutorsetCorePoolSize(int)
-| maximumSize | Integer | Maximum thread-pool size that gets passed to link ThreadPoolExecutorsetMaximumPoolSize(int). This is the maximum amount of concurrency that can be supported without starting to reject HystrixCommands. Please note that this setting only takes effect if you also set allowMaximumSizeToDivergeFromCoreSize
-| keepAliveTime | Integer | Keep-alive time in minutes that gets passed to link ThreadPoolExecutorsetKeepAliveTime(long TimeUnit)
-| maxQueueSize | Integer | Max queue size that gets passed to BlockingQueue in HystrixConcurrencyStrategy.getBlockingQueue(int) This should only affect the instantiation of a threadpool - it is not eliglible to change a queue size on the fly. For that use queueSizeRejectionThreshold().
-| queueSizeRejectionThreshold | Integer | Queue size rejection threshold is an artificial max size at which rejections will occur even if link maxQueueSize has not been reached. This is done because the link maxQueueSize of a BlockingQueue can not be dynamically changed and we want to support dynamically changing the queue size that affects rejections. This is used by HystrixCommand when queuing a thread for execution.
-| threadPoolRollingNumberStatisticalWindowInMilliseconds | Integer | Duration of statistical rolling window in milliseconds. This is passed into HystrixRollingNumber inside each HystrixThreadPoolMetrics instance.
-| threadPoolRollingNumberStatisticalWindowBuckets | Integer | Number of buckets the rolling statistical window is broken into. This is passed into HystrixRollingNumber inside each HystrixThreadPoolMetrics instance.
-| allowMaximumSizeToDivergeFromCoreSize | Boolean | Allows the configuration for maximumSize to take effect. That value can then be equal to or higher than coreSize
+| groupKey | String | 
+| threadPoolKey | String | 
+| circuitBreakerEnabled | Boolean | 
+| circuitBreakerErrorThresholdPercentage | Integer | 
+| circuitBreakerForceClosed | Boolean | 
+| circuitBreakerForceOpen | Boolean | 
+| circuitBreakerRequestVolumeThreshold | Integer | 
+| circuitBreakerSleepWindowInMilliseconds | Integer | 
+| executionIsolationSemaphoreMaxConcurrentRequests | Integer | 
+| executionIsolationStrategy | String | 
+| executionIsolationThreadInterruptOnTimeout | Boolean | 
+| executionTimeoutInMilliseconds | Integer | 
+| executionTimeoutEnabled | Boolean | 
+| fallbackIsolationSemaphoreMaxConcurrentRequests | Integer | 
+| fallbackEnabled | Boolean | 
+| metricsHealthSnapshotIntervalInMilliseconds | Integer | 
+| metricsRollingPercentileBucketSize | Integer | 
+| metricsRollingPercentileEnabled | Boolean | 
+| metricsRollingPercentileWindowInMilliseconds | Integer | 
+| metricsRollingPercentileWindowBuckets | Integer | 
+| metricsRollingStatisticalWindowInMilliseconds | Integer | 
+| metricsRollingStatisticalWindowBuckets | Integer | 
+| requestLogEnabled | Boolean | 
+| corePoolSize | Integer | 
+| maximumSize | Integer | 
+| keepAliveTime | Integer | 
+| maxQueueSize | Integer | 
+| queueSizeRejectionThreshold | Integer | 
+| threadPoolRollingNumberStatisticalWindowInMilliseconds | Integer | 
+| threadPoolRollingNumberStatisticalWindowBuckets | Integer | 
+| allowMaximumSizeToDivergeFromCoreSize | Boolean | 
 |=======================================================================
 // eip options: END

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/src/main/java/org/apache/camel/CamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/CamelContext.java b/camel-core/src/main/java/org/apache/camel/CamelContext.java
index a8bc8ef..1d5be88 100644
--- a/camel-core/src/main/java/org/apache/camel/CamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/CamelContext.java
@@ -31,6 +31,7 @@ import org.apache.camel.api.management.mbean.ManagedRouteMBean;
 import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.catalog.RuntimeCamelCatalog;
 import org.apache.camel.model.DataFormatDefinition;
+import org.apache.camel.model.HystrixConfigurationDefinition;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RoutesDefinition;
@@ -605,6 +606,37 @@ public interface CamelContext extends SuspendableService, RuntimeConfiguration {
     void addServiceCallConfiguration(String serviceName, ServiceCallConfigurationDefinition configuration);
 
     /**
+     * Gets the Hystrix configuration by the given name. If no name is given
+     * the default configuration is returned, see <tt>setHystrixConfiguration</tt>
+     *
+     * @param id id of the configuration, or <tt>null</tt> to return the default configuration
+     * @return the configuration, or <tt>null</tt> if no configuration has been registered
+     */
+    HystrixConfigurationDefinition getHystrixConfiguration(String id);
+
+    /**
+     * Sets the default Hystrix configuration
+     *
+     * @param configuration the configuration
+     */
+    void setHystrixConfiguration(HystrixConfigurationDefinition configuration);
+
+    /**
+     * Sets the Hystrix configurations
+     *
+     * @param configurations the configuration list
+     */
+    void setHystrixConfigurations(List<HystrixConfigurationDefinition> configurations);
+
+    /**
+     * Adds the Hystrix configuration
+     *
+     * @param id name of the configuration
+     * @param configuration the configuration
+     */
+    void addHystrixConfiguration(String id, HystrixConfigurationDefinition configuration);
+
+    /**
      * Returns the order in which the route inputs was started.
      * <p/>
      * The order may not be according to the startupOrder defined on the route.

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
index 5df4dd8..a171645 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultCamelContext.java
@@ -100,6 +100,7 @@ import org.apache.camel.management.JmxSystemPropertyKeys;
 import org.apache.camel.management.ManagementStrategyFactory;
 import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.FromDefinition;
+import org.apache.camel.model.HystrixConfigurationDefinition;
 import org.apache.camel.model.ModelCamelContext;
 import org.apache.camel.model.ModelHelper;
 import org.apache.camel.model.ProcessorDefinition;
@@ -226,6 +227,7 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
     private final List<RestDefinition> restDefinitions = new ArrayList<RestDefinition>();
     private Map<String, RestConfiguration> restConfigurations = new ConcurrentHashMap<>();
     private Map<String, ServiceCallConfigurationDefinition> serviceCallConfigurations = new ConcurrentHashMap<>();
+    private Map<String, HystrixConfigurationDefinition> hystrixConfigurations = new ConcurrentHashMap<>();
     private RestRegistry restRegistry = new DefaultRestRegistry();
     private List<InterceptStrategy> interceptStrategies = new ArrayList<InterceptStrategy>();
     private List<RoutePolicyFactory> routePolicyFactories = new ArrayList<RoutePolicyFactory>();
@@ -2617,6 +2619,34 @@ public class DefaultCamelContext extends ServiceSupport implements ModelCamelCon
         serviceCallConfigurations.put(serviceName, configuration);
     }
 
+    @Override
+    public HystrixConfigurationDefinition getHystrixConfiguration(String id) {
+        if (id == null) {
+            id = "";
+        }
+
+        return hystrixConfigurations.get(id);
+    }
+
+    @Override
+    public void setHystrixConfiguration(HystrixConfigurationDefinition configuration) {
+        hystrixConfigurations.put("", configuration);
+    }
+
+    @Override
+    public void setHystrixConfigurations(List<HystrixConfigurationDefinition> configurations) {
+        if (configurations != null) {
+            for (HystrixConfigurationDefinition configuration : configurations) {
+                hystrixConfigurations.put(configuration.getId(), configuration);
+            }
+        }
+    }
+
+    @Override
+    public void addHystrixConfiguration(String id, HystrixConfigurationDefinition configuration) {
+        hystrixConfigurations.put(id, configuration);
+    }
+
     public List<InterceptStrategy> getInterceptStrategies() {
         return interceptStrategies;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/src/main/java/org/apache/camel/impl/TypedProcessorFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/TypedProcessorFactory.java b/camel-core/src/main/java/org/apache/camel/impl/TypedProcessorFactory.java
new file mode 100644
index 0000000..f0aa1b8
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/TypedProcessorFactory.java
@@ -0,0 +1,57 @@
+/**
+ * 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.impl;
+
+import org.apache.camel.Processor;
+import org.apache.camel.model.ProcessorDefinition;
+import org.apache.camel.spi.ProcessorFactory;
+import org.apache.camel.spi.RouteContext;
+
+public class TypedProcessorFactory<T extends ProcessorDefinition<T>> implements ProcessorFactory {
+    private final Class<T> type;
+
+    protected TypedProcessorFactory(Class<T> type) {
+        this.type = type;
+    }
+
+    @Override
+    public Processor createChildProcessor(RouteContext routeContext, ProcessorDefinition<?> definition, boolean mandatory) throws Exception {
+        if (definition != null && type.isInstance(definition)) {
+            return doCreateChildProcessor(routeContext, type.cast(definition), mandatory);
+        }
+
+        return null;
+    }
+
+    @Override
+    public Processor createProcessor(RouteContext routeContext, ProcessorDefinition<?> definition) throws Exception {
+        if (definition != null && type.isInstance(definition)) {
+            return doCreateProcessor(routeContext, type.cast(definition));
+        }
+
+        return null;
+    }
+
+
+    protected Processor doCreateChildProcessor(RouteContext routeContext, T definition, boolean mandatory) throws Exception {
+        return null;
+    }
+
+    public Processor doCreateProcessor(RouteContext routeContext, T definition) throws Exception {
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationCommon.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationCommon.java b/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationCommon.java
new file mode 100644
index 0000000..fa91fff
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationCommon.java
@@ -0,0 +1,374 @@
+/**
+ * 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.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+import org.apache.camel.spi.Metadata;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class HystrixConfigurationCommon extends IdentifiedType {
+
+    @XmlAttribute @Metadata(defaultValue = "CamelHystrix")
+    private String groupKey;
+    @XmlAttribute @Metadata(defaultValue = "CamelHystrix")
+    private String threadPoolKey;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "true")
+    private Boolean circuitBreakerEnabled;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "50")
+    private Integer circuitBreakerErrorThresholdPercentage;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "true")
+    private Boolean circuitBreakerForceClosed;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "false")
+    private Boolean circuitBreakerForceOpen;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "20")
+    private Integer circuitBreakerRequestVolumeThreshold;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "5000")
+    private Integer circuitBreakerSleepWindowInMilliseconds;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "20")
+    private Integer executionIsolationSemaphoreMaxConcurrentRequests;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "THREAD", enums = "THREAD,SEMAPHORE")
+    private String executionIsolationStrategy;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "true")
+    private Boolean executionIsolationThreadInterruptOnTimeout;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "1000")
+    private Integer executionTimeoutInMilliseconds;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "true")
+    private Boolean executionTimeoutEnabled;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "10")
+    private Integer fallbackIsolationSemaphoreMaxConcurrentRequests;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "true")
+    private Boolean fallbackEnabled;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "500")
+    private Integer metricsHealthSnapshotIntervalInMilliseconds;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "10")
+    private Integer metricsRollingPercentileBucketSize;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "true")
+    private Boolean metricsRollingPercentileEnabled;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "10000")
+    private Integer metricsRollingPercentileWindowInMilliseconds;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "6")
+    private Integer metricsRollingPercentileWindowBuckets;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "10000")
+    private Integer metricsRollingStatisticalWindowInMilliseconds;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "10")
+    private Integer metricsRollingStatisticalWindowBuckets;
+    @XmlAttribute
+    @Metadata(label = "command", defaultValue = "true")
+    private Boolean requestLogEnabled;
+
+    // thread-pool
+
+    @XmlAttribute
+    @Metadata(label = "threadpool", defaultValue = "10")
+    private Integer corePoolSize;
+    @XmlAttribute
+    @Metadata(label = "threadpool", defaultValue = "10")
+    private Integer maximumSize;
+    @XmlAttribute
+    @Metadata(label = "threadpool", defaultValue = "1")
+    private Integer keepAliveTime;
+    @XmlAttribute
+    @Metadata(label = "threadpool", defaultValue = "-1")
+    private Integer maxQueueSize;
+    @XmlAttribute
+    @Metadata(label = "threadpool", defaultValue = "5")
+    private Integer queueSizeRejectionThreshold;
+    @XmlAttribute
+    @Metadata(label = "threadpool", defaultValue = "10000")
+    private Integer threadPoolRollingNumberStatisticalWindowInMilliseconds;
+    @XmlAttribute
+    @Metadata(label = "threadpool", defaultValue = "10")
+    private Integer threadPoolRollingNumberStatisticalWindowBuckets;
+    @XmlAttribute
+    @Metadata(label = "threadpool", defaultValue = "false")
+    private Boolean allowMaximumSizeToDivergeFromCoreSize;
+
+
+    // Getter/Setter
+    // -------------------------------------------------------------------------
+
+    public String getGroupKey() {
+        return groupKey;
+    }
+
+    public void setGroupKey(String groupKey) {
+        this.groupKey = groupKey;
+    }
+
+    public String getThreadPoolKey() {
+        return threadPoolKey;
+    }
+
+    public void setThreadPoolKey(String threadPoolKey) {
+        this.threadPoolKey = threadPoolKey;
+    }
+
+    public Boolean getCircuitBreakerEnabled() {
+        return circuitBreakerEnabled;
+    }
+
+    public void setCircuitBreakerEnabled(Boolean circuitBreakerEnabled) {
+        this.circuitBreakerEnabled = circuitBreakerEnabled;
+    }
+
+    public Integer getCircuitBreakerErrorThresholdPercentage() {
+        return circuitBreakerErrorThresholdPercentage;
+    }
+
+    public void setCircuitBreakerErrorThresholdPercentage(Integer circuitBreakerErrorThresholdPercentage) {
+        this.circuitBreakerErrorThresholdPercentage = circuitBreakerErrorThresholdPercentage;
+    }
+
+    public Boolean getCircuitBreakerForceClosed() {
+        return circuitBreakerForceClosed;
+    }
+
+    public void setCircuitBreakerForceClosed(Boolean circuitBreakerForceClosed) {
+        this.circuitBreakerForceClosed = circuitBreakerForceClosed;
+    }
+
+    public Boolean getCircuitBreakerForceOpen() {
+        return circuitBreakerForceOpen;
+    }
+
+    public void setCircuitBreakerForceOpen(Boolean circuitBreakerForceOpen) {
+        this.circuitBreakerForceOpen = circuitBreakerForceOpen;
+    }
+
+    public Integer getCircuitBreakerRequestVolumeThreshold() {
+        return circuitBreakerRequestVolumeThreshold;
+    }
+
+    public void setCircuitBreakerRequestVolumeThreshold(Integer circuitBreakerRequestVolumeThreshold) {
+        this.circuitBreakerRequestVolumeThreshold = circuitBreakerRequestVolumeThreshold;
+    }
+
+    public Integer getCircuitBreakerSleepWindowInMilliseconds() {
+        return circuitBreakerSleepWindowInMilliseconds;
+    }
+
+    public void setCircuitBreakerSleepWindowInMilliseconds(Integer circuitBreakerSleepWindowInMilliseconds) {
+        this.circuitBreakerSleepWindowInMilliseconds = circuitBreakerSleepWindowInMilliseconds;
+    }
+
+    public Integer getExecutionIsolationSemaphoreMaxConcurrentRequests() {
+        return executionIsolationSemaphoreMaxConcurrentRequests;
+    }
+
+    public void setExecutionIsolationSemaphoreMaxConcurrentRequests(Integer executionIsolationSemaphoreMaxConcurrentRequests) {
+        this.executionIsolationSemaphoreMaxConcurrentRequests = executionIsolationSemaphoreMaxConcurrentRequests;
+    }
+
+    public String getExecutionIsolationStrategy() {
+        return executionIsolationStrategy;
+    }
+
+    public void setExecutionIsolationStrategy(String executionIsolationStrategy) {
+        this.executionIsolationStrategy = executionIsolationStrategy;
+    }
+
+    public Boolean getExecutionIsolationThreadInterruptOnTimeout() {
+        return executionIsolationThreadInterruptOnTimeout;
+    }
+
+    public void setExecutionIsolationThreadInterruptOnTimeout(Boolean executionIsolationThreadInterruptOnTimeout) {
+        this.executionIsolationThreadInterruptOnTimeout = executionIsolationThreadInterruptOnTimeout;
+    }
+
+    public Integer getExecutionTimeoutInMilliseconds() {
+        return executionTimeoutInMilliseconds;
+    }
+
+    public void setExecutionTimeoutInMilliseconds(Integer executionTimeoutInMilliseconds) {
+        this.executionTimeoutInMilliseconds = executionTimeoutInMilliseconds;
+    }
+
+    public Boolean getExecutionTimeoutEnabled() {
+        return executionTimeoutEnabled;
+    }
+
+    public void setExecutionTimeoutEnabled(Boolean executionTimeoutEnabled) {
+        this.executionTimeoutEnabled = executionTimeoutEnabled;
+    }
+
+    public Integer getFallbackIsolationSemaphoreMaxConcurrentRequests() {
+        return fallbackIsolationSemaphoreMaxConcurrentRequests;
+    }
+
+    public void setFallbackIsolationSemaphoreMaxConcurrentRequests(Integer fallbackIsolationSemaphoreMaxConcurrentRequests) {
+        this.fallbackIsolationSemaphoreMaxConcurrentRequests = fallbackIsolationSemaphoreMaxConcurrentRequests;
+    }
+
+    public Boolean getFallbackEnabled() {
+        return fallbackEnabled;
+    }
+
+    public void setFallbackEnabled(Boolean fallbackEnabled) {
+        this.fallbackEnabled = fallbackEnabled;
+    }
+
+    public Integer getMetricsHealthSnapshotIntervalInMilliseconds() {
+        return metricsHealthSnapshotIntervalInMilliseconds;
+    }
+
+    public void setMetricsHealthSnapshotIntervalInMilliseconds(Integer metricsHealthSnapshotIntervalInMilliseconds) {
+        this.metricsHealthSnapshotIntervalInMilliseconds = metricsHealthSnapshotIntervalInMilliseconds;
+    }
+
+    public Integer getMetricsRollingPercentileBucketSize() {
+        return metricsRollingPercentileBucketSize;
+    }
+
+    public void setMetricsRollingPercentileBucketSize(Integer metricsRollingPercentileBucketSize) {
+        this.metricsRollingPercentileBucketSize = metricsRollingPercentileBucketSize;
+    }
+
+    public Boolean getMetricsRollingPercentileEnabled() {
+        return metricsRollingPercentileEnabled;
+    }
+
+    public void setMetricsRollingPercentileEnabled(Boolean metricsRollingPercentileEnabled) {
+        this.metricsRollingPercentileEnabled = metricsRollingPercentileEnabled;
+    }
+
+    public Integer getMetricsRollingPercentileWindowInMilliseconds() {
+        return metricsRollingPercentileWindowInMilliseconds;
+    }
+
+    public void setMetricsRollingPercentileWindowInMilliseconds(Integer metricsRollingPercentileWindowInMilliseconds) {
+        this.metricsRollingPercentileWindowInMilliseconds = metricsRollingPercentileWindowInMilliseconds;
+    }
+
+    public Integer getMetricsRollingPercentileWindowBuckets() {
+        return metricsRollingPercentileWindowBuckets;
+    }
+
+    public void setMetricsRollingPercentileWindowBuckets(Integer metricsRollingPercentileWindowBuckets) {
+        this.metricsRollingPercentileWindowBuckets = metricsRollingPercentileWindowBuckets;
+    }
+
+    public Integer getMetricsRollingStatisticalWindowInMilliseconds() {
+        return metricsRollingStatisticalWindowInMilliseconds;
+    }
+
+    public void setMetricsRollingStatisticalWindowInMilliseconds(Integer metricsRollingStatisticalWindowInMilliseconds) {
+        this.metricsRollingStatisticalWindowInMilliseconds = metricsRollingStatisticalWindowInMilliseconds;
+    }
+
+    public Integer getMetricsRollingStatisticalWindowBuckets() {
+        return metricsRollingStatisticalWindowBuckets;
+    }
+
+    public void setMetricsRollingStatisticalWindowBuckets(Integer metricsRollingStatisticalWindowBuckets) {
+        this.metricsRollingStatisticalWindowBuckets = metricsRollingStatisticalWindowBuckets;
+    }
+
+    public Boolean getRequestLogEnabled() {
+        return requestLogEnabled;
+    }
+
+    public void setRequestLogEnabled(Boolean requestLogEnabled) {
+        this.requestLogEnabled = requestLogEnabled;
+    }
+
+    public Integer getCorePoolSize() {
+        return corePoolSize;
+    }
+
+    public void setCorePoolSize(Integer corePoolSize) {
+        this.corePoolSize = corePoolSize;
+    }
+
+    public Integer getMaximumSize() {
+        return maximumSize;
+    }
+
+    public void setMaximumSize(Integer maximumSize) {
+        this.maximumSize = maximumSize;
+    }
+
+    public Integer getKeepAliveTime() {
+        return keepAliveTime;
+    }
+
+    public void setKeepAliveTime(Integer keepAliveTime) {
+        this.keepAliveTime = keepAliveTime;
+    }
+
+    public Integer getMaxQueueSize() {
+        return maxQueueSize;
+    }
+
+    public void setMaxQueueSize(Integer maxQueueSize) {
+        this.maxQueueSize = maxQueueSize;
+    }
+
+    public Integer getQueueSizeRejectionThreshold() {
+        return queueSizeRejectionThreshold;
+    }
+
+    public void setQueueSizeRejectionThreshold(Integer queueSizeRejectionThreshold) {
+        this.queueSizeRejectionThreshold = queueSizeRejectionThreshold;
+    }
+
+    public Integer getThreadPoolRollingNumberStatisticalWindowInMilliseconds() {
+        return threadPoolRollingNumberStatisticalWindowInMilliseconds;
+    }
+
+    public void setThreadPoolRollingNumberStatisticalWindowInMilliseconds(Integer threadPoolRollingNumberStatisticalWindowInMilliseconds) {
+        this.threadPoolRollingNumberStatisticalWindowInMilliseconds = threadPoolRollingNumberStatisticalWindowInMilliseconds;
+    }
+
+    public Integer getThreadPoolRollingNumberStatisticalWindowBuckets() {
+        return threadPoolRollingNumberStatisticalWindowBuckets;
+    }
+
+    public void setThreadPoolRollingNumberStatisticalWindowBuckets(Integer threadPoolRollingNumberStatisticalWindowBuckets) {
+        this.threadPoolRollingNumberStatisticalWindowBuckets = threadPoolRollingNumberStatisticalWindowBuckets;
+    }
+
+    public Boolean getAllowMaximumSizeToDivergeFromCoreSize() {
+        return allowMaximumSizeToDivergeFromCoreSize;
+    }
+
+    public void setAllowMaximumSizeToDivergeFromCoreSize(Boolean allowMaximumSizeToDivergeFromCoreSize) {
+        this.allowMaximumSizeToDivergeFromCoreSize = allowMaximumSizeToDivergeFromCoreSize;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationDefinition.java b/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationDefinition.java
index ae72ec3..b8bd4bc 100644
--- a/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/HystrixConfigurationDefinition.java
@@ -22,7 +22,6 @@ import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlTransient;
 
@@ -34,106 +33,12 @@ import org.apache.camel.spi.Metadata;
 @Metadata(label = "eip,routing,circuitbreaker")
 @XmlRootElement(name = "hystrixConfiguration")
 @XmlAccessorType(XmlAccessType.FIELD)
-public class HystrixConfigurationDefinition extends IdentifiedType {
+public class HystrixConfigurationDefinition extends HystrixConfigurationCommon {
 
     public static final String DEFAULT_GROUP_KEY = "CamelHystrix";
 
     @XmlTransient
     private HystrixDefinition parent;
-    @XmlAttribute @Metadata(defaultValue = "CamelHystrix")
-    private String groupKey;
-    @XmlAttribute @Metadata(defaultValue = "CamelHystrix")
-    private String threadPoolKey;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "true")
-    private Boolean circuitBreakerEnabled;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "50")
-    private Integer circuitBreakerErrorThresholdPercentage;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "true")
-    private Boolean circuitBreakerForceClosed;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "false")
-    private Boolean circuitBreakerForceOpen;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "20")
-    private Integer circuitBreakerRequestVolumeThreshold;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "5000")
-    private Integer circuitBreakerSleepWindowInMilliseconds;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "20")
-    private Integer executionIsolationSemaphoreMaxConcurrentRequests;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "THREAD", enums = "THREAD,SEMAPHORE")
-    private String executionIsolationStrategy;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "true")
-    private Boolean executionIsolationThreadInterruptOnTimeout;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "1000")
-    private Integer executionTimeoutInMilliseconds;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "true")
-    private Boolean executionTimeoutEnabled;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "10")
-    private Integer fallbackIsolationSemaphoreMaxConcurrentRequests;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "true")
-    private Boolean fallbackEnabled;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "500")
-    private Integer metricsHealthSnapshotIntervalInMilliseconds;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "10")
-    private Integer metricsRollingPercentileBucketSize;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "true")
-    private Boolean metricsRollingPercentileEnabled;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "10000")
-    private Integer metricsRollingPercentileWindowInMilliseconds;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "6")
-    private Integer metricsRollingPercentileWindowBuckets;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "10000")
-    private Integer metricsRollingStatisticalWindowInMilliseconds;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "10")
-    private Integer metricsRollingStatisticalWindowBuckets;
-    @XmlAttribute
-    @Metadata(label = "command", defaultValue = "true")
-    private Boolean requestLogEnabled;
-
-    // thread-pool
-
-    @XmlAttribute
-    @Metadata(label = "threadpool", defaultValue = "10")
-    private Integer corePoolSize;
-    @XmlAttribute
-    @Metadata(label = "threadpool", defaultValue = "10")
-    private Integer maximumSize;
-    @XmlAttribute
-    @Metadata(label = "threadpool", defaultValue = "1")
-    private Integer keepAliveTime;
-    @XmlAttribute
-    @Metadata(label = "threadpool", defaultValue = "-1")
-    private Integer maxQueueSize;
-    @XmlAttribute
-    @Metadata(label = "threadpool", defaultValue = "5")
-    private Integer queueSizeRejectionThreshold;
-    @XmlAttribute
-    @Metadata(label = "threadpool", defaultValue = "10000")
-    private Integer threadPoolRollingNumberStatisticalWindowInMilliseconds;
-    @XmlAttribute
-    @Metadata(label = "threadpool", defaultValue = "10")
-    private Integer threadPoolRollingNumberStatisticalWindowBuckets;
-    @XmlAttribute
-    @Metadata(label = "threadpool", defaultValue = "false")
-    private Boolean allowMaximumSizeToDivergeFromCoreSize;
 
     public HystrixConfigurationDefinition() {
     }
@@ -142,257 +47,6 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
         this.parent = parent;
     }
 
-    // Getter/Setter
-    // -------------------------------------------------------------------------
-
-    public String getGroupKey() {
-        return groupKey;
-    }
-
-    public void setGroupKey(String groupKey) {
-        this.groupKey = groupKey;
-    }
-
-    public String getThreadPoolKey() {
-        return threadPoolKey;
-    }
-
-    public void setThreadPoolKey(String threadPoolKey) {
-        this.threadPoolKey = threadPoolKey;
-    }
-
-    public Boolean getCircuitBreakerEnabled() {
-        return circuitBreakerEnabled;
-    }
-
-    public void setCircuitBreakerEnabled(Boolean circuitBreakerEnabled) {
-        this.circuitBreakerEnabled = circuitBreakerEnabled;
-    }
-
-    public Integer getCircuitBreakerErrorThresholdPercentage() {
-        return circuitBreakerErrorThresholdPercentage;
-    }
-
-    public void setCircuitBreakerErrorThresholdPercentage(Integer circuitBreakerErrorThresholdPercentage) {
-        this.circuitBreakerErrorThresholdPercentage = circuitBreakerErrorThresholdPercentage;
-    }
-
-    public Boolean getCircuitBreakerForceClosed() {
-        return circuitBreakerForceClosed;
-    }
-
-    public void setCircuitBreakerForceClosed(Boolean circuitBreakerForceClosed) {
-        this.circuitBreakerForceClosed = circuitBreakerForceClosed;
-    }
-
-    public Boolean getCircuitBreakerForceOpen() {
-        return circuitBreakerForceOpen;
-    }
-
-    public void setCircuitBreakerForceOpen(Boolean circuitBreakerForceOpen) {
-        this.circuitBreakerForceOpen = circuitBreakerForceOpen;
-    }
-
-    public Integer getCircuitBreakerRequestVolumeThreshold() {
-        return circuitBreakerRequestVolumeThreshold;
-    }
-
-    public void setCircuitBreakerRequestVolumeThreshold(Integer circuitBreakerRequestVolumeThreshold) {
-        this.circuitBreakerRequestVolumeThreshold = circuitBreakerRequestVolumeThreshold;
-    }
-
-    public Integer getCircuitBreakerSleepWindowInMilliseconds() {
-        return circuitBreakerSleepWindowInMilliseconds;
-    }
-
-    public void setCircuitBreakerSleepWindowInMilliseconds(Integer circuitBreakerSleepWindowInMilliseconds) {
-        this.circuitBreakerSleepWindowInMilliseconds = circuitBreakerSleepWindowInMilliseconds;
-    }
-
-    public Integer getExecutionIsolationSemaphoreMaxConcurrentRequests() {
-        return executionIsolationSemaphoreMaxConcurrentRequests;
-    }
-
-    public void setExecutionIsolationSemaphoreMaxConcurrentRequests(Integer executionIsolationSemaphoreMaxConcurrentRequests) {
-        this.executionIsolationSemaphoreMaxConcurrentRequests = executionIsolationSemaphoreMaxConcurrentRequests;
-    }
-
-    public String getExecutionIsolationStrategy() {
-        return executionIsolationStrategy;
-    }
-
-    public void setExecutionIsolationStrategy(String executionIsolationStrategy) {
-        this.executionIsolationStrategy = executionIsolationStrategy;
-    }
-
-    public Boolean getExecutionIsolationThreadInterruptOnTimeout() {
-        return executionIsolationThreadInterruptOnTimeout;
-    }
-
-    public void setExecutionIsolationThreadInterruptOnTimeout(Boolean executionIsolationThreadInterruptOnTimeout) {
-        this.executionIsolationThreadInterruptOnTimeout = executionIsolationThreadInterruptOnTimeout;
-    }
-
-    public Integer getExecutionTimeoutInMilliseconds() {
-        return executionTimeoutInMilliseconds;
-    }
-
-    public void setExecutionTimeoutInMilliseconds(Integer executionTimeoutInMilliseconds) {
-        this.executionTimeoutInMilliseconds = executionTimeoutInMilliseconds;
-    }
-
-    public Boolean getExecutionTimeoutEnabled() {
-        return executionTimeoutEnabled;
-    }
-
-    public void setExecutionTimeoutEnabled(Boolean executionTimeoutEnabled) {
-        this.executionTimeoutEnabled = executionTimeoutEnabled;
-    }
-
-    public Integer getFallbackIsolationSemaphoreMaxConcurrentRequests() {
-        return fallbackIsolationSemaphoreMaxConcurrentRequests;
-    }
-
-    public void setFallbackIsolationSemaphoreMaxConcurrentRequests(Integer fallbackIsolationSemaphoreMaxConcurrentRequests) {
-        this.fallbackIsolationSemaphoreMaxConcurrentRequests = fallbackIsolationSemaphoreMaxConcurrentRequests;
-    }
-
-    public Boolean getFallbackEnabled() {
-        return fallbackEnabled;
-    }
-
-    public void setFallbackEnabled(Boolean fallbackEnabled) {
-        this.fallbackEnabled = fallbackEnabled;
-    }
-
-    public Integer getMetricsHealthSnapshotIntervalInMilliseconds() {
-        return metricsHealthSnapshotIntervalInMilliseconds;
-    }
-
-    public void setMetricsHealthSnapshotIntervalInMilliseconds(Integer metricsHealthSnapshotIntervalInMilliseconds) {
-        this.metricsHealthSnapshotIntervalInMilliseconds = metricsHealthSnapshotIntervalInMilliseconds;
-    }
-
-    public Integer getMetricsRollingPercentileBucketSize() {
-        return metricsRollingPercentileBucketSize;
-    }
-
-    public void setMetricsRollingPercentileBucketSize(Integer metricsRollingPercentileBucketSize) {
-        this.metricsRollingPercentileBucketSize = metricsRollingPercentileBucketSize;
-    }
-
-    public Boolean getMetricsRollingPercentileEnabled() {
-        return metricsRollingPercentileEnabled;
-    }
-
-    public void setMetricsRollingPercentileEnabled(Boolean metricsRollingPercentileEnabled) {
-        this.metricsRollingPercentileEnabled = metricsRollingPercentileEnabled;
-    }
-
-    public Integer getMetricsRollingPercentileWindowInMilliseconds() {
-        return metricsRollingPercentileWindowInMilliseconds;
-    }
-
-    public void setMetricsRollingPercentileWindowInMilliseconds(Integer metricsRollingPercentileWindowInMilliseconds) {
-        this.metricsRollingPercentileWindowInMilliseconds = metricsRollingPercentileWindowInMilliseconds;
-    }
-
-    public Integer getMetricsRollingPercentileWindowBuckets() {
-        return metricsRollingPercentileWindowBuckets;
-    }
-
-    public void setMetricsRollingPercentileWindowBuckets(Integer metricsRollingPercentileWindowBuckets) {
-        this.metricsRollingPercentileWindowBuckets = metricsRollingPercentileWindowBuckets;
-    }
-
-    public Integer getMetricsRollingStatisticalWindowInMilliseconds() {
-        return metricsRollingStatisticalWindowInMilliseconds;
-    }
-
-    public void setMetricsRollingStatisticalWindowInMilliseconds(Integer metricsRollingStatisticalWindowInMilliseconds) {
-        this.metricsRollingStatisticalWindowInMilliseconds = metricsRollingStatisticalWindowInMilliseconds;
-    }
-
-    public Integer getMetricsRollingStatisticalWindowBuckets() {
-        return metricsRollingStatisticalWindowBuckets;
-    }
-
-    public void setMetricsRollingStatisticalWindowBuckets(Integer metricsRollingStatisticalWindowBuckets) {
-        this.metricsRollingStatisticalWindowBuckets = metricsRollingStatisticalWindowBuckets;
-    }
-
-    public Boolean getRequestLogEnabled() {
-        return requestLogEnabled;
-    }
-
-    public void setRequestLogEnabled(Boolean requestLogEnabled) {
-        this.requestLogEnabled = requestLogEnabled;
-    }
-
-    public Integer getCorePoolSize() {
-        return corePoolSize;
-    }
-
-    public void setCorePoolSize(Integer corePoolSize) {
-        this.corePoolSize = corePoolSize;
-    }
-
-    public Integer getMaximumSize() {
-        return maximumSize;
-    }
-
-    public void setMaximumSize(Integer maximumSize) {
-        this.maximumSize = maximumSize;
-    }
-
-    public Integer getKeepAliveTime() {
-        return keepAliveTime;
-    }
-
-    public void setKeepAliveTime(Integer keepAliveTime) {
-        this.keepAliveTime = keepAliveTime;
-    }
-
-    public Integer getMaxQueueSize() {
-        return maxQueueSize;
-    }
-
-    public void setMaxQueueSize(Integer maxQueueSize) {
-        this.maxQueueSize = maxQueueSize;
-    }
-
-    public Integer getQueueSizeRejectionThreshold() {
-        return queueSizeRejectionThreshold;
-    }
-
-    public void setQueueSizeRejectionThreshold(Integer queueSizeRejectionThreshold) {
-        this.queueSizeRejectionThreshold = queueSizeRejectionThreshold;
-    }
-
-    public Integer getThreadPoolRollingNumberStatisticalWindowInMilliseconds() {
-        return threadPoolRollingNumberStatisticalWindowInMilliseconds;
-    }
-
-    public void setThreadPoolRollingNumberStatisticalWindowInMilliseconds(Integer threadPoolRollingNumberStatisticalWindowInMilliseconds) {
-        this.threadPoolRollingNumberStatisticalWindowInMilliseconds = threadPoolRollingNumberStatisticalWindowInMilliseconds;
-    }
-
-    public Integer getThreadPoolRollingNumberStatisticalWindowBuckets() {
-        return threadPoolRollingNumberStatisticalWindowBuckets;
-    }
-
-    public void setThreadPoolRollingNumberStatisticalWindowBuckets(Integer threadPoolRollingNumberStatisticalWindowBuckets) {
-        this.threadPoolRollingNumberStatisticalWindowBuckets = threadPoolRollingNumberStatisticalWindowBuckets;
-    }
-
-    public Boolean getAllowMaximumSizeToDivergeFromCoreSize() {
-        return allowMaximumSizeToDivergeFromCoreSize;
-    }
-
-    public void setAllowMaximumSizeToDivergeFromCoreSize(Boolean allowMaximumSizeToDivergeFromCoreSize) {
-        this.allowMaximumSizeToDivergeFromCoreSize = allowMaximumSizeToDivergeFromCoreSize;
-    }
-
     // Fluent API
     // -------------------------------------------------------------------------
 
@@ -419,7 +73,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * should be open/closed, this property results in not even instantiating a circuit-breaker.
      */
     public HystrixConfigurationDefinition circuitBreakerEnabled(Boolean circuitBreakerEnabled) {
-        this.circuitBreakerEnabled = circuitBreakerEnabled;
+        setCircuitBreakerEnabled(circuitBreakerEnabled);
         return this;
     }
 
@@ -431,7 +85,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * The error percentage this is compared against comes from HystrixCommandMetrics.getHealthCounts().
      */
     public HystrixConfigurationDefinition circuitBreakerErrorThresholdPercentage(Integer circuitBreakerErrorThresholdPercentage) {
-        this.circuitBreakerErrorThresholdPercentage = circuitBreakerErrorThresholdPercentage;
+        setCircuitBreakerErrorThresholdPercentage(circuitBreakerErrorThresholdPercentage);
         return this;
     }
 
@@ -442,7 +96,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * The circuitBreakerForceOpen() property takes precedence so if it set to true this property does nothing.
      */
     public HystrixConfigurationDefinition circuitBreakerForceClosed(Boolean circuitBreakerForceClosed) {
-        this.circuitBreakerForceClosed = circuitBreakerForceClosed;
+        setCircuitBreakerForceClosed(circuitBreakerForceClosed);
         return this;
     }
 
@@ -452,7 +106,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * This property takes precedence over circuitBreakerForceClosed();
      */
     public HystrixConfigurationDefinition circuitBreakerForceOpen(Boolean circuitBreakerForceOpen) {
-        this.circuitBreakerForceOpen = circuitBreakerForceOpen;
+        setCircuitBreakerForceOpen(circuitBreakerForceOpen);
         return this;
     }
 
@@ -462,7 +116,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * If below this number the circuit will not trip regardless of error percentage.
      */
     public HystrixConfigurationDefinition circuitBreakerRequestVolumeThreshold(Integer circuitBreakerRequestVolumeThreshold) {
-        this.circuitBreakerRequestVolumeThreshold = circuitBreakerRequestVolumeThreshold;
+        setCircuitBreakerRequestVolumeThreshold(circuitBreakerRequestVolumeThreshold);
         return this;
     }
 
@@ -470,7 +124,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * The time in milliseconds after a HystrixCircuitBreaker trips open that it should wait before trying requests again.
      */
     public HystrixConfigurationDefinition circuitBreakerSleepWindowInMilliseconds(Integer circuitBreakerSleepWindowInMilliseconds) {
-        this.circuitBreakerSleepWindowInMilliseconds = circuitBreakerSleepWindowInMilliseconds;
+        setCircuitBreakerSleepWindowInMilliseconds(circuitBreakerSleepWindowInMilliseconds);
         return this;
     }
 
@@ -480,7 +134,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Applicable only when executionIsolationStrategy == SEMAPHORE.
      */
     public HystrixConfigurationDefinition executionIsolationSemaphoreMaxConcurrentRequests(Integer executionIsolationSemaphoreMaxConcurrentRequests) {
-        this.executionIsolationSemaphoreMaxConcurrentRequests = executionIsolationSemaphoreMaxConcurrentRequests;
+        setExecutionIsolationSemaphoreMaxConcurrentRequests(executionIsolationSemaphoreMaxConcurrentRequests);
         return this;
     }
 
@@ -492,7 +146,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * If SEMAPHORE then it will be executed on the calling thread and concurrent requests limited by the semaphore count.
      */
     public HystrixConfigurationDefinition executionIsolationStrategy(String executionIsolationStrategy) {
-        this.executionIsolationStrategy = executionIsolationStrategy;
+        setExecutionIsolationStrategy(executionIsolationStrategy);
         return this;
     }
 
@@ -502,7 +156,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Applicable only when executionIsolationStrategy() == THREAD.
      */
     public HystrixConfigurationDefinition executionIsolationThreadInterruptOnTimeout(Boolean executionIsolationThreadInterruptOnTimeout) {
-        this.executionIsolationThreadInterruptOnTimeout = executionIsolationThreadInterruptOnTimeout;
+        setExecutionIsolationThreadInterruptOnTimeout(executionIsolationThreadInterruptOnTimeout);
         return this;
     }
 
@@ -513,7 +167,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * If the command is semaphore-isolated and a HystrixObservableCommand, that command will get unsubscribed.
      */
     public HystrixConfigurationDefinition executionTimeoutInMilliseconds(Integer executionTimeoutInMilliseconds) {
-        this.executionTimeoutInMilliseconds = executionTimeoutInMilliseconds;
+        setExecutionTimeoutInMilliseconds(executionTimeoutInMilliseconds);
         return this;
     }
 
@@ -521,7 +175,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Whether the timeout mechanism is enabled for this command
      */
     public HystrixConfigurationDefinition executionTimeoutEnabled(Boolean executionTimeoutEnabled) {
-        this.executionTimeoutEnabled = executionTimeoutEnabled;
+        setExecutionTimeoutEnabled(executionTimeoutEnabled);
         return this;
     }
 
@@ -530,7 +184,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Requests beyond the concurrent limit will fail-fast and not attempt retrieving a fallback.
      */
     public HystrixConfigurationDefinition fallbackIsolationSemaphoreMaxConcurrentRequests(Integer fallbackIsolationSemaphoreMaxConcurrentRequests) {
-        this.fallbackIsolationSemaphoreMaxConcurrentRequests = fallbackIsolationSemaphoreMaxConcurrentRequests;
+        setFallbackIsolationSemaphoreMaxConcurrentRequests(fallbackIsolationSemaphoreMaxConcurrentRequests);
         return this;
     }
 
@@ -538,7 +192,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Whether HystrixCommand.getFallback() should be attempted when failure occurs.
      */
     public HystrixConfigurationDefinition fallbackEnabled(Boolean fallbackEnabled) {
-        this.fallbackEnabled = fallbackEnabled;
+        setFallbackEnabled(fallbackEnabled);
         return this;
     }
 
@@ -549,7 +203,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * On high-volume circuits the continual calculation of error percentage can become CPU intensive thus this controls how often it is calculated.
      */
     public HystrixConfigurationDefinition metricsHealthSnapshotIntervalInMilliseconds(Integer metricsHealthSnapshotIntervalInMilliseconds) {
-        this.metricsHealthSnapshotIntervalInMilliseconds = metricsHealthSnapshotIntervalInMilliseconds;
+        setMetricsHealthSnapshotIntervalInMilliseconds(metricsHealthSnapshotIntervalInMilliseconds);
         return this;
     }
 
@@ -558,7 +212,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
      */
     public HystrixConfigurationDefinition metricsRollingPercentileBucketSize(Integer metricsRollingPercentileBucketSize) {
-        this.metricsRollingPercentileBucketSize = metricsRollingPercentileBucketSize;
+        setMetricsRollingPercentileBucketSize(metricsRollingPercentileBucketSize);
         return this;
     }
 
@@ -566,7 +220,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Whether percentile metrics should be captured using HystrixRollingPercentile inside HystrixCommandMetrics.
      */
     public HystrixConfigurationDefinition metricsRollingPercentileEnabled(Boolean metricsRollingPercentileEnabled) {
-        this.metricsRollingPercentileEnabled = metricsRollingPercentileEnabled;
+        setMetricsRollingPercentileEnabled(metricsRollingPercentileEnabled);
         return this;
     }
 
@@ -575,7 +229,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
      */
     public HystrixConfigurationDefinition metricsRollingPercentileWindowInMilliseconds(Integer metricsRollingPercentileWindowInMilliseconds) {
-        this.metricsRollingPercentileWindowInMilliseconds = metricsRollingPercentileWindowInMilliseconds;
+        setMetricsRollingPercentileWindowInMilliseconds(metricsRollingPercentileWindowInMilliseconds);
         return this;
     }
 
@@ -584,7 +238,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * This is passed into HystrixRollingPercentile inside HystrixCommandMetrics.
      */
     public HystrixConfigurationDefinition metricsRollingPercentileWindowBuckets(Integer metricsRollingPercentileWindowBuckets) {
-        this.metricsRollingPercentileWindowBuckets = metricsRollingPercentileWindowBuckets;
+        setMetricsRollingPercentileWindowBuckets(metricsRollingPercentileWindowBuckets);
         return this;
     }
 
@@ -594,7 +248,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * The window is divided into buckets and \u201crolls\u201d by those increments.
      */
     public HystrixConfigurationDefinition metricsRollingStatisticalWindowInMilliseconds(Integer metricsRollingStatisticalWindowInMilliseconds) {
-        this.metricsRollingStatisticalWindowInMilliseconds = metricsRollingStatisticalWindowInMilliseconds;
+        setMetricsRollingStatisticalWindowInMilliseconds(metricsRollingStatisticalWindowInMilliseconds);
         return this;
     }
 
@@ -603,7 +257,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * This is passed into HystrixRollingNumber inside HystrixCommandMetrics.
      */
     public HystrixConfigurationDefinition metricsRollingStatisticalWindowBuckets(Integer metricsRollingStatisticalWindowBuckets) {
-        this.metricsRollingStatisticalWindowBuckets = metricsRollingStatisticalWindowBuckets;
+        setMetricsRollingStatisticalWindowBuckets(metricsRollingStatisticalWindowBuckets);
         return this;
     }
 
@@ -611,7 +265,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Whether HystrixCommand execution and events should be logged to HystrixRequestLog.
      */
     public HystrixConfigurationDefinition requestLogEnabled(Boolean requestLogEnabled) {
-        this.requestLogEnabled = requestLogEnabled;
+        setRequestLogEnabled(requestLogEnabled);
         return this;
     }
 
@@ -619,7 +273,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Core thread-pool size that gets passed to {@link java.util.concurrent.ThreadPoolExecutor#setCorePoolSize(int)}
      */
     public HystrixConfigurationDefinition corePoolSize(Integer corePoolSize) {
-        this.corePoolSize = corePoolSize;
+        setCorePoolSize(corePoolSize);
         return this;
     }
 
@@ -627,7 +281,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * Keep-alive time in minutes that gets passed to {@link ThreadPoolExecutor#setKeepAliveTime(long, TimeUnit)}
      */
     public HystrixConfigurationDefinition keepAliveTime(Integer keepAliveTime) {
-        this.keepAliveTime = keepAliveTime;
+        setKeepAliveTime(keepAliveTime);
         return this;
     }
 
@@ -638,17 +292,17 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * For that, use queueSizeRejectionThreshold().
      */
     public HystrixConfigurationDefinition maxQueueSize(Integer maxQueueSize) {
-        this.maxQueueSize = maxQueueSize;
+        setMaxQueueSize(maxQueueSize);
         return this;
     }
-    
+
     /**
      * Maximum thread-pool size that gets passed to {@link ThreadPoolExecutor#setMaximumPoolSize(int)}.
      * This is the maximum amount of concurrency that can be supported without starting to reject HystrixCommands.
      * Please note that this setting only takes effect if you also set allowMaximumSizeToDivergeFromCoreSize
      */
     public HystrixConfigurationDefinition maximumSize(Integer maximumSize) {
-        this.maximumSize = maximumSize;
+        setMaximumSize(maximumSize);
         return this;
     }
 
@@ -661,7 +315,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * This is used by HystrixCommand when queuing a thread for execution.
      */
     public HystrixConfigurationDefinition queueSizeRejectionThreshold(Integer queueSizeRejectionThreshold) {
-        this.queueSizeRejectionThreshold = queueSizeRejectionThreshold;
+        setQueueSizeRejectionThreshold(queueSizeRejectionThreshold);
         return this;
     }
 
@@ -670,7 +324,7 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * This is passed into HystrixRollingNumber inside each HystrixThreadPoolMetrics instance.
      */
     public HystrixConfigurationDefinition threadPoolRollingNumberStatisticalWindowInMilliseconds(Integer threadPoolRollingNumberStatisticalWindowInMilliseconds) {
-        this.threadPoolRollingNumberStatisticalWindowInMilliseconds = threadPoolRollingNumberStatisticalWindowInMilliseconds;
+        setThreadPoolRollingNumberStatisticalWindowInMilliseconds(threadPoolRollingNumberStatisticalWindowInMilliseconds);
         return this;
     }
 
@@ -679,15 +333,15 @@ public class HystrixConfigurationDefinition extends IdentifiedType {
      * This is passed into HystrixRollingNumber inside each HystrixThreadPoolMetrics instance.
      */
     public HystrixConfigurationDefinition threadPoolRollingNumberStatisticalWindowBuckets(Integer threadPoolRollingNumberStatisticalWindowBuckets) {
-        this.threadPoolRollingNumberStatisticalWindowBuckets = threadPoolRollingNumberStatisticalWindowBuckets;
+        setThreadPoolRollingNumberStatisticalWindowBuckets(threadPoolRollingNumberStatisticalWindowBuckets);
         return this;
     }
-    
+
     /**
      * Allows the configuration for maximumSize to take effect. That value can then be equal to, or higher, than coreSize
      */
     public HystrixConfigurationDefinition allowMaximumSizeToDivergeFromCoreSize(Boolean allowMaximumSizeToDivergeFromCoreSize) {
-        this.allowMaximumSizeToDivergeFromCoreSize = allowMaximumSizeToDivergeFromCoreSize;
+        setAllowMaximumSizeToDivergeFromCoreSize(allowMaximumSizeToDivergeFromCoreSize);
         return this;
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java
index 72a7701..fecbdc5 100644
--- a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java
@@ -827,6 +827,11 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
             () -> findByType(camelContext, ServiceDiscovery.class),
             // From registry
             () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_DISCOVERY_ID, ServiceDiscovery.class)
+        ).orElseGet(
+            // Default, that's s little ugly but a load balancer may live without
+            // (i.e. the Ribbon one) so let's delegate the null check to the actual
+            // impl.
+            () -> null
         );
     }
 
@@ -877,7 +882,8 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
             // Check if there is a single instance in the registry
             () -> findByType(camelContext, ServiceFilter.class),
             // From registry
-            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_FILTER_ID, ServiceFilter.class),
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_FILTER_ID, ServiceFilter.class)
+        ).orElseGet(
             // Default
             () -> new HealthyServiceFilter()
         );
@@ -925,7 +931,8 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
             // Check if there is a single instance in the registry
             () -> findByType(camelContext, ServiceChooser.class),
             // From registry
-            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_CHOOSER_ID, ServiceChooser.class),
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_CHOOSER_ID, ServiceChooser.class)
+        ).orElseGet(
             // Default
             () -> new RoundRobinServiceChooser()
         );
@@ -967,7 +974,8 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
             // Check if there is a single instance in the registry
             () -> findByType(camelContext, LoadBalancer.class),
             // From registry
-            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_LOAD_BALANCER_ID, LoadBalancer.class),
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_LOAD_BALANCER_ID, LoadBalancer.class)
+        ).orElseGet(
             // Default
             () -> new DefaultLoadBalancer()
         );
@@ -1007,7 +1015,8 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
             // Default configuration
             () -> retrieveExpression(camelContext, this::retrieveDefaultConfig),
             // From registry
-            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_CALL_EXPRESSION_ID, Expression.class),
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_CALL_EXPRESSION_ID, Expression.class)
+        ).orElseGet(
             // Default
             () -> new DefaultServiceCallExpression()
         );

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java b/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java
index 888de13..88cbe74 100644
--- a/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java
+++ b/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java
@@ -17,6 +17,7 @@
 package org.apache.camel.util.function;
 
 import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Supplier;
 
@@ -41,7 +42,7 @@ public final class Suppliers {
         };
     }
 
-    public static <T> T firstNotNull(ThrowingSupplier<T, Exception>... suppliers) throws Exception {
+    public static <T> Optional<T> firstNotNull(ThrowingSupplier<T, Exception>... suppliers) throws Exception {
         T answer = null;
 
         for (int i = 0; i < suppliers.length; i++) {
@@ -51,6 +52,6 @@ public final class Suppliers {
             }
         }
 
-        return answer;
+        return Optional.ofNullable(answer);
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
index e14132b..ecc74f1 100644
--- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
@@ -162,6 +162,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu
     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")
@@ -670,6 +672,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu
     }
 
     @Override
+    public HystrixConfigurationDefinition getDefaultHystrixConfiguration() {
+        return defaultHystrixConfiguration;
+    }
+
+    public void setDefaultHystrixConfiguration(HystrixConfigurationDefinition defaultHystrixConfiguration) {
+        this.defaultHystrixConfiguration = defaultHystrixConfiguration;
+    }
+
+    @Override
     public List<HystrixConfigurationDefinition> getHystrixConfigurations() {
         return hystrixConfigurations;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
index 5dbe230..f69e491 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
@@ -179,6 +179,9 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
     @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;
 
@@ -362,6 +365,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
     }
 
     @Override
+    public HystrixConfigurationDefinition getDefaultHystrixConfiguration() {
+        return defaultHystrixConfiguration;
+    }
+
+    public void setDefaultHystrixConfiguration(HystrixConfigurationDefinition defaultHystrixConfiguration) {
+        this.defaultHystrixConfiguration = defaultHystrixConfiguration;
+    }
+
+    @Override
     public List<HystrixConfigurationDefinition> getHystrixConfigurations() {
         return hystrixConfigurations;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index 998d782..912e1af 100644
--- a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -795,12 +795,14 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
 
     public abstract List<?> getBeans();
 
-    public abstract List<HystrixConfigurationDefinition> getHystrixConfigurations();
-
     public abstract ServiceCallConfigurationDefinition getDefaultServiceCallConfiguration();
 
     public abstract List<ServiceCallConfigurationDefinition> getServiceCallConfigurations();
 
+    public abstract HystrixConfigurationDefinition getDefaultHystrixConfiguration();
+
+    public abstract List<HystrixConfigurationDefinition> getHystrixConfigurations();
+
     // Implementation methods
     // -------------------------------------------------------------------------
 
@@ -888,6 +890,14 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
                 ctx.addServiceCallConfiguration(bean.getId(), bean);
             }
         }
+        if (getDefaultHystrixConfiguration() != null) {
+            ctx.setHystrixConfiguration(getDefaultHystrixConfiguration());
+        }
+        if (getHystrixConfigurations() != null) {
+            for (HystrixConfigurationDefinition bean : getHystrixConfigurations()) {
+                ctx.addHystrixConfiguration(bean.getId(), bean);
+            }
+        }
     }
 
     protected void initThreadPoolProfiles(T context) throws Exception {

http://git-wip-us.apache.org/repos/asf/camel/blob/b4d0038a/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixConstants.java b/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixConstants.java
index 18ac8c0..178af8c 100644
--- a/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixConstants.java
+++ b/components/camel-hystrix/src/main/java/org/apache/camel/component/hystrix/processor/HystrixConstants.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.hystrix.processor;
 
 public interface HystrixConstants {
+    String DEFAULT_HYSTRIX_CONFIGURATION_ID = "hystrix-configuration";
 
     // Hystrix EIP response properties
     String HYSTRIX_RESPONSE_SUCCESSFUL_EXECUTION = "CamelHystrixSuccessfulExecution";


[2/4] camel git commit: CAMEL-10991: ServiceCall - Allow to configure global configuration

Posted by lb...@apache.org.
CAMEL-10991: ServiceCall - Allow to configure global configuration


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9628b85c
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9628b85c
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9628b85c

Branch: refs/heads/master
Commit: 9628b85c472d64e5856d03282c524426b6a09b1f
Parents: 32f39ea
Author: lburgazzoli <lb...@gmail.com>
Authored: Fri Mar 10 18:41:45 2017 +0100
Committer: lburgazzoli <lb...@gmail.com>
Committed: Tue Mar 14 21:18:07 2017 +0100

----------------------------------------------------------------------
 .../impl/cloud/DefaultServiceCallProcessor.java |  14 +
 .../ServiceCallConfigurationDefinition.java     |  12 +
 .../camel/model/cloud/ServiceCallConstants.java |  27 +-
 .../model/cloud/ServiceCallDefinition.java      | 434 +++++++++++--------
 ...erviceCallServiceDiscoveryConfiguration.java |  15 +-
 .../apache/camel/util/CamelContextHelper.java   |  13 +
 .../apache/camel/util/function/Suppliers.java   |  13 +
 .../camel/impl/cloud/LoadBalancerTest.java      |   1 -
 .../cloud/ServiceCallConfigurationTest.java     | 285 ++++++++++++
 .../blueprint/CamelContextFactoryBean.java      |  11 +
 .../camel/cdi/xml/CamelContextFactoryBean.java  |  12 +
 .../ConsulDefaultServiceCallRouteTest.java      |   3 +-
 .../cloud/ConsulRibbonServiceCallRouteTest.java |   3 +-
 .../cloud/SpringConsulServiceCallRouteTest.java |  32 +-
 .../SpringConsulDefaultServiceCallRouteTest.xml |  81 +++-
 .../SpringConsulRibbonServiceCallRouteTest.xml  |  74 +++-
 .../xml/AbstractCamelContextFactoryBean.java    |   5 +
 .../SpringEtcdServiceCallDefaultRouteTest.xml   |   4 +-
 .../camel/spring/CamelContextFactoryBean.java   |  11 +
 .../spring/handler/CamelNamespaceHandler.java   |   1 +
 .../cloud/ConsulCloudAutoConfiguration.java     |  31 +-
 .../cloud/DnsCloudAutoConfiguration.java        |  31 +-
 .../cloud/EtcdCloudAutoConfiguration.java       |  35 +-
 .../cloud/KubernetesCloudAutoConfiguration.java |  31 +-
 .../cloud/RibbonCloudAutoConfiguration.java     |  31 +-
 25 files changed, 852 insertions(+), 358 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java
index 8e36968..e75c8cb 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java
@@ -80,6 +80,19 @@ public class DefaultServiceCallProcessor extends ServiceSupport implements Async
     }
 
     // *************************************
+    // Properties
+    // *************************************
+
+    public LoadBalancer getLoadBalancer() {
+        return loadBalancer;
+    }
+
+    public Expression getExpression() {
+        return expression;
+    }
+
+
+    // *************************************
     // Lifecycle
     // *************************************
 
@@ -112,6 +125,7 @@ public class DefaultServiceCallProcessor extends ServiceSupport implements Async
     // Processor
     // *************************************
 
+
     @Override
     public void process(Exchange exchange) throws Exception {
         AsyncProcessorHelper.process(this, exchange);

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java
index 82b2603..e0b3818 100644
--- a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConfigurationDefinition.java
@@ -530,6 +530,12 @@ public class ServiceCallConfigurationDefinition extends IdentifiedType {
         return conf;
     }
 
+    public ServiceCallConfigurationDefinition multiServiceDiscovery(ChainedServiceCallServiceDiscoveryConfiguration conf) {
+        setServiceDiscoveryConfiguration(conf);
+
+        return this;
+    }
+
     public StaticServiceCallServiceDiscoveryConfiguration staticServiceDiscovery() {
         StaticServiceCallServiceDiscoveryConfiguration conf = new StaticServiceCallServiceDiscoveryConfiguration();
         setServiceDiscoveryConfiguration(conf);
@@ -537,6 +543,12 @@ public class ServiceCallConfigurationDefinition extends IdentifiedType {
         return conf;
     }
 
+    public ServiceCallConfigurationDefinition staticServiceDiscovery(StaticServiceCallServiceDiscoveryConfiguration conf) {
+        setServiceDiscoveryConfiguration(conf);
+
+        return this;
+    }
+
     // *****************************
     // Shortcuts - ServiceFilter
     // *****************************

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConstants.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConstants.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConstants.java
index 04ee654..951d25a 100644
--- a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConstants.java
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallConstants.java
@@ -16,26 +16,13 @@
  */
 package org.apache.camel.model.cloud;
 
-import java.util.Arrays;
-import java.util.List;
-
-final class ServiceCallConstants {
-    public static final List<ServiceCallServiceDiscoveryConfiguration> SERVICE_DISCOVERY_CONFIGURATIONS = Arrays.asList(
-        new ConsulServiceCallServiceDiscoveryConfiguration(),
-        new DnsServiceCallServiceDiscoveryConfiguration(),
-        new EtcdServiceCallServiceDiscoveryConfiguration(),
-        new KubernetesServiceCallServiceDiscoveryConfiguration()
-    );
-
-    public static final List<ServiceCallServiceFilterConfiguration> SERVICE_FILTER_CONFIGURATIONS = Arrays.asList(
-        new HealthyServiceCallServiceFilterConfiguration(),
-        new PassThroughServiceCallServiceFilterConfiguration()
-    );
-
-    public static final List<ServiceCallLoadBalancerConfiguration> LOAD_BALANCER_CONFIGURATIONS = Arrays.asList(
-        new RibbonServiceCallLoadBalancerConfiguration(),
-        new DefaultServiceCallLoadBalancerConfiguration()
-    );
+public final class ServiceCallConstants {
+    public static final String DEFAULT_SERVICE_CALL_CONFIG_ID = "service-call-configuration";
+    public static final String DEFAULT_SERVICE_CALL_EXPRESSION_ID = "service-call-expression";
+    public static final String DEFAULT_SERVICE_DISCOVERY_ID = "service-discovery";
+    public static final String DEFAULT_SERVICE_FILTER_ID = "service-filter";
+    public static final String DEFAULT_SERVICE_CHOOSER_ID = "service-chooser";
+    public static final String DEFAULT_LOAD_BALANCER_ID = "load-balancer";
 
     private ServiceCallConstants() {
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java
index b6f7ab0..72a7701 100644
--- a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallDefinition.java
@@ -16,7 +16,7 @@
  */
 package org.apache.camel.model.cloud;
 
-import java.util.Set;
+import java.util.function.Function;
 import java.util.function.Supplier;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
@@ -30,7 +30,6 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.Expression;
-import org.apache.camel.NoFactoryAvailableException;
 import org.apache.camel.Processor;
 import org.apache.camel.cloud.LoadBalancer;
 import org.apache.camel.cloud.ServiceChooser;
@@ -49,8 +48,11 @@ import org.apache.camel.impl.cloud.RoundRobinServiceChooser;
 import org.apache.camel.model.NoOutputDefinition;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.RouteContext;
-import org.apache.camel.util.CamelContextHelper;
 import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.function.Suppliers;
+
+import static org.apache.camel.util.CamelContextHelper.findByType;
+import static org.apache.camel.util.CamelContextHelper.lookup;
 
 /**
  * Remote service call definition
@@ -522,6 +524,15 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
         return conf;
     }
 
+    public ServiceCallDefinition consulServiceDiscovery(String url) {
+        ConsulServiceCallServiceDiscoveryConfiguration conf = new ConsulServiceCallServiceDiscoveryConfiguration(this);
+        conf.setUrl(url);
+
+        setServiceDiscoveryConfiguration(conf);
+
+        return this;
+    }
+
     public DnsServiceCallServiceDiscoveryConfiguration dnsServiceDiscovery() {
         DnsServiceCallServiceDiscoveryConfiguration conf = new DnsServiceCallServiceDiscoveryConfiguration(this);
         setServiceDiscoveryConfiguration(conf);
@@ -555,6 +566,25 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
         return conf;
     }
 
+    public ServiceCallDefinition etcdServiceDiscovery(String uris) {
+        EtcdServiceCallServiceDiscoveryConfiguration conf = new EtcdServiceCallServiceDiscoveryConfiguration(this);
+        conf.setUris(uris);
+
+        setServiceDiscoveryConfiguration(conf);
+
+        return this;
+    }
+
+    public ServiceCallDefinition etcdServiceDiscovery(String uris, String servicePath) {
+        EtcdServiceCallServiceDiscoveryConfiguration conf = new EtcdServiceCallServiceDiscoveryConfiguration(this);
+        conf.setUris(uris);
+        conf.setServicePath(servicePath);
+
+        setServiceDiscoveryConfiguration(conf);
+
+        return this;
+    }
+
     public KubernetesServiceCallServiceDiscoveryConfiguration kubernetesServiceDiscovery() {
         KubernetesServiceCallServiceDiscoveryConfiguration conf = new KubernetesServiceCallServiceDiscoveryConfiguration(this);
         setServiceDiscoveryConfiguration(conf);
@@ -682,13 +712,11 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
     @Override
     public Processor createProcessor(RouteContext routeContext) throws Exception {
         final CamelContext camelContext = routeContext.getCamelContext();
-        final ServiceCallConfigurationDefinition config = retrieveConfig(camelContext);
-
-        ServiceDiscovery serviceDiscovery = retrieveServiceDiscovery(camelContext, config);
-        ServiceFilter serviceFilter = retrieveServiceFilter(camelContext, config);
-        ServiceChooser serviceChooser = retrieveServiceChooser(camelContext, config);
-        LoadBalancer loadBalancer = retrieveLoadBalancer(camelContext, config);
-        Expression expression = retrieveExpression(camelContext, config);
+        final ServiceDiscovery serviceDiscovery = retrieveServiceDiscovery(camelContext);
+        final ServiceFilter serviceFilter = retrieveServiceFilter(camelContext);
+        final ServiceChooser serviceChooser = retrieveServiceChooser(camelContext);
+        final LoadBalancer loadBalancer = retrieveLoadBalancer(camelContext);
+        final Expression expression = retrieveExpression(camelContext);
 
         if (loadBalancer instanceof CamelContextAware) {
             ((CamelContextAware) loadBalancer).setCamelContext(camelContext);
@@ -703,11 +731,20 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
             ((ServiceChooserAware) loadBalancer).setServiceChooser(serviceChooser);
         }
 
-        // The component is used to configure what the default scheme to use (eg camel component name).
+        // The component is used to configure the default scheme to use (eg camel component name).
         // The component configured on EIP takes precedence vs configured on configuration.
         String component = this.component;
         if (component == null) {
-            component = config != null ? config.getComponent() : null;
+            ServiceCallConfigurationDefinition conf = retrieveConfig(camelContext);
+            if (conf != null) {
+                component = conf.getComponent();
+            }
+        }
+        if (component == null) {
+            ServiceCallConfigurationDefinition conf = retrieveDefaultConfig(camelContext);
+            if (conf != null) {
+                component = conf.getComponent();
+            }
         }
 
         return new DefaultServiceCallProcessor(camelContext, name, component, uri, pattern, loadBalancer, expression);
@@ -717,118 +754,151 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
     // Helpers
     // *****************************
 
-    private ServiceCallConfigurationDefinition retrieveConfig(CamelContext camelContext) {
-        ServiceCallConfigurationDefinition config = null;
-        if (configurationRef != null) {
-            // lookup in registry first
-            config = CamelContextHelper.lookup(camelContext, configurationRef, ServiceCallConfigurationDefinition.class);
-            if (config == null) {
-                // and fallback as service configuration
-                config = camelContext.getServiceCallConfiguration(configurationRef);
-            }
-        }
+    private ServiceCallConfigurationDefinition retrieveDefaultConfig(CamelContext camelContext) {
+        // check if a default configuration is bound to the registry
+        ServiceCallConfigurationDefinition config = camelContext.getServiceCallConfiguration(null);
 
         if (config == null) {
-            config = camelContext.getServiceCallConfiguration(null);
+            // Or if it is in the registry
+            config = lookup(
+                camelContext,
+                ServiceCallConstants.DEFAULT_SERVICE_CALL_CONFIG_ID,
+                ServiceCallConfigurationDefinition.class);
         }
+
         if (config == null) {
-            // if no default then try to find if there configuration in the registry of the given type
-            Set<ServiceCallConfigurationDefinition> set = camelContext.getRegistry().findByType(ServiceCallConfigurationDefinition.class);
-            if (set.size() == 1) {
-                config = set.iterator().next();
-            }
+            // If no default is set either by searching by name or bound to the
+            // camel context, assume that if there is a single instance in the
+            // registry, that is the default one
+            config = findByType(camelContext, ServiceCallConfigurationDefinition.class);
         }
 
         return config;
     }
 
-    private ServiceDiscovery retrieveServiceDiscovery(CamelContext camelContext, ServiceCallConfigurationDefinition config) throws Exception {
-        ServiceDiscovery answer;
-        if (serviceDiscoveryConfiguration != null) {
-            answer = serviceDiscoveryConfiguration.newInstance(camelContext);
-        } else if (config != null && config.getServiceDiscoveryConfiguration() != null) {
-            answer = config.getServiceDiscoveryConfiguration().newInstance(camelContext);
-        } else {
-            answer = retrieve(ServiceDiscovery.class, camelContext, this::getServiceDiscovery, this::getServiceDiscoveryRef);
-            if (answer == null && config != null) {
-                answer = retrieve(ServiceDiscovery.class, camelContext, config::getServiceDiscovery, config::getServiceDiscoveryRef);
-            }
-
-            if (answer == null) {
-                answer = camelContext.getRegistry().lookupByNameAndType("service-discovery", ServiceDiscovery.class);
-            }
-            if (answer == null) {
-                answer = findByType(camelContext, ServiceDiscovery.class);
+    private ServiceCallConfigurationDefinition retrieveConfig(CamelContext camelContext) {
+        ServiceCallConfigurationDefinition config = null;
+        if (configurationRef != null) {
+            // lookup in registry firstNotNull
+            config = lookup(camelContext, configurationRef, ServiceCallConfigurationDefinition.class);
+            if (config == null) {
+                // and fallback as service configuration
+                config = camelContext.getServiceCallConfiguration(configurationRef);
             }
         }
 
-        // If there's no configuration, let's try to find a suitable implementation
-        if (answer == null) {
-            for (ServiceCallServiceDiscoveryConfiguration configuration : ServiceCallConstants.SERVICE_DISCOVERY_CONFIGURATIONS) {
-                try {
-                    answer = configuration.newInstance(camelContext);
-
-                    if (answer != null) {
-                        break;
-                    }
-                } catch (NoFactoryAvailableException e) {
-                    // skip
-                }
+        return config;
+    }
+
+    // ******************************************
+    // ServiceDiscovery
+    // ******************************************
+
+    private ServiceDiscovery retrieveServiceDiscovery(CamelContext camelContext, Function<CamelContext, ServiceCallConfigurationDefinition> function) throws Exception {
+        ServiceDiscovery answer = null;
+
+        ServiceCallConfigurationDefinition config = function.apply(camelContext);
+        if (config != null) {
+            if (config.getServiceDiscoveryConfiguration() != null) {
+                answer = config.getServiceDiscoveryConfiguration().newInstance(camelContext);
+            } else {
+                answer = retrieve(
+                    ServiceDiscovery.class,
+                    camelContext,
+                    config::getServiceDiscovery,
+                    config::getServiceDiscoveryRef
+                );
             }
         }
 
         return answer;
     }
 
-    private ServiceFilter retrieveServiceFilter(CamelContext camelContext, ServiceCallConfigurationDefinition config) throws Exception {
-        ServiceFilter answer;
-
-        if (serviceFilterConfiguration != null) {
-            answer = serviceFilterConfiguration.newInstance(camelContext);
-        } else if (config != null && config.getServiceFilterConfiguration() != null) {
-            answer = config.getServiceFilterConfiguration().newInstance(camelContext);
-        } else {
-            answer = retrieve(ServiceFilter.class, camelContext, this::getServiceFilter, this::getServiceFilterRef);
-            if (answer == null && config != null) {
-                answer = retrieve(ServiceFilter.class, camelContext, config::getServiceFilter, config::getServiceFilterRef);
-
-                // If the ServiceFilter is not found but a ref is set, try to determine
-                // the implementation according to the ref name.
-                if (answer == null) {
-                    String ref = config.getServiceFilterRef();
-                    if (ObjectHelper.equal("healthy", ref, true)) {
-                        answer = new HealthyServiceFilter();
-                    } else if (ObjectHelper.equal("pass-through", ref, true)) {
-                        answer = new PassThroughServiceFilter();
-                    } else if (ObjectHelper.equal("passthrough", ref, true)) {
-                        answer = new PassThroughServiceFilter();
-                    }
-                }
+    private ServiceDiscovery retrieveServiceDiscovery(CamelContext camelContext) throws Exception {
+        return Suppliers.firstNotNull(
+            () -> (serviceDiscoveryConfiguration != null) ?  serviceDiscoveryConfiguration.newInstance(camelContext) : null,
+            // Local configuration
+            () -> retrieve(ServiceDiscovery.class, camelContext, this::getServiceDiscovery, this::getServiceDiscoveryRef),
+            // Linked configuration
+            () -> retrieveServiceDiscovery(camelContext, this::retrieveConfig),
+            // Default configuration
+            () -> retrieveServiceDiscovery(camelContext, this::retrieveDefaultConfig),
+            // Check if there is a single instance in the registry
+            () -> findByType(camelContext, ServiceDiscovery.class),
+            // From registry
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_DISCOVERY_ID, ServiceDiscovery.class)
+        );
+    }
+
+    // ******************************************
+    // ServiceFilter
+    // ******************************************
+
+    private ServiceFilter retrieveServiceFilter(CamelContext camelContext, Function<CamelContext, ServiceCallConfigurationDefinition> function) throws Exception {
+        ServiceFilter answer = null;
+
+        ServiceCallConfigurationDefinition config = function.apply(camelContext);
+        if (config != null) {
+            if (config.getServiceFilterConfiguration() != null) {
+                answer = config.getServiceFilterConfiguration().newInstance(camelContext);
+            } else {
+                answer = retrieve(
+                    ServiceFilter.class,
+                    camelContext,
+                    config::getServiceFilter,
+                    config::getServiceFilterRef
+                );
             }
-        }
-
-        if (answer == null) {
-            answer = camelContext.getRegistry().lookupByNameAndType("service-filter", ServiceFilter.class);
-        }
-        if (answer == null) {
-            answer = findByType(camelContext, ServiceFilter.class);
-        }
 
-        // If there's no configuration, let's use the healthy strategy
-        if (answer == null) {
-            answer = new HealthyServiceFilter();
+            if (answer == null) {
+                String ref = config.getServiceFilterRef();
+                if (ObjectHelper.equal("healthy", ref, true)) {
+                    answer = new HealthyServiceFilter();
+                } else if (ObjectHelper.equal("pass-through", ref, true)) {
+                    answer = new PassThroughServiceFilter();
+                } else if (ObjectHelper.equal("passthrough", ref, true)) {
+                    answer = new PassThroughServiceFilter();
+                }
+            }
         }
 
         return answer;
     }
 
-    private ServiceChooser retrieveServiceChooser(CamelContext camelContext, ServiceCallConfigurationDefinition config) {
-        ServiceChooser answer = retrieve(ServiceChooser.class, camelContext, this::getServiceChooser, this::getServiceChooserRef);
-        if (answer == null && config != null) {
-            answer = retrieve(ServiceChooser.class, camelContext, config::getServiceChooser, config::getServiceChooserRef);
+    private ServiceFilter retrieveServiceFilter(CamelContext camelContext) throws Exception {
+        return Suppliers.firstNotNull(
+            () -> (serviceFilterConfiguration != null) ? serviceFilterConfiguration.newInstance(camelContext) : null,
+            // Local configuration
+            () -> retrieve(ServiceFilter.class, camelContext, this::getServiceFilter, this::getServiceFilterRef),
+            // Linked configuration
+            () -> retrieveServiceFilter(camelContext, this::retrieveConfig),
+            // Default configuration
+            () -> retrieveServiceFilter(camelContext, this::retrieveDefaultConfig),
+            // Check if there is a single instance in the registry
+            () -> findByType(camelContext, ServiceFilter.class),
+            // From registry
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_FILTER_ID, ServiceFilter.class),
+            // Default
+            () -> new HealthyServiceFilter()
+        );
+    }
+
+    // ******************************************
+    // ServiceChooser
+    // ******************************************
+
+    private ServiceChooser retrieveServiceChooser(CamelContext camelContext, Function<CamelContext, ServiceCallConfigurationDefinition> function) throws Exception {
+        ServiceChooser answer = null;
+
+        ServiceCallConfigurationDefinition config = function.apply(camelContext);
+        if (config != null) {
+            answer = retrieve(
+                ServiceChooser.class,
+                camelContext,
+                config::getServiceChooser,
+                config::getServiceChooserRef
+            );
 
-            // If the ServiceChooser is not found but a ref is set, try to determine
-            // the implementation according to the ref name.
             if (answer == null) {
                 String ref = config.getServiceChooserRef();
                 if (ObjectHelper.equal("roundrobin", ref, true)) {
@@ -841,87 +911,112 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
             }
         }
 
-        if (answer == null) {
-            answer = camelContext.getRegistry().lookupByNameAndType("service-chooser", ServiceChooser.class);
-        }
-        if (answer == null) {
-            answer = findByType(camelContext, ServiceChooser.class);
-        }
-
-        // If there's no configuration, let's use the round-robin strategy
-        if (answer == null) {
-            answer = new RoundRobinServiceChooser();
-        }
-
         return answer;
     }
 
-    private LoadBalancer retrieveLoadBalancer(CamelContext camelContext, ServiceCallConfigurationDefinition config) throws Exception {
-        LoadBalancer answer;
-        if (loadBalancerConfiguration != null) {
-            answer = loadBalancerConfiguration.newInstance(camelContext);
-        } else if (config != null && config.getLoadBalancerConfiguration() != null) {
-            answer = config.getLoadBalancerConfiguration().newInstance(camelContext);
-        } else {
-            answer = retrieve(LoadBalancer.class, camelContext, this::getLoadBalancer, this::getLoadBalancerRef);
-            if (answer == null && config != null) {
-                answer = retrieve(LoadBalancer.class, camelContext, config::getLoadBalancer, config::getLoadBalancerRef);
-            }
-
-            if (answer == null) {
-                answer = camelContext.getRegistry().lookupByNameAndType("load-balancer", LoadBalancer.class);
-            }
-            if (answer == null) {
-                answer = findByType(camelContext, LoadBalancer.class);
+    private ServiceChooser retrieveServiceChooser(CamelContext camelContext) throws Exception {
+        return Suppliers.firstNotNull(
+            // Local configuration
+            () -> retrieve(ServiceChooser.class, camelContext, this::getServiceChooser, this::getServiceChooserRef),
+            // Linked configuration
+            () -> retrieveServiceChooser(camelContext, this::retrieveConfig),
+            // Default configuration
+            () -> retrieveServiceChooser(camelContext, this::retrieveDefaultConfig),
+            // Check if there is a single instance in the registry
+            () -> findByType(camelContext, ServiceChooser.class),
+            // From registry
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_CHOOSER_ID, ServiceChooser.class),
+            // Default
+            () -> new RoundRobinServiceChooser()
+        );
+    }
+
+    // ******************************************
+    // LoadBalancer
+    // ******************************************
+
+    private LoadBalancer retrieveLoadBalancer(CamelContext camelContext, Function<CamelContext, ServiceCallConfigurationDefinition> function) throws Exception {
+        LoadBalancer answer = null;
+
+        ServiceCallConfigurationDefinition config = function.apply(camelContext);
+        if (config != null) {
+            if (config.getLoadBalancerConfiguration() != null) {
+                answer = config.getLoadBalancerConfiguration().newInstance(camelContext);
+            } else {
+                answer = retrieve(
+                    LoadBalancer.class,
+                    camelContext,
+                    config::getLoadBalancer,
+                    config::getLoadBalancerRef
+                );
             }
         }
 
-        // If there's no configuration, let's try to find a suitable implementation
-        if (answer == null) {
-            for (ServiceCallLoadBalancerConfiguration configuration : ServiceCallConstants.LOAD_BALANCER_CONFIGURATIONS) {
-                try {
-                    answer = configuration.newInstance(camelContext);
-
-                    if (answer != null) {
-                        break;
-                    }
-                } catch (NoFactoryAvailableException e) {
-                    // skip
-                }
-            }
-        }
-
-        if (answer == null) {
-            answer = new DefaultLoadBalancer();
-        }
-
         return answer;
     }
 
-    private Expression retrieveExpression(CamelContext camelContext, ServiceCallConfigurationDefinition config) throws Exception {
-        Expression answer;
-
-        if (expressionConfiguration != null) {
-            answer = expressionConfiguration.newInstance(camelContext);
-        } else if (config != null && config.getExpressionConfiguration() != null) {
-            answer = config.getExpressionConfiguration().newInstance(camelContext);
-        } else {
-            answer = retrieve(Expression.class, camelContext, this::getExpression, this::getExpressionRef);
-            if (answer == null && config != null) {
-                answer = retrieve(Expression.class, camelContext, config::getExpression, config::getExpressionRef);
-            }
-            if (answer == null) {
-                answer = findByType(camelContext, Expression.class);
+    private LoadBalancer retrieveLoadBalancer(CamelContext camelContext) throws Exception {
+        return Suppliers.firstNotNull(
+            () -> (loadBalancerConfiguration != null) ? loadBalancerConfiguration.newInstance(camelContext) : null,
+            // Local configuration
+            () -> retrieve(LoadBalancer.class, camelContext, this::getLoadBalancer, this::getLoadBalancerRef),
+            // Linked configuration
+            () -> retrieveLoadBalancer(camelContext, this::retrieveConfig),
+            // Default configuration
+            () -> retrieveLoadBalancer(camelContext, this::retrieveDefaultConfig),
+            // Check if there is a single instance in the registry
+            () -> findByType(camelContext, LoadBalancer.class),
+            // From registry
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_LOAD_BALANCER_ID, LoadBalancer.class),
+            // Default
+            () -> new DefaultLoadBalancer()
+        );
+    }
+
+    // ******************************************
+    // Expression
+    // ******************************************
+
+    private Expression retrieveExpression(CamelContext camelContext, Function<CamelContext, ServiceCallConfigurationDefinition> function) throws Exception {
+        Expression answer = null;
+
+        ServiceCallConfigurationDefinition config = function.apply(camelContext);
+        if (config != null) {
+            if (config.getExpressionConfiguration() != null) {
+                answer = config.getExpressionConfiguration().newInstance(camelContext);
+            } else {
+                answer = retrieve(
+                    Expression.class,
+                    camelContext,
+                    config::getExpression,
+                    config::getExpressionRef
+                );
             }
         }
 
-        if (answer == null) {
-            answer = new DefaultServiceCallExpression();
-        }
-
         return answer;
     }
 
+    private Expression retrieveExpression(CamelContext camelContext) throws Exception {
+        return Suppliers.firstNotNull(
+            () -> (expressionConfiguration != null) ? expressionConfiguration.newInstance(camelContext) : null,
+            // Local configuration
+            () -> retrieve(Expression.class, camelContext, this::getExpression, this::getExpressionRef),
+            // Linked configuration
+            () -> retrieveExpression(camelContext, this::retrieveConfig),
+            // Default configuration
+            () -> retrieveExpression(camelContext, this::retrieveDefaultConfig),
+            // From registry
+            () -> lookup(camelContext, ServiceCallConstants.DEFAULT_SERVICE_CALL_EXPRESSION_ID, Expression.class),
+            // Default
+            () -> new DefaultServiceCallExpression()
+        );
+    }
+
+    // ************************************
+    // Helpers
+    // ************************************
+
     private <T> T retrieve(Class<T> type, CamelContext camelContext, Supplier<T> instanceSupplier, Supplier<String> refSupplier) {
         T answer = null;
         if (instanceSupplier != null) {
@@ -931,19 +1026,10 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit
         if (answer == null && refSupplier != null) {
             String ref = refSupplier.get();
             if (ref != null) {
-                answer = CamelContextHelper.lookup(camelContext, ref, type);
+                answer = lookup(camelContext, ref, type);
             }
         }
 
         return answer;
     }
-
-    private <T> T findByType(CamelContext camelContext, Class<T> type) {
-        Set<T> set = camelContext.getRegistry().findByType(type);
-        if (set.size() == 1) {
-            return set.iterator().next();
-        }
-
-        return null;
-    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java
index fed3134..b6e59df 100644
--- a/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ServiceCallServiceDiscoveryConfiguration.java
@@ -22,6 +22,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlElement;
@@ -47,7 +48,7 @@ public class ServiceCallServiceDiscoveryConfiguration extends IdentifiedType imp
     private static final String RESOURCE_PATH = "META-INF/services/org/apache/camel/cloud/";
 
     @XmlTransient
-    private final ServiceCallDefinition parent;
+    private final Optional<ServiceCallDefinition> parent;
     @XmlTransient
     private final String factoryKey;
     @XmlElement(name = "properties") @Metadata(label = "advanced")
@@ -58,16 +59,22 @@ public class ServiceCallServiceDiscoveryConfiguration extends IdentifiedType imp
     }
 
     public ServiceCallServiceDiscoveryConfiguration(ServiceCallDefinition parent, String factoryKey) {
-        this.parent = parent;
+        this.parent = Optional.ofNullable(parent);
         this.factoryKey = factoryKey;
     }
 
     public ServiceCallDefinition end() {
-        return this.parent;
+        return this.parent.orElseThrow(
+            () -> new IllegalStateException("Parent definition is not set")
+        );
     }
 
     public ProcessorDefinition<?> endParent() {
-        return this.parent.end();
+        return this.parent.map(
+                ServiceCallDefinition::end
+            ).orElseThrow(
+                () -> new IllegalStateException("Parent definition is not set")
+            );
     }
 
     // *************************************************************************

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java b/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
index 3e7a970..d126005 100644
--- a/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java
@@ -139,6 +139,19 @@ public final class CamelContextHelper {
     }
 
     /**
+     * Look up a bean of the give type in the {@link org.apache.camel.spi.Registry} on the
+     * {@link CamelContext} returning an instance if only one bean is present,
+     */
+    public static <T> T findByType(CamelContext camelContext, Class<T> type) {
+        Set<T> set = camelContext.getRegistry().findByType(type);
+        if (set.size() == 1) {
+            return set.iterator().next();
+        }
+
+        return null;
+    }
+
+    /**
      * Look up the given named bean in the {@link org.apache.camel.spi.Registry} on the
      * {@link CamelContext} or throws {@link NoSuchBeanException} if not found.
      */

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java b/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java
index 4f8f845..888de13 100644
--- a/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java
+++ b/camel-core/src/main/java/org/apache/camel/util/function/Suppliers.java
@@ -40,4 +40,17 @@ public final class Suppliers {
             return supplied;
         };
     }
+
+    public static <T> T firstNotNull(ThrowingSupplier<T, Exception>... suppliers) throws Exception {
+        T answer = null;
+
+        for (int i = 0; i < suppliers.length; i++) {
+            answer = suppliers[i].get();
+            if (answer != null) {
+                break;
+            }
+        }
+
+        return answer;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/test/java/org/apache/camel/impl/cloud/LoadBalancerTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/impl/cloud/LoadBalancerTest.java b/camel-core/src/test/java/org/apache/camel/impl/cloud/LoadBalancerTest.java
index 280d8af..5e17bfb 100644
--- a/camel-core/src/test/java/org/apache/camel/impl/cloud/LoadBalancerTest.java
+++ b/camel-core/src/test/java/org/apache/camel/impl/cloud/LoadBalancerTest.java
@@ -14,7 +14,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package org.apache.camel.impl.cloud;
 
 import java.util.stream.Collectors;

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/camel-core/src/test/java/org/apache/camel/impl/cloud/ServiceCallConfigurationTest.java
----------------------------------------------------------------------
diff --git a/camel-core/src/test/java/org/apache/camel/impl/cloud/ServiceCallConfigurationTest.java b/camel-core/src/test/java/org/apache/camel/impl/cloud/ServiceCallConfigurationTest.java
new file mode 100644
index 0000000..de15763
--- /dev/null
+++ b/camel-core/src/test/java/org/apache/camel/impl/cloud/ServiceCallConfigurationTest.java
@@ -0,0 +1,285 @@
+/**
+ * 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.impl.cloud;
+
+import java.util.UUID;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Processor;
+import org.apache.camel.Route;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.impl.SimpleRegistry;
+import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ServiceCallConfigurationTest {
+
+    // ****************************************
+    // test default resolution
+    // ****************************************
+
+    @Test
+    public void testDefaultConfigurationFromCamelContext() throws Exception {
+        StaticServiceDiscovery sd = new StaticServiceDiscovery();
+        sd.addServer("127.0.0.1:8080");
+        sd.addServer("127.0.0.1:8081");
+
+        BlacklistServiceFilter sf = new BlacklistServiceFilter();
+        sf.addServer("127.0.0.1:8080");
+
+        ServiceCallConfigurationDefinition conf = new ServiceCallConfigurationDefinition();
+        conf.setServiceDiscovery(sd);
+        conf.setServiceFilter(sf);
+
+        CamelContext context = new DefaultCamelContext();
+        context.setServiceCallConfiguration(conf);
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .routeId("default")
+                    .serviceCall()
+                        .name("scall")
+                        .component("file")
+                        .end();
+            }
+        });
+
+        context.start();
+
+        DefaultServiceCallProcessor proc = findServiceCallProcessor(context.getRoute("default"));
+
+        Assert.assertNotNull(proc);
+        Assert.assertTrue(proc.getLoadBalancer() instanceof DefaultLoadBalancer);
+
+        DefaultLoadBalancer loadBalancer = (DefaultLoadBalancer)proc.getLoadBalancer();
+        Assert.assertEquals(sd, loadBalancer.getServiceDiscovery());
+        Assert.assertEquals(sf, loadBalancer.getServiceFilter());
+
+        context.stop();
+    }
+
+    @Test
+    public void testDefaultConfigurationFromRegistryWithDefaultName() throws Exception {
+        StaticServiceDiscovery sd = new StaticServiceDiscovery();
+        sd.addServer("127.0.0.1:8080");
+        sd.addServer("127.0.0.1:8081");
+
+        BlacklistServiceFilter sf = new BlacklistServiceFilter();
+        sf.addServer("127.0.0.1:8080");
+
+        ServiceCallConfigurationDefinition conf = new ServiceCallConfigurationDefinition();
+        conf.setServiceDiscovery(sd);
+        conf.serviceFilter(sf);
+
+        SimpleRegistry reg = new SimpleRegistry();
+        reg.put(org.apache.camel.model.cloud.ServiceCallConstants.DEFAULT_SERVICE_CALL_CONFIG_ID, conf);
+
+        CamelContext context = new DefaultCamelContext(reg);
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .routeId("default")
+                    .serviceCall()
+                        .name("scall")
+                        .component("file")
+                        .end();
+            }
+        });
+
+        context.start();
+
+        DefaultServiceCallProcessor proc = findServiceCallProcessor(context.getRoute("default"));
+
+        Assert.assertNotNull(proc);
+        Assert.assertTrue(proc.getLoadBalancer() instanceof DefaultLoadBalancer);
+
+        DefaultLoadBalancer loadBalancer = (DefaultLoadBalancer)proc.getLoadBalancer();
+        Assert.assertEquals(sd, loadBalancer.getServiceDiscovery());
+        Assert.assertEquals(sf, loadBalancer.getServiceFilter());
+
+        context.stop();
+    }
+
+
+    @Test
+    public void testDefaultConfigurationFromRegistryWithNonDefaultName() throws Exception {
+        StaticServiceDiscovery sd = new StaticServiceDiscovery();
+        sd.addServer("127.0.0.1:8080");
+        sd.addServer("127.0.0.1:8081");
+
+        BlacklistServiceFilter sf = new BlacklistServiceFilter();
+        sf.addServer("127.0.0.1:8080");
+
+        ServiceCallConfigurationDefinition conf = new ServiceCallConfigurationDefinition();
+        conf.setServiceDiscovery(sd);
+        conf.serviceFilter(sf);
+
+        SimpleRegistry reg = new SimpleRegistry();
+        reg.put(UUID.randomUUID().toString(), conf);
+
+        CamelContext context = new DefaultCamelContext(reg);
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start")
+                    .routeId("default")
+                    .serviceCall()
+                        .name("scall")
+                        .component("file")
+                        .end();
+            }
+        });
+
+        context.start();
+
+        DefaultServiceCallProcessor proc = findServiceCallProcessor(context.getRoute("default"));
+
+        Assert.assertNotNull(proc);
+        Assert.assertTrue(proc.getLoadBalancer() instanceof DefaultLoadBalancer);
+
+        DefaultLoadBalancer loadBalancer = (DefaultLoadBalancer)proc.getLoadBalancer();
+        Assert.assertEquals(sd, loadBalancer.getServiceDiscovery());
+        Assert.assertEquals(sf, loadBalancer.getServiceFilter());
+
+        context.stop();
+    }
+
+    // ****************************************
+    // test mixed resolution
+    // ****************************************
+
+    @Test
+    public void testMixedConfiguration() throws Exception {
+        // Default
+        StaticServiceDiscovery defaultServiceDiscovery = new StaticServiceDiscovery();
+        defaultServiceDiscovery.addServer("127.0.0.1:8080");
+        defaultServiceDiscovery.addServer("127.0.0.1:8081");
+        defaultServiceDiscovery.addServer("127.0.0.1:8082");
+
+        BlacklistServiceFilter defaultServiceFilter = new BlacklistServiceFilter();
+        defaultServiceFilter.addServer("127.0.0.1:8080");
+
+        ServiceCallConfigurationDefinition defaultConfiguration = new ServiceCallConfigurationDefinition();
+        defaultConfiguration.setServiceDiscovery(defaultServiceDiscovery);
+        defaultConfiguration.serviceFilter(defaultServiceFilter);
+
+        // Named
+        BlacklistServiceFilter namedServiceFilter = new BlacklistServiceFilter();
+        namedServiceFilter.addServer("127.0.0.1:8081");
+
+        ServiceCallConfigurationDefinition namedConfiguration = new ServiceCallConfigurationDefinition();
+        namedConfiguration.serviceFilter(namedServiceFilter);
+
+        // Local
+        StaticServiceDiscovery localServiceDiscovery = new StaticServiceDiscovery();
+        localServiceDiscovery.addServer("127.0.0.1:8080");
+        localServiceDiscovery.addServer("127.0.0.1:8081");
+        localServiceDiscovery.addServer("127.0.0.1:8082");
+        localServiceDiscovery.addServer("127.0.0.1:8084");
+
+
+        // Camel context
+        CamelContext context = new DefaultCamelContext();
+        context.setServiceCallConfiguration(defaultConfiguration);
+        context.addServiceCallConfiguration("named", namedConfiguration);
+        context.addRoutes(new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:default")
+                    .id("default")
+                    .serviceCall()
+                        .name("default-scall")
+                        .component("file")
+                        .end();
+                from("direct:named")
+                    .id("named")
+                    .serviceCall()
+                        .serviceCallConfiguration("named")
+                        .name("named-scall")
+                        .component("file")
+                        .end();
+                from("direct:local")
+                    .id("local")
+                    .serviceCall()
+                        .serviceCallConfiguration("named")
+                        .name("local-scall")
+                        .component("file")
+                        .serviceDiscovery(localServiceDiscovery)
+                        .end();
+            }
+        });
+
+        context.start();
+
+        {
+            // Default
+            DefaultServiceCallProcessor proc = findServiceCallProcessor(context.getRoute("default"));
+
+            Assert.assertNotNull(proc);
+            Assert.assertTrue(proc.getLoadBalancer() instanceof DefaultLoadBalancer);
+
+            DefaultLoadBalancer loadBalancer = (DefaultLoadBalancer) proc.getLoadBalancer();
+            Assert.assertEquals(defaultServiceDiscovery, loadBalancer.getServiceDiscovery());
+            Assert.assertEquals(defaultServiceFilter, loadBalancer.getServiceFilter());
+        }
+
+        {
+            // Named
+            DefaultServiceCallProcessor proc = findServiceCallProcessor(context.getRoute("named"));
+
+            Assert.assertNotNull(proc);
+            Assert.assertTrue(proc.getLoadBalancer() instanceof DefaultLoadBalancer);
+
+            DefaultLoadBalancer loadBalancer = (DefaultLoadBalancer) proc.getLoadBalancer();
+            Assert.assertEquals(defaultServiceDiscovery, loadBalancer.getServiceDiscovery());
+            Assert.assertEquals(namedServiceFilter, loadBalancer.getServiceFilter());
+        }
+
+        {
+            // Local
+            DefaultServiceCallProcessor proc = findServiceCallProcessor(context.getRoute("local"));
+
+            Assert.assertNotNull(proc);
+            Assert.assertTrue(proc.getLoadBalancer() instanceof DefaultLoadBalancer);
+
+            DefaultLoadBalancer loadBalancer = (DefaultLoadBalancer) proc.getLoadBalancer();
+            Assert.assertEquals(localServiceDiscovery, loadBalancer.getServiceDiscovery());
+            Assert.assertEquals(namedServiceFilter, loadBalancer.getServiceFilter());
+        }
+
+        context.stop();
+    }
+
+    // **********************************************
+    // Helper
+    // **********************************************
+
+    private DefaultServiceCallProcessor findServiceCallProcessor(Route route) {
+        for (Processor processor : route.navigate().next()) {
+            if (processor instanceof DefaultServiceCallProcessor) {
+                return (DefaultServiceCallProcessor)processor;
+            }
+        }
+
+        throw new IllegalStateException("Unable to find a ServiceCallProcessor");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
index 31b54de..e14132b 100644
--- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
+++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java
@@ -158,6 +158,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu
     @XmlElements({
         @XmlElement(name = "export", type = CamelServiceExporterDefinition.class) })
     private List<?> beans;
+    @XmlElement(name = "defaultServiceCallConfiguration")
+    private ServiceCallConfigurationDefinition defaultServiceCallConfiguration;
     @XmlElement(name = "serviceCallConfiguration", type = ServiceCallConfigurationDefinition.class)
     private List<ServiceCallConfigurationDefinition> serviceCallConfigurations;
     @XmlElement(name = "hystrixConfiguration", type = HystrixConfigurationDefinition.class)
@@ -650,6 +652,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu
     }
 
     @Override
+    public ServiceCallConfigurationDefinition getDefaultServiceCallConfiguration() {
+        return defaultServiceCallConfiguration;
+    }
+
+    public void setDefaultServiceCallConfiguration(ServiceCallConfigurationDefinition defaultServiceCallConfiguration) {
+        this.defaultServiceCallConfiguration = defaultServiceCallConfiguration;
+    }
+
+    @Override
     public List<ServiceCallConfigurationDefinition> getServiceCallConfigurations() {
         return serviceCallConfigurations;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
index d91605b..5dbe230 100644
--- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
+++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java
@@ -173,6 +173,9 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
     @XmlTransient
     private List<?> beans;
 
+    @XmlElement(name = "defaultServiceCallConfiguration")
+    private ServiceCallConfigurationDefinition defaultServiceCallConfiguration;
+
     @XmlElement(name = "serviceCallConfiguration", type = ServiceCallConfigurationDefinition.class)
     private List<ServiceCallConfigurationDefinition> serviceCallConfigurations;
 
@@ -341,6 +344,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def
     }
 
     @Override
+    public ServiceCallConfigurationDefinition getDefaultServiceCallConfiguration() {
+        return defaultServiceCallConfiguration;
+    }
+
+    public void setDefaultServiceCallConfiguration(ServiceCallConfigurationDefinition defaultServiceCallConfiguration) {
+        this.defaultServiceCallConfiguration = defaultServiceCallConfiguration;
+    }
+
+    @Override
     public List<ServiceCallConfigurationDefinition> getServiceCallConfigurations() {
         return serviceCallConfigurations;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulDefaultServiceCallRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulDefaultServiceCallRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulDefaultServiceCallRouteTest.java
index fd790e1..fcb4479 100644
--- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulDefaultServiceCallRouteTest.java
+++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulDefaultServiceCallRouteTest.java
@@ -97,7 +97,8 @@ public class ConsulDefaultServiceCallRouteTest extends ConsulTestSupport {
                     .serviceCall()
                         .name(SERVICE_NAME)
                         .defaultLoadBalancer()
-                        .end()
+                        .consulServiceDiscovery()
+                        .endParent()
                     .to("log:org.apache.camel.component.consul.cloud?level=INFO&showAll=true&multiline=true")
                     .to("mock:result");
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulRibbonServiceCallRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulRibbonServiceCallRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulRibbonServiceCallRouteTest.java
index 9009b20..b154835 100644
--- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulRibbonServiceCallRouteTest.java
+++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulRibbonServiceCallRouteTest.java
@@ -97,7 +97,8 @@ public class ConsulRibbonServiceCallRouteTest extends ConsulTestSupport {
                 from("direct:start")
                     .serviceCall()
                         .name(SERVICE_NAME)
-                        .end()
+                        .consulServiceDiscovery()
+                        .endParent()
                     .to("log:org.apache.camel.component.consul.processor.service?level=INFO&showAll=true&multiline=true")
                     .to("mock:result");
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java
----------------------------------------------------------------------
diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java
index 81517be..ac10b06 100644
--- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java
+++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java
@@ -40,28 +40,40 @@ public abstract class SpringConsulServiceCallRouteTest extends CamelSpringTestSu
         this.client = Consul.builder().build().agentClient();
         this.registrations = Arrays.asList(
             ImmutableRegistration.builder()
-                .id("service-1")
+                .id("service-1-1")
                 .name("http-service-1")
                 .address("127.0.0.1")
-                .port(9091)
+                .port(9011)
                 .build(),
             ImmutableRegistration.builder()
-                .id("service-2")
+                .id("service-1-2")
                 .name("http-service-1")
                 .address("127.0.0.1")
-                .port(9092)
+                .port(9012)
                 .build(),
             ImmutableRegistration.builder()
-                .id("service-3")
+                .id("service-1-3")
+                .name("http-service-1")
+                .address("127.0.0.1")
+                .port(9013)
+                .build(),
+            ImmutableRegistration.builder()
+                .id("service-2-1")
+                .name("http-service-2")
+                .address("127.0.0.1")
+                .port(9021)
+                .build(),
+            ImmutableRegistration.builder()
+                .id("service-2-2")
                 .name("http-service-2")
                 .address("127.0.0.1")
-                .port(9093)
+                .port(9022)
                 .build(),
             ImmutableRegistration.builder()
-                .id("service-4")
+                .id("service-2-3")
                 .name("http-service-2")
                 .address("127.0.0.1")
-                .port(9094)
+                .port(9023)
                 .build()
         );
 
@@ -82,9 +94,9 @@ public abstract class SpringConsulServiceCallRouteTest extends CamelSpringTestSu
     @Test
     public void testServiceCall() throws Exception {
         getMockEndpoint("mock:result-1").expectedMessageCount(2);
-        getMockEndpoint("mock:result-1").expectedBodiesReceivedInAnyOrder("service-1 9091", "service-1 9092");
+        getMockEndpoint("mock:result-1").expectedBodiesReceivedInAnyOrder("service-1 9012", "service-1 9013");
         getMockEndpoint("mock:result-2").expectedMessageCount(2);
-        getMockEndpoint("mock:result-2").expectedBodiesReceivedInAnyOrder("service-2 9093", "service-2 9094");
+        getMockEndpoint("mock:result-2").expectedBodiesReceivedInAnyOrder("service-2 9021", "service-2 9023");
 
         template.sendBody("direct:start", "service-1");
         template.sendBody("direct:start", "service-1");

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml b/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml
index c4d0950..f050001 100644
--- a/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml
+++ b/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml
@@ -25,63 +25,100 @@
 
   <camelContext xmlns="http://camel.apache.org/schema/spring">
 
-    <!-- shared config -->
-    <serviceCallConfiguration id="shared-config" serviceChooserRef="round-robin">
-      <consulServiceDiscovery readTimeoutMillis="1444" url="http://localhost:8500"/>
+    <!-- ************************************* -->
+    <!-- ServiceCall                           -->
+    <!-- ************************************* -->
+
+    <defaultServiceCallConfiguration id="default">
+      <!-- service discovery -->
+      <consulServiceDiscovery url="http://localhost:8500"/>
+
+      <!-- service filter -->
+      <blacklistServiceFilter>
+        <servers>http-service-1@127.0.0.1:9011</servers>
+        <servers>http-service-2@127.0.0.1:9021</servers>
+      </blacklistServiceFilter>
+    </defaultServiceCallConfiguration>
+
+    <serviceCallConfiguration id="service-2">
+      <!-- service filter -->
+      <blacklistServiceFilter>
+        <servers>http-service-2@127.0.0.1:9022</servers>
+      </blacklistServiceFilter>
     </serviceCallConfiguration>
 
+    <!-- ************************************* -->
+    <!-- Routes                                -->
+    <!-- ************************************* -->
+
     <route>
       <from uri="direct:start"/>
       <choice>
         <when>
           <simple>${body} == 'service-1'</simple>
-          <serviceCall name="http-service-1">
-            <consulServiceDiscovery readTimeoutMillis="1222" url="http://localhost:8500"/>
-          </serviceCall>
+          <serviceCall name="http-service-1"/>
           <to uri="mock:result-1"/>
         </when>
         <when>
           <simple>${body} == 'service-2'</simple>
-          <serviceCall name="http-service-2">
-            <consulServiceDiscovery readTimeoutMillis="1333" url="http://localhost:8500"/>
-          </serviceCall>
-          <to uri="mock:result-2"/>
-        </when>
-        <when>
-          <simple>${body} == 'service-3'</simple>
-          <serviceCall name="http-service-3" configurationRef="shared-config"/>
+          <serviceCall name="http-service-2" configurationRef="service-2"/>
           <to uri="mock:result-2"/>
         </when>
       </choice>
     </route>
 
+    <!-- ************************************* -->
+    <!-- http-service-1                        -->
+    <!-- ************************************* -->
+
+    <route>
+      <from uri="jetty:http://localhost:9011"/>
+      <transform>
+        <simple>${body} 9011</simple>
+      </transform>
+    </route>
+
     <route>
-      <from uri="jetty:http://localhost:9091"/>
+      <from uri="jetty:http://localhost:9012"/>
       <transform>
-        <simple>${body} 9091</simple>
+        <simple>${body} 9012</simple>
       </transform>
     </route>
 
     <route>
-      <from uri="jetty:http://localhost:9092"/>
+      <from uri="jetty:http://localhost:9013"/>
       <transform>
-        <simple>${body} 9092</simple>
+        <simple>${body} 9013</simple>
       </transform>
     </route>
 
+    <!-- ************************************* -->
+    <!-- http-service-2                        -->
+    <!-- ************************************* -->
+
     <route>
-      <from uri="jetty:http://localhost:9093"/>
+      <from uri="jetty:http://localhost:9021"/>
       <transform>
-        <simple>${body} 9093</simple>
+        <simple>${body} 9021</simple>
       </transform>
     </route>
 
     <route>
-      <from uri="jetty:http://localhost:9094"/>
+      <from uri="jetty:http://localhost:9022"/>
       <transform>
-        <simple>${body} 9094</simple>
+        <simple>${body} 9022</simple>
       </transform>
     </route>
+
+    <route>
+      <from uri="jetty:http://localhost:9023"/>
+      <transform>
+        <simple>${body} 9023</simple>
+      </transform>
+    </route>
+
+
+
   </camelContext>
 
 </beans>

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml b/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml
index ac1b642..582ccee 100644
--- a/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml
+++ b/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml
@@ -24,11 +24,32 @@
          http://camel.apache.org/schema/spring/camel-spring.xsd">
 
   <camelContext xmlns="http://camel.apache.org/schema/spring">
-    <!--
+
+    <!-- ************************************* -->
+    <!-- ServiceCall                           -->
+    <!-- ************************************* -->
+
+    <defaultServiceCallConfiguration id="default">
+      <!-- service discovery -->
+      <consulServiceDiscovery url="http://localhost:8500"/>
+
+      <!-- service filter -->
+      <blacklistServiceFilter>
+        <servers>http-service-1@127.0.0.1:9011</servers>
+        <servers>http-service-2@127.0.0.1:9021</servers>
+      </blacklistServiceFilter>
+    </defaultServiceCallConfiguration>
+
     <serviceCallConfiguration id="service-2">
-      <consulServiceDiscovery"/>
+      <!-- service filter -->
+      <blacklistServiceFilter>
+        <servers>http-service-2@127.0.0.1:9022</servers>
+      </blacklistServiceFilter>
     </serviceCallConfiguration>
-    -->
+
+    <!-- ************************************* -->
+    <!-- Routes                                -->
+    <!-- ************************************* -->
 
     <route>
       <from uri="direct:start"/>
@@ -36,15 +57,13 @@
         <when>
           <simple>${body} == 'service-1'</simple>
           <serviceCall name="http-service-1">
-            <consulServiceDiscovery readTimeoutMillis="1222" url="http://localhost:8500"/>
             <ribbonLoadBalancer/>
           </serviceCall>
           <to uri="mock:result-1"/>
         </when>
         <when>
           <simple>${body} == 'service-2'</simple>
-          <serviceCall name="http-service-2">
-            <consulServiceDiscovery readTimeoutMillis="1333" url="http://localhost:8500"/>
+          <serviceCall name="http-service-2" configurationRef="service-2">
             <ribbonLoadBalancer/>
           </serviceCall>
           <to uri="mock:result-2"/>
@@ -52,33 +71,58 @@
       </choice>
     </route>
 
+    <!-- ************************************* -->
+    <!-- http-service-1                        -->
+    <!-- ************************************* -->
+
+    <route>
+      <from uri="jetty:http://localhost:9011"/>
+      <transform>
+        <simple>${body} 9011</simple>
+      </transform>
+    </route>
+
+    <route>
+      <from uri="jetty:http://localhost:9012"/>
+      <transform>
+        <simple>${body} 9012</simple>
+      </transform>
+    </route>
+
     <route>
-      <from uri="jetty:http://localhost:9091"/>
+      <from uri="jetty:http://localhost:9013"/>
       <transform>
-        <simple>${body} 9091</simple>
+        <simple>${body} 9013</simple>
       </transform>
     </route>
 
+    <!-- ************************************* -->
+    <!-- http-service-2                        -->
+    <!-- ************************************* -->
+
     <route>
-      <from uri="jetty:http://localhost:9092"/>
+      <from uri="jetty:http://localhost:9021"/>
       <transform>
-        <simple>${body} 9092</simple>
+        <simple>${body} 9021</simple>
       </transform>
     </route>
 
     <route>
-      <from uri="jetty:http://localhost:9093"/>
+      <from uri="jetty:http://localhost:9022"/>
       <transform>
-        <simple>${body} 9093</simple>
+        <simple>${body} 9022</simple>
       </transform>
     </route>
 
     <route>
-      <from uri="jetty:http://localhost:9094"/>
+      <from uri="jetty:http://localhost:9023"/>
       <transform>
-        <simple>${body} 9094</simple>
+        <simple>${body} 9023</simple>
       </transform>
     </route>
+
+
+
   </camelContext>
 
-</beans>
\ No newline at end of file
+</beans>

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
----------------------------------------------------------------------
diff --git a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
index 1b89a39..998d782 100644
--- a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
+++ b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java
@@ -797,6 +797,8 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
 
     public abstract List<HystrixConfigurationDefinition> getHystrixConfigurations();
 
+    public abstract ServiceCallConfigurationDefinition getDefaultServiceCallConfiguration();
+
     public abstract List<ServiceCallConfigurationDefinition> getServiceCallConfigurations();
 
     // Implementation methods
@@ -878,6 +880,9 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex
         if (getRestConfiguration() != null) {
             ctx.setRestConfiguration(getRestConfiguration().asRestConfiguration(ctx));
         }
+        if (getDefaultServiceCallConfiguration() != null) {
+            ctx.setServiceCallConfiguration(getDefaultServiceCallConfiguration());
+        }
         if (getServiceCallConfigurations() != null) {
             for (ServiceCallConfigurationDefinition bean : getServiceCallConfigurations()) {
                 ctx.addServiceCallConfiguration(bean.getId(), bean);

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml
----------------------------------------------------------------------
diff --git a/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml b/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml
index d0194c8..006893c 100644
--- a/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml
+++ b/components/camel-etcd/src/test/resources/org/apache/camel/component/etcd/cloud/SpringEtcdServiceCallDefaultRouteTest.xml
@@ -26,7 +26,9 @@
   <camelContext xmlns="http://camel.apache.org/schema/spring">
     <route>
       <from uri="direct:start"/>
-      <serviceCall name="http-service"/>
+      <serviceCall name="http-service">
+        <etcdServiceDiscovery/>
+      </serviceCall>
       <to uri="mock:result"/>
     </route>
 

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/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 e0a3f07..514985e 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
@@ -167,6 +167,8 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
         @XmlElement(name = "export", type = CamelServiceExporterDefinition.class),
         @XmlElement(name = "errorHandler", type = ErrorHandlerDefinition.class) })
     private List<?> beans;
+    @XmlElement(name = "defaultServiceCallConfiguration")
+    private ServiceCallConfigurationDefinition defaultServiceCallConfiguration;
     @XmlElement(name = "serviceCallConfiguration", type = ServiceCallConfigurationDefinition.class)
     private List<ServiceCallConfigurationDefinition> serviceCallConfigurations;
     @XmlElement(name = "hystrixConfiguration", type = HystrixConfigurationDefinition.class)
@@ -953,6 +955,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Spr
     }
 
     @Override
+    public ServiceCallConfigurationDefinition getDefaultServiceCallConfiguration() {
+        return defaultServiceCallConfiguration;
+    }
+
+    public void setDefaultServiceCallConfiguration(ServiceCallConfigurationDefinition defaultServiceCallConfiguration) {
+        this.defaultServiceCallConfiguration = defaultServiceCallConfiguration;
+    }
+
+    @Override
     public List<ServiceCallConfigurationDefinition> getServiceCallConfigurations() {
         return serviceCallConfigurations;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/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 04737cf..072e904 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
@@ -403,6 +403,7 @@ public class CamelNamespaceHandler extends NamespaceHandlerSupport {
                 builder.addPropertyValue("threadPoolProfiles", factoryBean.getThreadPoolProfiles());
                 builder.addPropertyValue("beansFactory", factoryBean.getBeansFactory());
                 builder.addPropertyValue("beans", factoryBean.getBeans());
+                builder.addPropertyValue("defaultServiceCallConfiguration", factoryBean.getDefaultServiceCallConfiguration());
                 builder.addPropertyValue("serviceCallConfigurations", factoryBean.getServiceCallConfigurations());
                 builder.addPropertyValue("hystrixConfigurations", factoryBean.getHystrixConfigurations());
                 // add any depends-on

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulCloudAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulCloudAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulCloudAutoConfiguration.java
index db5cf32..240a8fc 100644
--- a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulCloudAutoConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulCloudAutoConfiguration.java
@@ -23,21 +23,16 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.cloud.ServiceDiscovery;
 import org.apache.camel.component.consul.cloud.ConsulServiceDiscoveryFactory;
 import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.util.GroupCondition;
 import org.apache.camel.util.IntrospectionSupport;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionMessage;
-import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
-import org.springframework.boot.bind.RelaxedPropertyResolver;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ConditionContext;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Lazy;
-import org.springframework.core.type.AnnotatedTypeMetadata;
 
 @Configuration
 @ConditionalOnBean(CamelAutoConfiguration.class)
@@ -58,22 +53,16 @@ public class ConsulCloudAutoConfiguration {
         return factory.newInstance(camelContext);
     }
 
-    public static class Condition extends SpringBootCondition {
-        @Override
-        public ConditionOutcome getMatchOutcome(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
-            boolean groupEnabled = isEnabled(conditionContext, "camel.cloud.", true);
+    // *******************************
+    // Condition
+    // *******************************
 
-            ConditionMessage.Builder message = ConditionMessage.forCondition("camel.cloud.consul");
-            if (isEnabled(conditionContext, "camel.cloud.consul.", groupEnabled)) {
-                return ConditionOutcome.match(message.because("enabled"));
-            }
-
-            return ConditionOutcome.noMatch(message.because("not enabled"));
-        }
-
-        private boolean isEnabled(ConditionContext context, String prefix, boolean defaultValue) {
-            RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), prefix);
-            return resolver.getProperty("enabled", Boolean.class, defaultValue);
+    public static class Condition extends GroupCondition {
+        public Condition() {
+            super(
+                "camel.cloud",
+                "camel.cloud.consul"
+            );
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/platforms/spring-boot/components-starter/camel-dns-starter/src/main/java/org/apache/camel/component/dns/springboot/cloud/DnsCloudAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-dns-starter/src/main/java/org/apache/camel/component/dns/springboot/cloud/DnsCloudAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-dns-starter/src/main/java/org/apache/camel/component/dns/springboot/cloud/DnsCloudAutoConfiguration.java
index a3e9b09..3d794d3 100644
--- a/platforms/spring-boot/components-starter/camel-dns-starter/src/main/java/org/apache/camel/component/dns/springboot/cloud/DnsCloudAutoConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-dns-starter/src/main/java/org/apache/camel/component/dns/springboot/cloud/DnsCloudAutoConfiguration.java
@@ -23,21 +23,16 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.cloud.ServiceDiscovery;
 import org.apache.camel.component.dns.cloud.DnsServiceDiscoveryFactory;
 import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.util.GroupCondition;
 import org.apache.camel.util.IntrospectionSupport;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionMessage;
-import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
-import org.springframework.boot.bind.RelaxedPropertyResolver;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ConditionContext;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Lazy;
-import org.springframework.core.type.AnnotatedTypeMetadata;
 
 @Configuration
 @ConditionalOnBean(CamelAutoConfiguration.class)
@@ -58,22 +53,16 @@ public class DnsCloudAutoConfiguration {
         return factory.newInstance(camelContext);
     }
 
-    public static class Condition extends SpringBootCondition {
-        @Override
-        public ConditionOutcome getMatchOutcome(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
-            boolean groupEnabled = isEnabled(conditionContext, "camel.cloud.", true);
+    // *******************************
+    // Condition
+    // *******************************
 
-            ConditionMessage.Builder message = ConditionMessage.forCondition("camel.cloud.dns");
-            if (isEnabled(conditionContext, "camel.cloud.dns.", groupEnabled)) {
-                return ConditionOutcome.match(message.because("enabled"));
-            }
-
-            return ConditionOutcome.noMatch(message.because("not enabled"));
-        }
-
-        private boolean isEnabled(ConditionContext context, String prefix, boolean defaultValue) {
-            RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), prefix);
-            return resolver.getProperty("enabled", Boolean.class, defaultValue);
+    public static class Condition extends GroupCondition {
+        public Condition() {
+            super(
+                "camel.cloud",
+                "camel.cloud.dns"
+            );
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/9628b85c/platforms/spring-boot/components-starter/camel-etcd-starter/src/main/java/org/apache/camel/component/etcd/springboot/cloud/EtcdCloudAutoConfiguration.java
----------------------------------------------------------------------
diff --git a/platforms/spring-boot/components-starter/camel-etcd-starter/src/main/java/org/apache/camel/component/etcd/springboot/cloud/EtcdCloudAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-etcd-starter/src/main/java/org/apache/camel/component/etcd/springboot/cloud/EtcdCloudAutoConfiguration.java
index 9af3218..a202698 100644
--- a/platforms/spring-boot/components-starter/camel-etcd-starter/src/main/java/org/apache/camel/component/etcd/springboot/cloud/EtcdCloudAutoConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-etcd-starter/src/main/java/org/apache/camel/component/etcd/springboot/cloud/EtcdCloudAutoConfiguration.java
@@ -21,27 +21,18 @@ import java.util.Map;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.cloud.ServiceDiscovery;
-import org.apache.camel.component.etcd.cloud.EtcdOnDemandServiceDiscovery;
 import org.apache.camel.component.etcd.cloud.EtcdServiceDiscoveryFactory;
-import org.apache.camel.component.etcd.cloud.EtcdWatchServiceDiscovery;
 import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.util.GroupCondition;
 import org.apache.camel.util.IntrospectionSupport;
-import org.apache.camel.util.ObjectHelper;
 import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionMessage;
-import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
 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.SpringBootCondition;
-import org.springframework.boot.bind.RelaxedPropertyResolver;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ConditionContext;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Lazy;
-import org.springframework.core.type.AnnotatedTypeMetadata;
 
 @Configuration
 @ConditionalOnBean(CamelAutoConfiguration.class)
@@ -62,22 +53,16 @@ public class EtcdCloudAutoConfiguration {
         return factory.newInstance(camelContext);
     }
 
-    public static class Condition extends SpringBootCondition {
-        @Override
-        public ConditionOutcome getMatchOutcome(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
-            boolean groupEnabled = isEnabled(conditionContext, "camel.cloud.", true);
+    // *******************************
+    // Condition
+    // *******************************
 
-            ConditionMessage.Builder message = ConditionMessage.forCondition("camel.cloud.etcd");
-            if (isEnabled(conditionContext, "camel.cloud.etcd.", groupEnabled)) {
-                return ConditionOutcome.match(message.because("enabled"));
-            }
-
-            return ConditionOutcome.noMatch(message.because("not enabled"));
-        }
-
-        private boolean isEnabled(ConditionContext context, String prefix, boolean defaultValue) {
-            RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(context.getEnvironment(), prefix);
-            return resolver.getProperty("enabled", Boolean.class, defaultValue);
+    public static class Condition extends GroupCondition {
+        public Condition() {
+            super(
+                "camel.cloud",
+                "camel.cloud.etcd"
+            );
         }
     }
 }