CAMEL-10638: Refactor ServiceCall EIP

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

Branch: refs/heads/master
Commit: a811f4004040a6548cadf922f6f89a5268c6ce60
Parents: c928453
Author: lburgazzoli <lburgazz...@gmail.com>
Authored: Thu Dec 22 18:27:11 2016 +0100
Committer: lburgazzoli <lburgazz...@gmail.com>
Committed: Wed Jan 11 13:03:02 2017 +0100

----------------------------------------------------------------------
 camel-core/readme-eip.adoc                      |  17 +-
 .../java/org/apache/camel/CamelContext.java     |  16 +-
 .../org/apache/camel/cloud/LoadBalancer.java    |  29 +
 .../apache/camel/cloud/LoadBalancerFactory.java |  31 +
 .../camel/cloud/LoadBalancerFunction.java       |  25 +
 .../org/apache/camel/cloud/ServiceChooser.java  |  35 +
 .../apache/camel/cloud/ServiceChooserAware.java |  37 +
 .../camel/cloud/ServiceChooserFactory.java      |  31 +
 .../apache/camel/cloud/ServiceDefinition.java   |  52 ++
 .../apache/camel/cloud/ServiceDiscovery.java    |  47 ++
 .../camel/cloud/ServiceDiscoveryAware.java      |  37 +
 .../camel/cloud/ServiceDiscoveryFactory.java    |  31 +
 .../camel/cloud/ServiceExpressionFactory.java   |  33 +
 .../org/apache/camel/cloud/ServiceFilter.java   |  35 +
 .../apache/camel/cloud/ServiceFilterAware.java  |  37 +
 .../camel/cloud/ServiceFilterFactory.java       |  31 +
 .../org/apache/camel/cloud/ServiceHealth.java   |  32 +
 .../apache/camel/impl/DefaultCamelContext.java  |  33 +-
 .../camel/impl/cloud/AllServiceFilter.java      |  32 +
 .../impl/cloud/CachingServiceDiscovery.java     | 104 +++
 .../camel/impl/cloud/DefaultLoadBalancer.java   | 148 ++++
 .../cloud/DefaultServiceCallExpression.java     |  85 +++
 .../impl/cloud/DefaultServiceCallProcessor.java | 153 ++++
 .../impl/cloud/DefaultServiceDefinition.java    |  98 +++
 .../impl/cloud/DefaultServiceDiscovery.java     |  64 ++
 .../camel/impl/cloud/DefaultServiceFilter.java  |  30 +
 .../camel/impl/cloud/DefaultServiceHealth.java  |  57 ++
 .../camel/impl/cloud/HealthyServiceFilter.java  |  33 +
 .../camel/impl/cloud/RandomServiceChooser.java  |  45 ++
 .../impl/cloud/RoundRobinServiceChooser.java    |  41 ++
 .../camel/impl/cloud/ServiceCallConstants.java  |  29 +
 .../impl/cloud/StaticServiceDiscovery.java      | 132 ++++
 .../cloud/StaticServiceDiscoveryFactory.java    |  57 ++
 .../AbstractServiceCallProcessorFactory.java    |  42 --
 .../CachingServiceCallServiceListStrategy.java  | 105 ---
 .../remote/DefaultServiceCallExpression.java    |  48 --
 .../remote/DefaultServiceCallProcessor.java     | 250 -------
 .../DefaultServiceCallProcessorFactory.java     | 289 --------
 .../impl/remote/DefaultServiceCallServer.java   |  62 --
 .../DefaultServiceCallServerListStrategy.java   |  63 --
 .../remote/RandomServiceCallLoadBalancer.java   |  44 --
 .../RoundRobinServiceCallLoadBalancer.java      |  41 --
 .../camel/impl/remote/ServiceCallConstants.java |  24 -
 .../org/apache/camel/impl/remote/package.html   |  25 -
 .../java/org/apache/camel/model/Constants.java  |   2 +-
 .../apache/camel/model/ProcessorDefinition.java |   2 +-
 ...erviceCallServiceDiscoveryConfiguration.java | 258 +++++++
 ...erviceCallServiceDiscoveryConfiguration.java |  88 +++
 ...erviceCallServiceDiscoveryConfiguration.java | 194 +++++
 ...erviceCallServiceDiscoveryConfiguration.java | 421 +++++++++++
 ...bonServiceCallLoadBalancerConfiguration.java |  67 ++
 .../ServiceCallConfigurationDefinition.java     | 407 +++++++++++
 .../camel/model/cloud/ServiceCallConstants.java |  36 +
 .../model/cloud/ServiceCallDefinition.java      | 721 +++++++++++++++++++
 .../ServiceCallExpressionConfiguration.java     | 221 ++++++
 .../ServiceCallLoadBalancerConfiguration.java   | 177 +++++
 .../ServiceCallServiceChooserConfiguration.java | 177 +++++
 ...erviceCallServiceDiscoveryConfiguration.java | 177 +++++
 .../ServiceCallServiceFilterConfiguration.java  | 177 +++++
 ...erviceCallServiceDiscoveryConfiguration.java |  69 ++
 .../apache/camel/model/cloud/package-info.java  |  23 +
 .../remote/ConsulConfigurationDefinition.java   | 232 ------
 .../remote/DnsConfigurationDefinition.java      |  87 ---
 .../remote/EtcdConfigurationDefinition.java     | 159 ----
 .../KubernetesConfigurationDefinition.java      | 364 ----------
 .../remote/RibbonConfigurationDefinition.java   |  48 --
 .../ServiceCallConfigurationDefinition.java     | 222 ------
 .../model/remote/ServiceCallDefinition.java     | 313 --------
 .../remote/ServiceCallProcessorFactory.java     |  22 -
 .../apache/camel/model/remote/package-info.java |  23 -
 .../camel/spi/ServiceCallLoadBalancer.java      |  21 +-
 .../spi/ServiceCallLoadBalancerRequest.java     |  29 +
 .../org/apache/camel/spi/ServiceCallServer.java |  42 --
 .../spi/ServiceCallServerListStrategy.java      |  49 --
 .../apache/camel/spi/ServiceCallService.java    |  47 ++
 .../camel/spi/ServiceCallServiceChooser.java    |  35 +
 .../spi/ServiceCallServiceChooserAware.java     |  37 +
 .../camel/spi/ServiceCallServiceDiscovery.java  |  47 ++
 .../spi/ServiceCallServiceDiscoveryAware.java   |  37 +
 .../support/ServiceCallExpressionSupport.java   |  98 +--
 .../apache/camel/cloud/static-service-discovery |  17 +
 .../org/apache/camel/model/cloud/jaxb.index     |  28 +
 .../org/apache/camel/model/remote/jaxb.index    |  23 -
 ...chingServiceCallServiceListStrategyTest.java |  56 ++
 ...chingServiceCallServiceListStrategyTest.java |  56 --
 .../BlueprintModelJAXBContextFactory.java       |   1 +
 .../blueprint/CamelContextFactoryBean.java      |  26 +-
 .../handler/CamelNamespaceHandler.java          |   2 +-
 .../org/apache/camel/cdi/XmlCdiBeanFactory.java |   4 +-
 .../camel/cdi/xml/CamelContextFactoryBean.java  |  24 +-
 .../test/XmlServiceCallConfigurationTest.java   |  79 ++
 ...camel-context-service-call-configuration.xml |  52 ++
 components/camel-consul/pom.xml                 |   5 +
 .../component/consul/ConsulConfiguration.java   |   4 +
 .../consul/cloud/ConsulServiceDiscovery.java    | 104 +++
 .../cloud/ConsulServiceDiscoveryFactory.java    | 124 ++++
 .../remote/ConsulServiceCallProcessor.java      |  43 --
 .../ConsulServiceCallProcessorFactory.java      |  67 --
 .../ConsulServiceCallServerListStrategies.java  |  65 --
 .../ConsulServiceCallServerListStrategy.java    | 128 ----
 .../apache/camel/cloud/consul-service-discovery |  17 +
 .../apache/camel/model/ServiceCallDefinition    |  18 -
 .../cloud/ConsulServiceCallRouteTest.java       | 118 +++
 .../cloud/ConsulServiceDiscoveryTest.java       |  90 +++
 ...SpringConsulDefaultServiceCallRouteTest.java |  28 +
 .../SpringConsulRibbonServiceCallRouteTest.java |  28 +
 .../cloud/SpringConsulServiceCallRouteTest.java |  96 +++
 .../consul/policy/ConsulRoutePolicyMain.java    |   1 -
 .../remote/ConsulServiceCallRouteTest.java      | 114 ---
 ...nsulServiceCallServerListStrategiesTest.java |  92 ---
 .../SpringConsulDefaultServiceCallRouteTest.xml |  87 +++
 .../SpringConsulRibbonServiceCallRouteTest.xml  |  84 +++
 .../xml/AbstractCamelContextFactoryBean.java    |  14 +
 .../dns/cloud/DnsServiceDiscovery.java          | 102 +++
 .../dns/cloud/DnsServiceDiscoveryFactory.java   |  59 ++
 .../remote/DnsServiceCallProcessor.java         |  42 --
 .../remote/DnsServiceCallProcessorFactory.java  |  68 --
 .../processor/remote/DnsServiceCallServer.java  |  53 --
 .../DnsServiceCallServerListStrategies.java     |  77 --
 .../DnsServiceCallServerListStrategy.java       |  33 -
 .../remote/DnsServiceLookupFactory.java         |  52 --
 .../apache/camel/cloud/dns-service-discovery    |  17 +
 .../apache/camel/model/ServiceCallDefinition    |  18 -
 .../dns/cloud/DnsServiceDiscoveryTest.java      |  48 ++
 .../DnsServiceCallServerListStrategiesTest.java |  47 --
 .../camel/component/etcd/EtcdConfiguration.java |   4 +
 .../cloud/EtcdOnDemandServiceDiscovery.java     |  34 +
 .../etcd/cloud/EtcdServiceDefinition.java       |  45 ++
 .../etcd/cloud/EtcdServiceDiscovery.java        | 120 +++
 .../etcd/cloud/EtcdServiceDiscoveryFactory.java | 112 +++
 .../etcd/cloud/EtcdWatchServiceDiscovery.java   | 122 ++++
 .../remote/EtcdServiceCallProcessor.java        |  42 --
 .../remote/EtcdServiceCallProcessorFactory.java |  69 --
 .../processor/remote/EtcdServiceCallServer.java |  52 --
 .../EtcdServiceCallServerListStrategies.java    | 203 ------
 .../EtcdServiceCallServerListStrategy.java      |  73 --
 .../apache/camel/cloud/etcd-service-discovery   |  17 +
 .../apache/camel/model/ServiceCallDefinition    |  18 -
 .../etcd/cloud/EtcdServiceCallRouteTest.java    | 118 +++
 .../etcd/cloud/EtcdServiceDiscoveryTest.java    | 127 ++++
 .../SpringEtcdServiceCallDefaultRouteTest.java  |  83 +++
 .../cloud/SpringEtcdServiceCallRouteTest.java   |  96 +++
 .../remote/EtcdServiceCallRouteTest.java        | 117 ---
 .../EtcdServiceCallServerListStrategyTest.java  | 128 ----
 .../SpringEtcdServiceCallDefaultRouteTest.xml   |  48 ++
 .../cloud/SpringEtcdServiceCallRouteTest.xml    |  85 +++
 .../cloud/KubernetesClientServiceDiscovery.java | 148 ++++
 .../cloud/KubernetesDnsServiceDiscovery.java    |  48 ++
 .../cloud/KubernetesEnvServiceDiscovery.java    |  47 ++
 .../cloud/KubernetesServiceDiscovery.java       |  69 ++
 .../KubernetesServiceDiscoveryFactory.java      | 187 +++++
 .../KubernetesDnsServiceCallExpression.java     |  80 --
 .../processor/KubernetesProcessorFactory.java   |  74 --
 .../KubernetesServiceCallProcessor.java         |  53 --
 ...bernetesServiceCallServerListStrategies.java | 246 -------
 ...KubernetesServiceCallServerListStrategy.java |  70 --
 .../camel/cloud/kubernetes-service-discovery    |  17 +
 .../apache/camel/model/ServiceCallDefinition    |  18 -
 .../cloud/ServiceCallClientRouteTest.java       |  64 ++
 .../cloud/ServiceCallEnvironmentRouteTest.java  |  60 ++
 .../cloud/SpringServiceCallClientRouteTest.java |  42 ++
 .../cloud/SpringServiceCallDnsRouteTest.java    |  42 ++
 .../SpringServiceCallEnvironmentRouteTest.java  |  42 ++
 .../processor/ServiceCallClientRouteTest.java   |  62 --
 .../ServiceCallEnvironmentRouteTest.java        |  56 --
 .../SpringServiceCallClientRouteTest.java       |  41 --
 .../SpringServiceCallEnvironmentRouteTest.java  |  41 --
 .../cloud/SpringServiceCallClientRouteTest.xml  |  57 ++
 .../cloud/SpringServiceCallDnsRouteTest.xml     |  44 ++
 .../SpringServiceCallEnvironmentRouteTest.xml   |  44 ++
 .../SpringServiceCallClientRouteTest.xml        |  39 -
 .../SpringServiceCallEnvironmentRouteTest.xml   |  38 -
 .../component/ribbon/RibbonConfiguration.java   |  30 +-
 .../ribbon/cloud/RibbonLoadBalancer.java        | 231 ++++++
 .../ribbon/cloud/RibbonLoadBalancerFactory.java |  61 ++
 .../ribbon/cloud/RibbonServiceDefinition.java   |  74 ++
 .../processor/RibbonProcessorFactory.java       | 181 -----
 .../ribbon/processor/RibbonServer.java          |  59 --
 .../processor/RibbonServiceCallProcessor.java   | 250 -------
 ...bbonServiceCallStaticServerListStrategy.java | 108 ---
 .../org/apache/camel/cloud/ribbon-load-balancer |  17 +
 .../apache/camel/model/ServiceCallDefinition    |  18 -
 .../ribbon/cloud/RibbonServerListTest.java      |  56 ++
 .../RibbonServiceCallRegistryRouteTest.java     |  61 ++
 .../cloud/RibbonServiceCallRouteTest.java       |  72 ++
 .../cloud/RibbonServiceCallUpdateRouteTest.java |  99 +++
 .../cloud/SpringBeanServiceCallRouteTest.java   |  31 +
 .../SpringDslRibbonServiceCallRouteTest.java    |  31 +
 .../cloud/SpringRibbonServiceCallRouteTest.java |  40 +
 .../ribbon/processor/RibbonServerListTest.java  |  53 --
 .../RibbonServiceCallRegistryRouteTest.java     |  57 --
 .../processor/RibbonServiceCallRouteTest.java   |  65 --
 .../RibbonServiceCallUpdateRouteTest.java       |  90 ---
 .../SpringRibbonServiceCallRouteTest.java       |  46 --
 .../SpringBeanRibbonServiceCallRouteTest.xml    |  65 ++
 .../SpringDslRibbonServiceCallRouteTest.xml     |  58 ++
 .../SpringRibbonServiceCallRouteTest.xml        |  60 --
 .../spring/cloud/CamelCloudDiscoveryClient.java |  83 +++
 .../spring/cloud/CamelCloudLoadBalancer.java    |  71 ++
 .../cloud/CamelCloudServiceDiscovery.java       |  52 ++
 .../ServiceCallConfigurationProperties.java     | 113 +++
 ...erviceCallLoadBalancerAutoConfiguration.java |  54 ++
 ...viceCallServiceChooserAutoConfiguration.java |  64 ++
 ...ceCallServiceDiscoveryAutoConfiguration.java |  75 ++
 ...rviceCallServiceFilterAutoConfiguration.java |  58 ++
 .../CamelCloudServiceCallAutoConfiguration.java |  95 ---
 ...CloudServiceCallConfigurationProperties.java |  79 --
 .../CamelCloudServiceCallProcessor.java         | 200 -----
 .../CamelCloudServiceCallProcessorFactory.java  | 201 ------
 ...CamelCloudServiceCallServerListStrategy.java |  52 --
 .../apache/camel/model/ServiceCallDefinition    |  18 -
 .../main/resources/META-INF/spring.factories    |   4 +-
 .../CamelCloudServiceCallConfigurationTest.java |  76 ++
 .../cloud/CamelCloudServiceCallRibbonTest.java  |  85 +++
 .../spring/cloud/CamelCloudServiceCallTest.java |  86 +++
 .../remote/CamelCloudDiscoveryClient.java       |  71 --
 .../CamelCloudServiceCallConfigurationTest.java |  69 --
 .../remote/CamelCloudServiceCallRibbonTest.java |  83 ---
 .../remote/CamelCloudServiceCallTest.java       |  99 ---
 .../camel/osgi/CamelNamespaceHandler.java       |   1 +
 .../camel/spring/CamelContextFactoryBean.java   |  31 +-
 .../spring/handler/CamelNamespaceHandler.java   |  12 +-
 .../cloud/ServiceCallConfigurationTest.java     |  59 ++
 .../cloud/ServiceCallConfigurationTest.xml      |  51 ++
 .../cloud/ServiceCallConfigurationTest.java     |  50 ++
 .../cloud/ServiceCallConfigurationTest.xml      |  49 ++
 components/pom.xml                              |   4 +-
 227 files changed, 10338 insertions(+), 7192 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/readme-eip.adoc
