You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2016/05/23 08:05:02 UTC

[15/34] camel git commit: CAMEL-9683: Started on camel-ribbon

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 <da...@apache.org>
Authored: Wed Apr 27 15:16:29 2016 +0200
Committer: Claus Ibsen <da...@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