http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java ---------------------------------------------------------------------- diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java index 41da245..6d94f9f 100644 --- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java +++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelContextFactoryBean.java @@ -39,6 +39,7 @@ import org.apache.camel.core.osgi.OsgiCamelContextPublisher; import org.apache.camel.core.osgi.OsgiEventAdminNotifier; import org.apache.camel.core.osgi.utils.BundleDelegatingClassLoader; import org.apache.camel.core.xml.AbstractCamelContextFactoryBean; +import org.apache.camel.core.xml.AbstractCamelFactoryBean; import org.apache.camel.core.xml.CamelJMXAgentDefinition; import org.apache.camel.core.xml.CamelPropertyPlaceholderDefinition; import org.apache.camel.core.xml.CamelServiceExporterDefinition; @@ -57,12 +58,8 @@ import org.apache.camel.model.RouteBuilderDefinition; import org.apache.camel.model.RouteContextRefDefinition; import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.ThreadPoolProfileDefinition; +import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; import org.apache.camel.model.dataformat.DataFormatsDefinition; -import org.apache.camel.model.remote.ConsulConfigurationDefinition; -import org.apache.camel.model.remote.DnsConfigurationDefinition; -import org.apache.camel.model.remote.EtcdConfigurationDefinition; -import org.apache.camel.model.remote.KubernetesConfigurationDefinition; -import org.apache.camel.model.remote.RibbonConfigurationDefinition; import org.apache.camel.model.rest.RestConfigurationDefinition; import org.apache.camel.model.rest.RestDefinition; import org.apache.camel.model.transformer.TransformersDefinition; @@ -147,18 +144,16 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu @XmlElement(name = "streamCaching", type = CamelStreamCachingStrategyDefinition.class) private CamelStreamCachingStrategyDefinition camelStreamCachingStrategy; @XmlElements({ - @XmlElement(name = "hystrixConfiguration", type = HystrixConfigurationDefinition.class), - @XmlElement(name = "kubernetesConfiguration", type = KubernetesConfigurationDefinition.class), - @XmlElement(name = "ribbonConfiguration", type = RibbonConfigurationDefinition.class), - @XmlElement(name = "consulConfiguration", type = ConsulConfigurationDefinition.class), - @XmlElement(name = "dnsConfiguration", type = DnsConfigurationDefinition.class), - @XmlElement(name = "etcdConfiguration", type = EtcdConfigurationDefinition.class), @XmlElement(name = "template", type = CamelProducerTemplateFactoryBean.class), @XmlElement(name = "fluentTemplate", type = CamelFluentProducerTemplateFactoryBean.class), @XmlElement(name = "consumerTemplate", type = CamelConsumerTemplateFactoryBean.class), @XmlElement(name = "proxy", type = CamelProxyFactoryBean.class), @XmlElement(name = "export", type = CamelServiceExporterDefinition.class), @XmlElement(name = "errorHandler", type = CamelErrorHandlerFactoryBean.class)}) + private List<AbstractCamelFactoryBean<?>> beansFactory; + @XmlElements({ + @XmlElement(name = "serviceCallConfiguration", type = ServiceCallConfigurationDefinition.class), + @XmlElement(name = "hystrixConfiguration", type = HystrixConfigurationDefinition.class)}) private List<?> beans; @XmlElement(name = "routeBuilder") private List<RouteBuilderDefinition> builderRefs = new ArrayList<RouteBuilderDefinition>(); @@ -616,6 +611,15 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu this.camelStreamCachingStrategy = camelStreamCachingStrategy; } + public List<AbstractCamelFactoryBean<?>> getBeansFactory() { + return beansFactory; + } + + public void setBeansFactory(List<AbstractCamelFactoryBean<?>> beansFactory) { + this.beansFactory = beansFactory; + } + + @Override public List<?> getBeans() { return beans; }
http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java ---------------------------------------------------------------------- diff --git a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java index e95f5e1..a4801f1 100644 --- a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java +++ b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/handler/CamelNamespaceHandler.java @@ -282,7 +282,7 @@ public class CamelNamespaceHandler implements NamespaceHandler { registerBeans(context, contextId, ccfb.getThreadPools()); registerBeans(context, contextId, ccfb.getEndpoints()); registerBeans(context, contextId, ccfb.getRedeliveryPolicies()); - registerBeans(context, contextId, ccfb.getBeans()); + registerBeans(context, contextId, ccfb.getBeansFactory()); // Register processors MutablePassThroughMetadata beanProcessorFactory = context.createMetadata(MutablePassThroughMetadata.class); http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java index a9aaf05..53d7a6b 100644 --- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java +++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/XmlCdiBeanFactory.java @@ -193,8 +193,8 @@ final class XmlCdiBeanFactory { Set<SyntheticBean<?>> beans = new HashSet<>(); // TODO: WARN log if the definition doesn't have an id - if (factory.getBeans() != null) { - factory.getBeans().stream() + if (factory.getBeansFactory() != null) { + factory.getBeansFactory().stream() .filter(XmlCdiBeanFactory::hasId) .map(bean -> camelContextBean(context, bean, url)) .forEach(beans::add); http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java ---------------------------------------------------------------------- diff --git a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java index 9299424..e5135f6 100644 --- a/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java +++ b/components/camel-cdi/src/main/java/org/apache/camel/cdi/xml/CamelContextFactoryBean.java @@ -45,6 +45,7 @@ import org.apache.camel.core.xml.CamelServiceExporterDefinition; import org.apache.camel.core.xml.CamelStreamCachingStrategyDefinition; import org.apache.camel.impl.DefaultCamelContext; import org.apache.camel.model.ContextScanDefinition; +import org.apache.camel.model.HystrixConfigurationDefinition; import org.apache.camel.model.InterceptDefinition; import org.apache.camel.model.InterceptFromDefinition; import org.apache.camel.model.InterceptSendToEndpointDefinition; @@ -57,6 +58,7 @@ import org.apache.camel.model.RouteBuilderDefinition; import org.apache.camel.model.RouteContextRefDefinition; import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.ThreadPoolProfileDefinition; +import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; import org.apache.camel.model.dataformat.DataFormatsDefinition; import org.apache.camel.model.rest.RestConfigurationDefinition; import org.apache.camel.model.rest.RestDefinition; @@ -159,9 +161,14 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def @XmlElement(name = "consumerTemplate", type = ConsumerTemplateFactoryBean.class), @XmlElement(name = "redeliveryPolicyProfile", type = RedeliveryPolicyFactoryBean.class), @XmlElement(name = "template", type = ProducerTemplateFactoryBean.class), - @XmlElement(name = "threadPool", type = ThreadPoolFactoryBean.class) + @XmlElement(name = "threadPool", type = ThreadPoolFactoryBean.class), }) - private List<AbstractCamelFactoryBean<?>> beans; + private List<AbstractCamelFactoryBean<?>> beansFactory; + + @XmlElements({ + @XmlElement(name = "serviceCallConfiguration", type = ServiceCallConfigurationDefinition.class), + @XmlElement(name = "hystrixConfiguration", type = HystrixConfigurationDefinition.class)}) + private List<?> beans; @XmlElement(name = "errorHandler", type = ErrorHandlerDefinition.class) private List<ErrorHandlerDefinition> errorHandlers; @@ -303,11 +310,20 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Def return context; } - public List<AbstractCamelFactoryBean<?>> getBeans() { + public List<AbstractCamelFactoryBean<?>> getBeansFactory() { + return beansFactory; + } + + public void setBeansFactory(List<AbstractCamelFactoryBean<?>> beansFactory) { + this.beansFactory = beansFactory; + } + + @Override + public List<?> getBeans() { return beans; } - public void setBeans(List<AbstractCamelFactoryBean<?>> beans) { + public void setBeans(List<?> beans) { this.beans = beans; } http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/XmlServiceCallConfigurationTest.java ---------------------------------------------------------------------- diff --git a/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/XmlServiceCallConfigurationTest.java b/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/XmlServiceCallConfigurationTest.java new file mode 100644 index 0000000..23e0b14 --- /dev/null +++ b/components/camel-cdi/src/test/java/org/apache/camel/cdi/test/XmlServiceCallConfigurationTest.java @@ -0,0 +1,79 @@ +/** + * 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.cdi.test; + +import java.nio.file.Paths; +import javax.inject.Inject; + +import org.apache.camel.CamelContext; +import org.apache.camel.cdi.CdiCamelExtension; +import org.apache.camel.cdi.ImportResource; +import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; +import org.apache.camel.model.cloud.StaticServiceCallServiceDiscoveryConfiguration; +import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.shrinkwrap.api.Archive; +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@RunWith(Arquillian.class) +@ImportResource("imported-context.xml") +public class XmlServiceCallConfigurationTest { + + @Inject + private CamelContext context; + + @Deployment + public static Archive<?> deployment() { + return ShrinkWrap.create(JavaArchive.class) + // Camel CDI + .addPackage(CdiCamelExtension.class.getPackage()) + // Test Camel XML + .addAsResource( + Paths.get("src/test/resources/camel-context-service-call-configuration.xml").toFile(), + "imported-context.xml") + // Bean archive deployment descriptor + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); + } + + @Test + public void testServiceDiscoveryConfiguration() { + ServiceCallConfigurationDefinition conf1 = context.getServiceCallConfiguration("conf1"); + assertNotNull("No ServiceCallConfiguration (1)", conf1); + assertNotNull("No ServiceDiscoveryConfiguration (1)", conf1.getServiceDiscoveryConfiguration()); + + StaticServiceCallServiceDiscoveryConfiguration discovery1 = (StaticServiceCallServiceDiscoveryConfiguration)conf1.getServiceDiscoveryConfiguration(); + assertEquals(1, discovery1.getServers().size()); + assertEquals("localhost:9091", discovery1.getServers().get(0)); + + ServiceCallConfigurationDefinition conf2 = context.getServiceCallConfiguration("conf2"); + assertNotNull("No ServiceCallConfiguration (2)", conf2); + assertNotNull("No ServiceDiscoveryConfiguration (2)", conf2.getServiceDiscoveryConfiguration()); + + StaticServiceCallServiceDiscoveryConfiguration discovery2 = (StaticServiceCallServiceDiscoveryConfiguration)conf2.getServiceDiscoveryConfiguration(); + assertEquals(2, discovery2.getServers().size()); + assertEquals("localhost:9092", discovery2.getServers().get(0)); + assertEquals("localhost:9093,localhost:9094", discovery2.getServers().get(1)); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-cdi/src/test/resources/camel-context-service-call-configuration.xml ---------------------------------------------------------------------- diff --git a/components/camel-cdi/src/test/resources/camel-context-service-call-configuration.xml b/components/camel-cdi/src/test/resources/camel-context-service-call-configuration.xml new file mode 100644 index 0000000..cb18c8b --- /dev/null +++ b/components/camel-cdi/src/test/resources/camel-context-service-call-configuration.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring + http://camel.apache.org/schema/spring/camel-spring.xsd"> + + <camelContext id="test" xmlns="http://camel.apache.org/schema/spring"> + + <serviceCallConfiguration id="conf1"> + <staticServiceDiscovery> + <servers>localhost:9091</servers> + </staticServiceDiscovery> + </serviceCallConfiguration> + + <serviceCallConfiguration id="conf2"> + <staticServiceDiscovery> + <servers>localhost:9092</servers> + <servers>localhost:9093,localhost:9094</servers> + </staticServiceDiscovery> + </serviceCallConfiguration> + + <route id="test1"> + <from uri="direct:start1"/> + <serviceCall name="test" configurationRef="conf1"/> + </route> + <route id="test2"> + <from uri="direct:start2"/> + <serviceCall name="test" configurationRef="conf2"/> + </route> + + </camelContext> + +</beans> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-consul/pom.xml b/components/camel-consul/pom.xml index f660bf5..133d2ff 100644 --- a/components/camel-consul/pom.xml +++ b/components/camel-consul/pom.xml @@ -73,6 +73,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-ribbon</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <scope>test</scope> http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java index e64cd77..dbf1466 100644 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/ConsulConfiguration.java @@ -70,6 +70,10 @@ public class ConsulConfiguration { private final CamelContext context; + public ConsulConfiguration() { + this.context = null; + } + public ConsulConfiguration(CamelContext context) { this.context = context; } http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java new file mode 100644 index 0000000..104f65a --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscovery.java @@ -0,0 +1,104 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.consul.cloud; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import com.orbitz.consul.Consul; +import com.orbitz.consul.model.catalog.CatalogService; +import com.orbitz.consul.model.health.ServiceHealth; +import com.orbitz.consul.option.CatalogOptions; +import com.orbitz.consul.option.ImmutableCatalogOptions; +import org.apache.camel.cloud.ServiceDefinition; +import org.apache.camel.component.consul.ConsulConfiguration; +import org.apache.camel.impl.cloud.DefaultServiceDefinition; +import org.apache.camel.impl.cloud.DefaultServiceDiscovery; +import org.apache.camel.impl.cloud.DefaultServiceHealth; +import org.apache.camel.util.ObjectHelper; + +public final class ConsulServiceDiscovery extends DefaultServiceDiscovery { + private final Consul client; + private final CatalogOptions catalogOptions; + + public ConsulServiceDiscovery(ConsulConfiguration configuration) throws Exception { + this.client = configuration.createConsulClient(); + + ImmutableCatalogOptions.Builder builder = ImmutableCatalogOptions.builder(); + if (ObjectHelper.isNotEmpty(configuration.getDc())) { + builder.datacenter(configuration.getDc()); + } + if (ObjectHelper.isNotEmpty(configuration.getTags())) { + configuration.getTags().forEach(builder::tag); + } + + catalogOptions = builder.build(); + } + + @Override + public List<ServiceDefinition> getUpdatedListOfServices(String name) { + List<CatalogService> services = client.catalogClient() + .getService(name, catalogOptions) + .getResponse(); + List<ServiceHealth> healths = client.healthClient() + .getAllServiceInstances(name, catalogOptions) + .getResponse(); + + return services.stream() + .map(service -> newService(name, service, healths)) + .collect(Collectors.toList()); + } + + // ************************* + // Helpers + // ************************* + + private boolean isHealthy(ServiceHealth serviceHealth) { + return serviceHealth.getChecks().stream().allMatch( + check -> ObjectHelper.equal(check.getStatus(), "passing", true) + ); + } + + private ServiceDefinition newService(String serviceName, CatalogService service, List<ServiceHealth> serviceHealthList) { + Map<String, String> meta = new HashMap<>(); + ObjectHelper.ifNotEmpty(service.getServiceId(), val -> meta.put("service_id", val)); + ObjectHelper.ifNotEmpty(service.getNode(), val -> meta.put("node", val)); + ObjectHelper.ifNotEmpty(service.getServiceName(), val -> meta.put("service_name", val)); + + List<String> tags = service.getServiceTags(); + if (tags != null) { + for (String tag : service.getServiceTags()) { + String[] items = tag.split("="); + if (items.length == 1) { + meta.put(items[0], items[0]); + } else if (items.length == 2) { + meta.put(items[0], items[1]); + } + } + } + + return new DefaultServiceDefinition( + serviceName, + service.getServiceAddress(), + service.getServicePort(), + meta, + new DefaultServiceHealth(serviceHealthList.stream().allMatch(this::isHealthy)) + ); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryFactory.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryFactory.java new file mode 100644 index 0000000..9207d3e --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryFactory.java @@ -0,0 +1,124 @@ +/** + * 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.cloud; + +import org.apache.camel.CamelContext; +import org.apache.camel.cloud.ServiceDiscovery; +import org.apache.camel.cloud.ServiceDiscoveryFactory; +import org.apache.camel.component.consul.ConsulConfiguration; +import org.apache.camel.util.jsse.SSLContextParameters; + +public class ConsulServiceDiscoveryFactory implements ServiceDiscoveryFactory { + private final ConsulConfiguration configuration; + + public ConsulServiceDiscoveryFactory() { + this.configuration = new ConsulConfiguration(); + } + + // ************************************************************************* + // Properties + // ************************************************************************* + + public String getUrl() { + return configuration.getUrl(); + } + + public void setUrl(String url) { + configuration.setUrl(url); + } + + public String getDc() { + return configuration.getDc(); + } + + public void setDc(String dc) { + configuration.setDc(dc); + } + + public SSLContextParameters getSslContextParameters() { + return configuration.getSslContextParameters(); + } + + public void setSslContextParameters(SSLContextParameters sslContextParameters) { + configuration.setSslContextParameters(sslContextParameters); + } + + public String getAclToken() { + return configuration.getAclToken(); + } + + public void setAclToken(String aclToken) { + configuration.setAclToken(aclToken); + } + + public String getUserName() { + return configuration.getUserName(); + } + + public void setUserName(String userName) { + configuration.setUserName(userName); + } + + public String getPassword() { + return configuration.getPassword(); + } + + public void setPassword(String password) { + configuration.setPassword(password); + } + + public Long getConnectTimeoutMillis() { + return configuration.getConnectTimeoutMillis(); + } + + public void setConnectTimeoutMillis(Long connectTimeoutMillis) { + configuration.setConnectTimeoutMillis(connectTimeoutMillis); + } + + public Long getReadTimeoutMillis() { + return configuration.getReadTimeoutMillis(); + } + + public void setReadTimeoutMillis(Long readTimeoutMillis) { + configuration.setReadTimeoutMillis(readTimeoutMillis); + } + + public Long getWriteTimeoutMillis() { + return configuration.getWriteTimeoutMillis(); + } + + public void setWriteTimeoutMillis(Long writeTimeoutMillis) { + configuration.setWriteTimeoutMillis(writeTimeoutMillis); + } + + public Integer getBlockSeconds() { + return configuration.getBlockSeconds(); + } + + public void setBlockSeconds(Integer blockSeconds) { + configuration.setBlockSeconds(blockSeconds); + } + + // ************************************************************************* + // Factory + // ************************************************************************* + + @Override + public ServiceDiscovery newInstance(CamelContext camelContext) throws Exception { + return new ConsulServiceDiscovery(configuration); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessor.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessor.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessor.java deleted file mode 100644 index 7d98a8e..0000000 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessor.java +++ /dev/null @@ -1,43 +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.processor.remote; - -import org.apache.camel.ExchangePattern; -import org.apache.camel.component.consul.ConsulConfiguration; -import org.apache.camel.impl.remote.DefaultServiceCallProcessor; -import org.apache.camel.spi.ProcessorFactory; -import org.apache.camel.spi.ServiceCallServer; -import org.apache.camel.spi.ServiceCallServerListStrategy; - -/** - * {@link ProcessorFactory} that creates the Consul implementation of the ServiceCall EIP. - */ -public class ConsulServiceCallProcessor extends DefaultServiceCallProcessor<ServiceCallServer> { - public ConsulServiceCallProcessor(String name, String scheme, String uri, ExchangePattern exchangePattern, ConsulConfiguration conf) { - super(name, scheme, uri, exchangePattern); - } - - @Override - public void setServerListStrategy(ServiceCallServerListStrategy<ServiceCallServer> serverListStrategy) { - if (!(serverListStrategy instanceof ConsulServiceCallServerListStrategy)) { - throw new IllegalArgumentException("ServerListStrategy is not an instance of ConsulServiceCallServerListStrategy"); - } - - super.setServerListStrategy(serverListStrategy); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessorFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessorFactory.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessorFactory.java deleted file mode 100644 index 064fac2..0000000 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessorFactory.java +++ /dev/null @@ -1,67 +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.processor.remote; - -import java.util.Map; -import java.util.Optional; - -import org.apache.camel.ExchangePattern; -import org.apache.camel.component.consul.ConsulConfiguration; -import org.apache.camel.impl.remote.DefaultServiceCallProcessor; -import org.apache.camel.impl.remote.DefaultServiceCallProcessorFactory; -import org.apache.camel.spi.ProcessorFactory; -import org.apache.camel.spi.RouteContext; -import org.apache.camel.spi.ServiceCallServer; -import org.apache.camel.spi.ServiceCallServerListStrategy; -import org.apache.camel.util.ObjectHelper; - -/** - * {@link ProcessorFactory} that creates the Consul implementation of the ServiceCall EIP. - */ -public class ConsulServiceCallProcessorFactory extends DefaultServiceCallProcessorFactory<ConsulConfiguration, ServiceCallServer> { - @Override - protected ConsulConfiguration createConfiguration(RouteContext routeContext) throws Exception { - return new ConsulConfiguration(routeContext.getCamelContext()); - } - - @Override - protected DefaultServiceCallProcessor createProcessor( - String name, - String component, - String uri, - ExchangePattern mep, - ConsulConfiguration conf, - Map<String, String> properties) throws Exception { - - return new ConsulServiceCallProcessor(name, component, uri, mep, conf); - } - - @Override - protected Optional<ServiceCallServerListStrategy> builtInServerListStrategy(ConsulConfiguration conf, String name) throws Exception { - ServiceCallServerListStrategy strategy = null; - if (ObjectHelper.equal("ondemand", name, true)) { - strategy = new ConsulServiceCallServerListStrategies.OnDemand(conf); - } - - return Optional.ofNullable(strategy); - } - - @Override - protected ServiceCallServerListStrategy<ServiceCallServer> createDefaultServerListStrategy(ConsulConfiguration conf) throws Exception { - return new ConsulServiceCallServerListStrategies.OnDemand(conf); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategies.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategies.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategies.java deleted file mode 100644 index 81f95ff..0000000 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategies.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.processor.remote; - -import java.util.List; -import java.util.stream.Collectors; - -import com.orbitz.consul.model.catalog.CatalogService; -import com.orbitz.consul.model.health.ServiceHealth; -import org.apache.camel.component.consul.ConsulConfiguration; -import org.apache.camel.spi.ServiceCallServer; - -public final class ConsulServiceCallServerListStrategies { - private ConsulServiceCallServerListStrategies() { - } - - public static final class OnDemand extends ConsulServiceCallServerListStrategy { - public OnDemand(ConsulConfiguration configuration) throws Exception { - super(configuration); - } - - @Override - public List<ServiceCallServer> getUpdatedListOfServers(String name) { - List<CatalogService> services = getCatalogClient() - .getService(name, getCatalogOptions()) - .getResponse(); - - List<ServiceHealth> healths = getHealthClient() - .getAllServiceInstances(name, getCatalogOptions()) - .getResponse(); - - return services.stream() - .filter(service -> !hasFailingChecks(service, healths)) - .map(this::newServer) - .collect(Collectors.toList()); - } - - @Override - public String toString() { - return "OnDemand"; - } - } - - // ************************************************************************* - // Helpers - // ************************************************************************* - - public static ConsulServiceCallServerListStrategy onDemand(ConsulConfiguration configuration) throws Exception { - return new OnDemand(configuration); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategy.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategy.java deleted file mode 100644 index 116b2fc..0000000 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategy.java +++ /dev/null @@ -1,128 +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.processor.remote; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.orbitz.consul.CatalogClient; -import com.orbitz.consul.Consul; -import com.orbitz.consul.HealthClient; -import com.orbitz.consul.model.catalog.CatalogService; -import com.orbitz.consul.model.health.HealthCheck; -import com.orbitz.consul.model.health.ServiceHealth; -import com.orbitz.consul.option.CatalogOptions; -import com.orbitz.consul.option.ImmutableCatalogOptions; -import org.apache.camel.component.consul.ConsulConfiguration; -import org.apache.camel.impl.remote.DefaultServiceCallServer; -import org.apache.camel.impl.remote.DefaultServiceCallServerListStrategy; -import org.apache.camel.spi.ServiceCallServer; -import org.apache.camel.util.ObjectHelper; - -import static org.apache.camel.util.ObjectHelper.ifNotEmpty; - - -abstract class ConsulServiceCallServerListStrategy extends DefaultServiceCallServerListStrategy<ServiceCallServer> { - private final Consul client; - private final CatalogOptions catalogOptions; - - ConsulServiceCallServerListStrategy(ConsulConfiguration configuration) throws Exception { - this.client = configuration.createConsulClient(); - - ImmutableCatalogOptions.Builder builder = ImmutableCatalogOptions.builder(); - if (ObjectHelper.isNotEmpty(configuration.getDc())) { - builder.datacenter(configuration.getDc()); - } - if (ObjectHelper.isNotEmpty(configuration.getTags())) { - configuration.getTags().forEach(builder::tag); - } - - catalogOptions = builder.build(); - } - - @Override - public String toString() { - return "ConsulServiceCallServerListStrategy"; - } - - // ************************* - // Getter - // ************************* - - protected Consul getClient() { - return client; - } - - protected CatalogClient getCatalogClient() { - return client.catalogClient(); - } - - protected HealthClient getHealthClient() { - return client.healthClient(); - } - - protected CatalogOptions getCatalogOptions() { - return catalogOptions; - } - - // ************************* - // Helpers - // ************************* - - protected boolean isNotHealthy(HealthCheck check) { - final String status = check.getStatus(); - return status != null && !status.equalsIgnoreCase("passing"); - } - - protected boolean isNotHealthy(ServiceHealth health) { - return health.getChecks().stream().anyMatch(this::isNotHealthy); - } - - protected boolean isCheckOnService(ServiceHealth check, CatalogService service) { - return check.getService().getService().equalsIgnoreCase(service.getServiceName()); - } - - protected boolean hasFailingChecks(CatalogService service, List<ServiceHealth> healths) { - return healths.stream().anyMatch(health -> isCheckOnService(health, service) && isNotHealthy(health)); - } - - protected ServiceCallServer newServer(CatalogService service) { - Map<String, String> meta = new HashMap<>(); - ifNotEmpty(service.getServiceId(), val -> meta.put("service_id", val)); - ifNotEmpty(service.getNode(), val -> meta.put("node", val)); - ifNotEmpty(service.getServiceName(), val -> meta.put("service_name", val)); - - List<String> tags = service.getServiceTags(); - if (tags != null) { - for (String tag : service.getServiceTags()) { - String[] items = tag.split("="); - if (items.length == 1) { - meta.put(items[0], items[0]); - } else if (items.length == 2) { - meta.put(items[0], items[1]); - } - } - } - - return new DefaultServiceCallServer( - service.getServiceAddress(), - service.getServicePort(), - meta - ); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/resources/META-INF/services/org/apache/camel/cloud/consul-service-discovery ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/resources/META-INF/services/org/apache/camel/cloud/consul-service-discovery b/components/camel-consul/src/main/resources/META-INF/services/org/apache/camel/cloud/consul-service-discovery new file mode 100644 index 0000000..b8019a2 --- /dev/null +++ b/components/camel-consul/src/main/resources/META-INF/services/org/apache/camel/cloud/consul-service-discovery @@ -0,0 +1,17 @@ +# +# 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. +# +class=org.apache.camel.component.consul.cloud.ConsulServiceDiscoveryFactory http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/main/resources/META-INF/services/org/apache/camel/model/ServiceCallDefinition ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/resources/META-INF/services/org/apache/camel/model/ServiceCallDefinition b/components/camel-consul/src/main/resources/META-INF/services/org/apache/camel/model/ServiceCallDefinition deleted file mode 100644 index 3082d38..0000000 --- a/components/camel-consul/src/main/resources/META-INF/services/org/apache/camel/model/ServiceCallDefinition +++ /dev/null @@ -1,18 +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. -# - -class=org.apache.camel.component.consul.processor.remote.ConsulServiceCallProcessorFactory http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallRouteTest.java new file mode 100644 index 0000000..c32ec3e --- /dev/null +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceCallRouteTest.java @@ -0,0 +1,118 @@ +/** + * 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.cloud; + +import java.util.ArrayList; +import java.util.List; + +import com.orbitz.consul.AgentClient; +import com.orbitz.consul.model.agent.ImmutableRegistration; +import com.orbitz.consul.model.agent.Registration; +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.cloud.ServiceDiscovery; +import org.apache.camel.component.consul.ConsulConfiguration; +import org.apache.camel.component.consul.ConsulTestSupport; +import org.junit.Test; + +public class ConsulServiceCallRouteTest extends ConsulTestSupport { + private static final String SERVICE_NAME = "http-service"; + private static final int SERVICE_COUNT = 5; + private static final int SERVICE_PORT_BASE = 8080; + + private AgentClient client; + private List<Registration> registrations; + private List<String> expectedBodies; + + // ************************************************************************* + // Setup / tear down + // ************************************************************************* + + @Override + protected void doPreSetup() throws Exception { + client = getConsul().agentClient(); + + registrations = new ArrayList<>(SERVICE_COUNT); + expectedBodies = new ArrayList<>(SERVICE_COUNT); + + for (int i = 0; i < SERVICE_COUNT; i++) { + Registration r = ImmutableRegistration.builder() + .id("service-" + i) + .name(SERVICE_NAME) + .address("127.0.0.1") + .port(SERVICE_PORT_BASE + i) + .build(); + + client.register(r); + + registrations.add(r); + expectedBodies.add("ping on " + r.getPort().get()); + } + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + + + registrations.forEach(r -> client.deregister(r.getId())); + } + + // ************************************************************************* + // Test + // ************************************************************************* + + @Test + public void testServiceCall() throws Exception { + getMockEndpoint("mock:result").expectedMessageCount(SERVICE_COUNT); + getMockEndpoint("mock:result").expectedBodiesReceivedInAnyOrder(expectedBodies); + + registrations.forEach(r -> template.sendBody("direct:start", "ping")); + + assertMockEndpointsSatisfied(); + } + + // ************************************************************************* + // Route + // ************************************************************************* + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + ConsulConfiguration configuration = new ConsulConfiguration(null); + ServiceDiscovery discovery = new ConsulServiceDiscovery(configuration); + + from("direct:start") + .serviceCall() + .name(SERVICE_NAME) + .component("http") + .serviceDiscovery(discovery) + .end() + .to("log:org.apache.camel.component.consul.processor.service?level=INFO&showAll=true&multiline=true") + .to("mock:result"); + + registrations.forEach(r -> + fromF("jetty:http://%s:%d", r.getAddress().get(), r.getPort().get()) + .transform().simple("${in.body} on " + r.getPort().get()) + ); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java new file mode 100644 index 0000000..8046f1d --- /dev/null +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/ConsulServiceDiscoveryTest.java @@ -0,0 +1,90 @@ +/** + * 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.cloud; + +import java.util.ArrayList; +import java.util.List; + +import com.orbitz.consul.AgentClient; +import com.orbitz.consul.Consul; +import com.orbitz.consul.model.agent.ImmutableRegistration; +import com.orbitz.consul.model.agent.Registration; +import org.apache.camel.cloud.ServiceDefinition; +import org.apache.camel.cloud.ServiceDiscovery; +import org.apache.camel.component.consul.ConsulConfiguration; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class ConsulServiceDiscoveryTest { + private AgentClient client; + private List<Registration> registrations; + + @Before + public void setUp() throws Exception { + client = Consul.builder().build().agentClient(); + registrations = new ArrayList<>(3); + + for (int i = 0; i < 3; i++) { + Registration r = ImmutableRegistration.builder() + .id("service-" + i) + .name("my-service") + .address("127.0.0.1") + .addTags("a-tag") + .addTags("key1=value1") + .addTags("key2=value2") + .port(9000 + i) + .build(); + + client.register(r); + registrations.add(r); + } + } + + @After + public void tearDown() throws Exception { + registrations.forEach(r -> client.deregister(r.getId())); + } + + // ************************************************************************* + // Test + // ************************************************************************* + + @Test + public void testServiceDiscovery() throws Exception { + ConsulConfiguration configuration = new ConsulConfiguration(null); + ServiceDiscovery discovery = new ConsulServiceDiscovery(configuration); + + List<ServiceDefinition> services = discovery.getUpdatedListOfServices("my-service"); + assertNotNull(services); + assertEquals(3, services.size()); + + for (ServiceDefinition service : services) { + assertFalse(service.getMetadata().isEmpty()); + assertTrue(service.getMetadata().containsKey("service_name")); + assertTrue(service.getMetadata().containsKey("service_id")); + assertTrue(service.getMetadata().containsKey("a-tag")); + assertTrue(service.getMetadata().containsKey("key1")); + assertTrue(service.getMetadata().containsKey("key2")); + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.java new file mode 100644 index 0000000..05b28d7 --- /dev/null +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.java @@ -0,0 +1,28 @@ +/** + * 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.cloud; + +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class SpringConsulDefaultServiceCallRouteTest extends SpringConsulServiceCallRouteTest { + @Override + protected AbstractApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml"); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.java new file mode 100644 index 0000000..70eebfb --- /dev/null +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.java @@ -0,0 +1,28 @@ +/** + * 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.cloud; + +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +public class SpringConsulRibbonServiceCallRouteTest extends SpringConsulServiceCallRouteTest { + @Override + protected AbstractApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml"); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java new file mode 100644 index 0000000..81517be --- /dev/null +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/cloud/SpringConsulServiceCallRouteTest.java @@ -0,0 +1,96 @@ +/** + * 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.cloud; + +import java.util.Arrays; +import java.util.List; + +import com.orbitz.consul.AgentClient; +import com.orbitz.consul.Consul; +import com.orbitz.consul.model.agent.ImmutableRegistration; +import com.orbitz.consul.model.agent.Registration; +import org.apache.camel.test.spring.CamelSpringTestSupport; +import org.junit.Test; + +public abstract class SpringConsulServiceCallRouteTest extends CamelSpringTestSupport { + private AgentClient client; + private List<Registration> registrations; + + // ************************************************************************* + // Setup / tear down + // ************************************************************************* + + @Override + public void doPreSetup() throws Exception { + this.client = Consul.builder().build().agentClient(); + this.registrations = Arrays.asList( + ImmutableRegistration.builder() + .id("service-1") + .name("http-service-1") + .address("127.0.0.1") + .port(9091) + .build(), + ImmutableRegistration.builder() + .id("service-2") + .name("http-service-1") + .address("127.0.0.1") + .port(9092) + .build(), + ImmutableRegistration.builder() + .id("service-3") + .name("http-service-2") + .address("127.0.0.1") + .port(9093) + .build(), + ImmutableRegistration.builder() + .id("service-4") + .name("http-service-2") + .address("127.0.0.1") + .port(9094) + .build() + ); + + this.registrations.forEach(client::register); + super.doPreSetup(); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + registrations.forEach(r -> client.deregister(r.getId())); + } + + // ************************************************************************* + // Test + // ************************************************************************* + + @Test + public void testServiceCall() throws Exception { + getMockEndpoint("mock:result-1").expectedMessageCount(2); + getMockEndpoint("mock:result-1").expectedBodiesReceivedInAnyOrder("service-1 9091", "service-1 9092"); + getMockEndpoint("mock:result-2").expectedMessageCount(2); + getMockEndpoint("mock:result-2").expectedBodiesReceivedInAnyOrder("service-2 9093", "service-2 9094"); + + template.sendBody("direct:start", "service-1"); + template.sendBody("direct:start", "service-1"); + template.sendBody("direct:start", "service-2"); + template.sendBody("direct:start", "service-2"); + + assertMockEndpointsSatisfied(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/java/org/apache/camel/component/consul/policy/ConsulRoutePolicyMain.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/policy/ConsulRoutePolicyMain.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/policy/ConsulRoutePolicyMain.java index d5831c1..447f5b3 100644 --- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/policy/ConsulRoutePolicyMain.java +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/policy/ConsulRoutePolicyMain.java @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.camel.component.consul.policy; import org.apache.camel.builder.RouteBuilder; http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallRouteTest.java deleted file mode 100644 index a76580b..0000000 --- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallRouteTest.java +++ /dev/null @@ -1,114 +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.processor.remote; - -import java.util.ArrayList; -import java.util.List; - -import com.orbitz.consul.AgentClient; -import com.orbitz.consul.model.agent.ImmutableRegistration; -import com.orbitz.consul.model.agent.Registration; -import org.apache.camel.RoutesBuilder; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.component.consul.ConsulTestSupport; -import org.junit.Ignore; -import org.junit.Test; - -@Ignore("A consul server is needed for this test ") -public class ConsulServiceCallRouteTest extends ConsulTestSupport { - private static final String SERVICE_NAME = "http-service"; - private static final int SERVICE_COUNT = 5; - private static final int SERVICE_PORT_BASE = 8080; - - private AgentClient client; - private List<Registration> registrations; - private List<String> expectedBodies; - - // ************************************************************************* - // Setup / tear down - // ************************************************************************* - - @Override - protected void doPreSetup() throws Exception { - client = getConsul().agentClient(); - - registrations = new ArrayList<>(SERVICE_COUNT); - expectedBodies = new ArrayList<>(SERVICE_COUNT); - - for (int i = 0; i < SERVICE_COUNT; i++) { - Registration r = ImmutableRegistration.builder() - .id("service-" + i) - .name(SERVICE_NAME) - .address("127.0.0.1") - .port(SERVICE_PORT_BASE + i) - .build(); - - client.register(r); - - registrations.add(r); - expectedBodies.add("ping on " + r.getPort().get()); - } - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - registrations.forEach(r -> client.deregister(r.getId())); - } - - // ************************************************************************* - // Test - // ************************************************************************* - - @Test - public void testServiceCall() throws Exception { - getMockEndpoint("mock:result").expectedMessageCount(SERVICE_COUNT); - getMockEndpoint("mock:result").expectedBodiesReceivedInAnyOrder(expectedBodies); - - registrations.forEach(r -> template.sendBody("direct:start", "ping")); - - assertMockEndpointsSatisfied(); - } - - // ************************************************************************* - // Route - // ************************************************************************* - - @Override - protected RoutesBuilder createRouteBuilder() throws Exception { - return new RouteBuilder() { - @Override - public void configure() throws Exception { - from("direct:start") - .serviceCall() - .name(SERVICE_NAME) - .consulConfiguration() - .component("http") - .loadBalancer("roundrobin") - .serverListStrategy("ondemand") - .end() - .to("log:org.apache.camel.component.consul.processor.service?level=INFO&showAll=true&multiline=true") - .to("mock:result"); - - registrations.forEach(r -> - fromF("jetty:http://%s:%d", r.getAddress().get(), r.getPort().get()) - .transform().simple("${in.body} on " + r.getPort().get()) - ); - } - }; - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategiesTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategiesTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategiesTest.java deleted file mode 100644 index 65738e0..0000000 --- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategiesTest.java +++ /dev/null @@ -1,92 +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.processor.remote; - -import java.util.ArrayList; -import java.util.List; - -import com.orbitz.consul.AgentClient; -import com.orbitz.consul.Consul; -import com.orbitz.consul.model.agent.ImmutableRegistration; -import com.orbitz.consul.model.agent.Registration; -import org.apache.camel.component.consul.ConsulConfiguration; -import org.apache.camel.spi.ServiceCallServer; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -@Ignore("A consul server is needed for this test ") -public class ConsulServiceCallServerListStrategiesTest { - private AgentClient client; - private List<Registration> registrations; - - @Before - public void setUp() throws Exception { - client = Consul.builder().build().agentClient(); - registrations = new ArrayList<>(3); - - for (int i = 0; i < 3; i++) { - Registration r = ImmutableRegistration.builder() - .id("service-" + i) - .name("my-service") - .address("127.0.0.1") - .addTags("a-tag") - .addTags("key1=value1") - .addTags("key2=value2") - .port(9000 + i) - .build(); - - client.register(r); - registrations.add(r); - } - } - - @After - public void tearDown() throws Exception { - registrations.forEach(r -> client.deregister(r.getId())); - } - - // ************************************************************************* - // Test - // ************************************************************************* - - @Test - public void testOnDemand() throws Exception { - ConsulConfiguration configuration = new ConsulConfiguration(null); - ConsulServiceCallServerListStrategy strategy = ConsulServiceCallServerListStrategies.onDemand(configuration); - - List<ServiceCallServer> servers = strategy.getUpdatedListOfServers("my-service"); - assertNotNull(servers); - assertEquals(3, servers.size()); - - for (ServiceCallServer server : servers) { - assertFalse(server.getMetadata().isEmpty()); - assertTrue(server.getMetadata().containsKey("service_name")); - assertTrue(server.getMetadata().containsKey("service_id")); - assertTrue(server.getMetadata().containsKey("a-tag")); - assertTrue(server.getMetadata().containsKey("key1")); - assertTrue(server.getMetadata().containsKey("key2")); - } - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml b/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml new file mode 100644 index 0000000..c4d0950 --- /dev/null +++ b/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulDefaultServiceCallRouteTest.xml @@ -0,0 +1,87 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring + http://camel.apache.org/schema/spring/camel-spring.xsd"> + + <camelContext xmlns="http://camel.apache.org/schema/spring"> + + <!-- shared config --> + <serviceCallConfiguration id="shared-config" serviceChooserRef="round-robin"> + <consulServiceDiscovery readTimeoutMillis="1444" url="http://localhost:8500"/> + </serviceCallConfiguration> + + <route> + <from uri="direct:start"/> + <choice> + <when> + <simple>${body} == 'service-1'</simple> + <serviceCall name="http-service-1"> + <consulServiceDiscovery readTimeoutMillis="1222" url="http://localhost:8500"/> + </serviceCall> + <to uri="mock:result-1"/> + </when> + <when> + <simple>${body} == 'service-2'</simple> + <serviceCall name="http-service-2"> + <consulServiceDiscovery readTimeoutMillis="1333" url="http://localhost:8500"/> + </serviceCall> + <to uri="mock:result-2"/> + </when> + <when> + <simple>${body} == 'service-3'</simple> + <serviceCall name="http-service-3" configurationRef="shared-config"/> + <to uri="mock:result-2"/> + </when> + </choice> + </route> + + <route> + <from uri="jetty:http://localhost:9091"/> + <transform> + <simple>${body} 9091</simple> + </transform> + </route> + + <route> + <from uri="jetty:http://localhost:9092"/> + <transform> + <simple>${body} 9092</simple> + </transform> + </route> + + <route> + <from uri="jetty:http://localhost:9093"/> + <transform> + <simple>${body} 9093</simple> + </transform> + </route> + + <route> + <from uri="jetty:http://localhost:9094"/> + <transform> + <simple>${body} 9094</simple> + </transform> + </route> + </camelContext> + +</beans> http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml b/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml new file mode 100644 index 0000000..ac1b642 --- /dev/null +++ b/components/camel-consul/src/test/resources/org/apache/camel/component/consul/cloud/SpringConsulRibbonServiceCallRouteTest.xml @@ -0,0 +1,84 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://camel.apache.org/schema/spring + http://camel.apache.org/schema/spring/camel-spring.xsd"> + + <camelContext xmlns="http://camel.apache.org/schema/spring"> + <!-- + <serviceCallConfiguration id="service-2"> + <consulServiceDiscovery"/> + </serviceCallConfiguration> + --> + + <route> + <from uri="direct:start"/> + <choice> + <when> + <simple>${body} == 'service-1'</simple> + <serviceCall name="http-service-1"> + <consulServiceDiscovery readTimeoutMillis="1222" url="http://localhost:8500"/> + <ribbonLoadBalancer/> + </serviceCall> + <to uri="mock:result-1"/> + </when> + <when> + <simple>${body} == 'service-2'</simple> + <serviceCall name="http-service-2"> + <consulServiceDiscovery readTimeoutMillis="1333" url="http://localhost:8500"/> + <ribbonLoadBalancer/> + </serviceCall> + <to uri="mock:result-2"/> + </when> + </choice> + </route> + + <route> + <from uri="jetty:http://localhost:9091"/> + <transform> + <simple>${body} 9091</simple> + </transform> + </route> + + <route> + <from uri="jetty:http://localhost:9092"/> + <transform> + <simple>${body} 9092</simple> + </transform> + </route> + + <route> + <from uri="jetty:http://localhost:9093"/> + <transform> + <simple>${body} 9093</simple> + </transform> + </route> + + <route> + <from uri="jetty:http://localhost:9094"/> + <transform> + <simple>${body} 9094</simple> + </transform> + </route> + </camelContext> + +</beans> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java ---------------------------------------------------------------------- diff --git a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java index a4bb342..a5ce3f7 100644 --- a/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java +++ b/components/camel-core-xml/src/main/java/org/apache/camel/core/xml/AbstractCamelContextFactoryBean.java @@ -66,6 +66,7 @@ import org.apache.camel.model.RouteContextRefDefinition; import org.apache.camel.model.RouteDefinition; import org.apache.camel.model.RouteDefinitionHelper; import org.apache.camel.model.ThreadPoolProfileDefinition; +import org.apache.camel.model.cloud.ServiceCallConfigurationDefinition; import org.apache.camel.model.dataformat.DataFormatsDefinition; import org.apache.camel.model.rest.RestConfigurationDefinition; import org.apache.camel.model.rest.RestContainer; @@ -775,6 +776,10 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex public abstract String getDependsOn(); + public abstract List<AbstractCamelFactoryBean<?>> getBeansFactory(); + + public abstract List<?> getBeans(); + // Implementation methods // ------------------------------------------------------------------------- @@ -851,6 +856,15 @@ public abstract class AbstractCamelContextFactoryBean<T extends ModelCamelContex if (getRestConfiguration() != null) { ctx.setRestConfiguration(getRestConfiguration().asRestConfiguration(ctx)); } + if (getBeans() != null) { + for (Object bean : getBeans()) { + if (bean instanceof ServiceCallConfigurationDefinition) { + @SuppressWarnings("unchecked") + ServiceCallConfigurationDefinition configuration = (ServiceCallConfigurationDefinition)bean; + ctx.addServiceCallConfiguration(configuration.getId(), configuration); + } + } + } } protected void initThreadPoolProfiles(T context) throws Exception { http://git-wip-us.apache.org/repos/asf/camel/blob/a811f400/components/camel-dns/src/main/java/org/apache/camel/component/dns/cloud/DnsServiceDiscovery.java ---------------------------------------------------------------------- diff --git a/components/camel-dns/src/main/java/org/apache/camel/component/dns/cloud/DnsServiceDiscovery.java b/components/camel-dns/src/main/java/org/apache/camel/component/dns/cloud/DnsServiceDiscovery.java new file mode 100644 index 0000000..003fd8a --- /dev/null +++ b/components/camel-dns/src/main/java/org/apache/camel/component/dns/cloud/DnsServiceDiscovery.java @@ -0,0 +1,102 @@ +/** + * 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.dns.cloud; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +import org.apache.camel.RuntimeCamelException; +import org.apache.camel.cloud.ServiceDefinition; +import org.apache.camel.component.dns.DnsConfiguration; +import org.apache.camel.impl.cloud.DefaultServiceDefinition; +import org.apache.camel.impl.cloud.DefaultServiceDiscovery; +import org.apache.camel.util.ObjectHelper; +import org.xbill.DNS.Lookup; +import org.xbill.DNS.Record; +import org.xbill.DNS.SRVRecord; +import org.xbill.DNS.TextParseException; +import org.xbill.DNS.Type; + + +public final class DnsServiceDiscovery extends DefaultServiceDiscovery { + private static final Comparator<SRVRecord> COMPARATOR = comparator(); + private final DnsConfiguration configuration; + private final ConcurrentHashMap<String, Lookup> cache; + + public DnsServiceDiscovery(DnsConfiguration configuration) { + this.configuration = configuration; + this.cache = new ConcurrentHashMap<>(); + } + + @Override + public List<ServiceDefinition> getUpdatedListOfServices(String name) { + final Lookup lookup = cache.computeIfAbsent(name, this::createLookup); + final Record[] records = lookup.run(); + + List<ServiceDefinition> services; + if (Objects.nonNull(records) && lookup.getResult() == Lookup.SUCCESSFUL) { + services = Arrays.stream(records) + .filter(SRVRecord.class::isInstance) + .map(SRVRecord.class::cast) + .sorted(COMPARATOR) + .map(record -> asService(name, record)) + .collect(Collectors.toList()); + } else { + services = Collections.emptyList(); + } + + return services; + } + + private Lookup createLookup(String name) { + try { + return new Lookup( + String.format("%s.%s.%s", name, configuration.getProto(), configuration.getDomain()), + Type.SRV); + } catch (TextParseException e) { + throw new RuntimeCamelException(e); + } + } + + private static Comparator<SRVRecord> comparator() { + Comparator<SRVRecord> byPriority = (e1, e2) -> Integer.compare(e2.getPriority(), e1.getPriority()); + Comparator<SRVRecord> byWeight = (e1, e2) -> Integer.compare(e2.getWeight(), e1.getWeight()); + + return byPriority.thenComparing(byWeight); + } + + private static ServiceDefinition asService(String serviceName, SRVRecord record) { + Map<String, String> meta = new HashMap<>(); + ObjectHelper.ifNotEmpty(record.getPriority(), val -> meta.put("priority", Integer.toString(val))); + ObjectHelper.ifNotEmpty(record.getWeight(), val -> meta.put("weight", Integer.toString(val))); + + return new DefaultServiceDefinition( + serviceName, + record.getTarget().toString(true), + record.getPort(), + meta + ); + } +}