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/01/30 18:37:21 UTC

[2/2] camel git commit: CAMEL-10761: ServiceCall EIP : support for chaining service filters/discovery

CAMEL-10761: ServiceCall EIP : support for chaining service filters/discovery


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

Branch: refs/heads/master
Commit: 0aae1257b4317504a717ff490ce827a686ac8edb
Parents: 9c6263d
Author: lburgazzoli <lb...@gmail.com>
Authored: Fri Jan 27 11:16:29 2017 +0100
Committer: lburgazzoli <lb...@gmail.com>
Committed: Mon Jan 30 19:34:31 2017 +0100

----------------------------------------------------------------------
 .../org/apache/camel/cloud/ServiceFilter.java   |   2 +-
 .../camel/impl/cloud/AllServiceFilter.java      |  32 ----
 .../impl/cloud/BlacklistServiceFilter.java      | 133 +++++++++++++++
 .../cloud/BlacklistServiceFilterFactory.java    |  57 +++++++
 .../impl/cloud/CachingServiceDiscovery.java     |  39 ++---
 .../impl/cloud/ChainedServiceDiscovery.java     |  59 +++++++
 .../cloud/ChainedServiceDiscoveryFactory.java   |  54 ++++++
 .../camel/impl/cloud/ChainedServiceFilter.java  |  57 +++++++
 .../impl/cloud/ChainedServiceFilterFactory.java |  54 ++++++
 .../impl/cloud/DefaultServiceDefinition.java    |  26 +++
 .../camel/impl/cloud/DefaultServiceFilter.java  |   2 +-
 .../camel/impl/cloud/HealthyServiceFilter.java  |   2 +-
 .../impl/cloud/HealthyServiceFilterFactory.java |  35 ++++
 .../camel/impl/cloud/MultiServiceDiscovery.java |  59 -------
 .../cloud/MultiServiceDiscoveryFactory.java     |  54 ------
 .../impl/cloud/PassThroughServiceFilter.java    |  32 ++++
 .../cloud/PassThroughServiceFilterFactory.java  |  35 ++++
 .../impl/cloud/StaticServiceDiscovery.java      |  44 +++--
 ...stServiceCallServiceFilterConfiguration.java |  87 ++++++++++
 ...erviceCallServiceDiscoveryConfiguration.java |   6 +-
 ...erviceCallServiceDiscoveryConfiguration.java | 169 +++++++++++++++++++
 ...edServiceCallServiceFilterConfiguration.java | 138 +++++++++++++++
 ...omServiceCallServiceFilterConfiguration.java | 106 ++++++++++++
 ...hyServiceCallServiceFilterConfiguration.java |  36 ++++
 ...erviceCallServiceDiscoveryConfiguration.java | 169 -------------------
 ...ghServiceCallServiceFilterConfiguration.java |  36 ++++
 .../ServiceCallConfigurationDefinition.java     |  77 ++++++++-
 .../camel/model/cloud/ServiceCallConstants.java |  12 +-
 .../model/cloud/ServiceCallDefinition.java      | 116 +++++++++++--
 .../apache/camel/cloud/blacklist-service-filter |  17 ++
 .../camel/cloud/chained-service-discovery       |  17 ++
 .../apache/camel/cloud/chained-service-filter   |  17 ++
 .../apache/camel/cloud/healthy-service-filter   |  17 ++
 .../apache/camel/cloud/multi-service-discovery  |  17 --
 .../camel/cloud/pass-through-service-filter     |  17 ++
 .../org/apache/camel/model/cloud/jaxb.index     |   6 +-
 .../impl/cloud/ChainedServiceDiscoveryTest.java |  71 ++++++++
 .../impl/cloud/ChainedServiceFilterTest.java    |  66 ++++++++
 .../camel/impl/cloud/LoadBalancerTest.java      |  42 +++++
 .../impl/cloud/MultiServiceDiscoveryTest.java   |  71 --------
 .../ribbon/cloud/RibbonLoadBalancer.java        |  39 ++---
 .../ribbon/cloud/RibbonServerListTest.java      |  20 +--
 .../ServiceCallConfigurationProperties.java     |   5 +
 ...rviceCallServiceFilterAutoConfiguration.java |  32 ++--
 .../spring/cloud/CamelCloudServiceCallTest.java |   9 +-
 .../cloud/ServiceCallConfigurationTest.java     |  14 +-
 .../spring/cloud/ServiceCallFilterTest.java     |  69 ++++++++
 .../cloud/ServiceCallConfigurationTest.xml      |  12 +-
 .../spring/cloud/ServiceCallFilterTest.xml      |  53 ++++++
 .../blueprint/cloud/ServiceCallFilterTest.java  |  58 +++++++
 .../blueprint/cloud/ServiceCallFilterTest.xml   |  52 ++++++
 51 files changed, 1929 insertions(+), 520 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/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