----------------------------------------------------------------------
diff --git a/camel-core/readme-eip.adoc b/camel-core/readme-eip.adoc
index 1be6f05..1e7285e 100644
--- a/camel-core/readme-eip.adoc
+++ b/camel-core/readme-eip.adoc
@@ -21,9 +21,6 @@ Enterprise Integration Patterns
 | link:src/main/docs/eips/circuitBreaker-eip.adoc[Circuit Breaker] +
 `<circuitBreaker>` | Circuit break load balancer
 
-| link:src/main/docs/eips/consulConfiguration-eip.adoc[Consul Configuration] +
-`<consulConfiguration>` | Consul remote service call configuration
-
 | link:src/main/docs/eips/convertBodyTo-eip.adoc[Convert Body To] +
 `<convertBodyTo>` | Converts the message body to another type
 
@@ -33,18 +30,12 @@ Enterprise Integration Patterns
 | link:src/main/docs/eips/delay-eip.adoc[Delay] +
 `<delay>` | Delays processing for a specified length of time
 
-| link:src/main/docs/eips/dnsConfiguration-eip.adoc[Dns Configuration] +
-`<dnsConfiguration>` | DNS remote service call configuration
-
 | link:src/main/docs/eips/dynamicRouter-eip.adoc[Dynamic Router] +
 `<dynamicRouter>` | Routes messages based on dynamic rules
 
 | link:src/main/docs/eips/enrich-eip.adoc[Enrich] +
 `<enrich>` | Enriches a message with data from a secondary resource
 
