This is an automated email from the ASF dual-hosted git repository.

lburgazzoli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 4512c44b37332871c65ba156e4be6b5be2939e0d
Author: lburgazzoli <lburgazz...@gmail.com>
AuthorDate: Thu May 24 15:16:08 2018 +0200

    CAMEL-12518: camel cloud : leverage spring-cloud ServiceRegistry to 
register routes
---
 camel-core/pom.xml                                 |   6 +
 .../apache/camel/cloud/DiscoverableService.java    |   2 +-
 .../camel/impl/cloud/DefaultServiceDefinition.java |  44 ++-----
 .../impl/cloud/ServiceRegistrationRoutePolicy.java |  60 ++++-----
 .../camel/impl/cloud/ServiceRegistryTest.java      | 134 +++++++++++++++++++++
 .../camel/http/common/HttpCommonEndpoint.java      |   4 +-
 .../camel/component/service/ServiceComponent.java  |  24 ++--
 .../camel/component/service/ServiceEndpoint.java   |   6 +-
 .../boot/util/CompositeConversionService.java      |  83 +++++++++++++
 .../consul/ConsulServerToServiceDefinition.java    |  23 ++--
 ...erverToServiceDefinitionAutoConfiguration.java} |  34 +++---
 ...tionToConsulRegistrationAutoConfiguration.java} |   4 +-
 .../src/main/resources/META-INF/spring.factories   |   3 +-
 .../CamelCloudConsulAutoConfigurationTest.java     |  27 +++++
 .../CamelCloudConsulServiceRegistryTest.java       |   3 +-
 components/camel-spring-cloud-netflix/pom.xml      |   4 +
 ...CamelCloudNetflixRibbonClientConfiguration.java |  47 --------
 .../CamelCloudNetflixServiceLoadBalancer.java      |  88 ++++++++++++++
 ...tflixServiceLoadBalancerAutoConfiguration.java} |  35 +++---
 .../src/main/resources/META-INF/spring.factories   |   4 +-
 .../netflix/CamelCloudNetflixServiceCallTest.java  |  93 --------------
 ...ixServiceLoadBalancerAutoConfigurationTest.java |  78 ++++++++++++
 .../src/test/resources/logback.xml                 |   1 +
 ...nToZookeeperRegistrationAutoConfiguration.java} |   6 +-
 .../ZookeeperServerToServiceDefinition.java        |  23 ++--
 ...eeperToServiceDefinitionAutoConfiguration.java} |  20 ++-
 .../src/main/resources/META-INF/spring.factories   |   3 +-
 .../CamelCloudZookeeperAutoConfigurationTest.java  |  35 ++++++
 .../CamelCloudZookeeperServiceRegistryTest.java    |   3 +-
 .../cloud/CamelSpringCloudServiceLoadBalancer.java |  23 ++--
 ...gCloudServiceLoadBalancerAutoConfiguration.java |   9 +-
 .../cloud/CamelSpringCloudServiceRegistry.java     |  37 +++---
 .../cloud/DefaultLoadBalancerClientAdapter.java    |  15 +--
 .../spring/cloud/DefaultServiceLoadBalancer.java   |  50 ++++++++
 .../camel/component/undertow/UndertowEndpoint.java |   4 +-
 .../consumer/pom.xml                               |   4 +
 .../src/main/resources/application.properties      |   9 --
 37 files changed, 711 insertions(+), 337 deletions(-)

diff --git a/camel-core/pom.xml b/camel-core/pom.xml
index 22aa696..0166d5c 100644
--- a/camel-core/pom.xml
+++ b/camel-core/pom.xml
@@ -174,6 +174,12 @@
       <artifactId>awaitility</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+      <version>${assertj-version}</version>