index a8d61b3..99c697a 100644
--- a/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilter.java
+++ b/camel-core/src/main/java/org/apache/camel/cloud/ServiceFilter.java
@@ -31,5 +31,5 @@ public interface ServiceFilter {
      * @param services  list of services
      * @return the chosen service to use.
      */
-    <T extends ServiceDefinition> List<T> apply(List<T> services);
+    List<ServiceDefinition> apply(List<ServiceDefinition> services);
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/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
deleted file mode 100644
index 0635b33..0000000
--- a/camel-core/src/main/java/org/apache/camel/impl/cloud/AllServiceFilter.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * 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/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/BlacklistServiceFilter.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/BlacklistServiceFilter.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/BlacklistServiceFilter.java
new file mode 100644
index 0000000..44edb3d
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/BlacklistServiceFilter.java
@@ -0,0 +1,133 @@
+/**
+ * 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.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceFilter;
+import org.apache.camel.util.StringHelper;
+
+public class BlacklistServiceFilter implements ServiceFilter {
+    private List<ServiceDefinition> services;
+
+    public BlacklistServiceFilter() {
+        this.services = new ArrayList<>();
+    }
+
+    public BlacklistServiceFilter(List<ServiceDefinition> blacklist) {
+        this.services = new ArrayList<>(blacklist);
+    }
+
+    /**
+     * Set the servers.
+     *
+     * @param servers server in the format: [service@]host:port.
+     */
+    public void setServers(List<String> servers) {
+        this.services.clear();
+        servers.forEach(this::addServer);
+    }
+
+    /**
+     * Set the servers.
+     *
+     * @param servers servers separated by comma in the format: [service@]host:port,[service@]host2:port,[service@]host3:port and so on.
+     */
+    public void setServers(String servers) {
+        this.services.clear();
+        addServer(servers);
+    }
+
+    /**
+     * Add a server to the known list of servers.
+     */
+    public void addServer(ServiceDefinition server) {
+        services.add(server);
+    }
+
+    /**
+     * Add a server to the known list of servers.
+     * @param serverString servers separated by comma in the format: [service@]host:port,[service@]host2:port,[service@]host3:port and so on.
+     */
+    public void addServer(String serverString) {
+        String[] parts = serverString.split(",");
+        for (String part : parts) {
+            String service = StringHelper.before(part, "@");
+            if (service != null) {
+                part = StringHelper.after(part, "@");
+            }
+            String host = StringHelper.before(part, ":");
+            String port = StringHelper.after(part, ":");
+
+            addServer(service, host, Integer.valueOf(port));
+        }
+    }
+
+    /**
+     * Add a server to the known list of servers.
+     */
+    public void addServer(String host, int port) {
+        addServer(null, host, port, null);
+    }
+
+    /**
+     * Add a server to the known list of servers.
+     */
+    public void addServer(String name, String host, int port) {
+        addServer(name, host, port, null);
+    }
+
+    /**
+     * Add a server to the known list of servers.
+     */
+    public void addServer(String name, String host, int port, Map<String, String> meta) {
+        services.add(new DefaultServiceDefinition(name, host, port, meta));
+    }
+
+    @Override
+    public List<ServiceDefinition> apply(List<ServiceDefinition> services) {
+        return services.stream().filter(s -> !this.services.contains(s)).collect(Collectors.toList());
+    }
+
+    // *************************************************************************
+    // Helpers
+    // *************************************************************************
+
+    public static BlacklistServiceFilter forServices(Collection<ServiceDefinition> definitions) {
+        BlacklistServiceFilter filter = new BlacklistServiceFilter();
+        for (ServiceDefinition definition: definitions) {
+            filter.addServer(definition);
+        }
+
+        return filter;
+    }
+
+    public static BlacklistServiceFilter forServices(ServiceDefinition... definitions) {
+        BlacklistServiceFilter filter = new BlacklistServiceFilter();
+        for (ServiceDefinition definition: definitions) {
+            filter.addServer(definition);
+        }
+
+        return filter;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/BlacklistServiceFilterFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/BlacklistServiceFilterFactory.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/BlacklistServiceFilterFactory.java
new file mode 100644
index 0000000..5563fa3
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/BlacklistServiceFilterFactory.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.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.cloud.ServiceFilter;
+import org.apache.camel.cloud.ServiceFilterFactory;
+
+public class BlacklistServiceFilterFactory implements ServiceFilterFactory {
+    private List<String> servers;
+
+    public BlacklistServiceFilterFactory() {
+    }
+
+    // *************************************************************************
+    // Properties
+    // *************************************************************************
+
+    public List<String> getServers() {
+        return servers;
+    }
+
+    public void setServers(List<String> servers) {
+        this.servers = servers;
+    }
+
+    // *************************************************************************
+    // Factory
+    // *************************************************************************
+
+    @Override
+    public ServiceFilter newInstance(CamelContext camelContext) throws Exception {
+        BlacklistServiceFilter serviceFilter = new BlacklistServiceFilter();
+        if (servers != null) {
+            serviceFilter.setServers(servers);
+        }
+
+        return serviceFilter;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/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
index 56ee5fb..99923e9 100644
--- 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
@@ -17,30 +17,31 @@
 
 package org.apache.camel.impl.cloud;
 
-import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.LoadingCache;
 import org.apache.camel.cloud.ServiceDefinition;
 import org.apache.camel.cloud.ServiceDiscovery;
 import org.apache.camel.util.ObjectHelper;
 
-public class CachingServiceDiscovery implements ServiceDiscovery {
+public final class CachingServiceDiscovery implements ServiceDiscovery {
     private final ServiceDiscovery delegate;
-    private List<ServiceDefinition> services;
-    private long lastUpdate;
+    private LoadingCache<String, List<ServiceDefinition>> cache;
     private long timeout;
 
     public CachingServiceDiscovery(ServiceDiscovery delegate) {
         this(delegate, 60 * 1000);
     }
 
+    public CachingServiceDiscovery(ServiceDiscovery delegate, long timeout, TimeUnit unit) {
+        this(delegate, unit.toMillis(timeout));
+    }
+
     public CachingServiceDiscovery(ServiceDiscovery delegate, long timeout) {
         this.delegate = ObjectHelper.notNull(delegate, "delegate");
-        this.lastUpdate = 0;
-        this.services = Collections.emptyList();
-        this.timeout = timeout;
+        setTimeout(timeout);
     }
 
     public ServiceDiscovery getDelegate() {
@@ -49,10 +50,13 @@ public class CachingServiceDiscovery implements ServiceDiscovery {
 
     public void setTimeout(long timeout) {
         this.timeout = timeout;
+        this.cache = Caffeine.newBuilder()
+            .expireAfterAccess(timeout, TimeUnit.MILLISECONDS)
+            .build(delegate::getUpdatedListOfServices);
     }
 
     public void setTimeout(long timeout, TimeUnit unit) {
-        this.timeout = unit.toMillis(timeout);
+        setTimeout(unit.toMillis(timeout));
     }
 
     public long getTimeout() {
@@ -76,22 +80,7 @@ public class CachingServiceDiscovery implements ServiceDiscovery {
 
     @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;
+        return cache.get(name);
     }
 
     // **********************

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceDiscovery.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceDiscovery.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceDiscovery.java
new file mode 100644
index 0000000..a00fe5b
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceDiscovery.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.impl.cloud;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceDiscovery;
+
+public class ChainedServiceDiscovery implements ServiceDiscovery {
+    private final List<ServiceDiscovery> delegates;
+
+    public ChainedServiceDiscovery(List<ServiceDiscovery> delegates) {
+        this.delegates = Collections.unmodifiableList(delegates);
+    }
+
+    public List<ServiceDiscovery> getDelegates() {
+        return this.delegates;
+    }
+
+    @Override
+    public List<ServiceDefinition> getInitialListOfServices(String name) {
+        return delegates.stream()
+            .flatMap(d -> d.getInitialListOfServices(name).stream())
+            .collect(Collectors.toList());
+    }
+
+    @Override
+    public List<ServiceDefinition> getUpdatedListOfServices(String name) {
+        return delegates.stream()
+            .flatMap(d -> d.getInitialListOfServices(name).stream())
+            .collect(Collectors.toList());
+    }
+
+    // **********************
+    // Helpers
+    // **********************
+
+    public static ChainedServiceDiscovery wrap(ServiceDiscovery... delegates) {
+        return new ChainedServiceDiscovery(Arrays.asList(delegates));
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceDiscoveryFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceDiscoveryFactory.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceDiscoveryFactory.java
new file mode 100644
index 0000000..6c8acc8
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceDiscoveryFactory.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.impl.cloud;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.cloud.ServiceDiscovery;
+import org.apache.camel.cloud.ServiceDiscoveryFactory;
+import org.apache.camel.util.ObjectHelper;
+
+public class ChainedServiceDiscoveryFactory implements ServiceDiscoveryFactory {
+    private List<ServiceDiscovery> serviceDiscoveryList;
+
+    public ChainedServiceDiscoveryFactory() {
+    }
+
+    // *************************************************************************
+    // Properties
+    // *************************************************************************
+
+    public List<ServiceDiscovery> getServiceDiscoveryList() {
+        return serviceDiscoveryList;
+    }
+
+    public void setServiceDiscoveryList(List<ServiceDiscovery> serviceDiscoveryList) {
+        this.serviceDiscoveryList = serviceDiscoveryList;
+    }
+
+    // *************************************************************************
+    // Factory
+    // *************************************************************************
+
+    @Override
+    public ServiceDiscovery newInstance(CamelContext camelContext) throws Exception {
+        ObjectHelper.notNull(serviceDiscoveryList, "ServiceDiscovery list");
+
+        return new ChainedServiceDiscovery(serviceDiscoveryList);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceFilter.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceFilter.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceFilter.java
new file mode 100644
index 0000000..caeebbc
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceFilter.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.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceFilter;
+
+public class ChainedServiceFilter implements ServiceFilter {
+    private final List<ServiceFilter> delegates;
+    private final int delegatesSize;
+
+    public ChainedServiceFilter(List<ServiceFilter> delegates) {
+        this.delegates = Collections.unmodifiableList(new ArrayList<>(delegates));
+        this.delegatesSize = this.delegates.size();
+    }
+
+    public List<ServiceFilter> getDelegates() {
+        return this.delegates;
+    }
+
+
+    @Override
+    public List<ServiceDefinition> apply(List<ServiceDefinition> services) {
+        for (int i = 0; i < delegatesSize; i++) {
+            services = delegates.get(i).apply(services);
+        }
+
+        return services;
+    }
+
+    // **********************
+    // Helpers
+    // **********************
+
+    public static ChainedServiceFilter wrap(ServiceFilter... delegates) {
+        return new ChainedServiceFilter(Arrays.asList(delegates));
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceFilterFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceFilterFactory.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceFilterFactory.java
new file mode 100644
index 0000000..15c9af7
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/ChainedServiceFilterFactory.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.impl.cloud;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.cloud.ServiceFilter;
+import org.apache.camel.cloud.ServiceFilterFactory;
+import org.apache.camel.util.ObjectHelper;
+
+public class ChainedServiceFilterFactory implements ServiceFilterFactory {
+    private List<ServiceFilter> serviceFilterList;
+
+    public ChainedServiceFilterFactory() {
+    }
+
+    // *************************************************************************
+    // Properties
+    // *************************************************************************
+
+    public List<ServiceFilter> getServiceFilterList() {
+        return serviceFilterList;
+    }
+
+    public void setServiceFilterList(List<ServiceFilter> serviceFilterList) {
+        this.serviceFilterList = serviceFilterList;
+    }
+
+    // *************************************************************************
+    // Factory
+    // *************************************************************************
+
+    @Override
+    public ServiceFilter newInstance(CamelContext camelContext) throws Exception {
+        ObjectHelper.notNull(serviceFilterList, "ServiceFilter list");
+
+        return new ChainedServiceFilter(serviceFilterList);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/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
index d510847..5e72a7b 100644
--- 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
@@ -94,5 +94,31 @@ public class DefaultServiceDefinition implements ServiceDefinition {
         return "DefaultServiceCallService[" + name + "@" + host + ":" + port + "]";
     }
 
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        DefaultServiceDefinition that = (DefaultServiceDefinition) o;
+
+        if (port != that.port) {
+            return false;
+        }
+        if (name != null ? !name.equals(that.name) : that.name != null) {
+            return false;
+        }
+        return host != null ? host.equals(that.host) : that.host == null;
+    }
 
+    @Override
+    public int hashCode() {
+        int result = name != null ? name.hashCode() : 0;
+        result = 31 * result + (host != null ? host.hashCode() : 0);
+        result = 31 * result + port;
+        return result;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/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
index 2b58032..1fd6ee6 100644
--- 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
@@ -24,7 +24,7 @@ import org.apache.camel.cloud.ServiceFilter;
 
 public class DefaultServiceFilter implements ServiceFilter {
     @Override
-    public <T extends ServiceDefinition> List<T> apply(List<T> services) {
+    public List<ServiceDefinition> apply(List<ServiceDefinition> services) {
         return services;
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/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
index deb55ae..26c5795 100644
--- 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
@@ -27,7 +27,7 @@ public class HealthyServiceFilter implements ServiceFilter {
     public static final ServiceFilter INSTANCE = new HealthyServiceFilter();
 
     @Override
-    public <T extends ServiceDefinition> List<T> apply(List<T> services) {
+    public List<ServiceDefinition> apply(List<ServiceDefinition> services) {
         return services.stream().filter(s -> s.getHealth().isHealthy()).collect(Collectors.toList());
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/HealthyServiceFilterFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/HealthyServiceFilterFactory.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/HealthyServiceFilterFactory.java
new file mode 100644
index 0000000..2bde718
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/HealthyServiceFilterFactory.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.impl.cloud;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.cloud.ServiceFilter;
+import org.apache.camel.cloud.ServiceFilterFactory;
+
+public class HealthyServiceFilterFactory implements ServiceFilterFactory {
+    public HealthyServiceFilterFactory() {
+    }
+
+    // *************************************************************************
+    // Factory
+    // *************************************************************************
+
+    @Override
+    public ServiceFilter newInstance(CamelContext camelContext) throws Exception {
+        return new HealthyServiceFilter();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/MultiServiceDiscovery.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/MultiServiceDiscovery.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/MultiServiceDiscovery.java
deleted file mode 100644
index 44ea721..0000000
--- a/camel-core/src/main/java/org/apache/camel/impl/cloud/MultiServiceDiscovery.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * 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.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import org.apache.camel.cloud.ServiceDefinition;
-import org.apache.camel.cloud.ServiceDiscovery;
-
-public class MultiServiceDiscovery implements ServiceDiscovery {
-    private final List<ServiceDiscovery> delegates;
-
-    public MultiServiceDiscovery(List<ServiceDiscovery> delegates) {
-        this.delegates = Collections.unmodifiableList(delegates);
-    }
-
-    public List<ServiceDiscovery> getDelegates() {
-        return this.delegates;
-    }
-
-    @Override
-    public List<ServiceDefinition> getInitialListOfServices(String name) {
-        return delegates.stream()
-            .flatMap(d -> d.getInitialListOfServices(name).stream())
-            .collect(Collectors.toList());
-    }
-
-    @Override
-    public List<ServiceDefinition> getUpdatedListOfServices(String name) {
-        return delegates.stream()
-            .flatMap(d -> d.getInitialListOfServices(name).stream())
-            .collect(Collectors.toList());
-    }
-
-    // **********************
-    // Helpers
-    // **********************
-
-    public static MultiServiceDiscovery wrap(ServiceDiscovery... delegates) {
-        return new MultiServiceDiscovery(Arrays.asList(delegates));
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/MultiServiceDiscoveryFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/MultiServiceDiscoveryFactory.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/MultiServiceDiscoveryFactory.java
deleted file mode 100644
index 61dcd76..0000000
--- a/camel-core/src/main/java/org/apache/camel/impl/cloud/MultiServiceDiscoveryFactory.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * 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.CamelContext;
-import org.apache.camel.cloud.ServiceDiscovery;
-import org.apache.camel.cloud.ServiceDiscoveryFactory;
-import org.apache.camel.util.ObjectHelper;
-
-public class MultiServiceDiscoveryFactory implements ServiceDiscoveryFactory {
-    private List<ServiceDiscovery> serviceDiscoveryList;
-
-    public MultiServiceDiscoveryFactory() {
-    }
-
-    // *************************************************************************
-    // Properties
-    // *************************************************************************
-
-    public List<ServiceDiscovery> getServiceDiscoveryList() {
-        return serviceDiscoveryList;
-    }
-
-    public void setServiceDiscoveryList(List<ServiceDiscovery> serviceDiscoveryList) {
-        this.serviceDiscoveryList = serviceDiscoveryList;
-    }
-
-    // *************************************************************************
-    // Factory
-    // *************************************************************************
-
-    @Override
-    public ServiceDiscovery newInstance(CamelContext camelContext) throws Exception {
-        ObjectHelper.notNull(serviceDiscoveryList, "ServiceDiscovery list");
-
-        return new MultiServiceDiscovery(serviceDiscoveryList);
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/PassThroughServiceFilter.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/PassThroughServiceFilter.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/PassThroughServiceFilter.java
new file mode 100644
index 0000000..2b80a7c
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/PassThroughServiceFilter.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 PassThroughServiceFilter implements ServiceFilter {
+    public static final ServiceFilter INSTANCE = new PassThroughServiceFilter();
+
+    @Override
+    public List<ServiceDefinition> apply(List<ServiceDefinition> services) {
+        return services;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/PassThroughServiceFilterFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/PassThroughServiceFilterFactory.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/PassThroughServiceFilterFactory.java
new file mode 100644
index 0000000..86468c6
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/PassThroughServiceFilterFactory.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.impl.cloud;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.cloud.ServiceFilter;
+import org.apache.camel.cloud.ServiceFilterFactory;
+
+public class PassThroughServiceFilterFactory implements ServiceFilterFactory {
+    public PassThroughServiceFilterFactory() {
+    }
+
+    // *************************************************************************
+    // Factory
+    // *************************************************************************
+
+    @Override
+    public ServiceFilter newInstance(CamelContext camelContext) throws Exception {
+        return new PassThroughServiceFilter();
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/impl/cloud/StaticServiceDiscovery.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/impl/cloud/StaticServiceDiscovery.java b/camel-core/src/main/java/org/apache/camel/impl/cloud/StaticServiceDiscovery.java
index 49d3094..1507b24 100644
--- a/camel-core/src/main/java/org/apache/camel/impl/cloud/StaticServiceDiscovery.java
+++ b/camel-core/src/main/java/org/apache/camel/impl/cloud/StaticServiceDiscovery.java
@@ -18,6 +18,7 @@
 package org.apache.camel.impl.cloud;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -31,15 +32,14 @@ import org.apache.camel.util.StringHelper;
  * A static list of known servers Camel Service Call EIP.
  */
 public class StaticServiceDiscovery extends DefaultServiceDiscovery {
-
-    private final List<ServiceDefinition> servers;
+    private final List<ServiceDefinition> services;
 
     public StaticServiceDiscovery() {
-        this.servers = new ArrayList<>();
+        this.services = new ArrayList<>();
     }
 
     public StaticServiceDiscovery(List<ServiceDefinition> servers) {
-        this.servers = new ArrayList<>(servers);
+        this.services = new ArrayList<>(servers);
     }
 
     /**
@@ -48,7 +48,7 @@ public class StaticServiceDiscovery extends DefaultServiceDiscovery {
      * @param servers server in the format: [service@]host:port.
      */
     public void setServers(List<String> servers) {
-        this.servers.clear();
+        this.services.clear();
         servers.forEach(this::addServer);
     }
 
@@ -58,7 +58,7 @@ public class StaticServiceDiscovery extends DefaultServiceDiscovery {
      * @param servers servers separated by comma in the format: [service@]host:port,[service@]host2:port,[service@]host3:port and so on.
      */
     public void setServers(String servers) {
-        this.servers.clear();
+        this.services.clear();
         addServer(servers);
     }
 
@@ -66,7 +66,7 @@ public class StaticServiceDiscovery extends DefaultServiceDiscovery {
      * Add a server to the known list of servers.
      */
     public void addServer(ServiceDefinition server) {
-        servers.add(server);
+        services.add(server);
     }
 
     /**
@@ -105,14 +105,14 @@ public class StaticServiceDiscovery extends DefaultServiceDiscovery {
      * Add a server to the known list of servers.
      */
     public void addServer(String name, String host, int port, Map<String, String> meta) {
-        servers.add(new DefaultServiceDefinition(name, host, port, meta));
+        services.add(new DefaultServiceDefinition(name, host, port, meta));
     }
 
     /**
      * Remove an existing server from the list of known servers.
      */
     public void removeServer(String host, int port) {
-        servers.removeIf(
+        services.removeIf(
             s -> Objects.equals(host, s.getHost()) && port == s.getPort()
         );
     }
@@ -121,7 +121,7 @@ public class StaticServiceDiscovery extends DefaultServiceDiscovery {
      * Remove an existing server from the list of known servers.
      */
     public void removeServer(String name, String host, int port) {
-        servers.removeIf(
+        services.removeIf(
             s -> Objects.equals(name, s.getName()) && Objects.equals(host, s.getHost()) && port == s.getPort()
         );
     }
@@ -129,9 +129,31 @@ public class StaticServiceDiscovery extends DefaultServiceDiscovery {
     @Override
     public List<ServiceDefinition> getUpdatedListOfServices(String name) {
         return Collections.unmodifiableList(
-            servers.stream()
+            services.stream()
                 .filter(s -> Objects.isNull(s.getName()) || Objects.equals(name, s.getName()))
                 .collect(Collectors.toList())
         );
     }
+
+    // *************************************************************************
+    // Helpers
+    // *************************************************************************
+
+    public static StaticServiceDiscovery forServices(Collection<ServiceDefinition> definitions) {
+        StaticServiceDiscovery discovery = new StaticServiceDiscovery();
+        for (ServiceDefinition definition: definitions) {
+            discovery.addServer(definition);
+        }
+
+        return discovery;
+    }
+
+    public static StaticServiceDiscovery forServices(ServiceDefinition... definitions) {
+        StaticServiceDiscovery discovery = new StaticServiceDiscovery();
+        for (ServiceDefinition definition: definitions) {
+            discovery.addServer(definition);
+        }
+
+        return discovery;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/model/cloud/BlacklistServiceCallServiceFilterConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/BlacklistServiceCallServiceFilterConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/BlacklistServiceCallServiceFilterConfiguration.java
new file mode 100644
index 0000000..ea67c25
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/BlacklistServiceCallServiceFilterConfiguration.java
@@ -0,0 +1,87 @@
+/**
+ * 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.cloud;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.spi.Metadata;
+
+@Metadata(label = "routing,cloud,service-filter")
+@XmlRootElement(name = "blacklistServiceFilter")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class BlacklistServiceCallServiceFilterConfiguration extends ServiceCallServiceFilterConfiguration {
+    @XmlElement
+    private List<String> servers;
+
+    public BlacklistServiceCallServiceFilterConfiguration() {
+        this(null);
+    }
+
+    public BlacklistServiceCallServiceFilterConfiguration(ServiceCallDefinition parent) {
+        super(parent, "blacklist-service-filter");
+    }
+
+    // *************************************************************************
+    // Properties
+    // *************************************************************************
+
+    public List<String> getServers() {
+        return servers;
+    }
+
+    /**
+     * Sets the server list;
+     */
+    public void setServers(List<String> servers) {
+        this.servers = servers;
+    }
+
+    /**
+     * Sets the server list;
+     */
+    public void addServer(String server) {
+        if (this.servers == null) {
+            this.servers = new ArrayList<>();
+        }
+
+        this.servers.add(server);
+    }
+
+    // *************************************************************************
+    // Fluent API
+    // *************************************************************************
+
+    /**
+     * Sets the server list;
+     */
+    public BlacklistServiceCallServiceFilterConfiguration servers(List<String> servers) {
+        setServers(servers);
+        return this;
+    }
+    /**
+     * Add a server to the list of servers
+     */
+    public BlacklistServiceCallServiceFilterConfiguration server(String server) {
+        addServer(server);
+        return this;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/model/cloud/CachingServiceCallServiceDiscoveryConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/CachingServiceCallServiceDiscoveryConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/CachingServiceCallServiceDiscoveryConfiguration.java
index 5c1682b..9b7ee98 100644
--- a/camel-core/src/main/java/org/apache/camel/model/cloud/CachingServiceCallServiceDiscoveryConfiguration.java
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/CachingServiceCallServiceDiscoveryConfiguration.java
@@ -45,7 +45,7 @@ public class CachingServiceCallServiceDiscoveryConfiguration extends ServiceCall
         @XmlElement(name = "dnsServiceDiscovery", type = DnsServiceCallServiceDiscoveryConfiguration.class),
         @XmlElement(name = "etcdServiceDiscovery", type = EtcdServiceCallServiceDiscoveryConfiguration.class),
         @XmlElement(name = "kubernetesServiceDiscovery", type = KubernetesServiceCallServiceDiscoveryConfiguration.class),
-        @XmlElement(name = "multiServiceDiscovery", type = MultiServiceCallServiceDiscoveryConfiguration.class),
+        @XmlElement(name = "multiServiceDiscovery", type = ChainedServiceCallServiceDiscoveryConfiguration.class),
         @XmlElement(name = "staticServiceDiscovery", type = StaticServiceCallServiceDiscoveryConfiguration.class)}
     )
     private ServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration;
@@ -163,8 +163,8 @@ public class CachingServiceCallServiceDiscoveryConfiguration extends ServiceCall
         return conf;
     }
 
-    public MultiServiceCallServiceDiscoveryConfiguration multiServiceDiscovery() {
-        MultiServiceCallServiceDiscoveryConfiguration conf = new MultiServiceCallServiceDiscoveryConfiguration();
+    public ChainedServiceCallServiceDiscoveryConfiguration multiServiceDiscovery() {
+        ChainedServiceCallServiceDiscoveryConfiguration conf = new ChainedServiceCallServiceDiscoveryConfiguration();
         setServiceDiscoveryConfiguration(conf);
 
         return conf;

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/model/cloud/ChainedServiceCallServiceDiscoveryConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ChainedServiceCallServiceDiscoveryConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ChainedServiceCallServiceDiscoveryConfiguration.java
new file mode 100644
index 0000000..5197d0e
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ChainedServiceCallServiceDiscoveryConfiguration.java
@@ -0,0 +1,169 @@
+/**
+ * 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.cloud;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.cloud.ServiceDiscovery;
+import org.apache.camel.spi.Metadata;
+
+@Metadata(label = "routing,cloud,service-discovery")
+@XmlRootElement(name = "multiServiceDiscovery")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ChainedServiceCallServiceDiscoveryConfiguration extends ServiceCallServiceDiscoveryConfiguration {
+    @XmlElements({
+        @XmlElement(name = "consulServiceDiscovery", type = ConsulServiceCallServiceDiscoveryConfiguration.class),
+        @XmlElement(name = "dnsServiceDiscovery", type = DnsServiceCallServiceDiscoveryConfiguration.class),
+        @XmlElement(name = "etcdServiceDiscovery", type = EtcdServiceCallServiceDiscoveryConfiguration.class),
+        @XmlElement(name = "kubernetesServiceDiscovery", type = KubernetesServiceCallServiceDiscoveryConfiguration.class),
+        @XmlElement(name = "staticServiceDiscovery", type = StaticServiceCallServiceDiscoveryConfiguration.class),
+        @XmlElement(name = "cachingServiceDiscovery", type = CachingServiceCallServiceDiscoveryConfiguration.class)}
+    )
+    private List<ServiceCallServiceDiscoveryConfiguration> serviceDiscoveryConfigurations;
+
+    public ChainedServiceCallServiceDiscoveryConfiguration() {
+        this(null);
+    }
+
+    public ChainedServiceCallServiceDiscoveryConfiguration(ServiceCallDefinition parent) {
+        super(parent, "chained-service-discovery");
+    }
+
+    // *************************************************************************
+    // Properties
+    // *************************************************************************
+
+    public List<ServiceCallServiceDiscoveryConfiguration> getServiceDiscoveryConfigurations() {
+        return serviceDiscoveryConfigurations;
+    }
+
+    /**
+     * List of ServiceDiscovery configuration to use
+     * @param serviceDiscoveryConfigurations
+     */
+    public void setServiceDiscoveryConfigurations(List<ServiceCallServiceDiscoveryConfiguration> serviceDiscoveryConfigurations) {
+        this.serviceDiscoveryConfigurations = serviceDiscoveryConfigurations;
+    }
+
+    /**
+     *  Add a ServiceDiscovery configuration
+     */
+    public void addServiceDiscoveryConfigurations(ServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration) {
+        if (serviceDiscoveryConfigurations == null) {
+            serviceDiscoveryConfigurations = new ArrayList<>();
+        }
+
+        serviceDiscoveryConfigurations.add(serviceDiscoveryConfiguration);
+    }
+
+    // *************************************************************************
+    // Fluent API
+    // *************************************************************************
+
+    /**
+     *  List of ServiceDiscovery configuration to use
+     */
+    public ChainedServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfigurations(List<ServiceCallServiceDiscoveryConfiguration> serviceDiscoveryConfigurations) {
+        setServiceDiscoveryConfigurations(serviceDiscoveryConfigurations);
+        return this;
+    }
+
+    /**
+     *  Add a ServiceDiscovery configuration
+     */
+    public ChainedServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration(ServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration) {
+        addServiceDiscoveryConfigurations(serviceDiscoveryConfiguration);
+        return this;
+    }
+
+    // *****************************
+    // Shortcuts - ServiceDiscovery
+    // *****************************
+
+    public CachingServiceCallServiceDiscoveryConfiguration cachingServiceDiscovery() {
+        CachingServiceCallServiceDiscoveryConfiguration conf = new CachingServiceCallServiceDiscoveryConfiguration();
+        addServiceDiscoveryConfigurations(conf);
+
+        return conf;
+    }
+
+    public ConsulServiceCallServiceDiscoveryConfiguration consulServiceDiscovery() {
+        ConsulServiceCallServiceDiscoveryConfiguration conf = new ConsulServiceCallServiceDiscoveryConfiguration();
+        addServiceDiscoveryConfigurations(conf);
+
+        return conf;
+    }
+
+    public DnsServiceCallServiceDiscoveryConfiguration dnsServiceDiscovery() {
+        DnsServiceCallServiceDiscoveryConfiguration conf = new DnsServiceCallServiceDiscoveryConfiguration();
+        addServiceDiscoveryConfigurations(conf);
+
+        return conf;
+    }
+
+    public EtcdServiceCallServiceDiscoveryConfiguration etcdServiceDiscovery() {
+        EtcdServiceCallServiceDiscoveryConfiguration conf = new EtcdServiceCallServiceDiscoveryConfiguration();
+        addServiceDiscoveryConfigurations(conf);
+
+        return conf;
+    }
+
+    public KubernetesServiceCallServiceDiscoveryConfiguration kubernetesServiceDiscovery() {
+        KubernetesServiceCallServiceDiscoveryConfiguration conf = new KubernetesServiceCallServiceDiscoveryConfiguration();
+        addServiceDiscoveryConfigurations(conf);
+
+        return conf;
+    }
+
+    public ChainedServiceCallServiceDiscoveryConfiguration multiServiceDiscovery() {
+        ChainedServiceCallServiceDiscoveryConfiguration conf = new ChainedServiceCallServiceDiscoveryConfiguration();
+        addServiceDiscoveryConfigurations(conf);
+
+        return conf;
+    }
+
+    public StaticServiceCallServiceDiscoveryConfiguration staticServiceDiscovery() {
+        StaticServiceCallServiceDiscoveryConfiguration conf = new StaticServiceCallServiceDiscoveryConfiguration();
+        addServiceDiscoveryConfigurations(conf);
+
+        return conf;
+    }
+
+    // *************************************************************************
+    // Utilities
+    // *************************************************************************
+
+    @Override
+    protected void postProcessFactoryParameters(final CamelContext camelContext, final Map<String, Object> parameters) throws Exception {
+        if (serviceDiscoveryConfigurations != null && !serviceDiscoveryConfigurations.isEmpty()) {
+            List<ServiceDiscovery> discoveries = new ArrayList<>(serviceDiscoveryConfigurations.size());
+            for (ServiceCallServiceDiscoveryConfiguration conf : serviceDiscoveryConfigurations) {
+                discoveries.add(conf.newInstance(camelContext));
+            }
+
+            parameters.put("serviceDiscoveryList", discoveries);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/model/cloud/ChainedServiceCallServiceFilterConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/ChainedServiceCallServiceFilterConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/ChainedServiceCallServiceFilterConfiguration.java
new file mode 100644
index 0000000..e6e2ff3
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/ChainedServiceCallServiceFilterConfiguration.java
@@ -0,0 +1,138 @@
+/**
+ * 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.cloud;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElements;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.cloud.ServiceFilter;
+import org.apache.camel.spi.Metadata;
+
+@Metadata(label = "routing,cloud,service-filter")
+@XmlRootElement(name = "multiServiceFilter")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class ChainedServiceCallServiceFilterConfiguration extends ServiceCallServiceFilterConfiguration {
+    @XmlElements({
+        @XmlElement(name = "blacklistServiceFilter", type = BlacklistServiceCallServiceFilterConfiguration.class),
+        @XmlElement(name = "customServiceFilter", type = CustomServiceCallServiceFilterConfiguration.class),
+        @XmlElement(name = "healthyServiceFilter", type = HealthyServiceCallServiceFilterConfiguration.class),
+        @XmlElement(name = "passThroughServiceFilter", type = PassThroughServiceCallServiceFilterConfiguration.class) }
+    )
+    private List<ServiceCallServiceFilterConfiguration> serviceFilterConfigurations;
+
+    public ChainedServiceCallServiceFilterConfiguration() {
+        this(null);
+    }
+
+    public ChainedServiceCallServiceFilterConfiguration(ServiceCallDefinition parent) {
+        super(parent, "chained-service-filter");
+    }
+
+    // *************************************************************************
+    // Properties
+    // *************************************************************************
+
+    public List<ServiceCallServiceFilterConfiguration> getServiceFilterConfigurations() {
+        return serviceFilterConfigurations;
+    }
+
+    /**
+     * List of ServiceFilter configuration to use
+     * @param serviceFilterConfigurations
+     */
+    public void setServiceFilterConfigurations(List<ServiceCallServiceFilterConfiguration> serviceFilterConfigurations) {
+        this.serviceFilterConfigurations = serviceFilterConfigurations;
+    }
+
+    /**
+     *  Add a ServiceFilter configuration
+     */
+    public void addServiceFilterConfiguration(ServiceCallServiceFilterConfiguration serviceFilterConfiguration) {
+        if (serviceFilterConfigurations == null) {
+            serviceFilterConfigurations = new ArrayList<>();
+        }
+
+        serviceFilterConfigurations.add(serviceFilterConfiguration);
+    }
+
+    // *************************************************************************
+    // Fluent API
+    // *************************************************************************
+
+    /**
+     *  List of ServiceFilter configuration to use
+     */
+    public ChainedServiceCallServiceFilterConfiguration serviceFilterConfigurations(List<ServiceCallServiceFilterConfiguration> serviceFilterConfigurations) {
+        setServiceFilterConfigurations(serviceFilterConfigurations);
+        return this;
+    }
+
+    /**
+     *  Add a ServiceFilter configuration
+     */
+    public ChainedServiceCallServiceFilterConfiguration serviceFilterConfiguration(ServiceCallServiceFilterConfiguration serviceFilterConfiguration) {
+        addServiceFilterConfiguration(serviceFilterConfiguration);
+        return this;
+    }
+
+    // *****************************
+    // Shortcuts - ServiceFilter
+    // *****************************
+
+    public ChainedServiceCallServiceFilterConfiguration healthy() {
+        addServiceFilterConfiguration(new HealthyServiceCallServiceFilterConfiguration());
+        return this;
+    }
+
+    public ChainedServiceCallServiceFilterConfiguration passThrough() {
+        addServiceFilterConfiguration(new PassThroughServiceCallServiceFilterConfiguration());
+        return this;
+    }
+
+    public ChainedServiceCallServiceFilterConfiguration custom(String serviceFilter) {
+        addServiceFilterConfiguration(new CustomServiceCallServiceFilterConfiguration().serviceFilter(serviceFilter));
+        return this;
+    }
+
+    public ChainedServiceCallServiceFilterConfiguration custom(ServiceFilter serviceFilter) {
+        addServiceFilterConfiguration(new CustomServiceCallServiceFilterConfiguration().serviceFilter(serviceFilter));
+        return this;
+    }
+
+    // *************************************************************************
+    // Utilities
+    // *************************************************************************
+
+    @Override
+    protected void postProcessFactoryParameters(final CamelContext camelContext, final Map<String, Object> parameters) throws Exception {
+        if (serviceFilterConfigurations != null && !serviceFilterConfigurations.isEmpty()) {
+            List<ServiceFilter> discoveries = new ArrayList<>(serviceFilterConfigurations.size());
+            for (ServiceCallServiceFilterConfiguration conf : serviceFilterConfigurations) {
+                discoveries.add(conf.newInstance(camelContext));
+            }
+
+            parameters.put("serviceFilterList", discoveries);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/model/cloud/CustomServiceCallServiceFilterConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/CustomServiceCallServiceFilterConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/CustomServiceCallServiceFilterConfiguration.java
new file mode 100644
index 0000000..64f9548
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/CustomServiceCallServiceFilterConfiguration.java
@@ -0,0 +1,106 @@
+/**
+ * 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.cloud;
+
+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;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.cloud.ServiceFilter;
+import org.apache.camel.spi.Metadata;
+
+@Metadata(label = "routing,cloud,service-filter")
+@XmlRootElement(name = "customServiceFilter")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class CustomServiceCallServiceFilterConfiguration extends ServiceCallServiceFilterConfiguration {
+    @XmlAttribute(name = "ref")
+    private String serviceFilterRef;
+    @XmlTransient
+    private ServiceFilter serviceFilter;
+
+    public CustomServiceCallServiceFilterConfiguration() {
+        this(null);
+    }
+
+    public CustomServiceCallServiceFilterConfiguration(ServiceCallDefinition parent) {
+        super(parent, "custom-service-filter");
+    }
+
+    // *************************************************************************
+    // Properties
+    // *************************************************************************
+
+    public String getServiceFilterRef() {
+        return serviceFilterRef;
+    }
+
+    /**
+     * Reference of a ServiceFilter
+     */
+    public void setServiceFilterRef(String serviceFilterRef) {
+        this.serviceFilterRef = serviceFilterRef;
+    }
+
+    public ServiceFilter getServiceFilter() {
+        return serviceFilter;
+    }
+
+    /**
+     * Set the ServiceFilter
+     */
+    public void setServiceFilter(ServiceFilter serviceFilter) {
+        this.serviceFilter = serviceFilter;
+    }
+
+
+    // *************************************************************************
+    // Fluent API
+    // *************************************************************************
+
+    /**
+     * Reference of a ServiceFilter
+     */
+    public CustomServiceCallServiceFilterConfiguration serviceFilter(String serviceFilter) {
+        setServiceFilterRef(serviceFilter);
+        return this;
+    }
+
+    /**
+     * Set the ServiceFilter
+     */
+    public CustomServiceCallServiceFilterConfiguration serviceFilter(ServiceFilter serviceFilter) {
+        setServiceFilter(serviceFilter);
+        return this;
+    }
+
+    // *************************************************************************
+    // Factory
+    // *************************************************************************
+
+    @Override
+    public ServiceFilter newInstance(CamelContext camelContext) throws Exception {
+        ServiceFilter answer = serviceFilter;
+        if (serviceFilterRef != null) {
+            answer = camelContext.getRegistry().lookupByNameAndType(serviceFilterRef, ServiceFilter.class);
+        }
+
+        return answer;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/model/cloud/HealthyServiceCallServiceFilterConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/HealthyServiceCallServiceFilterConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/HealthyServiceCallServiceFilterConfiguration.java
new file mode 100644
index 0000000..898715d
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/HealthyServiceCallServiceFilterConfiguration.java
@@ -0,0 +1,36 @@
+/**
+ * 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.cloud;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.spi.Metadata;
+
+@Metadata(label = "routing,cloud,service-filter")
+@XmlRootElement(name = "healthyServiceFilter")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class HealthyServiceCallServiceFilterConfiguration extends ServiceCallServiceFilterConfiguration {
+    public HealthyServiceCallServiceFilterConfiguration() {
+        this(null);
+    }
+
+    public HealthyServiceCallServiceFilterConfiguration(ServiceCallDefinition parent) {
+        super(parent, "healthy-service-filter");
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/model/cloud/MultiServiceCallServiceDiscoveryConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/MultiServiceCallServiceDiscoveryConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/MultiServiceCallServiceDiscoveryConfiguration.java
deleted file mode 100644
index b45ac99..0000000
--- a/camel-core/src/main/java/org/apache/camel/model/cloud/MultiServiceCallServiceDiscoveryConfiguration.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * 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.cloud;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlElements;
-import javax.xml.bind.annotation.XmlRootElement;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.cloud.ServiceDiscovery;
-import org.apache.camel.spi.Metadata;
-
-@Metadata(label = "routing,cloud,service-discovery")
-@XmlRootElement(name = "multiServiceDiscovery")
-@XmlAccessorType(XmlAccessType.FIELD)
-public class MultiServiceCallServiceDiscoveryConfiguration extends ServiceCallServiceDiscoveryConfiguration {
-    @XmlElements({
-        @XmlElement(name = "consulServiceDiscovery", type = ConsulServiceCallServiceDiscoveryConfiguration.class),
-        @XmlElement(name = "dnsServiceDiscovery", type = DnsServiceCallServiceDiscoveryConfiguration.class),
-        @XmlElement(name = "etcdServiceDiscovery", type = EtcdServiceCallServiceDiscoveryConfiguration.class),
-        @XmlElement(name = "kubernetesServiceDiscovery", type = KubernetesServiceCallServiceDiscoveryConfiguration.class),
-        @XmlElement(name = "staticServiceDiscovery", type = StaticServiceCallServiceDiscoveryConfiguration.class),
-        @XmlElement(name = "cachingServiceDiscovery", type = CachingServiceCallServiceDiscoveryConfiguration.class)}
-    )
-    private List<ServiceCallServiceDiscoveryConfiguration> serviceDiscoveryConfigurations;
-
-    public MultiServiceCallServiceDiscoveryConfiguration() {
-        this(null);
-    }
-
-    public MultiServiceCallServiceDiscoveryConfiguration(ServiceCallDefinition parent) {
-        super(parent, "multi-service-discovery");
-    }
-
-    // *************************************************************************
-    // Properties
-    // *************************************************************************
-
-    public List<ServiceCallServiceDiscoveryConfiguration> getServiceDiscoveryConfigurations() {
-        return serviceDiscoveryConfigurations;
-    }
-
-    /**
-     * List of ServiceDiscovery configuration to use
-     * @param serviceDiscoveryConfigurations
-     */
-    public void setServiceDiscoveryConfigurations(List<ServiceCallServiceDiscoveryConfiguration> serviceDiscoveryConfigurations) {
-        this.serviceDiscoveryConfigurations = serviceDiscoveryConfigurations;
-    }
-
-    /**
-     *  Add a ServiceDiscovery configuration
-     */
-    public void addServiceDiscoveryConfigurations(ServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration) {
-        if (serviceDiscoveryConfigurations == null) {
-            serviceDiscoveryConfigurations = new ArrayList<>();
-        }
-
-        serviceDiscoveryConfigurations.add(serviceDiscoveryConfiguration);
-    }
-
-    // *************************************************************************
-    // Fluent API
-    // *************************************************************************
-
-    /**
-     *  List of ServiceDiscovery configuration to use
-     */
-    public MultiServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfigurations(List<ServiceCallServiceDiscoveryConfiguration> serviceDiscoveryConfigurations) {
-        setServiceDiscoveryConfigurations(serviceDiscoveryConfigurations);
-        return this;
-    }
-
-    /**
-     *  Add a ServiceDiscovery configuration
-     */
-    public MultiServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration(ServiceCallServiceDiscoveryConfiguration serviceDiscoveryConfiguration) {
-        addServiceDiscoveryConfigurations(serviceDiscoveryConfiguration);
-        return this;
-    }
-
-    // *****************************
-    // Shortcuts - ServiceDiscovery
-    // *****************************
-
-    public CachingServiceCallServiceDiscoveryConfiguration cachingServiceDiscovery() {
-        CachingServiceCallServiceDiscoveryConfiguration conf = new CachingServiceCallServiceDiscoveryConfiguration();
-        addServiceDiscoveryConfigurations(conf);
-
-        return conf;
-    }
-
-    public ConsulServiceCallServiceDiscoveryConfiguration consulServiceDiscovery() {
-        ConsulServiceCallServiceDiscoveryConfiguration conf = new ConsulServiceCallServiceDiscoveryConfiguration();
-        addServiceDiscoveryConfigurations(conf);
-
-        return conf;
-    }
-
-    public DnsServiceCallServiceDiscoveryConfiguration dnsServiceDiscovery() {
-        DnsServiceCallServiceDiscoveryConfiguration conf = new DnsServiceCallServiceDiscoveryConfiguration();
-        addServiceDiscoveryConfigurations(conf);
-
-        return conf;
-    }
-
-    public EtcdServiceCallServiceDiscoveryConfiguration etcdServiceDiscovery() {
-        EtcdServiceCallServiceDiscoveryConfiguration conf = new EtcdServiceCallServiceDiscoveryConfiguration();
-        addServiceDiscoveryConfigurations(conf);
-
-        return conf;
-    }
-
-    public KubernetesServiceCallServiceDiscoveryConfiguration kubernetesServiceDiscovery() {
-        KubernetesServiceCallServiceDiscoveryConfiguration conf = new KubernetesServiceCallServiceDiscoveryConfiguration();
-        addServiceDiscoveryConfigurations(conf);
-
-        return conf;
-    }
-
-    public MultiServiceCallServiceDiscoveryConfiguration multiServiceDiscovery() {
-        MultiServiceCallServiceDiscoveryConfiguration conf = new MultiServiceCallServiceDiscoveryConfiguration();
-        addServiceDiscoveryConfigurations(conf);
-
-        return conf;
-    }
-
-    public StaticServiceCallServiceDiscoveryConfiguration staticServiceDiscovery() {
-        StaticServiceCallServiceDiscoveryConfiguration conf = new StaticServiceCallServiceDiscoveryConfiguration();
-        addServiceDiscoveryConfigurations(conf);
-
-        return conf;
-    }
-
-    // *************************************************************************
-    // Utilities
-    // *************************************************************************
-
-    @Override
-    protected void postProcessFactoryParameters(final CamelContext camelContext, final Map<String, Object> parameters) throws Exception {
-        if (serviceDiscoveryConfigurations != null && !serviceDiscoveryConfigurations.isEmpty()) {
-            List<ServiceDiscovery> discoveries = new ArrayList<>(serviceDiscoveryConfigurations.size());
-            for (ServiceCallServiceDiscoveryConfiguration conf : serviceDiscoveryConfigurations) {
-                discoveries.add(conf.newInstance(camelContext));
-            }
-
-            parameters.put("serviceDiscoveryList", discoveries);
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/0aae1257/camel-core/src/main/java/org/apache/camel/model/cloud/PassThroughServiceCallServiceFilterConfiguration.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/cloud/PassThroughServiceCallServiceFilterConfiguration.java b/camel-core/src/main/java/org/apache/camel/model/cloud/PassThroughServiceCallServiceFilterConfiguration.java
new file mode 100644
index 0000000..a61c305
--- /dev/null
+++ b/camel-core/src/main/java/org/apache/camel/model/cloud/PassThroughServiceCallServiceFilterConfiguration.java
@@ -0,0 +1,36 @@
+/**
+ * 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.cloud;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.apache.camel.spi.Metadata;
+
+@Metadata(label = "routing,cloud,service-filter")
+@XmlRootElement(name = "passThroughServiceFilter")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class PassThroughServiceCallServiceFilterConfiguration extends ServiceCallServiceFilterConfiguration {
+    public PassThroughServiceCallServiceFilterConfiguration() {
+        this(null);
+    }
+
+    public PassThroughServiceCallServiceFilterConfiguration(ServiceCallDefinition parent) {
+        super(parent, "pass-through-service-filter");
+    }
+}
\ No newline at end of file