-| link:src/main/docs/eips/etcdConfiguration-eip.adoc[Etcd Configuration] +
-`<etcdConfiguration>` | Etcd remote service call configuration
-
 | link:src/main/docs/eips/failover-eip.adoc[Failover] +
 `<failover>` | Failover load balancer
 
@@ -69,9 +60,6 @@ Enterprise Integration Patterns
 | link:src/main/docs/eips/inOut-eip.adoc[In Out] +
 `<inOut>` | Marks the exchange pattern for the route to request/reply
 
-| link:src/main/docs/eips/kubernetesConfiguration-eip.adoc[Kubernetes 
Configuration] +
-`<kubernetesConfiguration>` | Kubernetes remote service call configuration
-
 | link:src/main/docs/eips/loadBalance-eip.adoc[Load Balance] +
 `<loadBalance>` | Balances message processing among a number of nodes
 
@@ -120,9 +108,6 @@ Enterprise Integration Patterns
 | link:src/main/docs/eips/resequence-eip.adoc[Resequence] +
 `<resequence>` | Resequences (re-order) messages based on an expression
 
-| link:src/main/docs/eips/ribbonConfiguration-eip.adoc[Ribbon Configuration] +
-`<ribbonConfiguration>` | Ribbon remote service call configuration
-
 | link:src/main/docs/eips/rollback-eip.adoc[Rollback] +
 `<rollback>` | Forces a rollback by stopping routing the message
 
@@ -139,7 +124,7 @@ Enterprise Integration Patterns
 `<script>` | Executes a script from a language which does not change the 
message body.
 
 | link:src/main/docs/eips/serviceCall-eip.adoc[Service Call] +