+      <scope>test</scope>
+    </dependency>
 
     <!-- logging -->
     <dependency>
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java 
b/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
index 6d1946c..d8cc9e3 100644
--- a/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
+++ b/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
@@ -22,5 +22,5 @@ public interface DiscoverableService {
     /**
      * Get the service properties.
      */
-    Map<String, Object> getServiceProperties();
+    Map<String, String> getServiceProperties();
 }
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 8deace6..cfc1bc1 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
@@ -169,7 +169,7 @@ public class DefaultServiceDefinition implements 
ServiceDefinition {
     }
 
     /**
-     * Fluent builder to contruct ServiceDefinition.
+     * Fluent builder to construct ServiceDefinition.
      */
     public static class Builder {
         private String id;
@@ -190,46 +190,18 @@ public class DefaultServiceDefinition implements 
ServiceDefinition {
             return this;
         }
 
-        public Builder from(Map<String, Object> properties) {
-            Map<String, Object> options = new HashMap<>(properties);
-            Object val = null;
+        public Builder from(Map<String, String> properties) {
+            
ObjectHelper.ifNotEmpty(properties.get(ServiceDefinition.SERVICE_META_ID), 
this::withId);
+            
ObjectHelper.ifNotEmpty(properties.get(ServiceDefinition.SERVICE_META_NAME), 
this::withName);
+            
ObjectHelper.ifNotEmpty(properties.get(ServiceDefinition.SERVICE_META_HOST), 
this::withHost);
+            
ObjectHelper.ifNotEmpty(properties.get(ServiceDefinition.SERVICE_META_PORT), 
this::withPort);
 
-            val = options.remove(ServiceDefinition.SERVICE_META_ID);
-            if (val != null && val instanceof String) {
-                withId((String)val);
-            }
-
-            val = options.remove(ServiceDefinition.SERVICE_META_NAME);
-            if (val != null && val instanceof String) {
-                withName((String)val);
-            }
-
-            val = options.remove(ServiceDefinition.SERVICE_META_HOST);
-            if (val != null && val instanceof String) {
-                withHost((String)val);
-            }
-
-            val = options.remove(ServiceDefinition.SERVICE_META_PORT);
-            if (val != null && val instanceof String) {
-                withPort((String)val);
-            }
-            if (val != null && val instanceof Integer) {
-                withPort((Integer)val);
-            }
-
-            val = options.remove(ServiceDefinition.SERVICE_META_HOST);
-            if (val != null && val instanceof String) {
-                withHost((String)val);
-            }
-
-            for (Map.Entry<String, Object> entry : options.entrySet()) {
+            for (Map.Entry<String, String> entry : properties.entrySet()) {
                 if 
(!entry.getKey().startsWith(ServiceDefinition.SERVICE_META_PREFIX)) {
                     continue;
                 }
 
-                if (entry.getValue() instanceof String) {
-                    addMeta(entry.getKey(), (String)entry.getValue());
-                }
+                addMeta(entry.getKey(), entry.getValue());
             }
 
             return this;
diff --git 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/ServiceRegistrationRoutePolicy.java
 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/ServiceRegistrationRoutePolicy.java
index f506a04..130b513 100644
--- 
a/camel-core/src/main/java/org/apache/camel/impl/cloud/ServiceRegistrationRoutePolicy.java
+++ 
b/camel-core/src/main/java/org/apache/camel/impl/cloud/ServiceRegistrationRoutePolicy.java
@@ -123,7 +123,7 @@ public class ServiceRegistrationRoutePolicy extends 
RoutePolicySupport implement
 
     private Optional<ServiceDefinition> computeServiceDefinition(Route route) {
         final Endpoint endpoint = route.getConsumer().getEndpoint();
-        final Map<String, Object> properties = new HashMap<>();
+        final Map<String, String> properties = new HashMap<>();
 
         if (endpoint instanceof DiscoverableService) {
             final DiscoverableService service = (DiscoverableService) endpoint;
@@ -132,8 +132,22 @@ public class ServiceRegistrationRoutePolicy extends 
RoutePolicySupport implement
             properties.putAll(service.getServiceProperties());
         }
 
+        // then add additional properties from route with 
ServiceDefinition.SERVICE_META_PREFIX,
+        // note that route defined properties may override DiscoverableService
+        // provided ones
+        for (Map.Entry<String, Object> entry: 
route.getProperties().entrySet()) {
+            if 
(!entry.getKey().startsWith(ServiceDefinition.SERVICE_META_PREFIX)) {
+                continue;
+            }
+
+            final String key = entry.getKey();
+            final String val = 
camelContext.getTypeConverter().convertTo(String.class, entry.getValue());
+
+            properties.put(key, val);
+        }
+
         // try to get the service id from route properties
-        String serviceId = 
(String)route.getProperties().get(ServiceDefinition.SERVICE_META_ID);
+        String serviceId = properties.get(ServiceDefinition.SERVICE_META_ID);
         if (serviceId == null) {
             // if not check if the route id is custom and use it
             if (route.getRouteContext().getRoute().hasCustomIdAssigned()) {
@@ -142,18 +156,18 @@ public class ServiceRegistrationRoutePolicy extends 
RoutePolicySupport implement
         }
         if (serviceId == null) {
             // finally get the id from the DiscoverableService
-            serviceId = 
(String)properties.get(ServiceDefinition.SERVICE_META_ID);
+            serviceId = properties.get(ServiceDefinition.SERVICE_META_ID);
         }
 
         // try to get the service name from route properties
-        String serviceName = 
(String)route.getProperties().get(ServiceDefinition.SERVICE_META_NAME);
+        String serviceName = 
properties.get(ServiceDefinition.SERVICE_META_NAME);
         if (serviceName == null) {
             // if not check if the route group is defined use the route group
             serviceName = route.getGroup();
         }
         if (serviceName == null) {
             // finally get the name from the DiscoverableService
-            serviceName = 
(String)properties.get(ServiceDefinition.SERVICE_META_NAME);
+            serviceName = properties.get(ServiceDefinition.SERVICE_META_NAME);
         }
 
         if (ObjectHelper.isEmpty(serviceId) || 
ObjectHelper.isEmpty(serviceName)) {
@@ -161,32 +175,20 @@ public class ServiceRegistrationRoutePolicy extends 
RoutePolicySupport implement
             return Optional.empty();
         }
 
+        String serviceHost = 
properties.get(ServiceDefinition.SERVICE_META_HOST);
+        String servicePort = 
properties.getOrDefault(ServiceDefinition.SERVICE_META_PORT, "-1");
+
         // Build the final resource definition from bits collected from the
         // endpoint and the route.
-        DefaultServiceDefinition.Builder builder = 
DefaultServiceDefinition.builder()
-            .from(properties)
-            .withId(serviceId)
-            .withName(serviceName)
-            .addMeta(ServiceDefinition.SERVICE_META_NAME, serviceName)
-            .addMeta(ServiceDefinition.SERVICE_META_ID, serviceId);
-
-        // Add additional metadata from route properties whose name starts
-        // with ServiceDefinition.SERVICE_META_PREFIX.
-        //
-        // NOTE: At the moment it is not possible to add properties to a route
-        // with fluent DSL
-        for (Map.Entry<String, Object> entry: 
route.getProperties().entrySet()) {
-            if 
(!entry.getKey().startsWith(ServiceDefinition.SERVICE_META_PREFIX)) {
-                continue;
-            }
-
-            final String key = 
entry.getKey().substring(ServiceDefinition.SERVICE_META_PREFIX.length());
-            final String val = 
camelContext.getTypeConverter().convertTo(String.class, entry.getValue());
-
-            builder.addMeta(key, val);
-        }
-
-        return Optional.of(builder.build());
+        return Optional.of(
+            new DefaultServiceDefinition(
+                serviceId,
+                serviceName,
+                serviceHost,
+                Integer.parseInt(servicePort),
+                properties
+            )
+        );
     }
 }
 
diff --git 
a/camel-core/src/test/java/org/apache/camel/impl/cloud/ServiceRegistryTest.java 
b/camel-core/src/test/java/org/apache/camel/impl/cloud/ServiceRegistryTest.java
new file mode 100644
index 0000000..6c3cdaa
--- /dev/null
+++ 
b/camel-core/src/test/java/org/apache/camel/impl/cloud/ServiceRegistryTest.java
@@ -0,0 +1,134 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.impl.cloud;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.model.RouteDefinition;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ServiceRegistryTest  extends ContextTestSupport {
+
+    // *********************
+    // Set up
+    // *********************
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    // *********************
+    // Tests
+    // *********************
+
+    @Test
+    public void testServiceRegistrationWithRouteproperties() throws Exception {
+        final String serviceName = UUID.randomUUID().toString();
+        final String serviceId = UUID.randomUUID().toString();
+        final int port = 9090;
+
+        context.addRouteDefinition(
+            new RouteDefinition()
+                .from("direct:start")
+                .routeProperty(ServiceDefinition.SERVICE_META_NAME, 
serviceName)
+                .routeProperty(ServiceDefinition.SERVICE_META_ID, serviceId)
+                .routeProperty(ServiceDefinition.SERVICE_META_HOST, 
"localhost")
+                .routeProperty(ServiceDefinition.SERVICE_META_PORT, "" + port)
+                .routeProperty("service.meta1", "meta1")
+                .routeProperty("meta2", "meta2")
+                .routePolicy(new ServiceRegistrationRoutePolicy())
+                .to("mock:end")
+        );
+
+        InMemoryServiceRegistry sr = new InMemoryServiceRegistry();
+
+        context.addService(sr);
+        context.start();
+
+        final Map<String, ServiceDefinition> defs = sr.getDefinitions();
+
+        assertThat(defs).hasSize(1);
+
+        // basic properties
+        assertThat(defs.values()).first().hasFieldOrPropertyWithValue("name", 
serviceName);
+        assertThat(defs.values()).first().hasFieldOrPropertyWithValue("id", 
serviceId);
+        assertThat(defs.values()).first().hasFieldOrPropertyWithValue("host", 
"localhost");
+        assertThat(defs.values()).first().hasFieldOrPropertyWithValue("port", 
port);
+
+        // metadata
+        
assertThat(defs.get(serviceId).getMetadata()).containsEntry(ServiceDefinition.SERVICE_META_NAME,
 serviceName);
+        
assertThat(defs.get(serviceId).getMetadata()).containsEntry(ServiceDefinition.SERVICE_META_ID,
 serviceId);
+        
assertThat(defs.get(serviceId).getMetadata()).containsEntry(ServiceDefinition.SERVICE_META_HOST,
 "localhost");
+        
assertThat(defs.get(serviceId).getMetadata()).containsEntry(ServiceDefinition.SERVICE_META_PORT,
 "" + port);
+        
assertThat(defs.get(serviceId).getMetadata()).containsEntry("service.meta1", 
"meta1");
+        
assertThat(defs.get(serviceId).getMetadata()).doesNotContainKeys("meta2");
+
+    }
+
+    // *********************
+    // Helpers
+    // *********************
+
+    private static class InMemoryServiceRegistry extends 
AbstractServiceRegistry {
+        private final ConcurrentMap<String, ServiceDefinition> definitions;
+
+        public InMemoryServiceRegistry() {
+            super(UUID.randomUUID().toString());
+
+            this.definitions = new ConcurrentHashMap<>();
+        }
+
+        @Override
+        public void register(ServiceDefinition definition) {
+            Objects.requireNonNull(definition.getId(), "ServiceDefinition ID");
+            Objects.requireNonNull(definition.getName(), "ServiceDefinition 
Name");
+
+            definitions.put(definition.getId(), definition);
+        }
+
+        @Override
+        public void deregister(ServiceDefinition definition) {
+            Objects.requireNonNull(definition.getId(), "ServiceDefinition ID");
+            Objects.requireNonNull(definition.getName(), "ServiceDefinition 
Name");
+
+            definitions.remove(definition.getId());
+        }
+
+        @Override
+        protected void doStart() throws Exception {
+        }
+
+        @Override
+        protected void doStop() throws Exception {
+            definitions.clear();
+        }
+
+        Map<String, ServiceDefinition> getDefinitions() {
+            return Collections.unmodifiableMap(definitions);
+        }
+    }
+}
diff --git 
a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
 
b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
index e7d465e..834cb63 100644
--- 
a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
+++ 
b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpCommonEndpoint.java
@@ -201,9 +201,9 @@ public abstract class HttpCommonEndpoint extends 
DefaultEndpoint implements Head
     //-------------------------------------------------------------------------
 
     @Override
-    public Map<String, Object> getServiceProperties() {
+    public Map<String, String> getServiceProperties() {
         return CollectionHelper.immutableMapOf(
-            ServiceDefinition.SERVICE_META_PORT, getPort(),
+            ServiceDefinition.SERVICE_META_PORT, Integer.toString(getPort()),
             ServiceDefinition.SERVICE_META_PATH, getPath(),
             ServiceDefinition.SERVICE_META_PROTOCOL, getProtocol()
         );
diff --git 
a/components/camel-service/src/main/java/org/apache/camel/component/service/ServiceComponent.java
 
b/components/camel-service/src/main/java/org/apache/camel/component/service/ServiceComponent.java
index b7e249b..26c3cb7 100644
--- 
a/components/camel-service/src/main/java/org/apache/camel/component/service/ServiceComponent.java
+++ 
b/components/camel-service/src/main/java/org/apache/camel/component/service/ServiceComponent.java
@@ -56,23 +56,27 @@ public class ServiceComponent extends DefaultComponent {
         ObjectHelper.notNull(serviceName, "Service Name");
         ObjectHelper.notNull(delegateUri, "Delegate URI");
 
-        // add service name to the parameters
-        parameters.put(ServiceDefinition.SERVICE_META_NAME, serviceName);
-
         // Lookup the service registry, this may be a static selected service
         // or dynamically selected one through a ServiceRegistry.Selector
         final ServiceRegistry service = getServiceRegistry();
 
         // Compute service definition from parameters, this is used as default
         // definition
-        final Map<String, Object> params = new HashMap<>();
-        parameters.forEach(
-            (k, v) -> {
-                if (k.startsWith(ServiceDefinition.SERVICE_META_PREFIX)) {
-                    params.put(k, v);
-                }
+        final Map<String, String> params = new HashMap<>();
+
+        for (Map.Entry<String, Object> entry: parameters.entrySet()) {
+            if 
(!entry.getKey().startsWith(ServiceDefinition.SERVICE_META_PREFIX)) {
+                continue;
             }
-        );
+
+            final String key = entry.getKey();
+            final String val = 
getCamelContext().getTypeConverter().convertTo(String.class, entry.getValue());
+
+            params.put(key, val);
+        }
+
+        // add service name, this is always set from an uri path param
+        params.put(ServiceDefinition.SERVICE_META_NAME, serviceName);
 
         // remove all the service related options so the underlying component
         // does not fail because of unknown parameters
diff --git 
a/components/camel-service/src/main/java/org/apache/camel/component/service/ServiceEndpoint.java
 
b/components/camel-service/src/main/java/org/apache/camel/component/service/ServiceEndpoint.java
index f4bcd55..d16f448 100644
--- 
a/components/camel-service/src/main/java/org/apache/camel/component/service/ServiceEndpoint.java
+++ 
b/components/camel-service/src/main/java/org/apache/camel/component/service/ServiceEndpoint.java
@@ -54,14 +54,14 @@ import org.apache.camel.spi.UriPath;
 public class ServiceEndpoint extends DefaultEndpoint implements 
DelegateEndpoint {
     private final Endpoint delegateEndpoint;
     private final ServiceRegistry serviceRegistry;
-    private final Map<String, Object> serviceParameters;
+    private final Map<String, String> serviceParameters;
     private final ServiceDefinition serviceDefinition;
 
     @UriPath(description = "The endpoint uri to expose as service")
     @Metadata(required = "true")
     private final String delegateUri;
 
-    public ServiceEndpoint(String uri, ServiceComponent component, 
ServiceRegistry serviceRegistry, Map<String, Object> serviceParameters, String 
delegateUri) {
+    public ServiceEndpoint(String uri, ServiceComponent component, 
ServiceRegistry serviceRegistry, Map<String, String> serviceParameters, String 
delegateUri) {
         super(uri, component);
 
         this.serviceRegistry = serviceRegistry;
@@ -101,7 +101,7 @@ public class ServiceEndpoint extends DefaultEndpoint 
implements DelegateEndpoint
     }
 
     private ServiceDefinition computeServiceDefinition(CamelContext context, 
Endpoint delegateEndpoint) {
-        Map<String, Object> parameters = new HashMap<>();
+        Map<String, String> parameters = new HashMap<>();
 
         if (delegateEndpoint instanceof DiscoverableService) {
             
parameters.putAll(((DiscoverableService)delegateEndpoint).getServiceProperties());
diff --git 
a/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/util/CompositeConversionService.java
 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/util/CompositeConversionService.java
new file mode 100644
index 0000000..e397653
--- /dev/null
+++ 
b/components/camel-spring-boot/src/main/java/org/apache/camel/spring/boot/util/CompositeConversionService.java
@@ -0,0 +1,83 @@
+/**
+ * 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.spring.boot.util;
+
+import java.util.List;
+
+import org.springframework.core.convert.ConversionException;
+import org.springframework.core.convert.ConversionService;
+import org.springframework.core.convert.TypeDescriptor;
+
+public class CompositeConversionService implements ConversionService {
+    private final List<ConversionService> delegates;
+
+    public CompositeConversionService(List<ConversionService> delegates) {
+        this.delegates = delegates;
+    }
+
+    @Override
+    public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
+        for (ConversionService service : this.delegates) {
+            if (service.canConvert(sourceType, targetType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean canConvert(TypeDescriptor sourceType, TypeDescriptor 
targetType) {
+        for (ConversionService service : this.delegates) {
+            if (service.canConvert(sourceType, targetType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public <T> T convert(Object source, Class<T> targetType) {
+        for (int i = 0; i < this.delegates.size() - 1; i++) {
+            try {
+                ConversionService delegate = this.delegates.get(i);
+                if (delegate.canConvert(source.getClass(), targetType)) {
+                    return delegate.convert(source, targetType);
+                }
+            } catch (ConversionException e) {
+                // ignored
+            }
+        }
+
+        return this.delegates.get(this.delegates.size() - 1).convert(source, 
targetType);
+    }
+
+    @Override
+    public Object convert(Object source, TypeDescriptor sourceType, 
TypeDescriptor targetType) {
+        for (int i = 0; i < this.delegates.size() - 1; i++) {
+            try {
+                ConversionService delegate = this.delegates.get(i);
+                if (delegate.canConvert(sourceType, targetType)) {
+                    return delegate.convert(source, sourceType, targetType);
+                }
+            } catch (ConversionException e) {
+                // ignored
+            }
+        }
+
+        return this.delegates.get(this.delegates.size() - 1).convert(source, 
sourceType, targetType);
+    }
+}
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java 
b/components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ConsulServerToServiceDefinition.java
similarity index 55%
copy from 
camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
copy to 
components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ConsulServerToServiceDefinition.java
index 6d1946c..cf50710 100644
--- a/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
+++ 
b/components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ConsulServerToServiceDefinition.java
@@ -14,13 +14,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.cloud;
+package org.apache.camel.spring.cloud.consul;
 
-import java.util.Map;
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.impl.cloud.DefaultServiceDefinition;
+import org.springframework.cloud.consul.discovery.ConsulServer;
+import org.springframework.core.convert.converter.Converter;
 
-public interface DiscoverableService {
-    /**
-     * Get the service properties.
-     */
-    Map<String, Object> getServiceProperties();
+public final class ConsulServerToServiceDefinition implements 
Converter<ConsulServer, ServiceDefinition> {
+
+    @Override
+    public ServiceDefinition convert(ConsulServer source) {
+        return new DefaultServiceDefinition(
+            source.getId(),
+            source.getHost(),
+            source.getPort(),
+            source.getMetadata()
+        );
+    }
 }
diff --git 
a/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixRibbonAutoConfiguration.java
 
b/components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ConsulServerToServiceDefinitionAutoConfiguration.java
similarity index 54%
rename from 
components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixRibbonAutoConfiguration.java
rename to 
components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ConsulServerToServiceDefinitionAutoConfiguration.java
index 5631507..ff94103 100644
--- 
a/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixRibbonAutoConfiguration.java
+++ 
b/components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ConsulServerToServiceDefinitionAutoConfiguration.java
@@ -14,25 +14,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.spring.cloud.netflix;
+package org.apache.camel.spring.cloud.consul;
 
+import org.apache.camel.cloud.ServiceDefinition;
 import org.apache.camel.spring.boot.util.GroupCondition;
-import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
-import org.springframework.cloud.netflix.ribbon.RibbonClients;
-import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
+import 
org.apache.camel.spring.cloud.CamelSpringCloudServiceLoadBalancerAutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.cloud.consul.ConditionalOnConsulEnabled;
+import org.springframework.cloud.consul.discovery.ConsulServer;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
 
 @Configuration
-@EnableConfigurationProperties
-@ConditionalOnBean(SpringClientFactory.class)
-@Conditional(CamelCloudNetflixRibbonAutoConfiguration.Condition.class)
-@AutoConfigureAfter({ CamelCloudNetflixAutoConfiguration.class, 
RibbonAutoConfiguration.class })
-@RibbonClients(defaultConfiguration = 
CamelCloudNetflixRibbonClientConfiguration.class)
-public class CamelCloudNetflixRibbonAutoConfiguration {
+@AutoConfigureBefore(CamelSpringCloudServiceLoadBalancerAutoConfiguration.class)
+@ConditionalOnConsulEnabled
+@Conditional(ConsulServerToServiceDefinitionAutoConfiguration.Condition.class)
+public class ConsulServerToServiceDefinitionAutoConfiguration {
+
+    @Bean(name = "consul-server-to-service-definition")
+    public Converter<ConsulServer, ServiceDefinition> 
consulServerToServiceDefinition() {
+        return new ConsulServerToServiceDefinition();
+    }
 
     // *******************************
     // Condition
@@ -41,8 +45,8 @@ public class CamelCloudNetflixRibbonAutoConfiguration {
     public static class Condition extends GroupCondition {
         public Condition() {
             super(
-                "camel.cloud.netflix",
-                "camel.cloud.netflix.ribbon"
+                "camel.cloud",
+                "camel.cloud.consul"
             );
         }
     }
diff --git 
a/components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulAutoConfiguration.java
 
b/components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ServiceDefinitionToConsulRegistrationAutoConfiguration.java
similarity index 94%
rename from 
components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulAutoConfiguration.java
rename to 
components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ServiceDefinitionToConsulRegistrationAutoConfiguration.java
index a1ba31f..1f42dcf 100644
--- 
a/components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulAutoConfiguration.java
+++ 
b/components/camel-spring-cloud-consul/src/main/java/org/apache/camel/spring/cloud/consul/ServiceDefinitionToConsulRegistrationAutoConfiguration.java
@@ -32,9 +32,9 @@ import org.springframework.core.convert.converter.Converter;
 @Configuration
 @AutoConfigureBefore(CamelSpringCloudServiceRegistryAutoConfiguration.class)
 @ConditionalOnConsulEnabled
-@Conditional(CamelCloudConsulAutoConfiguration.Condition.class)
+@Conditional(ServiceDefinitionToConsulRegistrationAutoConfiguration.Condition.class)
 @EnableConfigurationProperties(CamelCloudConfigurationProperties.class)
-public class CamelCloudConsulAutoConfiguration {
+public class ServiceDefinitionToConsulRegistrationAutoConfiguration {
 
     @Bean(name = "service-definition-to-consul-registration")
     public Converter<ServiceDefinition, ConsulRegistration> 
serviceDefinitionToConsulRegistration(
diff --git 
a/components/camel-spring-cloud-consul/src/main/resources/META-INF/spring.factories
 
b/components/camel-spring-cloud-consul/src/main/resources/META-INF/spring.factories
index 56dd79f..43705ca 100644
--- 
a/components/camel-spring-cloud-consul/src/main/resources/META-INF/spring.factories
+++ 
b/components/camel-spring-cloud-consul/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,5 @@
 #
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-    org.apache.camel.spring.cloud.consul.CamelCloudConsulAutoConfiguration
\ No newline at end of file
+    
org.apache.camel.spring.cloud.consul.ServiceDefinitionToConsulRegistrationAutoConfiguration,\
+    
org.apache.camel.spring.cloud.consul.ConsulServerToServiceDefinitionAutoConfiguration
\ No newline at end of file
diff --git 
a/components/camel-spring-cloud-consul/src/test/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulAutoConfigurationTest.java
 
b/components/camel-spring-cloud-consul/src/test/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulAutoConfigurationTest.java
index 83e50df..a291515 100644
--- 
a/components/camel-spring-cloud-consul/src/test/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulAutoConfigurationTest.java
+++ 
b/components/camel-spring-cloud-consul/src/test/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulAutoConfigurationTest.java
@@ -57,6 +57,33 @@ public class CamelCloudConsulAutoConfigurationTest {
         }
     }
 
+    @Test
+    public void testConsulServerToServiceDefinition() throws Exception {
+        ConfigurableApplicationContext context = new 
SpringApplicationBuilder(TestConfiguration.class)
+            .web(WebApplicationType.NONE)
+            .run(
+                "--debug=false",
+                "--spring.main.banner-mode=OFF",
+                "--spring.application.name=" + UUID.randomUUID().toString(),
+                "--ribbon.enabled=false",
+                "--ribbon.eureka.enabled=false",
+                "--management.endpoint.enabled=false",
+                "--spring.cloud.consul.enabled=true",
+                "--spring.cloud.consul.config.enabled=false",
+                "--spring.cloud.consul.discovery.enabled=true",
+                
"--spring.cloud.service-registry.auto-registration.enabled=false"
+            );
+
+        try {
+            Map<String, Converter> converters = 
context.getBeansOfType(Converter.class);
+
+            assertThat(converters).isNotNull();
+            
assertThat(converters.values().stream().anyMatch(ConsulServerToServiceDefinition.class::isInstance)).isTrue();
+        } finally {
+            context.close();
+        }
+    }
+
     // *************************************
     // Config
     // *************************************
diff --git 
a/components/camel-spring-cloud-consul/src/test/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulServiceRegistryTest.java
 
b/components/camel-spring-cloud-consul/src/test/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulServiceRegistryTest.java
index b576351..e1a9e95 100644
--- 
a/components/camel-spring-cloud-consul/src/test/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulServiceRegistryTest.java
+++ 
b/components/camel-spring-cloud-consul/src/test/java/org/apache/camel/spring/cloud/consul/CamelCloudConsulServiceRegistryTest.java
@@ -62,7 +62,8 @@ public class CamelCloudConsulServiceRegistryTest {
                 "--spring.cloud.consul.port=" + container.getMappedPort(8500),
                 "--spring.cloud.consul.config.enabled=false",
                 "--spring.cloud.consul.discovery.enabled=true",
-                
"--spring.cloud.service-registry.auto-registration.enabled=false"
+                
"--spring.cloud.service-registry.auto-registration.enabled=false",
+                "--camel.cloud.service-registry.service-host=localhost"
             );
 
         try {
diff --git a/components/camel-spring-cloud-netflix/pom.xml 
b/components/camel-spring-cloud-netflix/pom.xml
index b412e93..c5111e7 100644
--- a/components/camel-spring-cloud-netflix/pom.xml
+++ b/components/camel-spring-cloud-netflix/pom.xml
@@ -91,6 +91,10 @@
       <artifactId>camel-spring-boot</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>camel-spring-cloud</artifactId>
+    </dependency>
+    <dependency>
       <groupId>io.reactivex</groupId>
       <artifactId>rxjava</artifactId>
       <version>${rxjava-version}</version>
diff --git 
a/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixRibbonClientConfiguration.java
 
b/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixRibbonClientConfiguration.java
deleted file mode 100644
index 1b492a8..0000000
--- 
a/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixRibbonClientConfiguration.java
+++ /dev/null
@@ -1,47 +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.spring.cloud.netflix;
-
-import com.netflix.client.config.IClientConfig;
-import com.netflix.loadbalancer.ServerList;
-import org.apache.camel.spring.boot.cloud.CamelCloudServiceDiscovery;
-import org.apache.camel.spring.boot.cloud.CamelCloudServiceFilter;
-import org.springframework.beans.factory.annotation.Autowired;
-import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class CamelCloudNetflixRibbonClientConfiguration {
-    @Autowired
-    private IClientConfig clientConfig;
-    @Autowired
-    private CamelCloudServiceDiscovery serviceDiscovery;
-    @Autowired
-    private CamelCloudServiceFilter serviceFilter;
-
-    @Bean
-    @ConditionalOnMissingBean
-    public ServerList<?> ribbonServerList() {
-        CamelCloudNetflixServerList serverList = new 
CamelCloudNetflixServerList();
-        serverList.setServiceDiscovery(serviceDiscovery);
-        serverList.setServiceFilter(serviceFilter);
-        serverList.initWithNiwsConfig(clientConfig);
-
-        return serverList;
-    }
-}
diff --git 
a/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancer.java
 
b/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancer.java
new file mode 100644
index 0000000..a13211d
--- /dev/null
+++ 
b/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancer.java
@@ -0,0 +1,88 @@
+/**
+ * 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.spring.cloud.netflix;
+
+import java.util.List;
+
+import com.netflix.loadbalancer.Server;
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceLoadBalancer;
+import org.apache.camel.cloud.ServiceLoadBalancerFunction;
+import org.apache.camel.impl.cloud.DefaultServiceDefinition;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
+import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
+import org.springframework.core.convert.ConversionService;
+
+public class CamelCloudNetflixServiceLoadBalancer implements 
ServiceLoadBalancer {
+    private final LoadBalancerClient client;
+    private final List<ConversionService> conversionServices;
+
+    public CamelCloudNetflixServiceLoadBalancer(LoadBalancerClient client, 
List<ConversionService> conversionServices) {
+        this.client = client;
+        this.conversionServices = conversionServices;
+    }
+
+    @Override
+    public <T> T process(String serviceName, ServiceLoadBalancerFunction<T> 
function) throws Exception {
+        return client.execute(serviceName, instance -> {
+            ServiceDefinition definition = null;
+
+            //
+            // this should not be needed but there is a bug or misbehavior on
+            // spring cloud netflix side (2.x) that prevent ribbon load 
balancer
+            // to propagate metadata from i.e. consul, see:
+            //
+            //     
https://github.com/spring-cloud/spring-cloud-consul/issues/424
+            //
+            // so here we do try to find a converter that is able to use the
+            // underlying server implementation to extract meta-data and any
+            // other thing needed by Camel.
+            //
+
+            if (instance instanceof RibbonLoadBalancerClient.RibbonServer) {
+                Server server = 
RibbonLoadBalancerClient.RibbonServer.class.cast(instance).getServer();
+
+                for (int i = 0; i < conversionServices.size(); i++) {
+                    ConversionService cs = conversionServices.get(i);
+
+                    if (cs.canConvert(server.getClass(), 
ServiceDefinition.class)) {
+                        definition = cs.convert(server, 
ServiceDefinition.class);
+
+                        if (definition != null) {
+                            break;
+                        }
+                    }
+                }
+            }
+
+            // If no conversion is possible we use the info found on service
+            // instance given by the load balancer as it is so the result may
+            // be incomplete
+
+            if (definition == null) {
+                definition = new DefaultServiceDefinition(
+                    instance.getServiceId(),
+                    instance.getHost(),
+                    instance.getPort(),
+                    instance.getMetadata()
+                );
+            }
+
+            return function.apply(definition);
+        });
+    }
+}
diff --git 
a/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
 
b/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancerAutoConfiguration.java
similarity index 56%
copy from 
components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
copy to 
components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancerAutoConfiguration.java
index b223e02..9f01558 100644
--- 
a/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
+++ 
b/components/camel-spring-cloud-netflix/src/main/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancerAutoConfiguration.java
@@ -14,32 +14,35 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.spring.cloud.zookeeper;
+package org.apache.camel.spring.cloud.netflix;
+
+import java.util.List;
 
-import org.apache.camel.cloud.ServiceDefinition;
-import org.apache.camel.spring.boot.cloud.CamelCloudConfigurationProperties;
 import org.apache.camel.spring.boot.util.GroupCondition;
+import org.apache.camel.spring.cloud.CamelSpringCloudServiceLoadBalancer;
 import 
org.apache.camel.spring.cloud.CamelSpringCloudServiceRegistryAutoConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
 import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.cloud.zookeeper.ConditionalOnZookeeperEnabled;
-import 
org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
+import 
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
+import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.core.convert.converter.Converter;
+import org.springframework.core.convert.ConversionService;
 
 @Configuration
+@AutoConfigureAfter(RibbonAutoConfiguration.class)
 @AutoConfigureBefore(CamelSpringCloudServiceRegistryAutoConfiguration.class)
-@ConditionalOnZookeeperEnabled
-@Conditional(CamelCloudZookeeperAutoConfiguration.Condition.class)
-@EnableConfigurationProperties(CamelCloudConfigurationProperties.class)
-public class CamelCloudZookeeperAutoConfiguration {
+@Conditional(CamelCloudNetflixServiceLoadBalancerAutoConfiguration.Condition.class)
+public class CamelCloudNetflixServiceLoadBalancerAutoConfiguration {
 
-    @Bean(name = "service-definition-to-zookeeper-registration")
-    public Converter<ServiceDefinition, ZookeeperRegistration> 
serviceDefinitionToConsulRegistration(
-            CamelCloudConfigurationProperties properties) {
-        return new ServiceDefinitionToZookeeperRegistration(properties);
+    @ConditionalOnBean(LoadBalancerClient.class)
+    @ConditionalOnMissingBean
+    @Bean("netflix-client-load-balancer-adapter")
+    public CamelSpringCloudServiceLoadBalancer.LoadBalancerClientAdapter 
netflixClientLoadBalancerAdapter(List<ConversionService> conversionServices) {
+        return client -> new CamelCloudNetflixServiceLoadBalancer(client, 
conversionServices);
     }
 
     // *******************************
@@ -50,7 +53,7 @@ public class CamelCloudZookeeperAutoConfiguration {
         public Condition() {
             super(
                 "camel.cloud",
-                "camel.cloud.zookeeper"
+                "camel.cloud.netflix"
             );
         }
     }
diff --git 
a/components/camel-spring-cloud-netflix/src/main/resources/META-INF/spring.factories
 
b/components/camel-spring-cloud-netflix/src/main/resources/META-INF/spring.factories
index 1926ceb..4d93027 100644
--- 
a/components/camel-spring-cloud-netflix/src/main/resources/META-INF/spring.factories
+++ 
b/components/camel-spring-cloud-netflix/src/main/resources/META-INF/spring.factories
@@ -16,5 +16,5 @@
 #
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.apache.camel.spring.cloud.netflix.CamelCloudNetflixAutoConfiguration,\
-org.apache.camel.spring.cloud.netflix.CamelCloudNetflixRibbonAutoConfiguration
\ No newline at end of file
+    org.apache.camel.spring.cloud.netflix.CamelCloudNetflixAutoConfiguration,\
+    
org.apache.camel.spring.cloud.netflix.CamelCloudNetflixServiceLoadBalancerAutoConfiguration
\ No newline at end of file
diff --git 
a/components/camel-spring-cloud-netflix/src/test/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceCallTest.java
 
b/components/camel-spring-cloud-netflix/src/test/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceCallTest.java
deleted file mode 100644
index 0cd76bb..0000000
--- 
a/components/camel-spring-cloud-netflix/src/test/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceCallTest.java
+++ /dev/null
@@ -1,93 +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.spring.cloud.netflix;
-
-import org.apache.camel.ProducerTemplate;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.spring.boot.CamelAutoConfiguration;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.junit4.SpringRunner;
-
-@DirtiesContext
-@RunWith(SpringRunner.class)
-@SpringBootApplication
-@SpringBootTest(
-    classes = {
-        CamelAutoConfiguration.class,
-        CamelCloudNetflixAutoConfiguration.class,
-        CamelCloudNetflixServiceCallTest.TestConfiguration.class,
-        RibbonClientConfiguration.class,
-    },
-    properties = {
-        "camel.cloud.load-balancer.enabled=true",
-        
"camel.cloud.service-discovery.services[custom-svc-list]=localhost:9090,localhost:9091,localhost:9092",
-        "camel.cloud.service-filter.blacklist[custom-svc-list]=localhost:9091",
-        "ribbon.enabled=true",
-        "ribbon.client.name=custom-svc-list",
-        "ribbon.eureka.enabled=false",
-        "debug=false"
-    }
-)
-public class CamelCloudNetflixServiceCallTest {
-    @Autowired
-    private ProducerTemplate template;
-
-    @Test
-    public void testServiceCall() throws Exception {
-        Assert.assertEquals("9090", template.requestBody("direct:start", null, 
String.class));
-        Assert.assertEquals("9092", template.requestBody("direct:start", null, 
String.class));
-    }
-
-    // ***********************************************
-    // Configuration
-    // ***********************************************
-
-    @Configuration
-    public static class TestConfiguration {
-        @Bean
-        public RouteBuilder myRouteBuilder() {
-            return new RouteBuilder() {
-                @Override
-                public void configure() throws Exception {
-                    from("direct:start")
-                        .serviceCall()
-                        .name("custom-svc-list/hello");
-
-                    from("jetty:http://localhost:9090/hello";)
-                        .transform()
-                        .constant("9090");
-                    from("jetty:http://localhost:9091/hello";)
-                        .transform()
-                        .constant("9091");
-                    from("jetty:http://localhost:9092/hello";)
-                        .transform()
-                        .constant("9092");
-                }
-            };
-        }
-    }
-}
-
diff --git 
a/components/camel-spring-cloud-netflix/src/test/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancerAutoConfigurationTest.java
 
b/components/camel-spring-cloud-netflix/src/test/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancerAutoConfigurationTest.java
new file mode 100644
index 0000000..297638a
--- /dev/null
+++ 
b/components/camel-spring-cloud-netflix/src/test/java/org/apache/camel/spring/cloud/netflix/CamelCloudNetflixServiceLoadBalancerAutoConfigurationTest.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.spring.cloud.netflix;
+
+import org.apache.camel.cloud.ServiceLoadBalancer;
+import org.apache.camel.spring.boot.CamelAutoConfiguration;
+import org.apache.camel.spring.boot.cloud.CamelCloudAutoConfiguration;
+import org.apache.camel.spring.cloud.CamelSpringCloudServiceLoadBalancer;
+import 
org.apache.camel.spring.cloud.CamelSpringCloudServiceRegistryAutoConfiguration;
+import org.junit.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
+import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
+import org.springframework.cloud.netflix.ribbon.RibbonClientConfiguration;
+import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
+import org.springframework.context.annotation.Configuration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class CamelCloudNetflixServiceLoadBalancerAutoConfigurationTest {
+
+    @Test
+    public void testAutoConfiguration() {
+        new ApplicationContextRunner()
+            .withConfiguration(
+                AutoConfigurations.of(
+                    CamelAutoConfiguration.class,
+                    CamelCloudAutoConfiguration.class,
+                    CamelSpringCloudServiceRegistryAutoConfiguration.class,
+                    
CamelCloudNetflixServiceLoadBalancerAutoConfiguration.class,
+                    RibbonAutoConfiguration.class,
+                    RibbonClientConfiguration.class
+                ))
+            .withUserConfiguration(
+                TestConfiguration.class)
+            .withPropertyValues(
+                "debug=true",
+                "spring.main.banner-mode=off",
+                "ribbon.client.name=test")
+            .run(
+                context -> {
+                    
assertThat(context).hasSingleBean(LoadBalancerClient.class);
+                    
assertThat(context).getBean(LoadBalancerClient.class).isInstanceOf(RibbonLoadBalancerClient.class);
+
+                    
assertThat(context).hasSingleBean(CamelSpringCloudServiceLoadBalancer.LoadBalancerClientAdapter.class);
+
+                    LoadBalancerClient client = 
context.getBean(LoadBalancerClient.class);
+                    ServiceLoadBalancer balancer = 
context.getBean(CamelSpringCloudServiceLoadBalancer.LoadBalancerClientAdapter.class).adapt(client);
+
+                    
assertThat(balancer).isInstanceOf(CamelCloudNetflixServiceLoadBalancer.class);
+                }
+            );
+    }
+
+
+    @EnableAutoConfiguration
+    @Configuration
+    public static class TestConfiguration {
+
+    }
+}
+
diff --git 
a/components/camel-spring-cloud-netflix/src/test/resources/logback.xml 
b/components/camel-spring-cloud-netflix/src/test/resources/logback.xml
index 75c70d1..848cd0f 100644
--- a/components/camel-spring-cloud-netflix/src/test/resources/logback.xml
+++ b/components/camel-spring-cloud-netflix/src/test/resources/logback.xml
@@ -35,6 +35,7 @@
   </appender>
 
   <root level="INFO">
+    <!--<appender-ref ref="STDOUT"/>-->
     <appender-ref ref="FILE"/>
   </root>
 
diff --git 
a/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
 
b/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ServiceDefinitionToZookeeperRegistrationAutoConfiguration.java
similarity index 92%
copy from 
components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
copy to 
components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ServiceDefinitionToZookeeperRegistrationAutoConfiguration.java
index b223e02..38435af 100644
--- 
a/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
+++ 
b/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ServiceDefinitionToZookeeperRegistrationAutoConfiguration.java
@@ -32,12 +32,12 @@ import org.springframework.core.convert.converter.Converter;
 @Configuration
 @AutoConfigureBefore(CamelSpringCloudServiceRegistryAutoConfiguration.class)
 @ConditionalOnZookeeperEnabled
-@Conditional(CamelCloudZookeeperAutoConfiguration.Condition.class)
+@Conditional(ServiceDefinitionToZookeeperRegistrationAutoConfiguration.Condition.class)
 @EnableConfigurationProperties(CamelCloudConfigurationProperties.class)
-public class CamelCloudZookeeperAutoConfiguration {
+public class ServiceDefinitionToZookeeperRegistrationAutoConfiguration {
 
     @Bean(name = "service-definition-to-zookeeper-registration")
-    public Converter<ServiceDefinition, ZookeeperRegistration> 
serviceDefinitionToConsulRegistration(
+    public Converter<ServiceDefinition, ZookeeperRegistration> 
serviceDefinitionToZookeeperRegistration(
             CamelCloudConfigurationProperties properties) {
         return new ServiceDefinitionToZookeeperRegistration(properties);
     }
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java 
b/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ZookeeperServerToServiceDefinition.java
similarity index 53%
copy from 
camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
copy to 
components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ZookeeperServerToServiceDefinition.java
index 6d1946c..463146a 100644
--- a/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
+++ 
b/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ZookeeperServerToServiceDefinition.java
@@ -14,13 +14,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.cloud;
+package org.apache.camel.spring.cloud.zookeeper;
 
-import java.util.Map;
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.impl.cloud.DefaultServiceDefinition;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperServer;
+import org.springframework.core.convert.converter.Converter;
 
-public interface DiscoverableService {
-    /**
-     * Get the service properties.
-     */
-    Map<String, Object> getServiceProperties();
+public final class ZookeeperServerToServiceDefinition implements 
Converter<ZookeeperServer, ServiceDefinition> {
+
+    @Override
+    public ServiceDefinition convert(ZookeeperServer source) {
+        return new DefaultServiceDefinition(
+            source.getId(),
+            source.getHost(),
+            source.getPort(),
+            source.getInstance().getPayload().getMetadata()
+        );
+    }
 }
diff --git 
a/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
 
b/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ZookeeperToServiceDefinitionAutoConfiguration.java
similarity index 65%
rename from 
components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
rename to 
components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ZookeeperToServiceDefinitionAutoConfiguration.java
index b223e02..535c9e5 100644
--- 
a/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfiguration.java
+++ 
b/components/camel-spring-cloud-zookeeper/src/main/java/org/apache/camel/spring/cloud/zookeeper/ZookeeperToServiceDefinitionAutoConfiguration.java
@@ -17,29 +17,25 @@
 package org.apache.camel.spring.cloud.zookeeper;
 
 import org.apache.camel.cloud.ServiceDefinition;
-import org.apache.camel.spring.boot.cloud.CamelCloudConfigurationProperties;
 import org.apache.camel.spring.boot.util.GroupCondition;
-import 
org.apache.camel.spring.cloud.CamelSpringCloudServiceRegistryAutoConfiguration;
+import 
org.apache.camel.spring.cloud.CamelSpringCloudServiceLoadBalancerAutoConfiguration;
 import org.springframework.boot.autoconfigure.AutoConfigureBefore;
-import 
org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.cloud.zookeeper.ConditionalOnZookeeperEnabled;
-import 
org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
+import org.springframework.cloud.zookeeper.discovery.ZookeeperServer;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Conditional;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.core.convert.converter.Converter;
 
 @Configuration
-@AutoConfigureBefore(CamelSpringCloudServiceRegistryAutoConfiguration.class)
+@AutoConfigureBefore(CamelSpringCloudServiceLoadBalancerAutoConfiguration.class)
 @ConditionalOnZookeeperEnabled
-@Conditional(CamelCloudZookeeperAutoConfiguration.Condition.class)
-@EnableConfigurationProperties(CamelCloudConfigurationProperties.class)
-public class CamelCloudZookeeperAutoConfiguration {
+@Conditional(ZookeeperToServiceDefinitionAutoConfiguration.Condition.class)
+public class ZookeeperToServiceDefinitionAutoConfiguration {
 
-    @Bean(name = "service-definition-to-zookeeper-registration")
-    public Converter<ServiceDefinition, ZookeeperRegistration> 
serviceDefinitionToConsulRegistration(
-            CamelCloudConfigurationProperties properties) {
-        return new ServiceDefinitionToZookeeperRegistration(properties);
+    @Bean(name = "zookeeper-server-to-service-definition")
+    public Converter<ZookeeperServer, ServiceDefinition> 
zookeeperServerToServiceDefinition() {
+        return new ZookeeperServerToServiceDefinition();
     }
 
     // *******************************
diff --git 
a/components/camel-spring-cloud-zookeeper/src/main/resources/META-INF/spring.factories
 
b/components/camel-spring-cloud-zookeeper/src/main/resources/META-INF/spring.factories
index 04d8a13..f6b9530 100644
--- 
a/components/camel-spring-cloud-zookeeper/src/main/resources/META-INF/spring.factories
+++ 
b/components/camel-spring-cloud-zookeeper/src/main/resources/META-INF/spring.factories
@@ -16,4 +16,5 @@
 #
 
 org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-    
org.apache.camel.spring.cloud.zookeeper.CamelCloudZookeeperAutoConfiguration
\ No newline at end of file
+    
org.apache.camel.spring.cloud.zookeeper.ServiceDefinitionToZookeeperRegistrationAutoConfiguration,\
+    
org.apache.camel.spring.cloud.zookeeper.ZookeeperToServiceDefinitionAutoConfiguration
\ No newline at end of file
diff --git 
a/components/camel-spring-cloud-zookeeper/src/test/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfigurationTest.java
 
b/components/camel-spring-cloud-zookeeper/src/test/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfigurationTest.java
index 205b5a9..9d28b93 100644
--- 
a/components/camel-spring-cloud-zookeeper/src/test/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfigurationTest.java
+++ 
b/components/camel-spring-cloud-zookeeper/src/test/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperAutoConfigurationTest.java
@@ -73,6 +73,41 @@ public class CamelCloudZookeeperAutoConfigurationTest {
         }
     }
 
+    @Test
+    public void testZookeeperServerToServiceDefinition() throws Exception {
+        final ZookeeperServer server = new 
ZookeeperServer(temporaryFolder.newFolder(testName.getMethodName()));
+
+        ConfigurableApplicationContext context = new 
SpringApplicationBuilder(TestConfiguration.class)
+            .web(WebApplicationType.NONE)
+            .run(
+                "--debug=false",
+                "--spring.main.banner-mode=OFF",
+                "--spring.application.name=" + UUID.randomUUID().toString(),
+                "--ribbon.enabled=false",
+                "--ribbon.eureka.enabled=false",
+                "--management.endpoint.enabled=false",
+                "--spring.cloud.zookeeper.enabled=true",
+                "--spring.cloud.zookeeper.connect-string=" + 
server.connectString(),
+                "--spring.cloud.zookeeper.config.enabled=false",
+                "--spring.cloud.zookeeper.discovery.enabled=true",
+                
"--spring.cloud.service-registry.auto-registration.enabled=false"
+            );
+
+        try {
+            Map<String, Converter> converters = 
context.getBeansOfType(Converter.class);
+
+            assertThat(converters).isNotNull();
+            
assertThat(converters.values().stream().anyMatch(ZookeeperServerToServiceDefinition.class::isInstance)).isTrue();
+        } finally {
+
+            // shutdown spring context
+            context.close();
+
+            // shutdown zookeeper
+            server.shutdown();
+        }
+    }
+
     // *************************************
     // Config
     // *************************************
diff --git 
a/components/camel-spring-cloud-zookeeper/src/test/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperServiceRegistryTest.java
 
b/components/camel-spring-cloud-zookeeper/src/test/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperServiceRegistryTest.java
index 465dcd6..4c62084 100644
--- 
a/components/camel-spring-cloud-zookeeper/src/test/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperServiceRegistryTest.java
+++ 
b/components/camel-spring-cloud-zookeeper/src/test/java/org/apache/camel/spring/cloud/zookeeper/CamelCloudZookeeperServiceRegistryTest.java
@@ -69,7 +69,8 @@ public class CamelCloudZookeeperServiceRegistryTest {
                 "--spring.cloud.zookeeper.connect-string=" + 
server.connectString(),
                 "--spring.cloud.zookeeper.config.enabled=false",
                 "--spring.cloud.zookeeper.discovery.enabled=true",
-                
"--spring.cloud.service-registry.auto-registration.enabled=false"
+                
"--spring.cloud.service-registry.auto-registration.enabled=false",
+                "--camel.cloud.service-registry.service-host=" + SERVICE_HOST
             );
 
         try {
diff --git 
a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceLoadBalancer.java
 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceLoadBalancer.java
index 50447f7..d1b6dd6 100644
--- 
a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceLoadBalancer.java
+++ 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceLoadBalancer.java
@@ -16,27 +16,28 @@
  */
 package org.apache.camel.spring.cloud;
 
+import java.util.Optional;
+
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
-import org.apache.camel.cloud.ServiceDefinition;
 import org.apache.camel.cloud.ServiceLoadBalancer;
 import org.apache.camel.cloud.ServiceLoadBalancerFunction;
-import org.apache.camel.impl.cloud.DefaultServiceDefinition;
 import org.apache.camel.support.ServiceSupport;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.cloud.client.ServiceInstance;
 import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
 
 public class CamelSpringCloudServiceLoadBalancer extends ServiceSupport 
implements CamelContextAware, ServiceLoadBalancer {
     private static final Logger LOGGER = 
LoggerFactory.getLogger(CamelSpringCloudServiceLoadBalancer.class);
 
     private final LoadBalancerClient loadBalancerClient;
+    private final ServiceLoadBalancer loadBalancer;
     private CamelContext camelContext;
 
-    public CamelSpringCloudServiceLoadBalancer(LoadBalancerClient 
loadBalancerClient) {
+    public CamelSpringCloudServiceLoadBalancer(LoadBalancerClient 
loadBalancerClient, Optional<LoadBalancerClientAdapter> clientAdapter) {
         this.loadBalancerClient = loadBalancerClient;
+        this.loadBalancer = 
clientAdapter.orElseGet(DefaultLoadBalancerClientAdapter::new).adapt(loadBalancerClient);
     }
 
     @Override
@@ -63,19 +64,15 @@ public class CamelSpringCloudServiceLoadBalancer extends 
ServiceSupport implemen
 
     @Override
     public <T> T process(String serviceName, ServiceLoadBalancerFunction<T> 
function) throws Exception {
-        return loadBalancerClient.execute(serviceName,  i -> 
function.apply(instanceToDefinition(i)));
+        return loadBalancer.process(serviceName, function);
     }
 
     // *******************************
-    // Helpers
+    //
     // *******************************
 
-    private ServiceDefinition instanceToDefinition(ServiceInstance instance) {
-        return new DefaultServiceDefinition(
-            instance.getServiceId(),
-            instance.getHost(),
-            instance.getPort(),
-            instance.getMetadata()
-        );
+    @FunctionalInterface
+    public interface LoadBalancerClientAdapter {
+        ServiceLoadBalancer adapt(LoadBalancerClient client);
     }
 }
\ No newline at end of file
diff --git 
a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceLoadBalancerAutoConfiguration.java
 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceLoadBalancerAutoConfiguration.java
index eab3441..1406724 100644
--- 
a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceLoadBalancerAutoConfiguration.java
+++ 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceLoadBalancerAutoConfiguration.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.spring.cloud;
 
+import java.util.Optional;
+
 import org.apache.camel.cloud.ServiceLoadBalancer;
 import org.apache.camel.spring.boot.cloud.CamelCloudAutoConfiguration;
 import org.apache.camel.spring.boot.cloud.CamelCloudConfigurationProperties;
@@ -40,8 +42,11 @@ public class 
CamelSpringCloudServiceLoadBalancerAutoConfiguration {
 
     @Bean(name = "load-balancer")
     @ConditionalOnMissingBean
-    public ServiceLoadBalancer cloudLoadBalancer(LoadBalancerClient 
loadBalancerClient) {
-        return new CamelSpringCloudServiceLoadBalancer(loadBalancerClient);
+    public ServiceLoadBalancer cloudLoadBalancer(
+            LoadBalancerClient loadBalancerClient,
+            
Optional<CamelSpringCloudServiceLoadBalancer.LoadBalancerClientAdapter> 
clientAdapter) {
+
+        return new CamelSpringCloudServiceLoadBalancer(loadBalancerClient, 
clientAdapter);
     }
 
     // *******************************
diff --git 
a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceRegistry.java
 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceRegistry.java
index e376e08..f7674ac 100644
--- 
a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceRegistry.java
+++ 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/CamelSpringCloudServiceRegistry.java
@@ -47,16 +47,17 @@ public class CamelSpringCloudServiceRegistry extends 
AbstractServiceRegistry {
 
     @Override
     public void register(ServiceDefinition definition) {
-        Registration result = convertServiceDefinition(definition);
-
         synchronized (this) {
-            LOGGER.debug("Register service with definition: {} with 
registrations: {}", definition, registrationType);
-
-            serviceRegistry.register(result);
-
             // keep track of registered definition to remove them upon registry
             // shutdown
             if (definitions.stream().noneMatch(d -> matchById(d, definition))) 
{
+                LOGGER.debug("Register service with definition: {} with 
registrations: {}", definition, registrationType);
+
+                // compute registration from definition
+                Registration result = convertServiceDefinition(definition);
+
+                serviceRegistry.register(result);
+
                 definitions.add(definition);
             }
         }
@@ -64,12 +65,15 @@ public class CamelSpringCloudServiceRegistry extends 
AbstractServiceRegistry {
 
     @Override
     public void deregister(ServiceDefinition definition) {
-        Registration result = convertServiceDefinition(definition);
-
         synchronized (this) {
-            LOGGER.debug("Deregister service with definition: {} with 
registrations: {}", definition, registrationType);
+            if (definitions.stream().noneMatch(d -> matchById(d, definition))) 
{
+                LOGGER.debug("Deregister service with definition: {} with 
registrations: {}", definition, registrationType);
+                
+                // compute registration from definition
+                Registration result = convertServiceDefinition(definition);
 
-            serviceRegistry.deregister(result);
+                serviceRegistry.deregister(result);
+            }
 
             // remove any instance with the same id
             definitions.removeIf(d -> matchById(d, definition));
@@ -82,8 +86,9 @@ public class CamelSpringCloudServiceRegistry extends 
AbstractServiceRegistry {
 
     @Override
     protected void doStop() throws Exception {
-        // TODO: need to be improved
-        new ArrayList<>(definitions).forEach(this::deregister);
+        synchronized (this) {
+            new ArrayList<>(definitions).forEach(this::deregister);
+        }
     }
 
     public ServiceRegistry getNativeServiceRegistry() {
@@ -139,9 +144,11 @@ public class CamelSpringCloudServiceRegistry extends 
AbstractServiceRegistry {
     }
 
     private Registration convertServiceDefinition(ServiceDefinition 
definition) {
-        for (ConversionService conversionService: conversionServices) {
-            if (conversionService.canConvert(ServiceDefinition.class, 
registrationType)) {
-                return conversionService.convert(definition, registrationType);
+        for (int i = 0; i < conversionServices.size(); i++) {
+            ConversionService cs = conversionServices.get(i);
+
+            if (cs.canConvert(ServiceDefinition.class, registrationType)) {
+                return cs.convert(definition, registrationType);
             }
         }
 
diff --git 
a/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/DefaultLoadBalancerClientAdapter.java
similarity index 65%
copy from 
camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
copy to 
components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/DefaultLoadBalancerClientAdapter.java
index 6d1946c..3ecb6d2 100644
--- a/camel-core/src/main/java/org/apache/camel/cloud/DiscoverableService.java
+++ 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/DefaultLoadBalancerClientAdapter.java
@@ -14,13 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.cloud;
+package org.apache.camel.spring.cloud;
 
-import java.util.Map;
+import org.apache.camel.cloud.ServiceLoadBalancer;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
 
-public interface DiscoverableService {
-    /**
-     * Get the service properties.
-     */
-    Map<String, Object> getServiceProperties();
+public class DefaultLoadBalancerClientAdapter implements 
CamelSpringCloudServiceLoadBalancer.LoadBalancerClientAdapter {
+    @Override
+    public ServiceLoadBalancer adapt(LoadBalancerClient client) {
+        return new DefaultServiceLoadBalancer(client);
+    }
 }
diff --git 
a/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/DefaultServiceLoadBalancer.java
 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/DefaultServiceLoadBalancer.java
new file mode 100644
index 0000000..5ab886b
--- /dev/null
+++ 
b/components/camel-spring-cloud/src/main/java/org/apache/camel/spring/cloud/DefaultServiceLoadBalancer.java
@@ -0,0 +1,50 @@
+/**
+ * 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.spring.cloud;
+
+import org.apache.camel.cloud.ServiceDefinition;
+import org.apache.camel.cloud.ServiceLoadBalancer;
+import org.apache.camel.cloud.ServiceLoadBalancerFunction;
+import org.apache.camel.impl.cloud.DefaultServiceDefinition;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
+
+public class DefaultServiceLoadBalancer implements ServiceLoadBalancer {
+    private final LoadBalancerClient client;
+
+    public DefaultServiceLoadBalancer(LoadBalancerClient client) {
+        this.client = client;
+    }
+
+    @Override
+    public <T> T process(String serviceName, ServiceLoadBalancerFunction<T> 
function) throws Exception {
+        return client.execute(serviceName, instance -> {
+            return function.apply(
+                convertServiceInstanceToServiceDefinition(instance)
+            );
+        });
+    }
+
+    protected ServiceDefinition 
convertServiceInstanceToServiceDefinition(ServiceInstance instance) {
+        return new DefaultServiceDefinition(
+            instance.getServiceId(),
+            instance.getHost(),
+            instance.getPort(),
+            instance.getMetadata()
+        );
+    }
+}
diff --git 
a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
 
b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
index bd6ffa8..1165137 100644
--- 
a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
+++ 
b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowEndpoint.java
@@ -142,9 +142,9 @@ public class UndertowEndpoint extends DefaultEndpoint 
implements AsyncEndpoint,
     //-------------------------------------------------------------------------
 
     @Override
-    public Map<String, Object> getServiceProperties() {
+    public Map<String, String> getServiceProperties() {
         return CollectionHelper.immutableMapOf(
-            ServiceDefinition.SERVICE_META_PORT, httpURI.getPort(),
+            ServiceDefinition.SERVICE_META_PORT, 
Integer.toString(httpURI.getPort()),
             ServiceDefinition.SERVICE_META_PATH, httpURI.getPath(),
             ServiceDefinition.SERVICE_META_PROTOCOL, httpURI.getScheme()
         );
diff --git 
a/examples/camel-example-spring-cloud-serviceregistry/consumer/pom.xml 
b/examples/camel-example-spring-cloud-serviceregistry/consumer/pom.xml
index c0c293c..31188c5 100644
--- a/examples/camel-example-spring-cloud-serviceregistry/consumer/pom.xml
+++ b/examples/camel-example-spring-cloud-serviceregistry/consumer/pom.xml
@@ -103,6 +103,10 @@
     </dependency>
     <dependency>
       <groupId>org.apache.camel</groupId>
+      <artifactId>camel-spring-cloud-netflix-starter</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
       <artifactId>camel-spring-cloud-consul-starter</artifactId>
     </dependency>
     <dependency>
diff --git 
a/examples/camel-example-spring-cloud-serviceregistry/consumer/src/main/resources/application.properties
 
b/examples/camel-example-spring-cloud-serviceregistry/consumer/src/main/resources/application.properties
index 0eaa50e..cfd926a 100644
--- 
a/examples/camel-example-spring-cloud-serviceregistry/consumer/src/main/resources/application.properties
+++ 
b/examples/camel-example-spring-cloud-serviceregistry/consumer/src/main/resources/application.properties
@@ -41,12 +41,3 @@ camel.rest.binding-mode = auto
 # Camel Service Call
 camel.cloud.service-call.component = undertow
 
-# this should not be needed but there is a bug or misbehavior
-# on spring cloud netflix side that prevent ribbon load
-# balancer to propagate metadata from i.e. consul, see:
-#
-#     https://github.com/spring-cloud/spring-cloud-consul/issues/424
-#
-camel.cloud.ribbon.load-balancer.enabled = false
-camel.cloud.service-call.default-load-balancer = true
-camel.cloud.service-call.service-chooser = roundrobin

-- 
To stop receiving notification emails like this one, please contact
lburgazz...@apache.org.

Reply via email to