CAMEL-9683: Started on camel-ribbon
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/38b6c345 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/38b6c345 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/38b6c345 Branch: refs/heads/remoteServiceCall Commit: 38b6c345990e9ca11e3236526dbd054b7c641704 Parents: 6da5b41 Author: Claus Ibsen <davscl...@apache.org> Authored: Wed Apr 27 15:16:29 2016 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Mon May 23 09:25:59 2016 +0200 ---------------------------------------------------------------------- .../ServiceCallConfigurationDefinition.java | 2 +- .../camel/model/ServiceCallDefinition.java | 2 +- .../KubernetesServiceCallProcessor.java | 2 +- .../processor/ServiceCallRouteTest.java | 2 + components/camel-ribbon/pom.xml | 2 +- .../component/ribbon/RibbonConfiguration.java | 59 +++++ .../camel/component/ribbon/RibbonConstants.java | 25 +++ ...onDelegateServiceCallServerListStrategy.java | 85 -------- .../camel/component/ribbon/RibbonServer.java | 32 --- .../RibbonServiceCallServerListStrategy.java | 53 ----- .../ribbon/processor/RibbonLoadBalancer.java | 62 ++++++ .../processor/RibbonProcessorFactory.java | 174 +++++++++++++++ .../ribbon/processor/RibbonServer.java | 32 +++ .../processor/RibbonServiceCallProcessor.java | 215 +++++++++++++++++++ ...bbonServiceCallStaticServerListStrategy.java | 53 +++++ .../ribbon/processor/ServiceCallExpression.java | 92 ++++++++ .../apache/camel/model/ServiceCallDefinition | 18 ++ .../component/ribbon/RibbonServerListTest.java | 52 ----- .../RibbonServiceCallKubernetesRouteTest.java | 58 ----- .../ribbon/RibbonServiceCallRouteTest.java | 76 ------- .../ribbon/processor/RibbonServerListTest.java | 52 +++++ .../RibbonServiceCallKubernetesRouteTest.java | 58 +++++ .../processor/RibbonServiceCallRouteTest.java | 75 +++++++ .../src/test/resources/log4j.properties | 2 +- 24 files changed, 922 insertions(+), 361 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/camel-core/src/main/java/org/apache/camel/model/ServiceCallConfigurationDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/ServiceCallConfigurationDefinition.java b/camel-core/src/main/java/org/apache/camel/model/ServiceCallConfigurationDefinition.java index cda3338..34fe14d 100644 --- a/camel-core/src/main/java/org/apache/camel/model/ServiceCallConfigurationDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/ServiceCallConfigurationDefinition.java @@ -27,7 +27,7 @@ import org.apache.camel.spi.ServiceCallLoadBalancer; import org.apache.camel.spi.ServiceCallServerListStrategy; @Metadata(label = "eip,routing") -@XmlRootElement(name = "toServiceConfiguration") +@XmlRootElement(name = "serviceCallConfiguration") @XmlAccessorType(XmlAccessType.FIELD) public class ServiceCallConfigurationDefinition extends IdentifiedType { http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/camel-core/src/main/java/org/apache/camel/model/ServiceCallDefinition.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/model/ServiceCallDefinition.java b/camel-core/src/main/java/org/apache/camel/model/ServiceCallDefinition.java index 1bfb0b5..c276659 100644 --- a/camel-core/src/main/java/org/apache/camel/model/ServiceCallDefinition.java +++ b/camel-core/src/main/java/org/apache/camel/model/ServiceCallDefinition.java @@ -76,7 +76,7 @@ public class ServiceCallDefinition extends NoOutputDefinition<ServiceCallDefinit if (discovery != null) { throw new IllegalStateException("Cannot find Camel component on the classpath implementing the discovery provider: " + discovery); } else { - throw new IllegalStateException("Cannot find Camel component supporting the ToService EIP. Add camel-kubernetes if you are using Kubernetes."); + throw new IllegalStateException("Cannot find Camel component supporting the ServiceCall EIP such as camel-kubernetes or camel-ribbon."); } } http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/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 index 8900017..0cd0d74 100644 --- 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 @@ -120,7 +120,7 @@ public class KubernetesServiceCallProcessor extends ServiceSupport implements As KubernetesServer server = loadBalancer.chooseServer(servers); String ip = server.getIp(); int port = server.getPort(); - LOG.debug("Random selected service {} active at server: {}:{}", name, ip, port); + LOG.debug("Service {} active at server: {}:{}", name, ip, port); // set selected server as header exchange.getIn().setHeader(KubernetesConstants.KUBERNETES_SERVER_IP, ip); http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/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 index ae26cb6..054c2f6 100644 --- 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 @@ -49,6 +49,8 @@ public class ServiceCallRouteTest extends CamelTestSupport { config.setLoadBalancerRef("roundrobin"); from("direct:start") +// .serviceCall("cdi-camel-jetty", null, config) + .to("http:{{service:cdi-camel-jetty}}") .serviceCall("cdi-camel-jetty", null, config) .to("mock:result"); } http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/pom.xml b/components/camel-ribbon/pom.xml index f4be469..111826b 100644 --- a/components/camel-ribbon/pom.xml +++ b/components/camel-ribbon/pom.xml @@ -60,7 +60,7 @@ </dependency> <dependency> <groupId>org.apache.camel</groupId> - <artifactId>camel-kubernetes</artifactId> + <artifactId>camel-http</artifactId> <scope>test</scope> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java new file mode 100644 index 0000000..ead659e --- /dev/null +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConfiguration.java @@ -0,0 +1,59 @@ +/** + * 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.ribbon; + +import com.netflix.loadbalancer.IRule; + +public class RibbonConfiguration { + + private String namespace; + private String username; + private String password; + private IRule rule; + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public IRule getRule() { + return rule; + } + + public void setRule(IRule rule) { + this.rule = rule; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConstants.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConstants.java new file mode 100644 index 0000000..0a860cd --- /dev/null +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonConstants.java @@ -0,0 +1,25 @@ +/** + * 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.ribbon; + +public interface RibbonConstants { + + // Service Call EIP + String RIBBON_SERVER_IP = "CamelRibbonServerIp"; + String RIBBON_SERVER_PORT = "CamelRibbonServerPort"; + +} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonDelegateServiceCallServerListStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonDelegateServiceCallServerListStrategy.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonDelegateServiceCallServerListStrategy.java deleted file mode 100644 index 46f512a..0000000 --- a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonDelegateServiceCallServerListStrategy.java +++ /dev/null @@ -1,85 +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 - * <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.ribbon; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.AbstractServerList; -import com.netflix.loadbalancer.ServerList; -import org.apache.camel.spi.ServiceCallServer; -import org.apache.camel.spi.ServiceCallServerListStrategy; - -/** - * To let an existing {@link ServiceCallServerListStrategy} by managed by Ribbon. - */ -public class RibbonDelegateServiceCallServerListStrategy extends AbstractServerList<RibbonServer> implements ServerList<RibbonServer> { - - // TODO: a plain ribbon server list without plugin for kube for now - // and some unit tests with static server list etc - // https://github.com/Netflix/ribbon/wiki/Working-with-load-balancers - // https://github.com/Netflix/ribbon/wiki/Getting-Started - // then later with a kube facade so the servers are looked up in k8s - - private IClientConfig clientConfig; - private final ServiceCallServerListStrategy delegate; - - /** - * Lets ribbon manage the {@link ServiceCallServerListStrategy}. - */ - public RibbonDelegateServiceCallServerListStrategy(ServiceCallServerListStrategy delegate) { - this.delegate = delegate; - } - - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { - this.clientConfig = clientConfig; - } - - @Override - @SuppressWarnings("unchecked") - public List<RibbonServer> getInitialListOfServers() { - Collection<ServiceCallServer> servers = delegate.getInitialListOfServers(); - if (servers == null || servers.isEmpty()) { - return Collections.EMPTY_LIST; - } - List<RibbonServer> answer = new ArrayList<>(servers.size()); - for (ServiceCallServer server : servers) { - RibbonServer ribbon = new RibbonServer(server.getIp(), server.getPort()); - answer.add(ribbon); - } - return answer; - } - - @Override - @SuppressWarnings("unchecked") - public List<RibbonServer> getUpdatedListOfServers() { - Collection<ServiceCallServer> servers = delegate.getUpdatedListOfServers(); - if (servers == null || servers.isEmpty()) { - return Collections.EMPTY_LIST; - } - List<RibbonServer> answer = new ArrayList<>(servers.size()); - for (ServiceCallServer server : servers) { - RibbonServer ribbon = new RibbonServer(server.getIp(), server.getPort()); - answer.add(ribbon); - } - return answer; - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonServer.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonServer.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonServer.java deleted file mode 100644 index 0099975..0000000 --- a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonServer.java +++ /dev/null @@ -1,32 +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 - * <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.ribbon; - -import com.netflix.loadbalancer.Server; -import org.apache.camel.spi.ServiceCallServer; - -public class RibbonServer extends Server implements ServiceCallServer { - - public RibbonServer(String host, int port) { - super(host, port); - } - - @Override - public String getIp() { - return getHost(); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonServiceCallServerListStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonServiceCallServerListStrategy.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonServiceCallServerListStrategy.java deleted file mode 100644 index 848f9db..0000000 --- a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/RibbonServiceCallServerListStrategy.java +++ /dev/null @@ -1,53 +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 - * <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.ribbon; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.AbstractServerList; -import com.netflix.loadbalancer.ServerList; -import org.apache.camel.spi.ServiceCallServerListStrategy; - -public class RibbonServiceCallServerListStrategy extends AbstractServerList<RibbonServer> implements ServerList<RibbonServer>, ServiceCallServerListStrategy<RibbonServer> { - - private IClientConfig clientConfig; - private final List<RibbonServer> servers = new ArrayList<>(); - - public RibbonServiceCallServerListStrategy() { - } - - public RibbonServiceCallServerListStrategy(List<RibbonServer> servers) { - this.servers.addAll(servers); - } - - @Override - public void initWithNiwsConfig(IClientConfig clientConfig) { - this.clientConfig = clientConfig; - } - - @Override - public List<RibbonServer> getInitialListOfServers() { - return servers; - } - - @Override - public List<RibbonServer> getUpdatedListOfServers() { - return servers; - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonLoadBalancer.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonLoadBalancer.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonLoadBalancer.java new file mode 100644 index 0000000..80ab086 --- /dev/null +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonLoadBalancer.java @@ -0,0 +1,62 @@ +/** + * 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.ribbon.processor; + +import java.util.Collection; + +import com.netflix.loadbalancer.ILoadBalancer; +import com.netflix.loadbalancer.IRule; +import com.netflix.loadbalancer.Server; +import org.apache.camel.spi.ServiceCallLoadBalancer; + +/** + * Ribbon {@link IRule} based load balancer. + */ +@Deprecated +public class RibbonLoadBalancer implements ServiceCallLoadBalancer<RibbonServer>, IRule { + + private final IRule rule; + + public RibbonLoadBalancer(IRule rule) { + this.rule = rule; + } + + @Override + public RibbonServer chooseServer(Collection<RibbonServer> servers) { + Server server = choose(null); + if (server != null) { + return new RibbonServer(server.getHost(), server.getPort()); + } else { + return null; + } + } + + @Override + public Server choose(Object key) { + return rule.choose(key); + } + + @Override + public void setLoadBalancer(ILoadBalancer lb) { + rule.setLoadBalancer(lb); + } + + @Override + public ILoadBalancer getLoadBalancer() { + return rule.getLoadBalancer(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonProcessorFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonProcessorFactory.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonProcessorFactory.java new file mode 100644 index 0000000..efeb2e8 --- /dev/null +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonProcessorFactory.java @@ -0,0 +1,174 @@ +/** + * 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.ribbon.processor; + +import java.util.HashMap; +import java.util.Map; + +import com.netflix.loadbalancer.RandomRule; +import com.netflix.loadbalancer.RoundRobinRule; +import org.apache.camel.ExchangePattern; +import org.apache.camel.Processor; +import org.apache.camel.component.ribbon.RibbonConfiguration; +import org.apache.camel.model.ProcessorDefinition; +import org.apache.camel.model.ServiceCallConfigurationDefinition; +import org.apache.camel.model.ServiceCallDefinition; +import org.apache.camel.spi.ProcessorFactory; +import org.apache.camel.spi.RouteContext; +import org.apache.camel.spi.ServiceCallLoadBalancer; +import org.apache.camel.spi.ServiceCallServerListStrategy; +import org.apache.camel.util.CamelContextHelper; +import org.apache.camel.util.IntrospectionSupport; + +/** + * {@link ProcessorFactory} that creates the Ribbon implementation of the ServiceCall EIP. + */ +public class RibbonProcessorFactory implements ProcessorFactory { + + @Override + public Processor createChildProcessor(RouteContext routeContext, ProcessorDefinition<?> definition, boolean mandatory) throws Exception { + // not in use + return null; + } + + @Override + @SuppressWarnings("unchecked") + public Processor createProcessor(RouteContext routeContext, ProcessorDefinition<?> definition) throws Exception { + if (definition instanceof ServiceCallDefinition) { + ServiceCallDefinition sc = (ServiceCallDefinition) definition; + + // discovery must either not be set, or if set then must be us + if (sc.getDiscovery() != null && !"ribbon".equals(sc.getDiscovery())) { + return null; + } + + String name = sc.getName(); + String namespace = sc.getNamespace(); + String uri = sc.getUri(); + ExchangePattern mep = sc.getPattern(); + + ServiceCallConfigurationDefinition config = sc.getServiceCallConfiguration(); + ServiceCallConfigurationDefinition configRef = null; + if (sc.getServiceCallConfigurationRef() != null) { + configRef = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), sc.getServiceCallConfigurationRef(), ServiceCallConfigurationDefinition.class); + } + + // extract the properties from the configuration from the model + Map<String, Object> parameters = new HashMap<>(); + if (configRef != null) { + IntrospectionSupport.getProperties(configRef, parameters, null); + } + if (config != null) { + IntrospectionSupport.getProperties(config, parameters, null); + } + // and set them on the kubernetes configuration class + RibbonConfiguration rc = new RibbonConfiguration(); + IntrospectionSupport.setProperties(rc, parameters); + + // use namespace from config if not provided + if (namespace == null) { + namespace = rc.getNamespace(); + } + + // lookup the load balancer to use (configured on EIP takes precedence vs configured on configuration) + ServiceCallLoadBalancer lb = configureLoadBalancer(routeContext, sc); + if (lb == null && config != null) { + lb = configureLoadBalancer(routeContext, config); + } + if (lb == null && configRef != null) { + lb = configureLoadBalancer(routeContext, configRef); + } + + // lookup the server list strategy to use (configured on EIP takes precedence vs configured on configuration) + ServiceCallServerListStrategy sl = configureServerListStrategy(routeContext, sc); + if (sl == null && config != null) { + sl = configureServerListStrategy(routeContext, config); + } + if (sl == null && configRef != null) { + sl = configureServerListStrategy(routeContext, configRef); + } + + RibbonServiceCallProcessor processor = new RibbonServiceCallProcessor(name, namespace, uri, mep, rc); + processor.setLoadBalancer(lb); + processor.setServerListStrategy(sl); + return processor; + } else { + return null; + } + } + + private ServiceCallLoadBalancer configureLoadBalancer(RouteContext routeContext, ServiceCallDefinition sd) { + ServiceCallLoadBalancer lb = null; + + if (sd != null) { + lb = sd.getLoadBalancer(); + if (lb == null && sd.getLoadBalancerRef() != null) { + String ref = sd.getLoadBalancerRef(); + // special for ref is referring to built-in + if ("random".equalsIgnoreCase(ref)) { + lb = new RibbonLoadBalancer(new RandomRule()); + } else if ("roundrobin".equalsIgnoreCase(ref)) { + lb = new RibbonLoadBalancer(new RoundRobinRule()); + } else { + lb = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), ref, ServiceCallLoadBalancer.class); + } + } + } + + return lb; + } + + private ServiceCallLoadBalancer configureLoadBalancer(RouteContext routeContext, ServiceCallConfigurationDefinition config) { + ServiceCallLoadBalancer lb = config.getLoadBalancer(); + if (lb == null && config.getLoadBalancerRef() != null) { + String ref = config.getLoadBalancerRef(); + // special for ref is referring to built-in + if ("random".equalsIgnoreCase(ref)) { + lb = new RibbonLoadBalancer(new RandomRule()); + } else if ("roundrobin".equalsIgnoreCase(ref)) { + lb = new RibbonLoadBalancer(new RoundRobinRule()); + } else { + lb = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), ref, ServiceCallLoadBalancer.class); + } + } + return lb; + } + + private ServiceCallServerListStrategy configureServerListStrategy(RouteContext routeContext, ServiceCallDefinition sd) { + ServiceCallServerListStrategy lb = null; + + if (sd != null) { + lb = sd.getServerListStrategy(); + if (lb == null && sd.getServerListStrategyRef() != null) { + lb = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), sd.getServerListStrategyRef(), ServiceCallServerListStrategy.class); + } + } + + return lb; + } + + private ServiceCallServerListStrategy configureServerListStrategy(RouteContext routeContext, ServiceCallConfigurationDefinition config) { + ServiceCallServerListStrategy lb = config.getServerListStrategy(); + if (lb == null && config.getServerListStrategyRef() != null) { + String ref = config.getServerListStrategyRef(); + lb = CamelContextHelper.mandatoryLookup(routeContext.getCamelContext(), ref, ServiceCallServerListStrategy.class); + } + return lb; + } + +} + http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServer.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServer.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServer.java new file mode 100644 index 0000000..83233a2 --- /dev/null +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServer.java @@ -0,0 +1,32 @@ +/** + * 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.ribbon.processor; + +import com.netflix.loadbalancer.Server; +import org.apache.camel.spi.ServiceCallServer; + +public class RibbonServer extends Server implements ServiceCallServer { + + public RibbonServer(String host, int port) { + super(host, port); + } + + @Override + public String getIp() { + return getHost(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallProcessor.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallProcessor.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallProcessor.java new file mode 100644 index 0000000..ad74c1d --- /dev/null +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallProcessor.java @@ -0,0 +1,215 @@ +/** + * 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.ribbon.processor; + +import java.util.concurrent.RejectedExecutionException; + +import com.netflix.loadbalancer.IRule; +import com.netflix.loadbalancer.LoadBalancerBuilder; +import com.netflix.loadbalancer.RoundRobinRule; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; +import com.netflix.loadbalancer.ZoneAwareLoadBalancer; +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.ribbon.RibbonConfiguration; +import org.apache.camel.component.ribbon.RibbonConstants; +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; + +/** + * Ribbon based implementation of the the ServiceCall EIP. + */ +public class RibbonServiceCallProcessor extends ServiceSupport implements AsyncProcessor, CamelContextAware, Traceable, IdAware { + + private static final Logger LOG = LoggerFactory.getLogger(RibbonServiceCallProcessor.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 RibbonConfiguration configuration; + private ServiceCallServerListStrategy<RibbonServer> serverListStrategy; + private ServiceCallLoadBalancer<RibbonServer> loadBalancer; + private ZoneAwareLoadBalancer<RibbonServer> ribbonLoadBalancer; + private IRule rule; + private final ServiceCallExpression serviceCallExpression; + private SendDynamicProcessor processor; + + // TODO: allow to plugin custom load balancer like ribbon + + public RibbonServiceCallProcessor(String name, String namespace, String uri, ExchangePattern exchangePattern, RibbonConfiguration 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 ServiceCallExpression(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) { + Server server = null; + try { + // let the client load balancer chose which server to use + server = ribbonLoadBalancer.chooseServer(); + if (server == null) { + 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; + } + + String ip = server.getHost(); + int port = server.getPort(); + LOG.debug("Service {} active at server: {}:{}", name, ip, port); + + // set selected server as header + exchange.getIn().setHeader(RibbonConstants.RIBBON_SERVER_IP, ip); + exchange.getIn().setHeader(RibbonConstants.RIBBON_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<RibbonServer> getLoadBalancer() { + return loadBalancer; + } + + public void setLoadBalancer(ServiceCallLoadBalancer<RibbonServer> loadBalancer) { + this.loadBalancer = loadBalancer; + } + + public ServiceCallServerListStrategy getServerListStrategy() { + return serverListStrategy; + } + + public void setServerListStrategy(ServiceCallServerListStrategy serverListStrategy) { + this.serverListStrategy = serverListStrategy; + } + + @Override + @SuppressWarnings("unchecked") + protected void doStart() throws Exception { + ObjectHelper.notEmpty(name, "name", this); + + if (serverListStrategy == null) { + serverListStrategy = new RibbonServiceCallStaticServerListStrategy(); + } + + if (!(serverListStrategy instanceof ServerList)) { + throw new IllegalArgumentException("ServerListStrategy must be instanceof com.netflix.loadbalancer.ServerList but is of type: " + serverListStrategy.getClass().getName()); + } + + if (rule == null) { + // use round robin rule by default + rule = new RoundRobinRule(); + } + + ribbonLoadBalancer = LoadBalancerBuilder.<RibbonServer>newBuilder() + .withDynamicServerList((ServerList<RibbonServer>) serverListStrategy) + .withRule(rule) + .buildDynamicServerListLoadBalancer(); + + LOG.info("RibbonServiceCall at namespace: {} with service name: {} is using load balancer: {} and service discovery: {}", namespace, name, ribbonLoadBalancer, 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); + } + +} + http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallStaticServerListStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallStaticServerListStrategy.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallStaticServerListStrategy.java new file mode 100644 index 0000000..3b090fe --- /dev/null +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallStaticServerListStrategy.java @@ -0,0 +1,53 @@ +/** + * 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.ribbon.processor; + +import java.util.ArrayList; +import java.util.List; + +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.AbstractServerList; +import com.netflix.loadbalancer.ServerList; +import org.apache.camel.spi.ServiceCallServerListStrategy; + +public class RibbonServiceCallStaticServerListStrategy extends AbstractServerList<RibbonServer> implements ServerList<RibbonServer>, ServiceCallServerListStrategy<RibbonServer> { + + private IClientConfig clientConfig; + private final List<RibbonServer> servers = new ArrayList<>(); + + public RibbonServiceCallStaticServerListStrategy() { + } + + public RibbonServiceCallStaticServerListStrategy(List<RibbonServer> servers) { + this.servers.addAll(servers); + } + + @Override + public void initWithNiwsConfig(IClientConfig clientConfig) { + this.clientConfig = clientConfig; + } + + @Override + public List<RibbonServer> getInitialListOfServers() { + return servers; + } + + @Override + public List<RibbonServer> getUpdatedListOfServers() { + return servers; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/ServiceCallExpression.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/ServiceCallExpression.java b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/ServiceCallExpression.java new file mode 100644 index 0000000..12dbdf4 --- /dev/null +++ b/components/camel-ribbon/src/main/java/org/apache/camel/component/ribbon/processor/ServiceCallExpression.java @@ -0,0 +1,92 @@ +/** + * 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.ribbon.processor; + +import org.apache.camel.Exchange; +import org.apache.camel.component.ribbon.RibbonConstants; +import org.apache.camel.support.ExpressionAdapter; +import org.apache.camel.util.ExchangeHelper; +import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ServiceCallExpression extends ExpressionAdapter { + + private static final Logger LOG = LoggerFactory.getLogger(ServiceCallExpression.class); + + private final String name; + private final String scheme; + private final String contextPath; + private final String uri; + + public ServiceCallExpression(String name, String scheme, String contextPath, String uri) { + this.name = name; + this.scheme = scheme; + this.contextPath = contextPath; + this.uri = uri; + } + + @Override + public Object evaluate(Exchange exchange) { + try { + String ip = ExchangeHelper.getMandatoryHeader(exchange, RibbonConstants.RIBBON_SERVER_IP, String.class); + int port = ExchangeHelper.getMandatoryHeader(exchange, RibbonConstants.RIBBON_SERVER_PORT, int.class); + return buildCamelEndpointUri(ip, port, name, uri, contextPath, scheme); + } catch (Exception e) { + throw ObjectHelper.wrapRuntimeCamelException(e); + } + } + + 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) { + if (port == 443) { + scheme = "https"; + } else { + scheme = "http"; + } + } + answer = scheme + "://" + ip + ":" + port; + if (contextPath != null) { + answer += "" + contextPath; + } + } else { + // we have existing uri, then replace the serviceName with ip:port + if (answer.contains(name + ".host")) { + answer = answer.replaceFirst(name + "\\.host", ip); + } + if (answer.contains(name + ".port")) { + answer = answer.replaceFirst(name + "\\.port", "" + port); + } + if (answer.contains(name)) { + answer = answer.replaceFirst(name, ip + ":" + port); + } + } + + LOG.debug("Camel endpoint uri: {} for calling service: {} + on server {}:{}", answer, name, ip, port); + return answer; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/main/resources/META-INF/services/org/apache/camel/model/ServiceCallDefinition ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/main/resources/META-INF/services/org/apache/camel/model/ServiceCallDefinition b/components/camel-ribbon/src/main/resources/META-INF/services/org/apache/camel/model/ServiceCallDefinition new file mode 100644 index 0000000..5642951 --- /dev/null +++ b/components/camel-ribbon/src/main/resources/META-INF/services/org/apache/camel/model/ServiceCallDefinition @@ -0,0 +1,18 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +class=org.apache.camel.component.ribbon.processor.RibbonProcessorFactory http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServerListTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServerListTest.java b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServerListTest.java deleted file mode 100644 index 8fb96ff..0000000 --- a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServerListTest.java +++ /dev/null @@ -1,52 +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 - * <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.ribbon; - -import java.util.ArrayList; -import java.util.List; - -import com.netflix.loadbalancer.LoadBalancerBuilder; -import com.netflix.loadbalancer.RoundRobinRule; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import com.netflix.loadbalancer.ZoneAwareLoadBalancer; -import junit.framework.TestCase; -import org.junit.Test; - -public class RibbonServerListTest extends TestCase { - - @Test - public void testFixedServerList() throws Exception { - List<RibbonServer> servers = new ArrayList(); - servers.add(new RibbonServer("localhost", 9090)); - servers.add(new RibbonServer("localhost", 9091)); - - ServerList<RibbonServer> list = new RibbonServiceCallServerListStrategy(servers); - - ZoneAwareLoadBalancer<RibbonServer> lb = LoadBalancerBuilder.<RibbonServer>newBuilder() - .withDynamicServerList(list) - .withRule(new RoundRobinRule()).buildDynamicServerListLoadBalancer(); - - Server server = lb.chooseServer(); - assertEquals("localhost", server.getHost()); - assertEquals(9091, server.getPort()); - - server = lb.chooseServer(); - assertEquals("localhost", server.getHost()); - assertEquals(9090, server.getPort()); - } -} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServiceCallKubernetesRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServiceCallKubernetesRouteTest.java b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServiceCallKubernetesRouteTest.java deleted file mode 100644 index be0567f..0000000 --- a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServiceCallKubernetesRouteTest.java +++ /dev/null @@ -1,58 +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 - * <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.ribbon; - -import org.apache.camel.RoutesBuilder; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.model.ServiceCallConfigurationDefinition; -import org.apache.camel.test.junit4.CamelTestSupport; -import org.junit.Ignore; -import org.junit.Test; - -@Ignore("Manual test") -public class RibbonServiceCallKubernetesRouteTest extends CamelTestSupport { - - @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 { - ServiceCallConfigurationDefinition config = new ServiceCallConfigurationDefinition(); - 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"); - - from("direct:start") - .serviceCall("cdi-camel-jetty", null, config) - .to("mock:result"); - } - }; - } -} - http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServiceCallRouteTest.java b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServiceCallRouteTest.java deleted file mode 100644 index f8c5c06..0000000 --- a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/RibbonServiceCallRouteTest.java +++ /dev/null @@ -1,76 +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 - * <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.ribbon; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.camel.RoutesBuilder; -import org.apache.camel.builder.RouteBuilder; -import org.apache.camel.model.ServiceCallConfigurationDefinition; -import org.apache.camel.test.junit4.CamelTestSupport; -import org.junit.Test; - -public class RibbonServiceCallRouteTest extends CamelTestSupport { - - @Test - public void testServiceCall() throws Exception { - getMockEndpoint("mock:9090").expectedMessageCount(1); - getMockEndpoint("mock:9091").expectedMessageCount(1); - getMockEndpoint("mock:result").expectedMessageCount(2); - - String out = template.requestBody("direct:start", null, String.class); - String out2 = template.requestBody("direct:start", null, String.class); - assertEquals("9091", out); - assertEquals("9090", out2); - - assertMockEndpointsSatisfied(); - } - - @Override - protected RoutesBuilder createRouteBuilder() throws Exception { - return new RouteBuilder() { - @Override - public void configure() throws Exception { - // setup a static ribbon server list - List<RibbonServer> servers = new ArrayList<>(); - servers.add(new RibbonServer("localhost", 9090)); - servers.add(new RibbonServer("localhost", 9091)); - RibbonServiceCallServerListStrategy list = new RibbonServiceCallServerListStrategy(servers); - - - - // configure camel service call - ServiceCallConfigurationDefinition config = new ServiceCallConfigurationDefinition(); - config.setServerListStrategy(list); - - from("direct:start") - .serviceCall("cdi-camel-jetty", null, config) - .to("mock:result"); - - from("jetty:http://localhost:9090") - .to("mock:9090") - .transform().constant("9090"); - - from("jetty:http://localhost:9091") - .to("mock:9091") - .transform().constant("9091"); - } - }; - } -} - http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServerListTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServerListTest.java b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServerListTest.java new file mode 100644 index 0000000..38ea4d1 --- /dev/null +++ b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServerListTest.java @@ -0,0 +1,52 @@ +/** + * 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.ribbon.processor; + +import java.util.ArrayList; +import java.util.List; + +import com.netflix.loadbalancer.LoadBalancerBuilder; +import com.netflix.loadbalancer.RoundRobinRule; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; +import com.netflix.loadbalancer.ZoneAwareLoadBalancer; +import junit.framework.TestCase; +import org.junit.Test; + +public class RibbonServerListTest extends TestCase { + + @Test + public void testFixedServerList() throws Exception { + List<RibbonServer> servers = new ArrayList(); + servers.add(new RibbonServer("localhost", 9090)); + servers.add(new RibbonServer("localhost", 9091)); + + ServerList<RibbonServer> list = new RibbonServiceCallStaticServerListStrategy(servers); + + ZoneAwareLoadBalancer<RibbonServer> lb = LoadBalancerBuilder.<RibbonServer>newBuilder() + .withDynamicServerList(list) + .withRule(new RoundRobinRule()).buildDynamicServerListLoadBalancer(); + + Server server = lb.chooseServer(); + assertEquals("localhost", server.getHost()); + assertEquals(9091, server.getPort()); + + server = lb.chooseServer(); + assertEquals("localhost", server.getHost()); + assertEquals(9090, server.getPort()); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallKubernetesRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallKubernetesRouteTest.java b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallKubernetesRouteTest.java new file mode 100644 index 0000000..97fe567 --- /dev/null +++ b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallKubernetesRouteTest.java @@ -0,0 +1,58 @@ +/** + * 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.ribbon.processor; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.ServiceCallConfigurationDefinition; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Ignore; +import org.junit.Test; + +@Ignore("Manual test") +public class RibbonServiceCallKubernetesRouteTest extends CamelTestSupport { + + @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 { + ServiceCallConfigurationDefinition config = new ServiceCallConfigurationDefinition(); + 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"); + + from("direct:start") + .serviceCall("cdi-camel-jetty", null, config) + .to("mock:result"); + } + }; + } +} + http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallRouteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallRouteTest.java b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallRouteTest.java new file mode 100644 index 0000000..e58f7c6 --- /dev/null +++ b/components/camel-ribbon/src/test/java/org/apache/camel/component/ribbon/processor/RibbonServiceCallRouteTest.java @@ -0,0 +1,75 @@ +/** + * 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.ribbon.processor; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.ServiceCallConfigurationDefinition; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class RibbonServiceCallRouteTest extends CamelTestSupport { + + @Test + public void testServiceCall() throws Exception { + getMockEndpoint("mock:9090").expectedMessageCount(1); + getMockEndpoint("mock:9091").expectedMessageCount(1); + getMockEndpoint("mock:result").expectedMessageCount(2); + + String out = template.requestBody("direct:start", null, String.class); + String out2 = template.requestBody("direct:start", null, String.class); + assertEquals("9091", out); + assertEquals("9090", out2); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + // setup a static ribbon server list with these 2 servers to start with + List<RibbonServer> servers = new ArrayList<>(); + servers.add(new RibbonServer("localhost", 9090)); + servers.add(new RibbonServer("localhost", 9091)); + RibbonServiceCallStaticServerListStrategy list = new RibbonServiceCallStaticServerListStrategy(servers); + + // configure camel service call + ServiceCallConfigurationDefinition config = new ServiceCallConfigurationDefinition(); + config.setServerListStrategy(list); +// config.setLoadBalancerRef("roundrobin"); + + from("direct:start") + .serviceCall("myService", null, config) + .to("mock:result"); + + from("jetty:http://localhost:9090") + .to("mock:9090") + .transform().constant("9090"); + + from("jetty:http://localhost:9091") + .to("mock:9091") + .transform().constant("9091"); + } + }; + } +} + http://git-wip-us.apache.org/repos/asf/camel/blob/38b6c345/components/camel-ribbon/src/test/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/components/camel-ribbon/src/test/resources/log4j.properties b/components/camel-ribbon/src/test/resources/log4j.properties index f138e1d..98c945f 100644 --- a/components/camel-ribbon/src/test/resources/log4j.properties +++ b/components/camel-ribbon/src/test/resources/log4j.properties @@ -18,7 +18,7 @@ # # The logging properties used # -log4j.rootLogger=INFO, file +log4j.rootLogger=INFO, out log4j.logger.org.apache.camel.component.kubernetes=DEBUG log4j.logger.org.apache.camel.component.ribbon=DEBUG