-`<serviceCall>` | Remote service call
+`<serviceCall>` | Remote service call definition
 
 | link:src/main/docs/eips/serviceCallConfiguration-eip.adoc[Service Call 
Configuration] +
 `<serviceCallConfiguration>` | Remote service call configuration

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/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 72ad8a5..e37aa17 100644
--- a/camel-core/src/main/java/org/apache/camel/CamelContext.java
+++ b/camel-core/src/main/java/org/apache/camel/CamelContext.java
@@ -33,7 +33,7 @@ import org.apache.camel.model.DataFormatDefinition;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RoutesDefinition;
-import org.apache.camel.model.remote.ServiceCallConfigurationDefinition;
+import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
@@ -570,14 +570,13 @@ public interface CamelContext extends SuspendableService, 
RuntimeConfiguration {
     Collection<RestConfiguration> getRestConfigurations();
 
     /**
-     * Gets the service call configuration by the given name. If no name is 
given and there is only one configuration
-     * which matches the type then this configuration is returned.
+     * Gets the service call configuration by the given name. If no name is 
given
+     * the default configuration is returned, see 
<tt>setServiceCallConfiguration</tt>
      *
      * @param serviceName name of service, or <tt>null</tt> to return the 
default configuration
-     * @param type implementation of the configuration such as kubernetes, 
ribbon etc.
      * @return the configuration, or <tt>null</tt> if no configuration has 
been registered
      */
-    <T extends ServiceCallConfigurationDefinition> T 
getServiceCallConfiguration(String serviceName, Class<T> type);
+    ServiceCallConfigurationDefinition getServiceCallConfiguration(String 
serviceName);
 
     /**
      * Sets the default service call configuration
@@ -587,6 +586,13 @@ public interface CamelContext extends SuspendableService, 
RuntimeConfiguration {
     void setServiceCallConfiguration(ServiceCallConfigurationDefinition 
configuration);
 
     /**
+     * Sets the service call configurations
+     *
+     * @param configurations the configuration list
+     */
+    void setServiceCallConfigurations(List<ServiceCallConfigurationDefinition> 
configurations);
+
+    /**
      * Adds the service call configuration
      *
      * @param serviceName name of the service

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancer.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancer.java 
b/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancer.java
new file mode 100644
index 0000000..5974baf
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancer.java
@@ -0,0 +1,29 @@
+/**
+ * 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.cloud;
+
+/**
+ * Represents a Load Balancer.
+ *
+ * @see ServiceDiscovery
+ * @see ServiceFilter
+ * @see ServiceChooser
+ */
+@FunctionalInterface
+public interface LoadBalancer {
+    <T> T process(String serviceName, LoadBalancerFunction<T> function) throws 
Exception;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancerFactory.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancerFactory.java 
b/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancerFactory.java
new file mode 100644
index 0000000..3af581f
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancerFactory.java
@@ -0,0 +1,31 @@
+/**
+ * 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.cloud;
+
+import org.apache.camel.CamelContext;
+
+/**
+ * A factory to create LoadBalancer
+ *
+ * @see LoadBalancer
+ */
+public interface LoadBalancerFactory {
+    /**
+     * Creates an instance of a LoadBalancer.
+     */
+    LoadBalancer newInstance(CamelContext camelContext) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancerFunction.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancerFunction.java 
b/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancerFunction.java
new file mode 100644
index 0000000..b1a96d6
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/LoadBalancerFunction.java
@@ -0,0 +1,25 @@
+/**
+ * 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.cloud;
+
+/**
+ * Represents a load balancer function to be executed by the LoadBalancer.
+ */
+@FunctionalInterface
+public interface LoadBalancerFunction<T> {
+    T apply(ServiceDefinition serviceDefinition) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooser.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooser.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooser.java
new file mode 100644
index 0000000..7dc4eb3
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooser.java
@@ -0,0 +1,35 @@
+/**
+ * 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.cloud;
+
+import java.util.List;
+
+/**
+ * Allows SPIs to implement custom Service Chooser.
+ *
+ * @see ServiceDiscovery
+ */
+@FunctionalInterface
+public interface ServiceChooser {
+    /**
+     * Chooses one of the service to use
+     *
+     * @param services  list of services
+     * @return the chosen service to use.
+     */
+    ServiceDefinition choose(List<ServiceDefinition> services);
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooserAware.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooserAware.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooserAware.java
new file mode 100644
index 0000000..a2386de
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooserAware.java
@@ -0,0 +1,37 @@
+/**
+ * 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.cloud;
+
+/**
+ * An interface to represent an object which wishes to be injected with
+ * a {@link ServiceChooser}
+ */
+public interface ServiceChooserAware {
+    /**
+     * Injects the {@link ServiceChooser}
+     *
+     * @param serviceChooser the ServiceChooser
+     */
+    void setServiceChooser(ServiceChooser serviceChooser);
+
+    /**
+     * Get the {@link ServiceChooser}
+     *
+     * @return the ServiceChooser
+     */
+    ServiceChooser getServiceChooser();
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooserFactory.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooserFactory.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooserFactory.java
new file mode 100644
index 0000000..c3ab07f
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceChooserFactory.java
@@ -0,0 +1,31 @@
+/**
+ * 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.cloud;
+
+import org.apache.camel.CamelContext;
+
+/**
+ * A factory to create ServiceChooser
+ *
+ * @see ServiceChooser
+ */
+public interface ServiceChooserFactory {
+    /**
+     * Creates an instance of a ServiceChooser.
+     */
+    ServiceChooser newInstance(CamelContext camelContext) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceDefinition.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceDefinition.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceDefinition.java
new file mode 100644
index 0000000..f9dac27
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceDefinition.java
@@ -0,0 +1,52 @@
+/**
+ * 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.cloud;
+
+import java.util.Map;
+
+/**
+ * Represents a Service.
+ *
+ * @see ServiceChooser
+ * @see ServiceDiscovery
+ */
+public interface ServiceDefinition {
+    /**
+     * Gets the service name.
+     */
+    String getName();
+
+    /**
+     * Gets the IP or hostname of the server hosting the service.
+     */
+    String getHost();
+
+    /**
+     * Gets the port number of the server hosting the service.
+     */
+    int getPort();
+
+    /**
+     * Gets the health.
+     */
+    ServiceHealth getHealth();
+
+    /**
+     * Gets a key/value metadata associated with the service.
+     */
+    Map<String, String> getMetadata();
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscovery.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscovery.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscovery.java
new file mode 100644
index 0000000..28ff8af
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscovery.java
@@ -0,0 +1,47 @@
+/**
+ * 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.cloud;
+
+import java.util.List;
+
+/**
+ * Allows SPIs to implement custom Service Discovery.
+ *
+ * @see ServiceChooser
+ * @see ServiceDefinition
+ */
+public interface ServiceDiscovery {
+    /**
+     * Gets the initial list of services.
+     * <p/>
+     * This method may return <tt>null</tt> or an empty list.
+     *
+     * @param name the service name
+     */
+    List<ServiceDefinition> getInitialListOfServices(String name);
+
+    /**
+     * Gets the updated list of services.
+     * <p/>
+     * This method can either be called on-demand prior to a service call, or 
have
+     * a background job that is scheduled to update the list, or a watcher
+     * that triggers when the list of services changes.
+     *
+     * @param name the service name
+     */
+    List<ServiceDefinition> getUpdatedListOfServices(String name);
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscoveryAware.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscoveryAware.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscoveryAware.java
new file mode 100644
index 0000000..c33971b
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscoveryAware.java
@@ -0,0 +1,37 @@
+/**
+ * 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.cloud;
+
+/**
+ * An interface to represent an object which wishes to be injected with
+ * a {@link ServiceDiscovery}
+ */
+public interface ServiceDiscoveryAware {
+    /**
+     * Injects the {@link ServiceDiscovery}
+     *
+     * @param serviceDiscovery the ServiceDiscovery
+     */
+    void setServiceDiscovery(ServiceDiscovery serviceDiscovery);
+
+    /**
+     * Get the {@link ServiceDiscovery}
+     *
+     * @return the ServiceDiscovery
+     */
+    ServiceDiscovery getServiceDiscovery();
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscoveryFactory.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscoveryFactory.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscoveryFactory.java
new file mode 100644
index 0000000..44edfa9
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceDiscoveryFactory.java
@@ -0,0 +1,31 @@
+/**
+ * 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.cloud;
+
+import org.apache.camel.CamelContext;
+
+/**
+ * A factory to create ServiceDiscovery
+ *
+ * @see ServiceDiscovery
+ */
+public interface ServiceDiscoveryFactory {
+    /**
+     * Creates an instance of a ServiceDiscovery.
+     */
+    ServiceDiscovery newInstance(CamelContext camelContext) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceExpressionFactory.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceExpressionFactory.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceExpressionFactory.java
new file mode 100644
index 0000000..bcdbd52
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceExpressionFactory.java
@@ -0,0 +1,33 @@
+/**
+ * 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.cloud;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Expression;
+
+/**
+ * A factory to create Expression
+ *
+ * @see Expression
+ */
+public interface ServiceExpressionFactory {
+    /**
+     * Creates an instance of a ServiceChooser.
+     */
+    Expression newInstance(CamelContext camelContext) throws Exception;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilter.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilter.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilter.java
new file mode 100644
index 0000000..a8d61b3
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilter.java
@@ -0,0 +1,35 @@
+/**
+ * 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.cloud;
+
+import java.util.List;
+
+/**
+ * Allows SPIs to implement custom Service Filter.
+ *
+ * @see ServiceDiscovery
+ */
+@FunctionalInterface
+public interface ServiceFilter {
+    /**
+     * Chooses one of the service to use
+     *
+     * @param services  list of services
+     * @return the chosen service to use.
+     */
+    <T extends ServiceDefinition> List<T> apply(List<T> services);
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilterAware.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilterAware.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilterAware.java
new file mode 100644
index 0000000..ab0a21e
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilterAware.java
@@ -0,0 +1,37 @@
+/**
+ * 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.cloud;
+
+/**
+ * An interface to represent an object which wishes to be injected with
+ * a {@link ServiceFilter}
+ */
+public interface ServiceFilterAware {
+    /**
+     * Injects the {@link ServiceFilter}
+     *
+     * @param serviceFilter the ServiceFilter
+     */
+    void setServiceFilter(ServiceFilter serviceFilter);
+
+    /**
+     * Get the {@link ServiceFilter}
+     *
+     * @return the ServiceFilter
+     */
+    ServiceFilter getServiceFilter();
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilterFactory.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilterFactory.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilterFactory.java
new file mode 100644
index 0000000..f098351
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilterFactory.java
@@ -0,0 +1,31 @@
+/**
+ * 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.cloud;
+
+import org.apache.camel.CamelContext;
+
+/**
+ * A factory to create ServiceFilter
+ *
+ * @see ServiceFilter
+ */
+public interface ServiceFilterFactory {
+    /**
+     * Creates an instance of a ServiceFilter.
+     */
+    ServiceFilter newInstance(CamelContext camelContext) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/cloud/ServiceHealth.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/cloud/ServiceHealth.java 
b/camel-core/src/main/java/org/apache/camel/cloud/ServiceHealth.java
new file mode 100644
index 0000000..56257c6
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceHealth.java
@@ -0,0 +1,32 @@
+/**
+ * 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.cloud;
+
+import java.util.Map;
+
+public interface ServiceHealth {
+
+    /**
+     * Gets a key/value metadata associated with the service.
+     */
+    Map<String, String> getMetadata();
+
+    /**
+     * States if the service is healthy or not
+     */
+    boolean isHealthy();
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/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 788dc14..dc41670 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
@@ -104,7 +104,7 @@ import org.apache.camel.model.ProcessorDefinitionHelper;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RouteDefinitionHelper;
 import org.apache.camel.model.RoutesDefinition;
-import org.apache.camel.model.remote.ServiceCallConfigurationDefinition;
+import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition;
 import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.model.transformer.TransformerDefinition;
@@ -2598,33 +2598,30 @@ public class DefaultCamelContext extends ServiceSupport 
implements ModelCamelCon
         return config;
     }
 
-    @SuppressWarnings("unchecked")
-    public <T extends ServiceCallConfigurationDefinition> T 
getServiceCallConfiguration(String serviceName, Class<T> type) {
+    @Override
+    public ServiceCallConfigurationDefinition 
getServiceCallConfiguration(String serviceName) {
         if (serviceName == null) {
             serviceName = "";
         }
 
-        ServiceCallConfigurationDefinition config = 
serviceCallConfigurations.get(serviceName);
-        if (config == null) {
-            for (ServiceCallConfigurationDefinition candidate : 
serviceCallConfigurations.values()) {
-                if (type == null || type.isInstance(candidate)) {
-                    config = candidate;
-                    break;
-                }
-            }
-        }
-
-        if (config != null) {
-            return type != null ? type.cast(config) : (T) config;
-        } else {
-            return null;
-        }
+        return serviceCallConfigurations.get(serviceName);
     }
 
+    @Override
     public void setServiceCallConfiguration(ServiceCallConfigurationDefinition 
configuration) {
         serviceCallConfigurations.put("", configuration);
     }
 
+    @Override
+    public void 
setServiceCallConfigurations(List<ServiceCallConfigurationDefinition> 
configurations) {
+        if (configurations != null) {
+            for (ServiceCallConfigurationDefinition configuration : 
configurations) {
+                serviceCallConfigurations.put(configuration.getId(), 
configuration);
+            }
+        }
+    }
+
+    @Override
     public void addServiceCallConfiguration(String serviceName, 
ServiceCallConfigurationDefinition configuration) {
         serviceCallConfigurations.put(serviceName, configuration);
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/AllServiceFilter.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/AllServiceFilter.java 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/AllServiceFilter.java
new file mode 100644
index 0000000..0635b33
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/AllServiceFilter.java
@@ -0,0 +1,32 @@
+/**
+ * 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.List;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceFilter;
+
+public class AllServiceFilter implements ServiceFilter {
+    public static final ServiceFilter INSTANCE = new AllServiceFilter();
+
+    @Override
+    public <T extends ServiceDefinition> List<T> apply(List<T> services) {
+        return services;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/CachingServiceDiscovery.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/CachingServiceDiscovery.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/CachingServiceDiscovery.java
new file mode 100644
index 0000000..39394bb
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/CachingServiceDiscovery.java
@@ -0,0 +1,104 @@
+/**
+ * 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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceDiscovery;
+import org.apache.camel.util.ObjectHelper;
+
+public class CachingServiceDiscovery implements ServiceDiscovery {
+    private final ServiceDiscovery delegate;
+    private List<ServiceDefinition> services;
+    private long lastUpdate;
+    private long timeout;
+
+    public CachingServiceDiscovery(ServiceDiscovery delegate) {
+        this.delegate = ObjectHelper.notNull(delegate, "delegate");
+        this.lastUpdate = 0;
+        this.services = Collections.emptyList();
+        this.timeout = 60 * 1000; // 1 min;
+    }
+
+    public void setTimeout(long timeout) {
+        this.timeout = timeout;
+    }
+
+    public void setTimeout(long timeout, TimeUnit unit) {
+        this.timeout = unit.toMillis(timeout);
+    }
+
+    public long getTimeout() {
+        return timeout;
+    }
+
+    public CachingServiceDiscovery timeout(long timeout) {
+        setTimeout(timeout);
+        return this;
+    }
+
+    public CachingServiceDiscovery timeout(long timeout, TimeUnit unit) {
+        setTimeout(timeout, unit);
+        return this;
+    }
+
+    @Override
+    public List<ServiceDefinition> getInitialListOfServices(String name) {
+        return delegate.getInitialListOfServices(name);
+    }
+
+    @Override
+    public List<ServiceDefinition> getUpdatedListOfServices(String name) {
+        long now = System.currentTimeMillis();
+
+        if (lastUpdate == 0 || now > lastUpdate + timeout) {
+            List<ServiceDefinition> updatedList = 
delegate.getUpdatedListOfServices(name);
+            if (updatedList.isEmpty()) {
+                services = Collections.emptyList();
+            } else {
+                // List is copied as the delegated ServiceCallServiceDiscovery
+                // may update the list
+                services = Collections.unmodifiableList(new 
ArrayList<>(updatedList));
+            }
+
+            lastUpdate = now;
+        }
+
+        return services;
+    }
+
+    // **********************
+    // Helpers
+    // **********************
+
+    public static CachingServiceDiscovery wrap(ServiceDiscovery delegate) {
+        return new CachingServiceDiscovery(delegate);
+    }
+
+    public static CachingServiceDiscovery wrap(ServiceDiscovery delegate, long 
timeout) {
+        return new CachingServiceDiscovery(delegate).timeout(timeout);
+    }
+
+    public static CachingServiceDiscovery wrap(ServiceDiscovery delegate, long 
timeout, TimeUnit unit) {
+        return new CachingServiceDiscovery(delegate).timeout(timeout, unit);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultLoadBalancer.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultLoadBalancer.java 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultLoadBalancer.java
new file mode 100644
index 0000000..2e45ce2
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultLoadBalancer.java
@@ -0,0 +1,148 @@
+/**
+ * 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.List;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.cloud.LoadBalancer;
+import org.apache.camel.cloud.LoadBalancerFunction;
+import org.apache.camel.cloud.ServiceChooser;
+import org.apache.camel.cloud.ServiceChooserAware;
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceDiscovery;
+import org.apache.camel.cloud.ServiceDiscoveryAware;
+import org.apache.camel.cloud.ServiceFilter;
+import org.apache.camel.cloud.ServiceFilterAware;
+import org.apache.camel.support.ServiceSupport;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ServiceHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DefaultLoadBalancer
+        extends ServiceSupport
+        implements CamelContextAware, ServiceDiscoveryAware, 
ServiceChooserAware, ServiceFilterAware, LoadBalancer {
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultLoadBalancer.class);
+
+    private CamelContext camelContext;
+    private ServiceDiscovery serviceDiscovery;
+    private ServiceChooser serviceChooser;
+    private ServiceFilter serviceFilter;
+
+    public DefaultLoadBalancer() {
+    }
+
+    // *************************************
+    // Bean
+    // *************************************
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public ServiceDiscovery getServiceDiscovery() {
+        return serviceDiscovery;
+    }
+
+    @Override
+    public void setServiceDiscovery(ServiceDiscovery serverDiscovery) {
+        this.serviceDiscovery = serverDiscovery;
+    }
+
+    @Override
+    public ServiceChooser getServiceChooser() {
+        return serviceChooser;
+    }
+
+    @Override
+    public void setServiceChooser(ServiceChooser serverChooser) {
+        this.serviceChooser = serverChooser;
+    }
+
+    @Override
+    public void setServiceFilter(ServiceFilter serviceFilter) {
+        this.serviceFilter = serviceFilter;
+    }
+
+    @Override
+    public ServiceFilter getServiceFilter() {
+        return serviceFilter;
+    }
+
+    // *************************************
+    // Lifecycle
+    // *************************************
+
+    @Override
+    protected void doStart() throws Exception {
+        ObjectHelper.notNull(camelContext, "camel context");
+        ObjectHelper.notNull(serviceDiscovery, "service discovery");
+        ObjectHelper.notNull(serviceChooser, "service chooser");
+        ObjectHelper.notNull(serviceFilter, "service serviceFilter");
+
+        LOGGER.info("ServiceCall is using default load balancer with service 
discovery type: {}, service filter type: {} and service chooser type: {}",
+            serviceDiscovery.getClass(),
+            serviceFilter.getClass(),
+            serviceChooser.getClass());
+
+        ServiceHelper.startService(serviceChooser);
+        ServiceHelper.startService(serviceDiscovery);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        // Stop services if needed
+        ServiceHelper.stopService(serviceDiscovery);
+        ServiceHelper.stopService(serviceChooser);
+    }
+
+    // *************************************
+    // Load Balancer
+    // *************************************
+
+    @Override
+    public <T> T process(String serviceName, LoadBalancerFunction<T> function) 
throws Exception {
+        ServiceDefinition service;
+
+        List<ServiceDefinition> services = 
serviceDiscovery.getUpdatedListOfServices(serviceName);
+        if (services == null || services.isEmpty()) {
+            throw new RejectedExecutionException("No active services with name 
" + serviceName);
+        } else {
+            // filter services
+            services = serviceFilter.apply(services);
+            // let the client service chooser find which server to use
+            service = services.size() > 1 ? serviceChooser.choose(services) : 
services.get(0);
+            if (service == null) {
+                throw new RejectedExecutionException("No active services with 
name " + serviceName);
+            }
+        }
+
+        return function.apply(service);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallExpression.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallExpression.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallExpression.java
new file mode 100644
index 0000000..b642912
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallExpression.java
@@ -0,0 +1,85 @@
+/**
+ * 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 org.apache.camel.model.cloud.ServiceCallDefinition;
+import org.apache.camel.support.ServiceCallExpressionSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Support class for custom implementations of {@link ServiceCallDefinition 
ServiceCall EIP} components.
+ * <p/>
+ * Below are some examples how to call a service and what Camel endpoint URI 
is constructed based on the input:
+ * <pre>
+ serviceCall("myService") -> http://hostname:port
+ serviceCall("myService/foo") -> http://hostname:port/foo
+ serviceCall("http:myService/foo") -> http:hostname:port/foo
+ serviceCall("myService", "http:myService.host:myService.port/foo") -> 
http:hostname:port/foo
+ serviceCall("myService", "netty4:tcp:myService?connectTimeout=1000") -> 
netty:tcp:hostname:port?connectTimeout=1000
+ * </pre>
+ */
+public class DefaultServiceCallExpression extends ServiceCallExpressionSupport 
{
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultServiceCallExpression.class);
+
+    @Override
+    protected String buildCamelEndpointUri(String name, String host, Integer 
port, String uri, String contextPath, String scheme) {
+        // build basic uri if none provided
+        String answer = uri;
+        if (answer == null) {
+            if (scheme == null) {
+                // use http/https by default if no scheme or port have been 
configured
+                if (port == null) {
+                    scheme = "http";
+                } else if (port == 443) {
+                    scheme = "https";
+                } else {
+                    scheme = "http";
+                }
+            }
+            answer = scheme + "://" + host;
+            if (port != null) {
+                answer = answer + ":" + port;
+            }
+            if (contextPath != null) {
+                if (!contextPath.startsWith("/")) {
+                    contextPath = "/" + contextPath;
+                }
+
+                answer += contextPath;
+            }
+        } else {
+            // we have existing uri, then replace the serviceName with ip:port
+            if (answer.contains(name + ".host")) {
+                answer = answer.replaceFirst(name + "\\.host", host);
+            }
+            if (answer.contains(name + ".port") && port != null) {
+                answer = answer.replaceFirst(name + "\\.port", "" + port);
+            }
+            if (answer.contains(name) && port != null) {
+                answer = answer.replaceFirst(name, host + ":" + port);
+            }
+            if (answer.contains(name) && port == null) {
+                answer = answer.replaceFirst(name, host);
+            }
+        }
+
+        LOGGER.debug("Camel endpoint uri: {} for calling service: {} on server 
{}:{}", answer, name, host, port);
+        return answer;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/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
new file mode 100644
index 0000000..edf1f6a
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceCallProcessor.java
@@ -0,0 +1,153 @@
+/**
+ * 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 org.apache.camel.AsyncCallback;
+import org.apache.camel.AsyncProcessor;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.Expression;
+import org.apache.camel.Message;
+import org.apache.camel.cloud.LoadBalancer;
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.processor.SendDynamicProcessor;
+import org.apache.camel.support.ServiceSupport;
+import org.apache.camel.util.AsyncProcessorHelper;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ServiceHelper;
+import org.apache.camel.util.StringHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DefaultServiceCallProcessor extends ServiceSupport implements 
AsyncProcessor {
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(DefaultServiceCallProcessor.class);
+
+    private final ExchangePattern exchangePattern;
+    private final String name;
+    private final String scheme;
+    private final String uri;
+    private final String contextPath;
+    private final CamelContext camelContext;
+    private final LoadBalancer loadBalancer;
+    private final Expression expression;
+    private SendDynamicProcessor processor;
+
+    public DefaultServiceCallProcessor(
+        CamelContext camelContext, String name, String scheme, String uri, 
ExchangePattern exchangePattern,
+        LoadBalancer loadBalancer, Expression expression) {
+
+        this.uri = uri;
+        this.exchangePattern = exchangePattern;
+        this.camelContext = camelContext;
+        this.loadBalancer = loadBalancer;
+
+        // setup from the provided name which can contain scheme and 
context-path information as well
+        String serviceName;
+        if (name.contains("/")) {
+            serviceName = StringHelper.before(name, "/");
+            this.contextPath = StringHelper.after(name, "/");
+        } else if (name.contains("?")) {
+            serviceName = StringHelper.before(name, "?");
+            this.contextPath = StringHelper.after(name, "?");
+        } else {
+            serviceName = name;
+            this.contextPath = null;
+        }
+        if (serviceName.contains(":")) {
+            this.scheme = StringHelper.before(serviceName, ":");
+            this.name = StringHelper.after(serviceName, ":");
+        } else {
+            this.scheme = scheme;
+            this.name = serviceName;
+        }
+
+        this.expression = expression;
+    }
+
+    // *************************************
+    // Lifecycle
+    // *************************************
+
+    @Override
+    protected void doStart() throws Exception {
+        StringHelper.notEmpty(name, "name", "service name");
+        ObjectHelper.notNull(camelContext, "camel context");
+        ObjectHelper.notNull(expression, "expression");
+        ObjectHelper.notNull(loadBalancer, "load balancer");
+
+        processor = new SendDynamicProcessor(uri, expression);
+        processor.setCamelContext(camelContext);
+        if (exchangePattern != null) {
+            processor.setPattern(exchangePattern);
+        }
+
+        // Start services if needed
+        ServiceHelper.startService(processor);
+        ServiceHelper.startService(loadBalancer);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        // Stop services if needed
+        ServiceHelper.stopService(loadBalancer);
+        ServiceHelper.stopService(processor);
+    }
+
+    // *************************************
+    // Processor
+    // *************************************
+
+    @Override
+    public void process(Exchange exchange) throws Exception {
+        AsyncProcessorHelper.process(this, exchange);
+    }
+
+    @Override
+    public boolean process(final Exchange exchange, final AsyncCallback 
callback) {
+        Message message = exchange.getIn();
+        message.setHeader(ServiceCallConstants.SERVICE_CALL_URI, uri);
+        message.setHeader(ServiceCallConstants.SERVICE_CALL_CONTEXT_PATH, 
contextPath);
+        message.setHeader(ServiceCallConstants.SERVICE_CALL_SCHEME, scheme);
+
+        String serviceName = 
message.getHeader(ServiceCallConstants.SERVICE_NAME, name, String.class);
+
+        try {
+            return loadBalancer.process(serviceName, server -> execute(server, 
exchange, callback));
+        } catch (Exception e) {
+            exchange.setException(e);
+            return true;
+        }
+    }
+
+    private boolean execute(ServiceDefinition server, Exchange exchange, 
AsyncCallback callback) throws Exception {
+        String host = server.getHost();
+        int port = server.getPort();
+
+        LOGGER.debug("Service {} active at server: {}:{}", name, host, port);
+
+        // set selected server as header
+        exchange.getIn().setHeader(ServiceCallConstants.SERVICE_HOST, host);
+        exchange.getIn().setHeader(ServiceCallConstants.SERVICE_PORT, port > 0 
? port : null);
+        exchange.getIn().setHeader(ServiceCallConstants.SERVICE_NAME, 
server.getName());
+        exchange.getIn().setHeader(ServiceCallConstants.SERVICE_META, 
server.getMetadata());
+
+        // use the dynamic send processor to call the service
+        return processor.process(exchange, callback);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceDefinition.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceDefinition.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceDefinition.java
new file mode 100644
index 0000000..d510847
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceDefinition.java
@@ -0,0 +1,98 @@
+/**
+ * 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.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceHealth;
+
+public class DefaultServiceDefinition implements ServiceDefinition {
+
+    private final String name;
+    private final String host;
+    private final int port;
+    private final Map<String, String> meta;
+    private final ServiceHealth health;
+
+    public DefaultServiceDefinition(String name, String host, int port) {
+        this.name = name;
+        this.host = host;
+        this.port = port;
+        this.meta = Collections.emptyMap();
+        this.health = DefaultServiceHealth.INSTANCE;
+    }
+
+    public DefaultServiceDefinition(String name, String host, int port, 
ServiceHealth health) {
+        this.name = name;
+        this.host = host;
+        this.port = port;
+        this.meta = Collections.emptyMap();
+        this.health = health;
+    }
+
+    public DefaultServiceDefinition(String name, String host, int port, 
Map<String, String> meta) {
+        this.name = name;
+        this.host = host;
+        this.port = port;
+        this.meta = meta != null ? Collections.unmodifiableMap(new 
HashMap<>(meta)) : Collections.emptyMap();
+        this.health = DefaultServiceHealth.INSTANCE;
+    }
+
+    public DefaultServiceDefinition(String name, String host, int port, 
Map<String, String> meta, ServiceHealth health) {
+        this.name = name;
+        this.host = host;
+        this.port = port;
+        this.meta = meta != null ? Collections.unmodifiableMap(new 
HashMap<>(meta)) : Collections.emptyMap();
+        this.health = health;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public String getHost() {
+        return host;
+    }
+
+    @Override
+    public int getPort() {
+        return port;
+    }
+
+    @Override
+    public ServiceHealth getHealth() {
+        return health;
+    }
+
+    @Override
+    public Map<String, String> getMetadata() {
+        return this.meta;
+    }
+
+    @Override
+    public String toString() {
+        return "DefaultServiceCallService[" + name + "@" + host + ":" + port + 
"]";
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceDiscovery.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceDiscovery.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceDiscovery.java
new file mode 100644
index 0000000..cf4fb1b
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceDiscovery.java
@@ -0,0 +1,64 @@
+/**
+ * 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.Collections;
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceDiscovery;
+import org.apache.camel.support.ServiceSupport;
+
+
+public class DefaultServiceDiscovery
+    extends ServiceSupport implements ServiceDiscovery, CamelContextAware {
+
+    private CamelContext camelContext;
+
+    @Override
+    public List<ServiceDefinition> getInitialListOfServices(String name) {
+        return getUpdatedListOfServices(name);
+    }
+
+    @Override
+    public List<ServiceDefinition> getUpdatedListOfServices(String name) {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        // nop
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        // nop
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceFilter.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceFilter.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceFilter.java
new file mode 100644
index 0000000..2b58032
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceFilter.java
@@ -0,0 +1,30 @@
+/**
+ * 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.List;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceFilter;
+
+public class DefaultServiceFilter implements ServiceFilter {
+    @Override
+    public <T extends ServiceDefinition> List<T> apply(List<T> services) {
+        return services;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceHealth.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceHealth.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceHealth.java
new file mode 100644
index 0000000..f83b5ec
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/DefaultServiceHealth.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.cloud;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.camel.cloud.ServiceHealth;
+
+public class DefaultServiceHealth implements ServiceHealth {
+    public static final ServiceHealth INSTANCE = new DefaultServiceHealth();
+
+    private final boolean healthy;
+    private final Map<String, String> meta;
+
+    public DefaultServiceHealth() {
+        this(true, null);
+    }
+    public DefaultServiceHealth(boolean healthy) {
+        this(healthy, null);
+    }
+
+    public DefaultServiceHealth(Map<String, String> meta) {
+        this(true, meta);
+    }
+
+    public DefaultServiceHealth(boolean healthy, Map<String, String> meta) {
+        this.healthy = healthy;
+        this.meta = meta != null ? Collections.unmodifiableMap(new 
HashMap<>(meta)) : Collections.emptyMap();
+    }
+
+    @Override
+    public boolean isHealthy() {
+        return this.healthy;
+    }
+
+    @Override
+    public Map<String, String> getMetadata() {
+        return this.meta;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/HealthyServiceFilter.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/HealthyServiceFilter.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/HealthyServiceFilter.java
new file mode 100644
index 0000000..deb55ae
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/HealthyServiceFilter.java
@@ -0,0 +1,33 @@
+/**
+ * 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.List;
+import java.util.stream.Collectors;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceFilter;
+
+public class HealthyServiceFilter implements ServiceFilter {
+    public static final ServiceFilter INSTANCE = new HealthyServiceFilter();
+
+    @Override
+    public <T extends ServiceDefinition> List<T> apply(List<T> services) {
+        return services.stream().filter(s -> 
s.getHealth().isHealthy()).collect(Collectors.toList());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/RandomServiceChooser.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/RandomServiceChooser.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/RandomServiceChooser.java
new file mode 100644
index 0000000..00c4af1
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/RandomServiceChooser.java
@@ -0,0 +1,45 @@
+/**
+ * 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.List;
+import java.util.Random;
+
+import org.apache.camel.cloud.ServiceChooser;
+import org.apache.camel.cloud.ServiceDefinition;
+
+public class RandomServiceChooser implements ServiceChooser {
+    private final Random random;
+
+    public RandomServiceChooser() {
+        this.random = new Random();
+    }
+
+    @Override
+    public ServiceDefinition choose(List<ServiceDefinition> servers) {
+        int size = servers.size();
+        int index = (size > 1) ? random.nextInt(size) : 0;
+
+        return servers.get(index);
+    }
+
+    @Override
+    public String toString() {
+        return "RandomServiceCallServiceChooser";
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/camel-core/src/main/java/org/apache/camel/impl/cloud/RoundRobinServiceChooser.java
----------------------------------------------------------------------
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/RoundRobinServiceChooser.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/RoundRobinServiceChooser.java
new file mode 100644
index 0000000..79d6e39
--- /dev/null
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/RoundRobinServiceChooser.java
@@ -0,0 +1,41 @@
+/**
+ * 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.List;
+
+import org.apache.camel.cloud.ServiceChooser;
+import org.apache.camel.cloud.ServiceDefinition;
+
+public class RoundRobinServiceChooser implements ServiceChooser {
+    private int counter = -1;
+
+    @Override
+    public ServiceDefinition choose(List<ServiceDefinition> servers) {
+        int size = servers.size();
+        if (size == 1 || ++counter >= size) {
+            counter = 0;
+        }
+        return servers.get(counter);
+    }
+
+    @Override
+    public String toString() {
+        return "RoundRobinServiceCallServiceChooser";
+    }
+}

Reply via email to