CAMEL-9989: Create a Consul based ServiceCall EIP
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/dbfcd606 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/dbfcd606 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/dbfcd606 Branch: refs/heads/master Commit: dbfcd606c286da840075cf315e4f4ac16e7f9ef8 Parents: 326e615 Author: lburgazzoli <lburgazz...@gmail.com> Authored: Mon Jun 6 08:33:17 2016 +0200 Committer: lburgazzoli <lburgazz...@gmail.com> Committed: Tue Jun 7 16:30:43 2016 +0200 ---------------------------------------------------------------------- .../remote/ConsulConfigurationDefinition.java | 34 ------ .../blueprint/CamelContextFactoryBean.java | 1 + .../remote/ConsulServiceCallProcessor.java | 43 +++++++ .../ConsulServiceCallProcessorFactory.java | 67 +++++++++++ .../ConsulServiceCallServerListStrategies.java | 65 +++++++++++ .../ConsulServiceCallServerListStrategy.java | 106 +++++++++++++++++ .../service/ConsulProcessorFactory.java | 67 ----------- .../service/ConsulServiceCallProcessor.java | 43 ------- .../ConsulServiceCallServerListStrategies.java | 65 ----------- .../ConsulServiceCallServerListStrategy.java | 106 ----------------- .../apache/camel/model/ServiceCallDefinition | 2 +- .../remote/ConsulServiceCallRouteTest.java | 114 +++++++++++++++++++ .../service/ServiceCallClientRouteTest.java | 114 ------------------- .../processor/remote/EtcdProcessorFactory.java | 24 ++++ 14 files changed, 421 insertions(+), 430 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/dbfcd606/camel-core/src/main/java/org/apache/camel/model/remote/ConsulConfigurationDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/remote/ConsulConfigurationDefinition.java b/camel-core/src/main/java/org/apache/camel/model/remote/ConsulConfigurationDefinition.java index 6fe2a7f..f7174a4 100644 --- a/camel-core/src/main/java/org/apache/camel/model/remote/ConsulConfigurationDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/remote/ConsulConfigurationDefinition.java @@ -36,10 +36,6 @@ public class ConsulConfigurationDefinition extends ServiceCallConfigurationDefin private String url; @XmlAttribute private String dc; - //@XmlAttribute - //private Set<String> tags; - //@XmlAttribute @Metadata(label = "security") - //private SSLContextParameters sslContextParameters; @XmlAttribute @Metadata(label = "security") private String aclToken; @XmlAttribute @Metadata(label = "security") @@ -82,24 +78,6 @@ public class ConsulConfigurationDefinition extends ServiceCallConfigurationDefin this.dc = dc; } - /* - public Set<String> getTags() { - return tags; - } - - public void setTags(Set<String> tags) { - this.tags = tags; - } - - public SSLContextParameters getSslContextParameters() { - return sslContextParameters; - } - - public void setSslContextParameters(SSLContextParameters sslContextParameters) { - this.sslContextParameters = sslContextParameters; - } - */ - public String getAclToken() { return aclToken; } @@ -170,18 +148,6 @@ public class ConsulConfigurationDefinition extends ServiceCallConfigurationDefin return this; } - /* - public ConsulConfigurationDefinition tags(Set<String> tags) { - setTags(tags); - return this; - } - - public ConsulConfigurationDefinition sslContextParameters(SSLContextParameters sslContextParameters) { - setSslContextParameters(sslContextParameters); - return this; - } - */ - public ConsulConfigurationDefinition aclToken(String aclToken) { setAclToken(aclToken); return this; http://git-wip-us.apache.org/repos/asf/camel/blob/dbfcd606/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 d04ca11..1ca4507 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 @@ -146,6 +146,7 @@ public class CamelContextFactoryBean extends AbstractCamelContextFactoryBean<Blu @XmlElement(name = "hystrixConfiguration", type = HystrixConfigurationDefinition.class, required = false), @XmlElement(name = "kubernetesConfiguration", type = KubernetesConfigurationDefinition.class, required = false), @XmlElement(name = "ribbonConfiguration", type = RibbonConfigurationDefinition.class, required = false), + @XmlElement(name = "consulConfiguration", type = RibbonConfigurationDefinition.class, required = false), @XmlElement(name = "template", type = CamelProducerTemplateFactoryBean.class, required = false), @XmlElement(name = "consumerTemplate", type = CamelConsumerTemplateFactoryBean.class, required = false), @XmlElement(name = "proxy", type = CamelProxyFactoryBean.class, required = false), http://git-wip-us.apache.org/repos/asf/camel/blob/dbfcd606/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 new file mode 100644 index 0000000..7d98a8e --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessor.java @@ -0,0 +1,43 @@ +/** + * 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/dbfcd606/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 new file mode 100644 index 0000000..064fac2 --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallProcessorFactory.java @@ -0,0 +1,67 @@ +/** + * 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/dbfcd606/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 new file mode 100644 index 0000000..81f95ff --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategies.java @@ -0,0 +1,65 @@ +/** + * 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/dbfcd606/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 new file mode 100644 index 0000000..1db4bc4 --- /dev/null +++ b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallServerListStrategy.java @@ -0,0 +1,106 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.consul.processor.remote; + +import java.util.List; + +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; + + +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) { + return new DefaultServiceCallServer( + service.getServiceAddress(), + service.getServicePort() + ); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/dbfcd606/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulProcessorFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulProcessorFactory.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulProcessorFactory.java deleted file mode 100644 index 4b13d2f..0000000 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulProcessorFactory.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.service; - -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 ConsulProcessorFactory 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/dbfcd606/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallProcessor.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallProcessor.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallProcessor.java deleted file mode 100644 index e49bd31..0000000 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/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.service; - -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/dbfcd606/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallServerListStrategies.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallServerListStrategies.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallServerListStrategies.java deleted file mode 100644 index c8ab95d..0000000 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/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.service; - -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/dbfcd606/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallServerListStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallServerListStrategy.java b/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallServerListStrategy.java deleted file mode 100644 index c79a55c..0000000 --- a/components/camel-consul/src/main/java/org/apache/camel/component/consul/processor/service/ConsulServiceCallServerListStrategy.java +++ /dev/null @@ -1,106 +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.service; - -import java.util.List; - -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; - - -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) { - return new DefaultServiceCallServer( - service.getServiceAddress(), - service.getServicePort() - ); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/dbfcd606/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 index 0172512..3082d38 100644 --- 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 @@ -15,4 +15,4 @@ # limitations under the License. # -class=org.apache.camel.component.consul.processor.service.ConsulProcessorFactory +class=org.apache.camel.component.consul.processor.remote.ConsulServiceCallProcessorFactory http://git-wip-us.apache.org/repos/asf/camel/blob/dbfcd606/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 new file mode 100644 index 0000000..7eb6b40 --- /dev/null +++ b/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/remote/ConsulServiceCallRouteTest.java @@ -0,0 +1,114 @@ +/** + * 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 +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/dbfcd606/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/service/ServiceCallClientRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/service/ServiceCallClientRouteTest.java b/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/service/ServiceCallClientRouteTest.java deleted file mode 100644 index c19192b..0000000 --- a/components/camel-consul/src/test/java/org/apache/camel/component/consul/processor/service/ServiceCallClientRouteTest.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.service; - -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 -public class ServiceCallClientRouteTest 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/dbfcd606/components/camel-etcd/src/main/java/org/apache/camel/component/etcd/processor/remote/EtcdProcessorFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-etcd/src/main/java/org/apache/camel/component/etcd/processor/remote/EtcdProcessorFactory.java b/components/camel-etcd/src/main/java/org/apache/camel/component/etcd/processor/remote/EtcdProcessorFactory.java new file mode 100644 index 0000000..0e60a77 --- /dev/null +++ b/components/camel-etcd/src/main/java/org/apache/camel/component/etcd/processor/remote/EtcdProcessorFactory.java @@ -0,0 +1,24 @@ +/** + * 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.etcd.processor.remote; + +/** + * @author lburgazzoli + */ +public class EtcdProcessorFactory { +}