CAMEL-9683: Kubernetes can lookup service using client,env or dns.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3f61efcc Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3f61efcc Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3f61efcc Branch: refs/heads/remoteServiceCall Commit: 3f61efcc9e196ba2c9774ed571f0079a8bc2aa13 Parents: ba71865 Author: Claus Ibsen <davscl...@apache.org> Authored: Wed May 18 10:15:06 2016 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Mon May 23 09:27:46 2016 +0200 ---------------------------------------------------------------------- .../KubernetesConfigurationDefinition.java | 96 +++++-- .../support/ServiceCallExpressionSupport.java | 16 +- .../KubernetesClientServiceCallProcessor.java | 248 +++++++++++++++++++ ...bernetesEnvironmentServiceCallProcessor.java | 160 ++++++++++++ .../processor/KubernetesProcessorFactory.java | 31 ++- .../KubernetesServiceCallProcessor.java | 248 ------------------- .../processor/ServiceCallClientRouteTest.java | 71 ++++++ .../ServiceCallEnvironmentRouteTest.java | 65 +++++ .../processor/ServiceCallRouteTest.java | 70 ------ .../SpringServiceCallClientRouteTest.java | 41 +++ .../SpringServiceCallEnvironmentRouteTest.java | 41 +++ .../processor/SpringServiceCallRouteTest.java | 41 --- .../SpringServiceCallClientRouteTest.xml | 39 +++ .../SpringServiceCallEnvironmentRouteTest.xml | 38 +++ .../processor/SpringServiceCallRouteTest.xml | 39 --- 15 files changed, 805 insertions(+), 439 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/camel-core/src/main/java/org/apache/camel/model/remote/KubernetesConfigurationDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/remote/KubernetesConfigurationDefinition.java b/camel-core/src/main/java/org/apache/camel/model/remote/KubernetesConfigurationDefinition.java index 0a8726b..91a11a0 100644 --- a/camel-core/src/main/java/org/apache/camel/model/remote/KubernetesConfigurationDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/remote/KubernetesConfigurationDefinition.java @@ -38,29 +38,33 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD private String namespace; @XmlAttribute private String apiVersion; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(defaultValue = "dns") + private String lookup; + @XmlAttribute + private String dnsDomain; + @XmlAttribute @Metadata(label = "client") private String username; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String password; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String oauthToken; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String caCertData; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String caCertFile; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String clientCertData; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String clientCertFile; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String clientKeyAlgo; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String clientKeyData; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String clientKeyFile; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private String clientKeyPassphrase; - @XmlAttribute @Metadata(label = "security") + @XmlAttribute @Metadata(label = "client") private Boolean trustCerts; public KubernetesConfigurationDefinition() { @@ -98,6 +102,22 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD this.apiVersion = apiVersion; } + public String getLookup() { + return lookup; + } + + public void setLookup(String lookup) { + this.lookup = lookup; + } + + public String getDnsDomain() { + return dnsDomain; + } + + public void setDnsDomain(String dnsDomain) { + this.dnsDomain = dnsDomain; + } + public String getUsername() { return username; } @@ -198,7 +218,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD // ------------------------------------------------------------------------- /** - * Sets the URL to the master + * Sets the URL to the master when using client lookup */ public KubernetesConfigurationDefinition masterUrl(String masterUrl) { setMasterUrl(masterUrl); @@ -206,7 +226,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the namespace to use + * Sets the namespace to use (required) */ public KubernetesConfigurationDefinition namespace(String namespace) { setNamespace(namespace); @@ -222,7 +242,31 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the username for authentication + * How to perform service lookup. Possible values: client, dns, environment. + * When using dns the service name is resolved as <tt>name.namespace.service.dnsDomain</tt>. + * <p/> + * When using client, then the client queries the kubernetes master to obtain a list + * of active pods that provides the service, and then random (or round robin) select a pod. + * <p/> + * When using environment then environment variables are used to lookup the service. + * <p/> + * By default dns is used. + */ + public KubernetesConfigurationDefinition lookup(String lookup) { + setLookup(lookup); + return this; + } + + /** + * Sets the DNS domain to use for DNS lookup. + */ + public KubernetesConfigurationDefinition dnsDomain(String dnsDomain) { + setDnsDomain(dnsDomain); + return this; + } + + /** + * Sets the username for authentication when using client lookup */ public KubernetesConfigurationDefinition username(String username) { setUsername(username); @@ -230,7 +274,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the password for authentication + * Sets the password for authentication when using client lookup */ public KubernetesConfigurationDefinition password(String password) { setPassword(password); @@ -238,7 +282,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the OAUTH token for authentication (instead of username/password) + * Sets the OAUTH token for authentication (instead of username/password) when using client lookup */ public KubernetesConfigurationDefinition oauthToken(String oauthToken) { setOauthToken(oauthToken); @@ -246,7 +290,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the Certificate Authority data + * Sets the Certificate Authority data when using client lookup */ public KubernetesConfigurationDefinition caCertData(String caCertData) { setCaCertData(caCertData); @@ -254,7 +298,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the Certificate Authority data that are loaded from the file + * Sets the Certificate Authority data that are loaded from the file when using client lookup */ public KubernetesConfigurationDefinition caCertFile(String caCertFile) { setCaCertFile(caCertFile); @@ -262,7 +306,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the Client Certificate data + * Sets the Client Certificate data when using client lookup */ public KubernetesConfigurationDefinition clientCertData(String clientCertData) { setClientCertData(clientCertData); @@ -270,7 +314,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the Client Certificate data that are loaded from the file + * Sets the Client Certificate data that are loaded from the file when using client lookup */ public KubernetesConfigurationDefinition clientCertFile(String clientCertFile) { setClientCertFile(clientCertFile); @@ -278,7 +322,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the Client Keystore algorithm, such as RSA. + * Sets the Client Keystore algorithm, such as RSA when using client lookup */ public KubernetesConfigurationDefinition clientKeyAlgo(String clientKeyAlgo) { setClientKeyAlgo(clientKeyAlgo); @@ -286,7 +330,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the Client Keystore data + * Sets the Client Keystore data when using client lookup */ public KubernetesConfigurationDefinition clientKeyData(String clientKeyData) { setClientKeyData(clientKeyData); @@ -294,7 +338,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the Client Keystore data that are loaded from the file + * Sets the Client Keystore data that are loaded from the file when using client lookup */ public KubernetesConfigurationDefinition clientKeyFile(String clientKeyFile) { setClientKeyFile(clientKeyFile); @@ -302,7 +346,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets the Client Keystore passphrase + * Sets the Client Keystore passphrase when using client lookup */ public KubernetesConfigurationDefinition clientKeyPassphrase(String clientKeyPassphrase) { setClientKeyPassphrase(clientKeyPassphrase); @@ -310,7 +354,7 @@ public class KubernetesConfigurationDefinition extends ServiceCallConfigurationD } /** - * Sets whether to turn on trust certificate check + * Sets whether to turn on trust certificate check when using client lookup */ public KubernetesConfigurationDefinition trustCerts(boolean trustCerts) { setTrustCerts(trustCerts); http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/camel-core/src/main/java/org/apache/camel/support/ServiceCallExpressionSupport.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/support/ServiceCallExpressionSupport.java b/camel-core/src/main/java/org/apache/camel/support/ServiceCallExpressionSupport.java index eda1092..73e0e72 100644 --- a/camel-core/src/main/java/org/apache/camel/support/ServiceCallExpressionSupport.java +++ b/camel-core/src/main/java/org/apache/camel/support/ServiceCallExpressionSupport.java @@ -24,6 +24,15 @@ import org.slf4j.LoggerFactory; /** * Support class for custom implementations of {@link ServiceCallDefinition ServiceCall EIP} components. + * <p/> + * Below are some examples how to call a service and what Camel endpoint URI is constructed based on the input: + * <pre> + serviceCall("myService") -> http://hostname:port + serviceCall("myService/foo") -> http://hostname:port/foo + serviceCall("http:myService/foo") -> http:hostname:port/foo + serviceCall("myService", "http:myService.host:myService.port/foo") -> http:hostname:port/foo + serviceCall("myService", "netty4:tcp:myService?connectTimeout=1000") -> netty:tcp:hostname:port?connectTimeout=1000 + * </pre> */ public abstract class ServiceCallExpressionSupport extends ExpressionAdapter { @@ -57,16 +66,11 @@ public abstract class ServiceCallExpressionSupport extends ExpressionAdapter { } protected static String buildCamelEndpointUri(String ip, int port, String name, String uri, String contextPath, String scheme) { - // serviceCall("myService") (will use http by default) - // serviceCall("myService/foo") (will use http by default) - // serviceCall("http:myService/foo") - // serviceCall("myService", "http:myService.host:myService.port/foo") - // serviceCall("myService", "netty4:tcp:myService?connectTimeout=1000") - // build basic uri if none provided String answer = uri; if (answer == null) { if (scheme == null) { + // use http/https by default if no scheme has been configured if (port == 443) { scheme = "https"; } else { http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesClientServiceCallProcessor.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesClientServiceCallProcessor.java b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesClientServiceCallProcessor.java new file mode 100644 index 0000000..373f60e --- /dev/null +++ b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesClientServiceCallProcessor.java @@ -0,0 +1,248 @@ +/** + * 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.kubernetes.processor; + +import java.util.Collection; +import java.util.concurrent.RejectedExecutionException; + +import io.fabric8.kubernetes.client.Config; +import io.fabric8.kubernetes.client.ConfigBuilder; +import io.fabric8.openshift.client.DefaultOpenShiftClient; +import io.fabric8.openshift.client.OpenShiftClient; +import org.apache.camel.AsyncCallback; +import org.apache.camel.AsyncProcessor; +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; +import org.apache.camel.Exchange; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Traceable; +import org.apache.camel.component.kubernetes.KubernetesConfiguration; +import org.apache.camel.component.kubernetes.KubernetesConstants; +import org.apache.camel.processor.SendDynamicProcessor; +import org.apache.camel.spi.IdAware; +import org.apache.camel.spi.ServiceCallLoadBalancer; +import org.apache.camel.spi.ServiceCallServerListStrategy; +import org.apache.camel.support.ServiceSupport; +import org.apache.camel.util.AsyncProcessorHelper; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.ServiceHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Kubernetes based implementation of the the ServiceCall EIP where the service lookup is client based. + */ +public class KubernetesClientServiceCallProcessor extends ServiceSupport implements AsyncProcessor, CamelContextAware, Traceable, IdAware { + + private static final Logger LOG = LoggerFactory.getLogger(KubernetesClientServiceCallProcessor.class); + + private CamelContext camelContext; + private String id; + private final String name; + private final String scheme; + private final String contextPath; + private final String namespace; + private final String uri; + private final ExchangePattern exchangePattern; + private final KubernetesConfiguration configuration; + private final KubernetesServiceCallExpression serviceCallExpression; + private ServiceCallServerListStrategy<KubernetesServer> serverListStrategy; + private ServiceCallLoadBalancer<KubernetesServer> loadBalancer; + private SendDynamicProcessor processor; + + public KubernetesClientServiceCallProcessor(String name, String namespace, String uri, ExchangePattern exchangePattern, KubernetesConfiguration configuration) { + // setup from the provided name which can contain scheme and context-path information as well + String serviceName; + if (name.contains("/")) { + serviceName = ObjectHelper.before(name, "/"); + this.contextPath = ObjectHelper.after(name, "/"); + } else if (name.contains("?")) { + serviceName = ObjectHelper.before(name, "?"); + this.contextPath = ObjectHelper.after(name, "?"); + } else { + serviceName = name; + this.contextPath = null; + } + if (serviceName.contains(":")) { + this.scheme = ObjectHelper.before(serviceName, ":"); + this.name = ObjectHelper.after(serviceName, ":"); + } else { + this.scheme = null; + this.name = serviceName; + } + + this.namespace = namespace; + this.uri = uri; + this.exchangePattern = exchangePattern; + this.configuration = configuration; + this.serviceCallExpression = new KubernetesServiceCallExpression(this.name, this.scheme, this.contextPath, this.uri); + } + + @Override + public void process(Exchange exchange) throws Exception { + AsyncProcessorHelper.process(this, exchange); + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + Collection<KubernetesServer> servers = null; + try { + servers = serverListStrategy.getUpdatedListOfServers(); + if (servers == null || servers.isEmpty()) { + exchange.setException(new RejectedExecutionException("No active services with name " + name + " in namespace " + namespace)); + } + } catch (Throwable e) { + exchange.setException(e); + } + + if (exchange.getException() != null) { + callback.done(true); + return true; + } + + // let the client load balancer chose which server to use + KubernetesServer server = loadBalancer.chooseServer(servers); + String ip = server.getIp(); + int port = server.getPort(); + LOG.debug("Service {} active at server: {}:{}", name, ip, port); + + // set selected server as header + exchange.getIn().setHeader(KubernetesConstants.KUBERNETES_SERVER_IP, ip); + exchange.getIn().setHeader(KubernetesConstants.KUBERNETES_SERVER_PORT, port); + + // use the dynamic send processor to call the service + return processor.process(exchange, callback); + } + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public String getTraceLabel() { + return "kubernetes"; + } + + public ServiceCallLoadBalancer<KubernetesServer> getLoadBalancer() { + return loadBalancer; + } + + public void setLoadBalancer(ServiceCallLoadBalancer<KubernetesServer> loadBalancer) { + this.loadBalancer = loadBalancer; + } + + public ServiceCallServerListStrategy getServerListStrategy() { + return serverListStrategy; + } + + public void setServerListStrategy(ServiceCallServerListStrategy serverListStrategy) { + this.serverListStrategy = serverListStrategy; + } + + @Override + protected void doStart() throws Exception { + ObjectHelper.notEmpty(name, "name", this); + ObjectHelper.notEmpty(namespace, "namespace", this); + ObjectHelper.notEmpty(configuration.getMasterUrl(), "masterUrl", this); + + if (loadBalancer == null) { + loadBalancer = new RandomLoadBalancer(); + } + if (serverListStrategy == null) { + serverListStrategy = new KubernetesServiceCallServerListStrategy(name, namespace, null, createKubernetesClient()); + } + LOG.info("KubernetesServiceCall at namespace: {} with service name: {} is using load balancer: {} and service discovery: {}", namespace, name, loadBalancer, serverListStrategy); + + processor = new SendDynamicProcessor(uri, serviceCallExpression); + processor.setCamelContext(getCamelContext()); + if (exchangePattern != null) { + processor.setPattern(exchangePattern); + } + ServiceHelper.startServices(serverListStrategy, processor); + } + + @Override + protected void doStop() throws Exception { + ServiceHelper.stopServices(processor, serverListStrategy); + } + + private OpenShiftClient createKubernetesClient() { + // TODO: need to use OpenShiftClient until fabric8-client can auto detect OS vs Kube environment + LOG.debug("Create Kubernetes client with the following Configuration: " + configuration.toString()); + + ConfigBuilder builder = new ConfigBuilder(); + builder.withMasterUrl(configuration.getMasterUrl()); + if ((ObjectHelper.isNotEmpty(configuration.getUsername()) + && ObjectHelper.isNotEmpty(configuration.getPassword())) + && ObjectHelper.isEmpty(configuration.getOauthToken())) { + builder.withUsername(configuration.getUsername()); + builder.withPassword(configuration.getPassword()); + } else { + builder.withOauthToken(configuration.getOauthToken()); + } + if (ObjectHelper.isNotEmpty(configuration.getCaCertData())) { + builder.withCaCertData(configuration.getCaCertData()); + } + if (ObjectHelper.isNotEmpty(configuration.getCaCertFile())) { + builder.withCaCertFile(configuration.getCaCertFile()); + } + if (ObjectHelper.isNotEmpty(configuration.getClientCertData())) { + builder.withClientCertData(configuration.getClientCertData()); + } + if (ObjectHelper.isNotEmpty(configuration.getClientCertFile())) { + builder.withClientCertFile(configuration.getClientCertFile()); + } + if (ObjectHelper.isNotEmpty(configuration.getApiVersion())) { + builder.withApiVersion(configuration.getApiVersion()); + } + if (ObjectHelper.isNotEmpty(configuration.getClientKeyAlgo())) { + builder.withClientKeyAlgo(configuration.getClientKeyAlgo()); + } + if (ObjectHelper.isNotEmpty(configuration.getClientKeyData())) { + builder.withClientKeyData(configuration.getClientKeyData()); + } + if (ObjectHelper.isNotEmpty(configuration.getClientKeyFile())) { + builder.withClientKeyFile(configuration.getClientKeyFile()); + } + if (ObjectHelper.isNotEmpty(configuration.getClientKeyPassphrase())) { + builder.withClientKeyPassphrase(configuration.getClientKeyPassphrase()); + } + if (ObjectHelper.isNotEmpty(configuration.getTrustCerts())) { + builder.withTrustCerts(configuration.getTrustCerts()); + } + + Config conf = builder.build(); + return new DefaultOpenShiftClient(conf); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesEnvironmentServiceCallProcessor.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesEnvironmentServiceCallProcessor.java b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesEnvironmentServiceCallProcessor.java new file mode 100644 index 0000000..88ca752 --- /dev/null +++ b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesEnvironmentServiceCallProcessor.java @@ -0,0 +1,160 @@ +/** + * 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 + * <p/> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p/> + * 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.kubernetes.processor; + +import java.util.concurrent.RejectedExecutionException; + +import org.apache.camel.AsyncCallback; +import org.apache.camel.AsyncProcessor; +import org.apache.camel.CamelContext; +import org.apache.camel.CamelContextAware; +import org.apache.camel.Exchange; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Traceable; +import org.apache.camel.component.kubernetes.KubernetesConstants; +import org.apache.camel.processor.SendDynamicProcessor; +import org.apache.camel.spi.IdAware; +import org.apache.camel.support.ServiceSupport; +import org.apache.camel.util.AsyncProcessorHelper; +import org.apache.camel.util.ObjectHelper; +import org.apache.camel.util.ServiceHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Kubernetes based implementation of the the ServiceCall EIP where the service lookup is environment variable based. + */ +public class KubernetesEnvironmentServiceCallProcessor extends ServiceSupport implements AsyncProcessor, CamelContextAware, Traceable, IdAware { + + private static final Logger LOG = LoggerFactory.getLogger(KubernetesClientServiceCallProcessor.class); + + private CamelContext camelContext; + private String id; + private final String name; + private final String scheme; + private final String contextPath; + private final String namespace; + private final String uri; + private final ExchangePattern exchangePattern; + private final KubernetesServiceCallExpression serviceCallExpression; + private SendDynamicProcessor processor; + private String ip; + private long port; + + public KubernetesEnvironmentServiceCallProcessor(String name, String namespace, String uri, ExchangePattern exchangePattern) { + // setup from the provided name which can contain scheme and context-path information as well + String serviceName; + if (name.contains("/")) { + serviceName = ObjectHelper.before(name, "/"); + this.contextPath = ObjectHelper.after(name, "/"); + } else if (name.contains("?")) { + serviceName = ObjectHelper.before(name, "?"); + this.contextPath = ObjectHelper.after(name, "?"); + } else { + serviceName = name; + this.contextPath = null; + } + if (serviceName.contains(":")) { + this.scheme = ObjectHelper.before(serviceName, ":"); + this.name = ObjectHelper.after(serviceName, ":"); + } else { + this.scheme = null; + this.name = serviceName; + } + + this.namespace = namespace; + this.uri = uri; + this.exchangePattern = exchangePattern; + this.serviceCallExpression = new KubernetesServiceCallExpression(this.name, this.scheme, this.contextPath, this.uri); + } + + @Override + public void process(Exchange exchange) throws Exception { + AsyncProcessorHelper.process(this, exchange); + } + + @Override + public boolean process(Exchange exchange, AsyncCallback callback) { + if (ip == null) { + exchange.setException(new RejectedExecutionException("No active services with name " + name + " in namespace " + namespace)); + } + if (exchange.getException() != null) { + callback.done(true); + return true; + } + + LOG.debug("Service {} active at server: {}:{}", name, ip, port); + + // set selected server as header + exchange.getIn().setHeader(KubernetesConstants.KUBERNETES_SERVER_IP, ip); + exchange.getIn().setHeader(KubernetesConstants.KUBERNETES_SERVER_PORT, port); + + // use the dynamic send processor to call the service + return processor.process(exchange, callback); + } + + @Override + public CamelContext getCamelContext() { + return camelContext; + } + + @Override + public void setCamelContext(CamelContext camelContext) { + this.camelContext = camelContext; + } + + @Override + public String getId() { + return id; + } + + @Override + public void setId(String id) { + this.id = id; + } + + @Override + public String getTraceLabel() { + return "kubernetes"; + } + + @Override + protected void doStart() throws Exception { + // lookup ENV on startup + ip = getCamelContext().resolvePropertyPlaceholders("{{service.host:" + name + "}}"); + String num = getCamelContext().resolvePropertyPlaceholders("{{service.port:" + name + "}}"); + port = getCamelContext().getTypeConverter().tryConvertTo(long.class, num); + + ObjectHelper.notEmpty(name, "name", this); + ObjectHelper.notEmpty(namespace, "namespace", this); + + LOG.info("KubernetesServiceCall at namespace: {} with service name: {} using {}:{}", namespace, name, ip, port); + + processor = new SendDynamicProcessor(uri, serviceCallExpression); + processor.setCamelContext(getCamelContext()); + if (exchangePattern != null) { + processor.setPattern(exchangePattern); + } + ServiceHelper.startServices(processor); + } + + @Override + protected void doStop() throws Exception { + ServiceHelper.stopServices(processor); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesProcessorFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesProcessorFactory.java b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesProcessorFactory.java index a33e54e..4be66c6 100644 --- a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesProcessorFactory.java +++ b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesProcessorFactory.java @@ -24,6 +24,7 @@ import org.apache.camel.ExchangePattern; import org.apache.camel.Processor; import org.apache.camel.component.kubernetes.KubernetesConfiguration; import org.apache.camel.model.ProcessorDefinition; +import org.apache.camel.model.remote.KubernetesConfigurationDefinition; import org.apache.camel.model.remote.ServiceCallConfigurationDefinition; import org.apache.camel.model.remote.ServiceCallDefinition; import org.apache.camel.spi.ProcessorFactory; @@ -54,17 +55,17 @@ public class KubernetesProcessorFactory implements ProcessorFactory { String uri = sc.getUri(); ExchangePattern mep = sc.getPattern(); - ServiceCallConfigurationDefinition config = sc.getServiceCallConfiguration(); - ServiceCallConfigurationDefinition configRef = null; + KubernetesConfigurationDefinition config = (KubernetesConfigurationDefinition) sc.getServiceCallConfiguration(); + KubernetesConfigurationDefinition configRef = null; if (sc.getServiceCallConfigurationRef() != null) { - configRef = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), sc.getServiceCallConfigurationRef(), ServiceCallConfigurationDefinition.class); + configRef = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), sc.getServiceCallConfigurationRef(), KubernetesConfigurationDefinition.class); } // if no configuration explicit configured then try to lookup in registry by type and find the best candidate to use if (config == null && configRef == null) { - Set<ServiceCallConfigurationDefinition> set = routeContext.getCamelContext().getRegistry().findByType(ServiceCallConfigurationDefinition.class); + Set<KubernetesConfigurationDefinition> set = routeContext.getCamelContext().getRegistry().findByType(KubernetesConfigurationDefinition.class); if (set != null) { - for (ServiceCallConfigurationDefinition candidate : set) { + for (KubernetesConfigurationDefinition candidate : set) { if (candidate.getComponent() == null || "kubernetes".equals(candidate.getComponent())) { config = candidate; break; @@ -115,10 +116,22 @@ public class KubernetesProcessorFactory implements ProcessorFactory { sl = configureServerListStrategy(routeContext, configRef); } - KubernetesServiceCallProcessor processor = new KubernetesServiceCallProcessor(name, namespace, uri, mep, kc); - processor.setLoadBalancer(lb); - processor.setServerListStrategy(sl); - return processor; + String lookup = config != null ? config.getLookup() : null; + if (lookup == null && configRef != null) { + lookup = configRef.getLookup(); + } + + if ("client".equals(lookup)) { + KubernetesClientServiceCallProcessor processor = new KubernetesClientServiceCallProcessor(name, namespace, uri, mep, kc); + processor.setLoadBalancer(lb); + processor.setServerListStrategy(sl); + return processor; + } else if ("environment".equals(lookup)) { + return new KubernetesEnvironmentServiceCallProcessor(name, namespace, uri, mep); + } else { +// return new KubernetesDnsServiceCallProcessor(name, namespace, uri, mep); + return null; + } } else { return null; } http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesServiceCallProcessor.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesServiceCallProcessor.java b/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesServiceCallProcessor.java deleted file mode 100644 index 976cf63..0000000 --- a/components/camel-kubernetes/src/main/java/org/apache/camel/component/kubernetes/processor/KubernetesServiceCallProcessor.java +++ /dev/null @@ -1,248 +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.kubernetes.processor; - -import java.util.Collection; -import java.util.concurrent.RejectedExecutionException; - -import io.fabric8.kubernetes.client.Config; -import io.fabric8.kubernetes.client.ConfigBuilder; -import io.fabric8.openshift.client.DefaultOpenShiftClient; -import io.fabric8.openshift.client.OpenShiftClient; -import org.apache.camel.AsyncCallback; -import org.apache.camel.AsyncProcessor; -import org.apache.camel.CamelContext; -import org.apache.camel.CamelContextAware; -import org.apache.camel.Exchange; -import org.apache.camel.ExchangePattern; -import org.apache.camel.Traceable; -import org.apache.camel.component.kubernetes.KubernetesConfiguration; -import org.apache.camel.component.kubernetes.KubernetesConstants; -import org.apache.camel.processor.SendDynamicProcessor; -import org.apache.camel.spi.IdAware; -import org.apache.camel.spi.ServiceCallLoadBalancer; -import org.apache.camel.spi.ServiceCallServerListStrategy; -import org.apache.camel.support.ServiceSupport; -import org.apache.camel.util.AsyncProcessorHelper; -import org.apache.camel.util.ObjectHelper; -import org.apache.camel.util.ServiceHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Kubernetes based implementation of the the ServiceCall EIP. - */ -public class KubernetesServiceCallProcessor extends ServiceSupport implements AsyncProcessor, CamelContextAware, Traceable, IdAware { - - private static final Logger LOG = LoggerFactory.getLogger(KubernetesServiceCallProcessor.class); - - private CamelContext camelContext; - private String id; - private final String name; - private final String scheme; - private final String contextPath; - private final String namespace; - private final String uri; - private final ExchangePattern exchangePattern; - private final KubernetesConfiguration configuration; - private final KubernetesServiceCallExpression serviceCallExpression; - private ServiceCallServerListStrategy<KubernetesServer> serverListStrategy; - private ServiceCallLoadBalancer<KubernetesServer> loadBalancer; - private SendDynamicProcessor processor; - - public KubernetesServiceCallProcessor(String name, String namespace, String uri, ExchangePattern exchangePattern, KubernetesConfiguration configuration) { - // setup from the provided name which can contain scheme and context-path information as well - String serviceName; - if (name.contains("/")) { - serviceName = ObjectHelper.before(name, "/"); - this.contextPath = ObjectHelper.after(name, "/"); - } else if (name.contains("?")) { - serviceName = ObjectHelper.before(name, "?"); - this.contextPath = ObjectHelper.after(name, "?"); - } else { - serviceName = name; - this.contextPath = null; - } - if (serviceName.contains(":")) { - this.scheme = ObjectHelper.before(serviceName, ":"); - this.name = ObjectHelper.after(serviceName, ":"); - } else { - this.scheme = null; - this.name = serviceName; - } - - this.namespace = namespace; - this.uri = uri; - this.exchangePattern = exchangePattern; - this.configuration = configuration; - this.serviceCallExpression = new KubernetesServiceCallExpression(this.name, this.scheme, this.contextPath, this.uri); - } - - @Override - public void process(Exchange exchange) throws Exception { - AsyncProcessorHelper.process(this, exchange); - } - - @Override - public boolean process(Exchange exchange, AsyncCallback callback) { - Collection<KubernetesServer> servers = null; - try { - servers = serverListStrategy.getUpdatedListOfServers(); - if (servers == null || servers.isEmpty()) { - exchange.setException(new RejectedExecutionException("No active services with name " + name + " in namespace " + namespace)); - } - } catch (Throwable e) { - exchange.setException(e); - } - - if (exchange.getException() != null) { - callback.done(true); - return true; - } - - // let the client load balancer chose which server to use - KubernetesServer server = loadBalancer.chooseServer(servers); - String ip = server.getIp(); - int port = server.getPort(); - LOG.debug("Service {} active at server: {}:{}", name, ip, port); - - // set selected server as header - exchange.getIn().setHeader(KubernetesConstants.KUBERNETES_SERVER_IP, ip); - exchange.getIn().setHeader(KubernetesConstants.KUBERNETES_SERVER_PORT, port); - - // use the dynamic send processor to call the service - return processor.process(exchange, callback); - } - - @Override - public CamelContext getCamelContext() { - return camelContext; - } - - @Override - public void setCamelContext(CamelContext camelContext) { - this.camelContext = camelContext; - } - - @Override - public String getId() { - return id; - } - - @Override - public void setId(String id) { - this.id = id; - } - - @Override - public String getTraceLabel() { - return "kubernetes"; - } - - public ServiceCallLoadBalancer<KubernetesServer> getLoadBalancer() { - return loadBalancer; - } - - public void setLoadBalancer(ServiceCallLoadBalancer<KubernetesServer> loadBalancer) { - this.loadBalancer = loadBalancer; - } - - public ServiceCallServerListStrategy getServerListStrategy() { - return serverListStrategy; - } - - public void setServerListStrategy(ServiceCallServerListStrategy serverListStrategy) { - this.serverListStrategy = serverListStrategy; - } - - @Override - protected void doStart() throws Exception { - ObjectHelper.notEmpty(name, "name", this); - ObjectHelper.notEmpty(namespace, "namespace", this); - ObjectHelper.notEmpty(configuration.getMasterUrl(), "masterUrl", this); - - if (loadBalancer == null) { - loadBalancer = new RandomLoadBalancer(); - } - if (serverListStrategy == null) { - serverListStrategy = new KubernetesServiceCallServerListStrategy(name, namespace, null, createKubernetesClient()); - } - LOG.info("KubernetesServiceCall at namespace: {} with service name: {} is using load balancer: {} and service discovery: {}", namespace, name, loadBalancer, serverListStrategy); - - processor = new SendDynamicProcessor(uri, serviceCallExpression); - processor.setCamelContext(getCamelContext()); - if (exchangePattern != null) { - processor.setPattern(exchangePattern); - } - ServiceHelper.startServices(serverListStrategy, processor); - } - - @Override - protected void doStop() throws Exception { - ServiceHelper.stopServices(processor, serverListStrategy); - } - - private OpenShiftClient createKubernetesClient() { - // TODO: need to use OpenShiftClient until fabric8-client can auto detect OS vs Kube environment - LOG.debug("Create Kubernetes client with the following Configuration: " + configuration.toString()); - - ConfigBuilder builder = new ConfigBuilder(); - builder.withMasterUrl(configuration.getMasterUrl()); - if ((ObjectHelper.isNotEmpty(configuration.getUsername()) - && ObjectHelper.isNotEmpty(configuration.getPassword())) - && ObjectHelper.isEmpty(configuration.getOauthToken())) { - builder.withUsername(configuration.getUsername()); - builder.withPassword(configuration.getPassword()); - } else { - builder.withOauthToken(configuration.getOauthToken()); - } - if (ObjectHelper.isNotEmpty(configuration.getCaCertData())) { - builder.withCaCertData(configuration.getCaCertData()); - } - if (ObjectHelper.isNotEmpty(configuration.getCaCertFile())) { - builder.withCaCertFile(configuration.getCaCertFile()); - } - if (ObjectHelper.isNotEmpty(configuration.getClientCertData())) { - builder.withClientCertData(configuration.getClientCertData()); - } - if (ObjectHelper.isNotEmpty(configuration.getClientCertFile())) { - builder.withClientCertFile(configuration.getClientCertFile()); - } - if (ObjectHelper.isNotEmpty(configuration.getApiVersion())) { - builder.withApiVersion(configuration.getApiVersion()); - } - if (ObjectHelper.isNotEmpty(configuration.getClientKeyAlgo())) { - builder.withClientKeyAlgo(configuration.getClientKeyAlgo()); - } - if (ObjectHelper.isNotEmpty(configuration.getClientKeyData())) { - builder.withClientKeyData(configuration.getClientKeyData()); - } - if (ObjectHelper.isNotEmpty(configuration.getClientKeyFile())) { - builder.withClientKeyFile(configuration.getClientKeyFile()); - } - if (ObjectHelper.isNotEmpty(configuration.getClientKeyPassphrase())) { - builder.withClientKeyPassphrase(configuration.getClientKeyPassphrase()); - } - if (ObjectHelper.isNotEmpty(configuration.getTrustCerts())) { - builder.withTrustCerts(configuration.getTrustCerts()); - } - - Config conf = builder.build(); - return new DefaultOpenShiftClient(conf); - } - -} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallClientRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallClientRouteTest.java b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallClientRouteTest.java new file mode 100644 index 0000000..20485e5 --- /dev/null +++ b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallClientRouteTest.java @@ -0,0 +1,71 @@ +/** + * 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.kubernetes.processor; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.JndiRegistry; +import org.apache.camel.model.remote.KubernetesConfigurationDefinition; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Ignore; +import org.junit.Test; + +@Ignore("Manual test") +public class ServiceCallClientRouteTest extends CamelTestSupport { + + private JndiRegistry registry; + + @Override + protected JndiRegistry createRegistry() throws Exception { + registry = super.createRegistry(); + return registry; + } + + @Test + public void testServiceCall() throws Exception { + getMockEndpoint("mock:result").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + KubernetesConfigurationDefinition config = new KubernetesConfigurationDefinition(); + config.setMasterUrl("http://172.28.128.80:8080"); + config.setUsername("admin"); + config.setPassword("admin"); + config.setNamespace("default"); + config.setLookup("client"); + // lets use the built-in round robin (random is default) + config.setLoadBalancerRef("roundrobin"); + + // add the config to the registry so service call can use it + registry.bind("myConfig", config); + + from("direct:start") + .serviceCall("cdi-camel-jetty") + .serviceCall("cdi-camel-jetty") + .to("mock:result"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallEnvironmentRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallEnvironmentRouteTest.java b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallEnvironmentRouteTest.java new file mode 100644 index 0000000..6d4fa57 --- /dev/null +++ b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallEnvironmentRouteTest.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.kubernetes.processor; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.JndiRegistry; +import org.apache.camel.model.remote.KubernetesConfigurationDefinition; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Ignore; +import org.junit.Test; + +@Ignore("Manual test") +public class ServiceCallEnvironmentRouteTest extends CamelTestSupport { + + private JndiRegistry registry; + + @Override + protected JndiRegistry createRegistry() throws Exception { + registry = super.createRegistry(); + return registry; + } + + @Test + public void testServiceCall() throws Exception { + getMockEndpoint("mock:result").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + KubernetesConfigurationDefinition config = new KubernetesConfigurationDefinition(); + config.setLookup("environment"); + + // add the config to the registry so service call can use it + registry.bind("myConfig", config); + + from("direct:start") + .serviceCall("cdi-camel-jetty") + .serviceCall("cdi-camel-jetty") + .to("mock:result"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallRouteTest.java b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallRouteTest.java deleted file mode 100644 index b8bfdae..0000000 --- a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/ServiceCallRouteTest.java +++ /dev/null @@ -1,70 +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.kubernetes.processor; - -import org.apache.camel.RoutesBuilder; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.impl.JndiRegistry; -import org.apache.camel.model.remote.KubernetesConfigurationDefinition; -import org.apache.camel.test.junit4.CamelTestSupport; -import org.junit.Ignore; -import org.junit.Test; - -@Ignore("Manual test") -public class ServiceCallRouteTest extends CamelTestSupport { - - private JndiRegistry registry; - - @Override - protected JndiRegistry createRegistry() throws Exception { - registry = super.createRegistry(); - return registry; - } - - @Test - public void testServiceCall() throws Exception { - getMockEndpoint("mock:result").expectedMessageCount(1); - - template.sendBody("direct:start", "Hello World"); - - assertMockEndpointsSatisfied(); - } - - @Override - protected RoutesBuilder createRouteBuilder() throws Exception { - return new RouteBuilder() { - @Override - public void configure() throws Exception { - KubernetesConfigurationDefinition config = new KubernetesConfigurationDefinition(); - config.setMasterUrl("https://fabric8-master.vagrant.f8:8443"); - config.setUsername("admin"); - config.setPassword("admin"); - config.setNamespace("default"); - // lets use the built-in round robin (random is default) - config.setLoadBalancerRef("roundrobin"); - - // add the config to the registry so service call can use it - registry.bind("myConfig", config); - - from("direct:start") - .serviceCall("cdi-camel-jetty") - .serviceCall("cdi-camel-jetty") - .to("mock:result"); - } - }; - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.java b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.java new file mode 100644 index 0000000..3e8fcba3 --- /dev/null +++ b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.java @@ -0,0 +1,41 @@ +/** + * 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.kubernetes.processor; + +import org.apache.camel.test.spring.CamelSpringTestSupport; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +@Ignore("Manual test") +public class SpringServiceCallClientRouteTest extends CamelSpringTestSupport { + + @Override + protected AbstractApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.xml"); + } + + @Test + public void testServiceCall() throws Exception { + getMockEndpoint("mock:result").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.java b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.java new file mode 100644 index 0000000..bd09c31 --- /dev/null +++ b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.java @@ -0,0 +1,41 @@ +/** + * 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.kubernetes.processor; + +import org.apache.camel.test.spring.CamelSpringTestSupport; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.context.support.AbstractApplicationContext; +import org.springframework.context.support.ClassPathXmlApplicationContext; + +@Ignore("Manual test") +public class SpringServiceCallEnvironmentRouteTest extends CamelSpringTestSupport { + + @Override + protected AbstractApplicationContext createApplicationContext() { + return new ClassPathXmlApplicationContext("org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.xml"); + } + + @Test + public void testServiceCall() throws Exception { + getMockEndpoint("mock:result").expectedMessageCount(1); + + template.sendBody("direct:start", "Hello World"); + + assertMockEndpointsSatisfied(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.java b/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.java deleted file mode 100644 index 06fcb81..0000000 --- a/components/camel-kubernetes/src/test/java/org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.java +++ /dev/null @@ -1,41 +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.kubernetes.processor; - -import org.apache.camel.test.spring.CamelSpringTestSupport; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.context.support.AbstractApplicationContext; -import org.springframework.context.support.ClassPathXmlApplicationContext; - -@Ignore("Manual test") -public class SpringServiceCallRouteTest extends CamelSpringTestSupport { - - @Override - protected AbstractApplicationContext createApplicationContext() { - return new ClassPathXmlApplicationContext("org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.xml"); - } - - @Test - public void testServiceCall() throws Exception { - getMockEndpoint("mock:result").expectedMessageCount(1); - - template.sendBody("direct:start", "Hello World"); - - assertMockEndpointsSatisfied(); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.xml b/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.xml new file mode 100644 index 0000000..e9eda75 --- /dev/null +++ b/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallClientRouteTest.xml @@ -0,0 +1,39 @@ +<?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"> + + <!-- use client to lookup the service, which requires to setup a number of options --> + <kubernetesConfiguration id="myConfig" masterUrl="http://172.28.128.80:8080" lookup="client" + username="admin" password="admin" namespace="default" loadBalancerRef="roundrobin"/> + + <route> + <from uri="direct:start"/> + <serviceCall name="cdi-camel-jetty"/> + <serviceCall name="cdi-camel-jetty"/> + <to uri="mock:result"/> + </route> + </camelContext> + +</beans> http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.xml b/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.xml new file mode 100644 index 0000000..4546621 --- /dev/null +++ b/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallEnvironmentRouteTest.xml @@ -0,0 +1,38 @@ +<?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"> + + <!-- use environment variables to lookup the service --> + <kubernetesConfiguration id="myConfig" lookup="environment"/> + + <route> + <from uri="direct:start"/> + <serviceCall name="cdi-camel-jetty"/> + <serviceCall name="cdi-camel-jetty"/> + <to uri="mock:result"/> + </route> + </camelContext> + +</beans> http://git-wip-us.apache.org/repos/asf/camel/blob/3f61efcc/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.xml ---------------------------------------------------------------------- diff --git a/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.xml b/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.xml deleted file mode 100644 index efab9d1..0000000 --- a/components/camel-kubernetes/src/test/resources/org/apache/camel/component/kubernetes/processor/SpringServiceCallRouteTest.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?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"> - - <!-- service call configuration to use ribbon --> - <kubernetesConfiguration id="myConfig" masterUrl="https://fabric8-master.vagrant.f8:8443" - username="admin" password="admin" namespace="default" loadBalancerRef="roundrobin"/> - - <route> - <from uri="direct:start"/> - <serviceCall name="cdi-camel-jetty"/> - <serviceCall name="cdi-camel-jetty"/> - <to uri="mock:result"/> - </route> - </camelContext> - -</beans>