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 5314b540ab1b7add858a26a92c71911f0fe4539e Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Mon May 14 14:49:37 2018 +0200 CAMEL-12485: camel cloud : create camel-service component --- .../org/apache/camel/util/CollectionHelper.java | 45 +++ components/camel-consul/pom.xml | 5 + .../consul/cloud/ConsulServiceRegistry.java | 9 +- .../ConsulServiceCallWithRegistrationTest.java | 4 +- .../camel/http/common/HttpCommonEndpoint.java | 12 +- .../camel/component/undertow/UndertowEndpoint.java | 17 +- components/camel-zookeeper/pom.xml | 10 + .../zookeeper/cloud/ZooKeeperServiceDiscovery.java | 5 +- .../cloud/ZooKeeperServiceDiscoveryFactory.java | 4 - .../zookeeper/cloud/ZooKeeperServiceRegistry.java | 394 +++++++++++++++++++++ .../ZooKeeperServiceRegistryConfiguration.java | 78 ++++ .../cloud/ZooKeeperServiceDiscoveryTest.java | 2 +- .../ZooKeeperServiceRegistrationTestBase.java | 140 ++++++++ ...RegistrationWithRoutePolicyAndMetadataTest.java | 40 +++ ...viceRegistrationWithRoutePolicyFactoryTest.java | 46 +++ ...eperServiceRegistrationWithRoutePolicyTest.java | 38 ++ ...erviceRegistrationWithServiceComponentTest.java | 56 +++ components/pom.xml | 2 +- parent/pom.xml | 2 +- .../camel-consul-starter/pom.xml | 76 ++++ .../ConsulServiceDiscoveryAutoConfiguration.java | 1 - .../ConsulServiceRegistryAutoConfiguration.java} | 23 +- .../ConsulServiceRegistryConfiguration.java} | 11 +- .../cluster/ConsulClusterServiceConfiguration.java | 2 +- .../src/main/resources/META-INF/spring.factories | 9 +- .../cloud/ConsulServiceDiscoveryDisabledTest.java | 64 ---- .../cloud/ConsulServiceDiscoveryEnabledTest.java | 65 ---- .../cloud/ConsulServiceDiscoveryTest.java | 63 ++++ .../springboot/cloud/ConsulServiceRegistryIT.java | 98 +++++ .../cloud/support/ConsulContainerLogger.java | 31 ++ .../cloud/support/ConsulContainerSupport.java | 46 +++ .../cloud/support/ConsulContainerWaitStrategy.java | 48 +++ .../src/test/resources/logback.xml | 1 + .../camel-zookeeper-starter/pom.xml | 7 + ...ZooKeeperServiceRegistryAutoConfiguration.java} | 23 +- .../ZooKeeperServiceRegistryConfiguration.java} | 11 +- .../ZooKeeperClusterServiceAutoConfiguration.java | 2 +- .../ZooKeeperClusterServiceConfiguration.java | 2 +- .../src/main/resources/META-INF/spring.factories | 5 +- .../cloud/ZooKeeperServiceRegistryTest.java | 264 ++++++++++++++ .../resources/application.properties} | 4 +- .../src/test/resources/logback.xml | 3 +- platforms/spring-boot/spring-boot-dm/pom.xml | 1 + 43 files changed, 1564 insertions(+), 205 deletions(-) diff --git a/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java b/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java index 168e5ad..283682d 100644 --- a/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java +++ b/camel-core/src/main/java/org/apache/camel/util/CollectionHelper.java @@ -28,6 +28,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Supplier; import org.w3c.dom.NodeList; @@ -170,4 +171,48 @@ public final class CollectionHelper { ? Collections.emptyMap() : Collections.unmodifiableMap(new HashMap<>(map)); } + + + /** + * Build a map from varargs. + */ + public static <K, V> Map<K, V> mapOf(Supplier<Map<K,V>> creator, K key, V value, Object... keyVals) { + Map<K, V> map = creator.get(); + map.put(key, value); + + for(int i = 0; i < keyVals.length; i += 2) { + map.put( + (K) keyVals[i], + (V) keyVals[i + 1] + ); + } + + return map; + } + + + /** + * Build an immutable map from varargs. + */ + public static <K, V> Map<K, V> immutableMapOf(Supplier<Map<K,V>> creator, K key, V value, Object... keyVals) { + return Collections.unmodifiableMap( + mapOf(creator, key, value, keyVals) + ); + } + + /** + * Build a map from varargs. + */ + public static <K, V> Map<K, V> mapOf(K key, V value, Object... keyVals) { + return mapOf(HashMap::new, key, value, keyVals); + } + + /** + * Build an immutable map from varargs. + */ + public static <K, V> Map<K, V> immutableMapOf(K key, V value, Object... keyVals) { + return Collections.unmodifiableMap( + mapOf(HashMap::new, key, value, keyVals) + ); + } } diff --git a/components/camel-consul/pom.xml b/components/camel-consul/pom.xml index 4d735c7..e5807ec 100644 --- a/components/camel-consul/pom.xml +++ b/components/camel-consul/pom.xml @@ -71,6 +71,11 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-undertow</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-master</artifactId> <scope>test</scope> </dependency> diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceRegistry.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceRegistry.java index 2028936..9396207e 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceRegistry.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceRegistry.java @@ -228,9 +228,9 @@ public class ConsulServiceRegistry extends AbstractServiceRegistry { } } - // ********************************************* - // - // ********************************************* + // **************** + // Registry + // **************** @Override public void register(ServiceDefinition definition) { @@ -303,6 +303,9 @@ public class ConsulServiceRegistry extends AbstractServiceRegistry { } client.agentClient().deregister(definition.getId()); + + //remove the serviceId to the list of known server + serviceList.remove(definition.getId()); } private String computeServiceHost(ServiceDefinition definition) { diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallWithRegistrationTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallWithRegistrationTest.java index b0efaab..2bbd547 100644 --- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallWithRegistrationTest.java +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallWithRegistrationTest.java @@ -80,7 +80,7 @@ public class ConsulServiceCallWithRegistrationTest extends ConsulTestSupport { .end() .log("${body}"); - fromF("jetty:http://%s:%d/service/path", SERVICE_HOST, port) + fromF("undertow:http://%s:%d/service/path", SERVICE_HOST, port) .routeId(serviceId) .routeGroup(serviceName) .routePolicy(new ServiceRegistrationRoutePolicy()) @@ -116,7 +116,7 @@ public class ConsulServiceCallWithRegistrationTest extends ConsulTestSupport { .end() .log("${body}"); - fromF("jetty:http://%s:%d/service/path", SERVICE_HOST, port) + fromF("undertow:http://%s:%d/service/path", SERVICE_HOST, port) .routeId(serviceId) .routeGroup(serviceName) .routePolicy(new ServiceRegistrationRoutePolicy()) 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 9e9e196..e7d465e 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 @@ -18,7 +18,6 @@ package org.apache.camel.http.common; import java.net.URI; import java.net.URISyntaxException; -import java.util.HashMap; import java.util.Map; import org.apache.camel.cloud.DiscoverableService; @@ -30,6 +29,7 @@ import org.apache.camel.spi.HeaderFilterStrategyAware; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; +import org.apache.camel.util.CollectionHelper; public abstract class HttpCommonEndpoint extends DefaultEndpoint implements HeaderFilterStrategyAware, DiscoverableService { @@ -202,11 +202,11 @@ public abstract class HttpCommonEndpoint extends DefaultEndpoint implements Head @Override public Map<String, Object> getServiceProperties() { - return new HashMap<String, Object>() {{ - put(ServiceDefinition.SERVICE_META_PORT, getPort()); - put(ServiceDefinition.SERVICE_META_PATH, getPath()); - put(ServiceDefinition.SERVICE_META_PROTOCOL, getProtocol()); - }}; + return CollectionHelper.immutableMapOf( + ServiceDefinition.SERVICE_META_PORT, getPort(), + ServiceDefinition.SERVICE_META_PATH, getPath(), + ServiceDefinition.SERVICE_META_PROTOCOL, getProtocol() + ); } // Properties 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 23c8caa..bd6ffa8 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 @@ -30,6 +30,8 @@ import org.apache.camel.Message; import org.apache.camel.PollingConsumer; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.cloud.DiscoverableService; +import org.apache.camel.cloud.ServiceDefinition; import org.apache.camel.component.undertow.UndertowConstants.EventType; import org.apache.camel.component.undertow.handlers.CamelWebSocketHandler; import org.apache.camel.http.common.cookie.CookieHandler; @@ -40,6 +42,7 @@ import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; +import org.apache.camel.util.CollectionHelper; import org.apache.camel.util.jsse.SSLContextParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,7 +55,7 @@ import org.xnio.Options; */ @UriEndpoint(firstVersion = "2.16.0", scheme = "undertow", title = "Undertow", syntax = "undertow:httpURI", consumerClass = UndertowConsumer.class, label = "http,websocket", lenientProperties = true) -public class UndertowEndpoint extends DefaultEndpoint implements AsyncEndpoint, HeaderFilterStrategyAware { +public class UndertowEndpoint extends DefaultEndpoint implements AsyncEndpoint, HeaderFilterStrategyAware, DiscoverableService { private static final Logger LOG = LoggerFactory.getLogger(UndertowEndpoint.class); private UndertowComponent component; @@ -135,6 +138,18 @@ public class UndertowEndpoint extends DefaultEndpoint implements AsyncEndpoint, return true; } + // Service Registration + //------------------------------------------------------------------------- + + @Override + public Map<String, Object> getServiceProperties() { + return CollectionHelper.immutableMapOf( + ServiceDefinition.SERVICE_META_PORT, httpURI.getPort(), + ServiceDefinition.SERVICE_META_PATH, httpURI.getPath(), + ServiceDefinition.SERVICE_META_PROTOCOL, httpURI.getScheme() + ); + } + public Exchange createExchange(HttpServerExchange httpExchange) throws Exception { Exchange exchange = createExchange(ExchangePattern.InOut); diff --git a/components/camel-zookeeper/pom.xml b/components/camel-zookeeper/pom.xml index 0aaaedc..31b04ee 100644 --- a/components/camel-zookeeper/pom.xml +++ b/components/camel-zookeeper/pom.xml @@ -99,11 +99,21 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-undertow</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-master</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.camel</groupId> + <artifactId>camel-service</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.camel</groupId> <artifactId>camel-test-spring</artifactId> <scope>test</scope> </dependency> diff --git a/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscovery.java b/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscovery.java index 3a7dde9..a46ce09 100644 --- a/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscovery.java +++ b/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscovery.java @@ -118,9 +118,8 @@ public class ZooKeeperServiceDiscovery extends DefaultServiceDiscovery { Map<String, String> meta = new HashMap<>(); ObjectHelper.ifNotEmpty(si.getPayload(), meta::putAll); - meta.put("service_name", si.getName()); - meta.put("service_id", si.getId()); - meta.put("service_type", si.getServiceType().name()); + meta.putIfAbsent(ServiceDefinition.SERVICE_META_NAME, si.getName()); + meta.putIfAbsent(ServiceDefinition.SERVICE_META_ID, si.getId()); return new DefaultServiceDefinition( si.getName(), diff --git a/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscoveryFactory.java b/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscoveryFactory.java index b3b0604..25c29f9 100644 --- a/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscoveryFactory.java +++ b/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscoveryFactory.java @@ -167,10 +167,6 @@ public class ZooKeeperServiceDiscoveryFactory implements ServiceDiscoveryFactory configuration.setConnectionTimeoutUnit(connectionTimeoutUnit); } - public ZooKeeperCuratorConfiguration copy() { - return configuration.copy(); - } - public List<AuthInfo> getAuthInfoList() { return configuration.getAuthInfoList(); } diff --git a/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistry.java b/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistry.java new file mode 100644 index 0000000..89fb08d --- /dev/null +++ b/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistry.java @@ -0,0 +1,394 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.zookeeper.cloud; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import org.apache.camel.cloud.ServiceDefinition; +import org.apache.camel.component.zookeeper.ZooKeeperCuratorHelper; +import org.apache.camel.impl.cloud.AbstractServiceRegistry; +import org.apache.camel.util.ObjectHelper; +import org.apache.curator.RetryPolicy; +import org.apache.curator.framework.AuthInfo; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.x.discovery.ServiceDiscovery; +import org.apache.curator.x.discovery.ServiceInstance; +import org.codehaus.jackson.map.annotate.JsonRootName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ZooKeeperServiceRegistry extends AbstractServiceRegistry { + private static final Logger LOGGER = LoggerFactory.getLogger(ZooKeeperServiceRegistry.class); + + private final Set<String> serviceList; + private final boolean managedInstance; + private ZooKeeperServiceRegistryConfiguration configuration; + private CuratorFramework curator; + private ServiceDiscovery<MetaData> serviceDiscovery; + + public ZooKeeperServiceRegistry() { + this.serviceList = ConcurrentHashMap.newKeySet(); + this.configuration = new ZooKeeperServiceRegistryConfiguration(); + this.curator = configuration.getCuratorFramework(); + this.managedInstance = Objects.isNull(curator); + } + + public ZooKeeperServiceRegistry(ZooKeeperServiceRegistryConfiguration configuration) { + this.serviceList = ConcurrentHashMap.newKeySet(); + this.configuration = configuration.copy(); + this.curator = configuration.getCuratorFramework(); + this.managedInstance = Objects.isNull(curator); + } + + // **************** + // Properties + // **************** + + public ZooKeeperServiceRegistryConfiguration getConfiguration() { + return configuration; + } + + public void setConfiguration(ZooKeeperServiceRegistryConfiguration configuration) { + this.configuration = configuration.copy(); + } + + public CuratorFramework getCuratorFramework() { + return configuration.getCuratorFramework(); + } + + public void setCuratorFramework(CuratorFramework curatorFramework) { + configuration.setCuratorFramework(curatorFramework); + } + + public List<String> getNodes() { + return configuration.getNodes(); + } + + public void setNodes(String nodes) { + configuration.setNodes(nodes); + } + + public void setNodes(List<String> nodes) { + configuration.setNodes(nodes); + } + + public String getNamespace() { + return configuration.getNamespace(); + } + + public void setNamespace(String namespace) { + configuration.setNamespace(namespace); + } + + public long getReconnectBaseSleepTime() { + return configuration.getReconnectBaseSleepTime(); + } + + public void setReconnectBaseSleepTime(long reconnectBaseSleepTime) { + configuration.setReconnectBaseSleepTime(reconnectBaseSleepTime); + } + + public void setReconnectBaseSleepTime(long reconnectBaseSleepTime, TimeUnit reconnectBaseSleepTimeUnit) { + configuration.setReconnectBaseSleepTime(reconnectBaseSleepTime, reconnectBaseSleepTimeUnit); + } + + public TimeUnit getReconnectBaseSleepTimeUnit() { + return configuration.getReconnectBaseSleepTimeUnit(); + } + + public void setReconnectBaseSleepTimeUnit(TimeUnit reconnectBaseSleepTimeUnit) { + configuration.setReconnectBaseSleepTimeUnit(reconnectBaseSleepTimeUnit); + } + + public long getReconnectMaxSleepTime() { + return configuration.getReconnectMaxSleepTime(); + } + + public void setReconnectMaxSleepTime(long reconnectMaxSleepTime) { + configuration.setReconnectMaxSleepTime(reconnectMaxSleepTime); + } + + public void setReconnectMaxSleepTime(long reconnectMaxSleepTime, TimeUnit reconnectBaseSleepTimeUnit) { + configuration.setReconnectMaxSleepTime(reconnectMaxSleepTime, reconnectBaseSleepTimeUnit); + } + + public TimeUnit getReconnectMaxSleepTimeUnit() { + return configuration.getReconnectMaxSleepTimeUnit(); + } + + public void setReconnectMaxSleepTimeUnit(TimeUnit reconnectMaxSleepTimeUnit) { + configuration.setReconnectMaxSleepTimeUnit(reconnectMaxSleepTimeUnit); + } + + public int getReconnectMaxRetries() { + return configuration.getReconnectMaxRetries(); + } + + public void setReconnectMaxRetries(int reconnectMaxRetries) { + configuration.setReconnectMaxRetries(reconnectMaxRetries); + } + + public long getSessionTimeout() { + return configuration.getSessionTimeout(); + } + + public void setSessionTimeout(long sessionTimeout) { + configuration.setSessionTimeout(sessionTimeout); + } + + public void setSessionTimeout(long sessionTimeout, TimeUnit sessionTimeoutUnit) { + configuration.setSessionTimeout(sessionTimeout, sessionTimeoutUnit); + } + + public TimeUnit getSessionTimeoutUnit() { + return configuration.getSessionTimeoutUnit(); + } + + public void setSessionTimeoutUnit(TimeUnit sessionTimeoutUnit) { + configuration.setSessionTimeoutUnit(sessionTimeoutUnit); + } + + public long getConnectionTimeout() { + return configuration.getConnectionTimeout(); + } + + public void setConnectionTimeout(long connectionTimeout) { + configuration.setConnectionTimeout(connectionTimeout); + } + + public void setConnectionTimeout(long connectionTimeout, TimeUnit connectionTimeotUnit) { + configuration.setConnectionTimeout(connectionTimeout, connectionTimeotUnit); + } + + public TimeUnit getConnectionTimeoutUnit() { + return configuration.getConnectionTimeoutUnit(); + } + + public void setConnectionTimeoutUnit(TimeUnit connectionTimeoutUnit) { + configuration.setConnectionTimeoutUnit(connectionTimeoutUnit); + } + + public List<AuthInfo> getAuthInfoList() { + return configuration.getAuthInfoList(); + } + + public void setAuthInfoList(List<AuthInfo> authInfoList) { + configuration.setAuthInfoList(authInfoList); + } + + public long getMaxCloseWait() { + return configuration.getMaxCloseWait(); + } + + public void setMaxCloseWait(long maxCloseWait) { + configuration.setMaxCloseWait(maxCloseWait); + } + + public TimeUnit getMaxCloseWaitUnit() { + return configuration.getMaxCloseWaitUnit(); + } + + public void setMaxCloseWaitUnit(TimeUnit maxCloseWaitUnit) { + configuration.setMaxCloseWaitUnit(maxCloseWaitUnit); + } + + public RetryPolicy getRetryPolicy() { + return configuration.getRetryPolicy(); + } + + public void setRetryPolicy(RetryPolicy retryPolicy) { + configuration.setRetryPolicy(retryPolicy); + } + + public String getBasePath() { + return configuration.getBasePath(); + } + + public void setBasePath(String basePath) { + configuration.setBasePath(basePath); + } + + public boolean isDeregisterServicesOnStop() { + return configuration.isDeregisterServicesOnStop(); + } + + public void setDeregisterServicesOnStop(boolean deregisterServicesOnStop) { + configuration.setDeregisterServicesOnStop(deregisterServicesOnStop); + } + + public boolean isOverrideServiceHost() { + return configuration.isOverrideServiceHost(); + } + + public void setOverrideServiceHost(boolean overrideServiceHost) { + configuration.setOverrideServiceHost(overrideServiceHost); + } + + public String getServiceHost() { + return configuration.getServiceHost(); + } + + public void setServiceHost(String serviceHost) { + configuration.setServiceHost(serviceHost); + } + + // **************** + // Lifecycle + // **************** + + @Override + protected void doStart() throws Exception { + if (curator == null) { + // Validation + ObjectHelper.notNull(getCamelContext(), "Camel Context"); + ObjectHelper.notNull(configuration.getBasePath(), "ZooKeeper base path"); + + LOGGER.debug("Starting ZooKeeper Curator with namespace '{}', nodes: '{}'", + configuration.getNamespace(), + String.join(",", configuration.getNodes()) + ); + + curator = ZooKeeperCuratorHelper.createCurator(configuration); + curator.start(); + } + + if (serviceDiscovery == null) { + // Validation + ObjectHelper.notNull(configuration.getBasePath(), "ZooKeeper base path"); + + LOGGER.debug("Starting ZooKeeper ServiceDiscoveryBuilder with base path '{}'", + configuration.getBasePath() + ); + + serviceDiscovery = ZooKeeperCuratorHelper.createServiceDiscovery(configuration, curator, MetaData.class); + serviceDiscovery.start(); + } + } + + @Override + protected void doStop() throws Exception { + if (serviceDiscovery != null) { + try { + if (configuration.isDeregisterServicesOnStop()) { + for (String serviceName: serviceDiscovery.queryForNames()) { + for (ServiceInstance<MetaData> serviceInstance: serviceDiscovery.queryForInstances(serviceName)) { + if (serviceList.contains(serviceInstance.getId())) { + serviceDiscovery.unregisterService(serviceInstance); + + // remove the serviceId to the list of known server + serviceList.remove(serviceInstance.getId()); + } + } + } + } + + serviceDiscovery.close(); + } catch (Exception e) { + LOGGER.warn("Error closing Curator ServiceDiscovery", e); + } + } + + if (curator != null && managedInstance) { + curator.close(); + } + } + + // **************** + // Registry + // **************** + + @Override + public void register(ServiceDefinition definition) { + if (definition.getId() == null) { + throw new IllegalArgumentException("Service ID must be defined (definition=" + definition + ")"); + } + if (definition.getName() == null) { + throw new IllegalArgumentException("Service Name must be defined (definition=" + definition + ")"); + } + + try { + ServiceInstance<MetaData> instance = ServiceInstance.<MetaData>builder() + .address(computeServiceHost(definition)) + .port(definition.getPort()) + .name(definition.getName()) + .id(definition.getId()) + .payload(new MetaData(definition.getMetadata())) + .build(); + + serviceDiscovery.registerService(instance); + + // add the serviceId to the list of known server + serviceList.add(definition.getId()); + } catch (Exception e) { + LOGGER.warn("", e); + } + } + + @Override + public void deregister(ServiceDefinition definition) { + if (definition.getId() == null) { + throw new IllegalArgumentException("Service ID must be defined (definition=" + definition + ")"); + } + if (definition.getName() == null) { + throw new IllegalArgumentException("Service Name must be defined (definition=" + definition + ")"); + } + + try { + for (ServiceInstance<MetaData> serviceInstance: serviceDiscovery.queryForInstances(definition.getName())) { + if (Objects.equals(serviceInstance.getId(), definition.getId())) { + serviceDiscovery.unregisterService(serviceInstance); + + // remove the serviceId to the list of known server + serviceList.remove((serviceInstance.getId())); + } + } + } catch (Exception e) { + LOGGER.warn("", e); + } + } + + // ********************************************* + // Helpers + // ********************************************* + + + private String computeServiceHost(ServiceDefinition definition) { + String host = definition.getHost(); + + if (configuration.isOverrideServiceHost() && configuration.getServiceHost() != null) { + host = configuration.getServiceHost(); + } + + return ObjectHelper.notNull(host, "service host"); + } + + @JsonRootName("meta") + public static final class MetaData extends HashMap<String, String> { + public MetaData() { + } + + public MetaData(Map<? extends String, ? extends String> meta) { + super(meta); + } + } +} diff --git a/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistryConfiguration.java b/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistryConfiguration.java new file mode 100644 index 0000000..fd4d6aa --- /dev/null +++ b/components/camel-zookeeper/src/main/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistryConfiguration.java @@ -0,0 +1,78 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.zookeeper.cloud; + +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.component.zookeeper.ZooKeeperCuratorConfiguration; + +public class ZooKeeperServiceRegistryConfiguration extends ZooKeeperCuratorConfiguration { + /** + * Should we remove all the registered services know by this registry on stop? + */ + private boolean deregisterServicesOnStop = true; + + /** + * Should we override the service host if given ? + */ + private boolean overrideServiceHost = true; + + /** + * Service host. + */ + private String serviceHost; + + // *********************************************** + // Properties + // *********************************************** + + public boolean isDeregisterServicesOnStop() { + return deregisterServicesOnStop; + } + + public void setDeregisterServicesOnStop(boolean deregisterServicesOnStop) { + this.deregisterServicesOnStop = deregisterServicesOnStop; + } + + public boolean isOverrideServiceHost() { + return overrideServiceHost; + } + + public void setOverrideServiceHost(boolean overrideServiceHost) { + this.overrideServiceHost = overrideServiceHost; + } + + public String getServiceHost() { + return serviceHost; + } + + public void setServiceHost(String serviceHost) { + this.serviceHost = serviceHost; + } + + // *********************************************** + // + // *********************************************** + + @Override + public ZooKeeperServiceRegistryConfiguration copy() { + try { + return (ZooKeeperServiceRegistryConfiguration)super.clone(); + } catch (CloneNotSupportedException e) { + throw new RuntimeCamelException(e); + } + } +} diff --git a/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscoveryTest.java b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscoveryTest.java index e6d5551..82eca2d 100644 --- a/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscoveryTest.java +++ b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceDiscoveryTest.java @@ -92,7 +92,7 @@ public class ZooKeeperServiceDiscoveryTest { i -> { return i.getPort() == service.getPort() && i.getAddress().equals(service.getHost()) - && i.getId().equals(service.getMetadata().get("service_id")) + && i.getId().equals(service.getMetadata().get(ServiceDefinition.SERVICE_META_ID)) && i.getName().equals(service.getName()); } ).count() diff --git a/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationTestBase.java b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationTestBase.java new file mode 100644 index 0000000..99b08a1 --- /dev/null +++ b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationTestBase.java @@ -0,0 +1,140 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.zookeeper.cloud; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; + +import org.apache.camel.CamelContext; +import org.apache.camel.cloud.ServiceDefinition; +import org.apache.camel.component.zookeeper.ZooKeeperTestSupport; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.curator.utils.CloseableUtils; +import org.apache.curator.x.discovery.ServiceDiscovery; +import org.apache.curator.x.discovery.ServiceDiscoveryBuilder; +import org.apache.curator.x.discovery.ServiceInstance; +import org.apache.curator.x.discovery.details.JsonInstanceSerializer; +import org.junit.Test; + +public abstract class ZooKeeperServiceRegistrationTestBase extends CamelTestSupport { + protected final static String SERVICE_ID = UUID.randomUUID().toString(); + protected final static String SERVICE_NAME = "my-service"; + protected final static String SERVICE_HOST = "localhost"; + protected static final String SERVICE_PATH = "/camel"; + protected final static int SERVICE_PORT = AvailablePortFinder.getNextAvailable(); + protected final static int SERVER_PORT = AvailablePortFinder.getNextAvailable(); + + protected ZooKeeperTestSupport.TestZookeeperServer server; + protected CuratorFramework curator; + protected ServiceDiscovery<ZooKeeperServiceRegistry.MetaData> discovery; + + // *********************** + // Lifecycle + // *********************** + + @Override + protected void doPreSetup() throws Exception { + super.doPreSetup(); + + server = new ZooKeeperTestSupport.TestZookeeperServer(SERVER_PORT, true); + ZooKeeperTestSupport.waitForServerUp("127.0.0.1:" + SERVER_PORT, 1000); + + curator = CuratorFrameworkFactory.builder() + .connectString("127.0.0.1:" + SERVER_PORT) + .retryPolicy(new ExponentialBackoffRetry(1000, 3)) + .build(); + + discovery = ServiceDiscoveryBuilder.builder(ZooKeeperServiceRegistry.MetaData.class) + .client(curator) + .basePath(SERVICE_PATH) + .serializer(new JsonInstanceSerializer<>(ZooKeeperServiceRegistry.MetaData.class)) + .build(); + + curator.start(); + discovery.start(); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + + CloseableUtils.closeQuietly(discovery); + CloseableUtils.closeQuietly(curator); + + server.shutdown(); + } + + + protected Map<String, String> getMetadata() { + return Collections.emptyMap(); + } + + @Override + protected CamelContext createCamelContext() throws Exception { + final CamelContext context = super.createCamelContext(); + + ZooKeeperServiceRegistry registry = new ZooKeeperServiceRegistry(); + registry.setId(context.getUuidGenerator().generateUuid()); + registry.setCamelContext(context()); + registry.setNodes("localhost:" + SERVER_PORT); + registry.setBasePath(SERVICE_PATH); + registry.setServiceHost(SERVICE_HOST); + registry.setOverrideServiceHost(true); + + context.addService(registry, true, false); + + return context; + } + + @Test + public void testRegistrationFromRoute() throws Exception { + + // the service should not be registered as the route is not running + assertTrue(discovery.queryForInstances(SERVICE_NAME).isEmpty()); + + // let start the route + context().startRoute(SERVICE_ID); + + // check that service has been registered + Collection<ServiceInstance<ZooKeeperServiceRegistry.MetaData>> services = discovery.queryForInstances(SERVICE_NAME); + assertEquals(1, services.size()); + + ServiceInstance<ZooKeeperServiceRegistry.MetaData> instance = services.iterator().next(); + assertEquals(SERVICE_PORT, (int)instance.getPort()); + assertEquals("localhost", instance.getAddress()); + assertEquals("http", instance.getPayload().get(ServiceDefinition.SERVICE_META_PROTOCOL)); + assertEquals("/service/endpoint", instance.getPayload().get(ServiceDefinition.SERVICE_META_PATH)); + + getMetadata().forEach( + (k, v) -> { + assertEquals(v, instance.getPayload().get(k)); + } + ); + + // let stop the route + context().stopRoute(SERVICE_ID); + + // the service should be removed once the route is stopped + assertTrue(discovery.queryForInstances(SERVICE_NAME).isEmpty()); + } +} diff --git a/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyAndMetadataTest.java b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyAndMetadataTest.java new file mode 100644 index 0000000..f7d7dc6 --- /dev/null +++ b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyAndMetadataTest.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.zookeeper.cloud; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.cloud.ServiceDefinition; +import org.apache.camel.impl.cloud.ServiceRegistrationRoutePolicy; + +public class ZooKeeperServiceRegistrationWithRoutePolicyAndMetadataTest extends ZooKeeperServiceRegistrationTestBase { + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + fromF("jetty:http://0.0.0.0:%d/service/endpoint", SERVICE_PORT) + .routeId(SERVICE_ID) + .routeProperty(ServiceDefinition.SERVICE_META_ID, SERVICE_ID) + .routeProperty(ServiceDefinition.SERVICE_META_NAME, SERVICE_NAME) + .routePolicy(new ServiceRegistrationRoutePolicy()) + .noAutoStartup() + .to("log:service-registry?level=INFO"); + } + }; + } +} diff --git a/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyFactoryTest.java b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyFactoryTest.java new file mode 100644 index 0000000..6e90224 --- /dev/null +++ b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyFactoryTest.java @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.zookeeper.cloud; + +import org.apache.camel.CamelContext; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.cloud.ServiceRegistrationRoutePolicyFactory; + +public class ZooKeeperServiceRegistrationWithRoutePolicyFactoryTest extends ZooKeeperServiceRegistrationTestBase { + @Override + protected CamelContext createCamelContext() throws Exception { + CamelContext context = super.createCamelContext(); + context.addRoutePolicyFactory(new ServiceRegistrationRoutePolicyFactory()); + + return context; + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + fromF("jetty:http://0.0.0.0:%d/service/endpoint", SERVICE_PORT) + .routeId(SERVICE_ID) + .routeGroup(SERVICE_NAME) + .noAutoStartup() + .to("log:service-registry?level=INFO"); + } + }; + } +} diff --git a/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyTest.java b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyTest.java new file mode 100644 index 0000000..aa52d94 --- /dev/null +++ b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithRoutePolicyTest.java @@ -0,0 +1,38 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.zookeeper.cloud; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.cloud.ServiceRegistrationRoutePolicy; + +public class ZooKeeperServiceRegistrationWithRoutePolicyTest extends ZooKeeperServiceRegistrationTestBase { + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + fromF("jetty:http://0.0.0.0:%d/service/endpoint", SERVICE_PORT) + .routeId(SERVICE_ID) + .routeGroup(SERVICE_NAME) + .routePolicy(new ServiceRegistrationRoutePolicy()) + .noAutoStartup() + .to("log:service-registry?level=INFO"); + } + }; + } +} diff --git a/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithServiceComponentTest.java b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithServiceComponentTest.java new file mode 100644 index 0000000..23d70b7 --- /dev/null +++ b/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/cloud/ZooKeeperServiceRegistrationWithServiceComponentTest.java @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.zookeeper.cloud; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.service.ServiceComponent; +import org.apache.camel.impl.JndiRegistry; + +public class ZooKeeperServiceRegistrationWithServiceComponentTest extends ZooKeeperServiceRegistrationTestBase { + + protected Map<String, String> getMetadata() { + return new HashMap<String, String>() {{ + put("service.type", "zookeeper"); + }}; + } + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry registry = super.createRegistry(); + registry.bind("service", new ServiceComponent()); + + return registry; + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + fromF("service:%s:jetty:http://0.0.0.0:%d/service/endpoint?service.type=zookeeper", SERVICE_NAME, SERVICE_PORT) + .routeId(SERVICE_ID) + .routeGroup(SERVICE_NAME) + .noAutoStartup() + .to("log:service-registry?level=INFO"); + } + }; + } +} diff --git a/components/pom.xml b/components/pom.xml index 8651841..f52a668 100644 --- a/components/pom.xml +++ b/components/pom.xml @@ -56,6 +56,7 @@ <module>camel-jetty-common</module> <module>camel-jetty</module> <module>camel-jetty9</module> + <module>camel-undertow</module> <module>camel-cxf</module> <module>camel-cxf-transport</module> <module>camel-jms</module> @@ -302,7 +303,6 @@ <module>camel-thrift</module> <module>camel-twilio</module> <module>camel-twitter</module> - <module>camel-undertow</module> <module>camel-univocity-parsers</module> <module>camel-urlrewrite</module> <module>camel-velocity</module> diff --git a/parent/pom.xml b/parent/pom.xml index 0d00ad6..0d56081 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -680,7 +680,7 @@ <stringtemplate-version>4.0.8</stringtemplate-version> <tagsoup-bundle-version>1.2.1_1</tagsoup-bundle-version> <tagsoup-version>1.2.1</tagsoup-version> - <testcontainers-version>1.7.2</testcontainers-version> + <testcontainers-version>1.7.3</testcontainers-version> <testng-version>6.14.2</testng-version> <tinybundles-version>2.1.1</tinybundles-version> <tika-version>1.18</tika-version> diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/pom.xml b/platforms/spring-boot/components-starter/camel-consul-starter/pom.xml index 476c55b..f878775 100644 --- a/platforms/spring-boot/components-starter/camel-consul-starter/pom.xml +++ b/platforms/spring-boot/components-starter/camel-consul-starter/pom.xml @@ -39,6 +39,20 @@ <artifactId>camel-consul</artifactId> <version>${project.version}</version> </dependency> + <!-- testing --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-jetty</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <!-- testing (docker) --> + <dependency> + <groupId>org.testcontainers</groupId> + <artifactId>testcontainers</artifactId> + <version>${testcontainers-version}</version> + <scope>test</scope> + </dependency> <!--START OF GENERATED CODE--> <dependency> <groupId>org.apache.camel</groupId> @@ -50,4 +64,66 @@ </dependency> <!--END OF GENERATED CODE--> </dependencies> + <profiles> + <!-- activate integration test if the docker socket file is accessible --> + <profile> + <id>consul-integration-tests-docker-file</id> + <activation> + <file> + <exists>/var/run/docker.sock</exists> + </file> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <visibleassertions.silence>true</visibleassertions.silence> + </systemPropertyVariables> + </configuration> + <executions> + <execution> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + <!-- activate integration test if the DOCKER_HOST env var is set --> + <profile> + <id>consul-integration-tests-docker-env</id> + <activation> + <property> + <name>env.DOCKER_HOST</name> + </property> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-failsafe-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <visibleassertions.silence>true</visibleassertions.silence> + </systemPropertyVariables> + </configuration> + <executions> + <execution> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> </project> diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryAutoConfiguration.java index ec4e9d3..79e2134 100644 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryAutoConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryAutoConfiguration.java @@ -23,7 +23,6 @@ import javax.annotation.PostConstruct; import org.apache.camel.CamelContext; import org.apache.camel.cloud.ServiceDiscovery; import org.apache.camel.component.consul.cloud.ConsulServiceDiscoveryFactory; -import org.apache.camel.component.consul.springboot.ConsulComponentConfiguration; import org.apache.camel.model.cloud.springboot.ConsulServiceCallServiceDiscoveryConfigurationCommon; import org.apache.camel.model.cloud.springboot.ConsulServiceCallServiceDiscoveryConfigurationProperties; import org.apache.camel.spring.boot.CamelAutoConfiguration; diff --git a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryAutoConfiguration.java similarity index 63% copy from platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java copy to platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryAutoConfiguration.java index c34d82e..e44af74 100644 --- a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryAutoConfiguration.java @@ -14,14 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.component.zookeeper.cluster.springboot; +package org.apache.camel.component.consul.springboot.cloud; -import org.apache.camel.cluster.CamelClusterService; -import org.apache.camel.component.zookeeper.cluster.ZooKeeperClusterService; +import org.apache.camel.component.consul.cloud.ConsulServiceRegistry; import org.apache.camel.spring.boot.CamelAutoConfiguration; -import org.apache.camel.spring.boot.cluster.ClusteredRouteControllerAutoConfiguration; import org.apache.camel.util.IntrospectionSupport; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -31,17 +28,15 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration -@AutoConfigureBefore({ ClusteredRouteControllerAutoConfiguration.class, CamelAutoConfiguration.class }) -@ConditionalOnProperty(prefix = "camel.component.zookeeper.cluster.service", name = "enabled") -@EnableConfigurationProperties(ZooKeeperClusterServiceConfiguration.class) -public class ZooKeeperClusterServiceAutoConfiguration { - @Autowired - private ZooKeeperClusterServiceConfiguration configuration; +@AutoConfigureBefore(CamelAutoConfiguration.class) +@ConditionalOnProperty(prefix = "camel.component.consul.service-registry", name = "enabled") +@EnableConfigurationProperties(ConsulServiceRegistryConfiguration.class) +public class ConsulServiceRegistryAutoConfiguration { - @Bean(name = "zookeeper-cluster-service") + @Bean(name = "consul-service-registry") @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) - public CamelClusterService zookeeperClusterService() throws Exception { - ZooKeeperClusterService service = new ZooKeeperClusterService(); + public ConsulServiceRegistry consulServiceRegistry(ConsulServiceRegistryConfiguration configuration) throws Exception { + ConsulServiceRegistry service = new ConsulServiceRegistry(); IntrospectionSupport.setProperties( service, diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryConfiguration.java similarity index 81% copy from platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java copy to platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryConfiguration.java index 6cb1bf9..d9e457d 100644 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryConfiguration.java @@ -14,22 +14,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.component.consul.springboot.cluster; +package org.apache.camel.component.consul.springboot.cloud; import java.util.Map; -import org.apache.camel.component.consul.cluster.ConsulClusterConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; -@ConfigurationProperties(prefix = "camel.component.consul.cluster.service") -public class ConsulClusterServiceConfiguration extends ConsulClusterConfiguration { +@ConfigurationProperties(prefix = "camel.component.consul.service-registry") +public class ConsulServiceRegistryConfiguration extends org.apache.camel.component.consul.cloud.ConsulServiceRegistryConfiguration { /** - * Sets if the zookeeper cluster service should be enabled or not, default is false. + * Sets if the consul service registry should be enabled or not, default is false. */ private boolean enabled; /** - * Cluster Service ID + * Service Registry ID */ private String id; diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java index 6cb1bf9..01600ff 100644 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java @@ -24,7 +24,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "camel.component.consul.cluster.service") public class ConsulClusterServiceConfiguration extends ConsulClusterConfiguration { /** - * Sets if the zookeeper cluster service should be enabled or not, default is false. + * Sets if the consul cluster service should be enabled or not, default is false. */ private boolean enabled; diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/resources/META-INF/spring.factories index 1e63a81..a8142d0 100644 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/resources/META-INF/spring.factories +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/main/resources/META-INF/spring.factories @@ -15,7 +15,8 @@ ## limitations under the License. ## --------------------------------------------------------------------------- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.apache.camel.component.consul.springboot.ConsulComponentAutoConfiguration,\ -org.apache.camel.component.consul.springboot.cloud.ConsulServiceDiscoveryAutoConfiguration,\ -org.apache.camel.component.consul.springboot.cluster.ConsulClusterServiceAutoConfiguration,\ -org.apache.camel.component.consul.springboot.health.HealthCheckRepositoryAutoConfiguration \ No newline at end of file + org.apache.camel.component.consul.springboot.ConsulComponentAutoConfiguration,\ + org.apache.camel.component.consul.springboot.cloud.ConsulServiceDiscoveryAutoConfiguration,\ + org.apache.camel.component.consul.springboot.cloud.ConsulServiceRegistryAutoConfiguration,\ + org.apache.camel.component.consul.springboot.cluster.ConsulClusterServiceAutoConfiguration,\ + org.apache.camel.component.consul.springboot.health.HealthCheckRepositoryAutoConfiguration \ No newline at end of file diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryDisabledTest.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryDisabledTest.java deleted file mode 100644 index 01cc252..0000000 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryDisabledTest.java +++ /dev/null @@ -1,64 +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.component.consul.springboot.cloud; - -import java.util.Map; - -import org.apache.camel.cloud.ServiceDiscovery; -import org.apache.camel.model.cloud.springboot.ConsulServiceCallServiceDiscoveryConfigurationProperties; -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.context.ApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@DirtiesContext -@SpringBootApplication -@SpringBootTest( - classes = { - ConsulServiceDiscoveryEnabledTest.TestConfiguration.class - }, - properties = { - "debug=false", - "camel.cloud.consul.service-discovery.enabled=false" -}) -public class ConsulServiceDiscoveryDisabledTest { - @Autowired - ApplicationContext context; - - @Test - public void testConfiguration() throws Exception { - Map<String, ?> beans; - - beans = context.getBeansOfType(ConsulServiceCallServiceDiscoveryConfigurationProperties.class); - Assert.assertTrue(beans.isEmpty()); - - beans = context.getBeansOfType(ServiceDiscovery.class); - Assert.assertFalse(beans.isEmpty()); - Assert.assertFalse(beans.containsKey("consul-service-discovery")); - } - - @Configuration - public static class TestConfiguration { - } -} diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryEnabledTest.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryEnabledTest.java deleted file mode 100644 index cedfde5..0000000 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryEnabledTest.java +++ /dev/null @@ -1,65 +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.component.consul.springboot.cloud; - -import java.util.Map; - -import org.apache.camel.cloud.ServiceDiscovery; -import org.apache.camel.model.cloud.springboot.ConsulServiceCallServiceDiscoveryConfigurationProperties; -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.context.ApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.junit4.SpringRunner; - -@RunWith(SpringRunner.class) -@DirtiesContext -@SpringBootApplication -@SpringBootTest( - classes = { - ConsulServiceDiscoveryEnabledTest.TestConfiguration.class - }, - properties = { - "debug=false", - "camel.cloud.consul.service-discovery.enabled=true" -}) -public class ConsulServiceDiscoveryEnabledTest { - @Autowired - ApplicationContext context; - - @Test - public void testConfiguration() throws Exception { - Map<String, ?> beans; - - beans = context.getBeansOfType(ConsulServiceCallServiceDiscoveryConfigurationProperties.class); - Assert.assertFalse(beans.isEmpty()); - Assert.assertEquals(1, beans.size()); - - beans = context.getBeansOfType(ServiceDiscovery.class); - Assert.assertFalse(beans.isEmpty()); - Assert.assertTrue(beans.containsKey("consul-service-discovery")); - } - - @Configuration - public static class TestConfiguration { - } -} diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryTest.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryTest.java new file mode 100644 index 0000000..1d2b30d --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceDiscoveryTest.java @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.consul.springboot.cloud; + +import org.apache.camel.cloud.ServiceDiscovery; +import org.apache.camel.model.cloud.springboot.ConsulServiceCallServiceDiscoveryConfigurationProperties; +import org.junit.Test; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ConsulServiceDiscoveryTest { + @Test + public void testConsulServiceDiscoveryDisabled() { + new ApplicationContextRunner() + .withUserConfiguration(TestConfiguration.class) + .withPropertyValues( + "spring.main.banner-mode=off", + "camel.cloud.consul.service-discovery.enabled=false") + .run( + context -> { + assertThat(context).doesNotHaveBean(ConsulServiceCallServiceDiscoveryConfigurationProperties.class); + assertThat(context).getBeans(ServiceDiscovery.class).doesNotContainKeys("consul-service-discovery"); + } + ); + } + + @Test + public void testConsulServiceDiscoveryEnabled() { + new ApplicationContextRunner() + .withUserConfiguration(TestConfiguration.class) + .withPropertyValues( + "spring.main.banner-mode=off", + "camel.cloud.consul.service-discovery.enabled=true") + .run( + context -> { + assertThat(context).hasSingleBean(ConsulServiceCallServiceDiscoveryConfigurationProperties.class); + assertThat(context).getBeans(ServiceDiscovery.class).containsKeys("consul-service-discovery"); + } + ); + } + + @EnableAutoConfiguration + @Configuration + public static class TestConfiguration { + } +} diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryIT.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryIT.java new file mode 100644 index 0000000..b3045d9 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/ConsulServiceRegistryIT.java @@ -0,0 +1,98 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.consul.springboot.cloud; + +import java.util.List; +import java.util.UUID; + +import com.orbitz.consul.Consul; +import com.orbitz.consul.model.catalog.CatalogService; +import org.apache.camel.CamelContext; +import org.apache.camel.cloud.ServiceRegistry; +import org.apache.camel.component.consul.springboot.cloud.support.ConsulContainerSupport; +import org.apache.camel.impl.cloud.DefaultServiceDefinition; +import org.junit.Rule; +import org.junit.Test; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.SocketUtils; +import org.testcontainers.containers.GenericContainer; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ConsulServiceRegistryIT { + protected static final String SERVICE_ID = UUID.randomUUID().toString(); + protected static final String SERVICE_NAME = "my-service"; + protected static final String SERVICE_HOST = "localhost"; + protected static final int SERVICE_PORT = SocketUtils.findAvailableTcpPort(); + + @Rule + public GenericContainer container = ConsulContainerSupport.consulContainer(); + + @Test + public void testServiceRegistry() { + new ApplicationContextRunner() + .withUserConfiguration(TestConfiguration.class) + .withPropertyValues( + "debug=false", + "spring.main.banner-mode=OFF", + "spring.application.name=" + UUID.randomUUID().toString(), + "camel.component.consul.service-registry.enabled=true", + "camel.component.consul.service-registry.url=" + ConsulContainerSupport.consulUrl(container), + "camel.component.consul.service-registry.id=" + UUID.randomUUID().toString(), + "camel.component.consul.service-registry.service-host=localhost") + .run( + context -> { + assertThat(context).hasSingleBean(CamelContext.class); + assertThat(context).hasSingleBean(ServiceRegistry.class); + + final CamelContext camelContext = context.getBean(CamelContext.class); + final ServiceRegistry serviceRegistry = camelContext.hasService(ServiceRegistry.class); + + assertThat(serviceRegistry).isNotNull(); + + serviceRegistry.register( + DefaultServiceDefinition.builder() + .withHost(SERVICE_HOST) + .withPort(SERVICE_PORT) + .withName(SERVICE_NAME) + .withId(SERVICE_ID) + .build() + ); + + final Consul client = Consul.builder().withUrl(ConsulContainerSupport.consulUrl(container)).build(); + final List<CatalogService> services = client.catalogClient().getService(SERVICE_NAME).getResponse(); + + assertThat(services).hasSize(1); + assertThat(services).first().hasFieldOrPropertyWithValue("serviceId", SERVICE_ID); + assertThat(services).first().hasFieldOrPropertyWithValue("serviceName", SERVICE_NAME); + assertThat(services).first().hasFieldOrPropertyWithValue("serviceAddress", SERVICE_HOST); + assertThat(services).first().hasFieldOrPropertyWithValue("servicePort", SERVICE_PORT); + } + ); + } + + // ************************************* + // Config + // ************************************* + + @EnableAutoConfiguration + @Configuration + public static class TestConfiguration { + } +} diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerLogger.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerLogger.java new file mode 100644 index 0000000..533c3cf --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerLogger.java @@ -0,0 +1,31 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.consul.springboot.cloud.support; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testcontainers.containers.output.Slf4jLogConsumer; + +public final class ConsulContainerLogger extends Slf4jLogConsumer { + private static final Logger LOGGER = LoggerFactory.getLogger(ConsulContainerLogger.class); + + public ConsulContainerLogger() { + super(LOGGER); + + withPrefix("consul"); + } +} diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerSupport.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerSupport.java new file mode 100644 index 0000000..9a101de --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerSupport.java @@ -0,0 +1,46 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.consul.springboot.cloud.support; + +import com.orbitz.consul.Consul; +import org.testcontainers.containers.GenericContainer; + +public final class ConsulContainerSupport { + private ConsulContainerSupport() { + } + + public static GenericContainer consulContainer() { + return new GenericContainer("consul:1.0.0") + .withExposedPorts(Consul.DEFAULT_HTTP_PORT) + .waitingFor(new ConsulContainerWaitStrategy()) + .withLogConsumer(new ConsulContainerLogger()) + .withCommand( + "agent", + "-dev", + "-server", + "-bootstrap", + "-client", + "0.0.0.0", + "-log-level", + "trace" + ); + } + + public static String consulUrl(GenericContainer container) { + return String.format("http://%s:%d", container.getContainerIpAddress(), container.getMappedPort(Consul.DEFAULT_HTTP_PORT)); + } +} diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerWaitStrategy.java b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerWaitStrategy.java new file mode 100644 index 0000000..79633b0 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/java/org/apache/camel/component/consul/springboot/cloud/support/ConsulContainerWaitStrategy.java @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.consul.springboot.cloud.support; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import com.github.dockerjava.api.DockerClient; +import org.testcontainers.DockerClientFactory; +import org.testcontainers.containers.ContainerLaunchException; +import org.testcontainers.containers.output.WaitingConsumer; +import org.testcontainers.containers.wait.strategy.AbstractWaitStrategy; +import org.testcontainers.utility.LogUtils; + +public final class ConsulContainerWaitStrategy extends AbstractWaitStrategy { + @Override + protected void waitUntilReady() { + final DockerClient client = DockerClientFactory.instance().client(); + final WaitingConsumer waitingConsumer = new WaitingConsumer(); + + LogUtils.followOutput(client, waitStrategyTarget.getContainerId(), waitingConsumer); + + try { + waitingConsumer.waitUntil( + f -> f.getUtf8String().contains("Synced node info"), + startupTimeout.getSeconds(), + TimeUnit.SECONDS, + 1 + ); + } catch (TimeoutException e) { + throw new ContainerLaunchException("Timed out"); + } + } +} \ No newline at end of file diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/resources/logback.xml b/platforms/spring-boot/components-starter/camel-consul-starter/src/test/resources/logback.xml index 9b17d4a..972efdc0 100644 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/resources/logback.xml +++ b/platforms/spring-boot/components-starter/camel-consul-starter/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/platforms/spring-boot/components-starter/camel-zookeeper-starter/pom.xml b/platforms/spring-boot/components-starter/camel-zookeeper-starter/pom.xml index 7c274d2..f6996a0 100644 --- a/platforms/spring-boot/components-starter/camel-zookeeper-starter/pom.xml +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/pom.xml @@ -39,6 +39,13 @@ <artifactId>camel-zookeeper</artifactId> <version>${project.version}</version> </dependency> + <!-- testing --> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-jetty</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> <!--START OF GENERATED CODE--> <dependency> <groupId>org.apache.camel</groupId> diff --git a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryAutoConfiguration.java similarity index 63% copy from platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java copy to platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryAutoConfiguration.java index c34d82e..16d9722 100644 --- a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryAutoConfiguration.java @@ -14,14 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.component.zookeeper.cluster.springboot; +package org.apache.camel.component.zookeeper.springboot.cloud; -import org.apache.camel.cluster.CamelClusterService; -import org.apache.camel.component.zookeeper.cluster.ZooKeeperClusterService; +import org.apache.camel.component.zookeeper.cloud.ZooKeeperServiceRegistry; import org.apache.camel.spring.boot.CamelAutoConfiguration; -import org.apache.camel.spring.boot.cluster.ClusteredRouteControllerAutoConfiguration; import org.apache.camel.util.IntrospectionSupport; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -31,17 +28,15 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration -@AutoConfigureBefore({ ClusteredRouteControllerAutoConfiguration.class, CamelAutoConfiguration.class }) -@ConditionalOnProperty(prefix = "camel.component.zookeeper.cluster.service", name = "enabled") -@EnableConfigurationProperties(ZooKeeperClusterServiceConfiguration.class) -public class ZooKeeperClusterServiceAutoConfiguration { - @Autowired - private ZooKeeperClusterServiceConfiguration configuration; +@AutoConfigureBefore(CamelAutoConfiguration.class) +@ConditionalOnProperty(prefix = "camel.component.zookeeper.service-registry", name = "enabled") +@EnableConfigurationProperties(ZooKeeperServiceRegistryConfiguration.class) +public class ZooKeeperServiceRegistryAutoConfiguration { - @Bean(name = "zookeeper-cluster-service") + @Bean(name = "zookeeper-service-registry") @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) - public CamelClusterService zookeeperClusterService() throws Exception { - ZooKeeperClusterService service = new ZooKeeperClusterService(); + public ZooKeeperServiceRegistry zookeeperServiceRegistry(ZooKeeperServiceRegistryConfiguration configuration) throws Exception { + ZooKeeperServiceRegistry service = new ZooKeeperServiceRegistry(); IntrospectionSupport.setProperties( service, diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryConfiguration.java similarity index 81% copy from platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java copy to platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryConfiguration.java index 6cb1bf9..699e8c8 100644 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/main/java/org/apache/camel/component/consul/springboot/cluster/ConsulClusterServiceConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryConfiguration.java @@ -14,22 +14,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.component.consul.springboot.cluster; +package org.apache.camel.component.zookeeper.springboot.cloud; import java.util.Map; -import org.apache.camel.component.consul.cluster.ConsulClusterConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; -@ConfigurationProperties(prefix = "camel.component.consul.cluster.service") -public class ConsulClusterServiceConfiguration extends ConsulClusterConfiguration { +@ConfigurationProperties(prefix = "camel.component.zookeeper.service-registry") +public class ZooKeeperServiceRegistryConfiguration extends org.apache.camel.component.zookeeper.cloud.ZooKeeperServiceRegistryConfiguration { /** - * Sets if the zookeeper cluster service should be enabled or not, default is false. + * Sets if the zookeeper service registry should be enabled or not, default is false. */ private boolean enabled; /** - * Cluster Service ID + * Service Registry ID */ private String id; diff --git a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cluster/ZooKeeperClusterServiceAutoConfiguration.java similarity index 97% rename from platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java rename to platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cluster/ZooKeeperClusterServiceAutoConfiguration.java index c34d82e..5017b92 100644 --- a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceAutoConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cluster/ZooKeeperClusterServiceAutoConfiguration.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.component.zookeeper.cluster.springboot; +package org.apache.camel.component.zookeeper.springboot.cluster; import org.apache.camel.cluster.CamelClusterService; import org.apache.camel.component.zookeeper.cluster.ZooKeeperClusterService; diff --git a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceConfiguration.java b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cluster/ZooKeeperClusterServiceConfiguration.java similarity index 97% rename from platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceConfiguration.java rename to platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cluster/ZooKeeperClusterServiceConfiguration.java index 1feb5af..fffa14e 100644 --- a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/cluster/springboot/ZooKeeperClusterServiceConfiguration.java +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/java/org/apache/camel/component/zookeeper/springboot/cluster/ZooKeeperClusterServiceConfiguration.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.camel.component.zookeeper.cluster.springboot; +package org.apache.camel.component.zookeeper.springboot.cluster; import java.util.Map; diff --git a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/resources/META-INF/spring.factories index f3a7b4b..383172c 100644 --- a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/resources/META-INF/spring.factories +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/resources/META-INF/spring.factories @@ -15,5 +15,6 @@ ## limitations under the License. ## --------------------------------------------------------------------------- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.apache.camel.component.zookeeper.springboot.ZooKeeperComponentAutoConfiguration,\ -org.apache.camel.component.zookeeper.cluster.springboot.ZooKeeperClusterServiceAutoConfiguration + org.apache.camel.component.zookeeper.springboot.ZooKeeperComponentAutoConfiguration,\ + org.apache.camel.component.zookeeper.springboot.cloud.ZooKeeperServiceRegistryAutoConfiguration,\ + org.apache.camel.component.zookeeper.springboot.cluster.ZooKeeperClusterServiceAutoConfiguration diff --git a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryTest.java b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryTest.java new file mode 100644 index 0000000..7243d61 --- /dev/null +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/java/org/apache/camel/component/zookeeper/springboot/cloud/ZooKeeperServiceRegistryTest.java @@ -0,0 +1,264 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.zookeeper.springboot.cloud; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.util.Collection; +import java.util.UUID; + +import org.apache.camel.CamelContext; +import org.apache.camel.cloud.ServiceRegistry; +import org.apache.camel.component.zookeeper.cloud.ZooKeeperServiceRegistry; +import org.apache.camel.impl.cloud.DefaultServiceDefinition; +import org.apache.camel.test.AvailablePortFinder; +import org.apache.camel.util.IOHelper; +import org.apache.curator.framework.CuratorFramework; +import org.apache.curator.framework.CuratorFrameworkFactory; +import org.apache.curator.retry.ExponentialBackoffRetry; +import org.apache.curator.utils.CloseableUtils; +import org.apache.curator.x.discovery.ServiceDiscovery; +import org.apache.curator.x.discovery.ServiceDiscoveryBuilder; +import org.apache.curator.x.discovery.ServiceInstance; +import org.apache.curator.x.discovery.details.JsonInstanceSerializer; +import org.apache.zookeeper.server.NIOServerCnxnFactory; +import org.apache.zookeeper.server.ZooKeeperServer; +import org.apache.zookeeper.server.persistence.FileTxnSnapLog; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.SocketUtils; + +import static org.assertj.core.api.Assertions.assertThat; + +public class ZooKeeperServiceRegistryTest { + private static final Logger LOGGER = LoggerFactory.getLogger(ZooKeeperServiceRegistryTest.class); + + private static final String SERVICE_PATH = "/camel"; + private static final String SERVICE_ID = UUID.randomUUID().toString(); + private static final String SERVICE_NAME = "my-service"; + private static final String SERVICE_HOST = "localhost"; + private static final int SERVICE_PORT = SocketUtils.findAvailableTcpPort(); + + @Rule + public final TestName testName = new TestName(); + @Rule + public final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + @Test + public void testServiceRegistry() throws Exception { + final ZooKeeperTestServer zkServer = new ZooKeeperTestServer(temporaryFolder.newFolder()); + zkServer.start(); + + final ZooKeeperTestClient zkClient = new ZooKeeperTestClient(zkServer.serverList()); + zkClient.start(); + + try { + new ApplicationContextRunner() + .withUserConfiguration(TestConfiguration.class) + .withPropertyValues( + "debug=false", + "spring.main.banner-mode=OFF", + "spring.application.name=" + UUID.randomUUID().toString(), + "camel.component.zookeeper.service-registry.enabled=true", + "camel.component.zookeeper.service-registry.nodes=" + zkServer.serverList(), + "camel.component.zookeeper.service-registry.id=" + UUID.randomUUID().toString(), + "camel.component.zookeeper.service-registry.base-path=" + SERVICE_PATH, + "camel.component.zookeeper.service-registry.service-host=localhost") + .run( + context -> { + assertThat(context).hasSingleBean(CamelContext.class); + assertThat(context).hasSingleBean(ServiceRegistry.class); + + final CamelContext camelContext = context.getBean(CamelContext.class); + final ServiceRegistry serviceRegistry = camelContext.hasService(ServiceRegistry.class); + + assertThat(serviceRegistry).isNotNull(); + + serviceRegistry.register( + DefaultServiceDefinition.builder() + .withHost(SERVICE_HOST) + .withPort(SERVICE_PORT) + .withName(SERVICE_NAME) + .withId(SERVICE_ID) + .build() + ); + + final Collection<ServiceInstance<ZooKeeperServiceRegistry.MetaData>> services = zkClient.discovery().queryForInstances(SERVICE_NAME); + + assertThat(services).hasSize(1); + assertThat(services).first().hasFieldOrPropertyWithValue("id", SERVICE_ID); + assertThat(services).first().hasFieldOrPropertyWithValue("name", SERVICE_NAME); + assertThat(services).first().hasFieldOrPropertyWithValue("address", SERVICE_HOST); + assertThat(services).first().hasFieldOrPropertyWithValue("port", SERVICE_PORT); + } + ); + } finally { + zkClient.stop(); + zkServer.stop(); + } + } + + // ************************************* + // Config + // ************************************* + + @EnableAutoConfiguration + @Configuration + public static class TestConfiguration { + } + + // ************************************* + // Helpers + // ************************************* + + public static class ZooKeeperTestServer { + private NIOServerCnxnFactory connectionFactory; + private ZooKeeperServer zkServer; + + public ZooKeeperTestServer(File root) throws Exception { + zkServer = new ZooKeeperServer(); + + File dataDir = new File(root, "log"); + File snapDir = new File(root, "data"); + FileTxnSnapLog ftxn = new FileTxnSnapLog(dataDir, snapDir); + + zkServer.setTxnLogFactory(ftxn); + zkServer.setTickTime(1000); + + connectionFactory = new NIOServerCnxnFactory(); + connectionFactory.configure(new InetSocketAddress("localhost", AvailablePortFinder.getNextAvailable()), 0); + connectionFactory.startup(zkServer); + } + + public String serverList() { + return "localhost:" + connectionFactory.getLocalPort(); + } + + private String send4LetterWord(String hp, String cmd) throws IOException { + String split[] = hp.split(":"); + String host = split[0]; + int port; + try { + port = Integer.parseInt(split[1]); + } catch (RuntimeException e) { + throw new RuntimeException("Problem parsing " + hp + e.toString()); + } + + Socket sock = new Socket(host, port); + BufferedReader reader = null; + try { + OutputStream outstream = sock.getOutputStream(); + outstream.write(cmd.getBytes()); + outstream.flush(); + + reader = IOHelper.buffered(new InputStreamReader(sock.getInputStream())); + StringBuilder sb = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + sb.append(line + "\n"); + } + return sb.toString(); + } finally { + sock.close(); + if (reader != null) { + reader.close(); + } + } + } + + public void start() throws Exception { + long start = System.currentTimeMillis(); + while (true) { + try { + String result = send4LetterWord(serverList(), "stat"); + if (result.startsWith("Zookeeper version:")) { + return; + } + } catch (IOException e) { + LOGGER.info("server {} not up {}", LOGGER, e); + } + + if (System.currentTimeMillis() > start + 1000) { + break; + } + try { + Thread.sleep(250); + } catch (InterruptedException e) { + // ignore + } + } + } + + public void stop() throws Exception { + connectionFactory.shutdown(); + connectionFactory.join(); + zkServer.shutdown(); + + while (zkServer.isRunning()) { + zkServer.shutdown(); + Thread.sleep(100); + } + } + } + + public static class ZooKeeperTestClient { + private final CuratorFramework curator; + private final ServiceDiscovery<ZooKeeperServiceRegistry.MetaData> discovery; + + public ZooKeeperTestClient(String nodes) { + curator = CuratorFrameworkFactory.builder() + .connectString(nodes) + .retryPolicy(new ExponentialBackoffRetry(1000, 3)) + .build(); + discovery = ServiceDiscoveryBuilder.builder(ZooKeeperServiceRegistry.MetaData.class) + .client(curator) + .basePath(SERVICE_PATH) + .serializer(new JsonInstanceSerializer<>(ZooKeeperServiceRegistry.MetaData.class)) + .build(); + } + + public CuratorFramework curator() { + return curator; + } + + public ServiceDiscovery<ZooKeeperServiceRegistry.MetaData> discovery() { + return discovery; + } + + public void start() throws Exception { + curator.start(); + discovery.start(); + } + + public void stop() throws Exception { + CloseableUtils.closeQuietly(discovery); + CloseableUtils.closeQuietly(curator); + } + } +} diff --git a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/resources/META-INF/spring.factories b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/resources/application.properties similarity index 79% copy from platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/resources/META-INF/spring.factories copy to platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/resources/application.properties index f3a7b4b..2f91fc3 100644 --- a/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/main/resources/META-INF/spring.factories +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/resources/application.properties @@ -14,6 +14,4 @@ ## See the License for the specific language governing permissions and ## limitations under the License. ## --------------------------------------------------------------------------- -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -org.apache.camel.component.zookeeper.springboot.ZooKeeperComponentAutoConfiguration,\ -org.apache.camel.component.zookeeper.cluster.springboot.ZooKeeperClusterServiceAutoConfiguration +spring.main.banner-mode=off diff --git a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/resources/logback.xml b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/resources/logback.xml similarity index 92% copy from platforms/spring-boot/components-starter/camel-consul-starter/src/test/resources/logback.xml copy to platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/resources/logback.xml index 9b17d4a..3e6fbd7 100644 --- a/platforms/spring-boot/components-starter/camel-consul-starter/src/test/resources/logback.xml +++ b/platforms/spring-boot/components-starter/camel-zookeeper-starter/src/test/resources/logback.xml @@ -31,10 +31,11 @@ <encoder> <pattern>%d{HH:mm:ss.SSS} [%-15.15thread] %-5level %-30.30logger - %msg%n</pattern> </encoder> - <file>target/camel-consul-starter-test.log</file> + <file>target/camel-zookeeper-starter-test.log</file> </appender> <root level="INFO"> + <!--<appender-ref ref="STDOUT"/>--> <appender-ref ref="FILE"/> </root> diff --git a/platforms/spring-boot/spring-boot-dm/pom.xml b/platforms/spring-boot/spring-boot-dm/pom.xml index 4503db3..73ab6c2 100644 --- a/platforms/spring-boot/spring-boot-dm/pom.xml +++ b/platforms/spring-boot/spring-boot-dm/pom.xml @@ -47,6 +47,7 @@ <!-- Needed by BOM generator--> <avro-version>1.8.2</avro-version> <jackson-version>1.9.12</jackson-version> + <testcontainers-version>1.7.3</testcontainers-version> <!-- Needed by starters --> <egit-github-core-version>2.1.5</egit-github-core-version> -- To stop receiving notification emails like this one, please contact lburgazz...@apache.org.