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 2018/05/30 10:05:04 UTC
[camel] 12/20: CAMEL-12518: camel cloud : leverage spring-cloud
ServiceRegistry to register routes
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 <lb...@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
lburgazzoli@apache.org.