You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by nf...@apache.org on 2018/12/03 13:12:14 UTC

[camel-k] 01/03: chore: support for computing knative channel/service host name from uri

This is an automated email from the ASF dual-hosted git repository.

nferraro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 76e46c9703f6fbc74547b8e46685eda0520cd409
Author: lburgazzoli <lb...@gmail.com>
AuthorDate: Thu Nov 29 16:23:18 2018 +0100

    chore: support for computing knative channel/service host name from uri
---
 .../src/test/resources/log4j2-test.xml             |   4 +-
 .../apache/camel/component/knative/Knative.java    |   1 +
 .../camel/component/knative/KnativeComponent.java  |   1 -
 .../component/knative/KnativeConfiguration.java    |   5 -
 .../camel/component/knative/KnativeEndpoint.java   |  45 +++++--
 .../component/knative/KnativeEnvironment.java      |  26 ++++
 .../camel/component/knative/KnativeSupport.java    |  13 ++
 .../component/knative/KnativeComponentMain.java    |  89 -------------
 .../component/knative/KnativeComponentTest.java    | 139 ++++++++++++++++++++-
 .../src/test/resources/log4j2-test.xml             |   4 +-
 10 files changed, 214 insertions(+), 113 deletions(-)

diff --git a/runtime/camel-knative-http/src/test/resources/log4j2-test.xml b/runtime/camel-knative-http/src/test/resources/log4j2-test.xml
index 403c946..b31e8b4 100644
--- a/runtime/camel-knative-http/src/test/resources/log4j2-test.xml
+++ b/runtime/camel-knative-http/src/test/resources/log4j2-test.xml
@@ -9,10 +9,10 @@
 
   <Loggers>
     <Root level="INFO">
-      <AppenderRef ref="STDOUT"/>
       <!--
-      <AppenderRef ref="NONE"/>
+      <AppenderRef ref="STDOUT"/>
       -->
+      <AppenderRef ref="NONE"/>
     </Root>
   </Loggers>
 
diff --git a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/Knative.java b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/Knative.java
index 4ea19d4..ce701ef 100644
--- a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/Knative.java
+++ b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/Knative.java
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
 public final class Knative {
     public static final ObjectMapper MAPPER = new ObjectMapper().registerModule(new Jdk8Module());
 
+
     public static final String HTTP_COMPONENT = "knative-http";
     public static final String KNATIVE_PROTOCOL = "knative.protocol";
     public static final String KNATIVE_TYPE = "knative.type";
diff --git a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeComponent.java b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeComponent.java
index 496a71a..0767fda 100644
--- a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeComponent.java
+++ b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeComponent.java
@@ -22,7 +22,6 @@ import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.impl.DefaultComponent;
 import org.apache.camel.util.IntrospectionSupport;
-import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
 
 public class KnativeComponent extends DefaultComponent {
diff --git a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeConfiguration.java b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeConfiguration.java
index f3b0472..cc3fa65 100644
--- a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeConfiguration.java
+++ b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeConfiguration.java
@@ -17,14 +17,9 @@
 package org.apache.camel.component.knative;
 
 import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.cloud.ServiceDefinition;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriParam;
 
-import java.util.Arrays;
-
-import static org.apache.camel.util.CollectionHelper.mapOf;
-
 public class KnativeConfiguration implements Cloneable {
     @UriParam
     @Metadata(required = "true")
diff --git a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEndpoint.java b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEndpoint.java
index ce50beb..10f264c 100644
--- a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEndpoint.java
+++ b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEndpoint.java
@@ -20,6 +20,7 @@ import java.io.InputStream;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
@@ -37,7 +38,6 @@ import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.UriEndpoint;
 import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.UriPath;
-import org.apache.camel.util.CollectionHelper;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ServiceHelper;
 import org.apache.camel.util.StringHelper;
@@ -76,7 +76,7 @@ public class KnativeEndpoint extends DefaultEndpoint implements DelegateEndpoint
         this.name = remaining.indexOf('/') != -1 ? StringHelper.before(remaining, "/") : remaining;
         this.configuration = configuration;
         this.environment =  this.configuration.getEnvironment();
-        this.service = this.environment.mandatoryLookupService(targetType, remaining);
+        this.service = this.environment.lookupServiceOrDefault(targetType, remaining);
 
         switch (service.getProtocol()) {
         case http:
@@ -205,10 +205,29 @@ public class KnativeEndpoint extends DefaultEndpoint implements DelegateEndpoint
 
     private static Endpoint http(CamelContext context, ServiceDefinition definition) {
         try {
-            final String host = definition.getHost();
-            final int port = definition.getPort();
             final String scheme = Knative.HTTP_COMPONENT;
-            final String protocol = definition.getMetadata().get(Knative.KNATIVE_PROTOCOL);
+            final String protocol = definition.getMetadata().getOrDefault(Knative.KNATIVE_PROTOCOL, "http");
+
+            String host = definition.getHost();
+            int port = definition.getPort();
+
+            if (ObjectHelper.isEmpty(host)) {
+                String name = definition.getName();
+                String zone = definition.getMetadata().get(ServiceDefinition.SERVICE_META_ZONE);
+
+                if (ObjectHelper.isNotEmpty(zone)) {
+                    try {
+                        zone = context.resolvePropertyPlaceholders(zone);
+                    } catch (IllegalArgumentException e) {
+                        zone = null;
+                    }
+                }
+                if (ObjectHelper.isNotEmpty(zone)) {
+                    name = name + "." + zone;
+                }
+
+                host = name;
+            }
 
             ObjectHelper.notNull(host, ServiceDefinition.SERVICE_META_HOST);
             ObjectHelper.notNull(protocol, Knative.KNATIVE_PROTOCOL);
@@ -229,18 +248,18 @@ public class KnativeEndpoint extends DefaultEndpoint implements DelegateEndpoint
 
             final String filterKey = definition.getMetadata().get(Knative.FILTER_HEADER_NAME);
             final String filterVal = definition.getMetadata().get(Knative.FILTER_HEADER_VALUE);
+            final Map<String, Object> parameters = new HashMap<>();
 
             if (ObjectHelper.isNotEmpty(filterKey) && ObjectHelper.isNotEmpty(filterVal)) {
-                uri = URISupport.appendParametersToURI(
-                    uri,
-                    CollectionHelper.mapOf("filter.headerName", filterKey, "filter.headerValue", filterVal)
-                );
+                parameters.put("filter.headerName", filterKey);
+                parameters.put("filter.headerValue", filterVal);
             }
 
-            uri = URISupport.appendParametersToURI(
-                    uri,
-                    CollectionHelper.mapOf("useRelativePath", "true")
-            );
+            // configure netty to use relative path instead of full
+            // path that is the default to make istio working
+            parameters.put("useRelativePath", "true");
+
+            uri = URISupport.appendParametersToURI(uri, parameters);
 
             return context.getEndpoint(uri);
         } catch (Exception e) {
diff --git a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEnvironment.java b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEnvironment.java
index 9ec4406..e133f4b 100644
--- a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEnvironment.java
+++ b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeEnvironment.java
@@ -21,6 +21,7 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -93,6 +94,31 @@ public class KnativeEnvironment {
         );
     }
 
+
+    public KnativeServiceDefinition lookupServiceOrDefault(Knative.Type type, String name) {
+        return lookupService(type, name).orElseGet(() -> {
+            final String contextPath = StringHelper.after(name, "/");
+            final String serviceName = (contextPath == null) ? name : StringHelper.before(name, "/");
+            final Map<String, String> meta = new HashMap<>();
+
+            // namespace derived by default from env var
+            meta.put(ServiceDefinition.SERVICE_META_ZONE, "{{env:NAMESPACE}}");
+
+            if (contextPath != null) {
+                meta.put(ServiceDefinition.SERVICE_META_PATH, "/" + contextPath);
+            }
+
+            return new KnativeEnvironment.KnativeServiceDefinition(
+                type,
+                Knative.Protocol.http,
+                serviceName,
+                "",
+                -1,
+                meta
+            );
+        });
+    }
+
     // ************************
     //
     // Helpers
diff --git a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeSupport.java b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeSupport.java
index 9c6c049..f84ac46 100644
--- a/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeSupport.java
+++ b/runtime/camel-knative/src/main/java/org/apache/camel/component/knative/KnativeSupport.java
@@ -16,11 +16,15 @@
  */
 package org.apache.camel.component.knative;
 
+import java.io.UnsupportedEncodingException;
+import java.net.URISyntaxException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
 import org.apache.camel.Exchange;
+import org.apache.camel.util.CollectionHelper;
+import org.apache.camel.util.URISupport;
 
 public final class KnativeSupport {
     private KnativeSupport() {
@@ -43,4 +47,13 @@ public final class KnativeSupport {
 
         return answer;
     }
+
+    public static String appendParametersToURI(String uri, String key, Object value, Object... keyVals)
+            throws UnsupportedEncodingException, URISyntaxException {
+
+        return URISupport.appendParametersToURI(
+            uri,
+            CollectionHelper.mapOf(key, value, keyVals)
+        );
+    }
 }
diff --git a/runtime/camel-knative/src/test/java/org/apache/camel/component/knative/KnativeComponentMain.java b/runtime/camel-knative/src/test/java/org/apache/camel/component/knative/KnativeComponentMain.java
deleted file mode 100644
index b983695..0000000
--- a/runtime/camel-knative/src/test/java/org/apache/camel/component/knative/KnativeComponentMain.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.knative;
-
-import java.util.Arrays;
-
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.impl.DefaultCamelContext;
-import org.apache.camel.impl.SimpleRegistry;
-
-import static org.apache.camel.util.CollectionHelper.mapOf;
-
-public class KnativeComponentMain {
-    public static void main(String[] args) throws Exception {
-        KnativeComponent component = new KnativeComponent();
-        component.setEnvironment(newEnv());
-
-        SimpleRegistry registry = new SimpleRegistry();
-        registry.put("knative", component);
-
-        DefaultCamelContext context = new DefaultCamelContext(registry);
-
-        try {
-            context.disableJMX();
-            context.addRoutes(new RouteBuilder() {
-                @Override
-                public void configure() throws Exception {
-                    from("knative:endpoint/ep1")
-                        .convertBodyTo(String.class)
-                        .to("log:ep1?showAll=true&multiline=true")
-                        .setBody().constant("Hello from CH1");
-                    from("knative:endpoint/ep2")
-                        .convertBodyTo(String.class)
-                        .to("log:ep2?showAll=true&multiline=true")
-                        .setBody().constant("Hello from CH2");
-                }
-            });
-
-            context.start();
-
-            Thread.sleep(Integer.MAX_VALUE);
-        } finally {
-            context.stop();
-        }
-    }
-
-    private static KnativeEnvironment newEnv() {
-        return new KnativeEnvironment(Arrays.asList(
-            new KnativeEnvironment.KnativeServiceDefinition(
-                Knative.Type.endpoint,
-                Knative.Protocol.http,
-                "ep1",
-                "localhost",
-                8080,
-                mapOf(
-                    Knative.KNATIVE_EVENT_TYPE, "org.apache.camel.event",
-                    Knative.CONTENT_TYPE, "text/plain",
-                    Knative.FILTER_HEADER_NAME, "CE-Source",
-                    Knative.FILTER_HEADER_VALUE, "CE1"
-                )),
-            new KnativeEnvironment.KnativeServiceDefinition(
-                Knative.Type.endpoint,
-                Knative.Protocol.http,
-                "ep2",
-                "localhost",
-                8080,
-                mapOf(
-                    Knative.KNATIVE_EVENT_TYPE, "org.apache.camel.event",
-                    Knative.CONTENT_TYPE, "text/plain",
-                    Knative.FILTER_HEADER_NAME, "CE-Source",
-                    Knative.FILTER_HEADER_VALUE, "CE2"
-                ))
-        ));
-    }
-}
diff --git a/runtime/camel-knative/src/test/java/org/apache/camel/component/knative/KnativeComponentTest.java b/runtime/camel-knative/src/test/java/org/apache/camel/component/knative/KnativeComponentTest.java
index 631e95b..571e368 100644
--- a/runtime/camel-knative/src/test/java/org/apache/camel/component/knative/KnativeComponentTest.java
+++ b/runtime/camel-knative/src/test/java/org/apache/camel/component/knative/KnativeComponentTest.java
@@ -19,6 +19,8 @@ package org.apache.camel.component.knative;
 import java.time.ZonedDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Properties;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.camel.CamelContext;
@@ -27,6 +29,7 @@ import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.cloud.ServiceDefinition;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.component.netty4.NettyEndpoint;
+import org.apache.camel.component.properties.PropertiesComponent;
 import org.apache.camel.impl.DefaultCamelContext;
 import org.apache.camel.test.AvailablePortFinder;
 import org.junit.jupiter.api.AfterEach;
@@ -149,6 +152,140 @@ public class KnativeComponentTest {
     }
 
     @Test
+    void testCreateEndpointWithComputedHost() throws Exception {
+        KnativeEnvironment env = new KnativeEnvironment(Arrays.asList(
+            new KnativeEnvironment.KnativeServiceDefinition(
+                Knative.Type.endpoint,
+                Knative.Protocol.http,
+                "myEndpoint",
+                "",
+                -1,
+                mapOf(ServiceDefinition.SERVICE_META_PATH, "/a/path"))
+        ));
+
+        KnativeComponent component = context.getComponent("knative", KnativeComponent.class);
+        component.setEnvironment(env);
+
+        context.start();
+
+        //
+        // Endpoint with context path derived from service definition
+        //
+
+        KnativeEndpoint e1 = context.getEndpoint("knative:endpoint/myEndpoint", KnativeEndpoint.class);
+
+        assertThat(e1).isNotNull();
+        assertThat(e1.getService()).isNotNull();
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("name", "myEndpoint");
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("type", Knative.Type.endpoint);
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("protocol", Knative.Protocol.http);
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("path", "/a/path");
+        assertThat(e1.getEndpoint()).isInstanceOf(NettyEndpoint.class);
+        assertThat(e1.getEndpoint()).hasFieldOrPropertyWithValue("endpointUri", "http://myEndpoint/a/path");
+    }
+
+    @Test
+    void testCreateEndpointWithComputedHostAndNamespace() throws Exception {
+        KnativeEnvironment env = new KnativeEnvironment(Arrays.asList(
+            new KnativeEnvironment.KnativeServiceDefinition(
+                Knative.Type.endpoint,
+                Knative.Protocol.http,
+                "myEndpoint",
+                "",
+                -1,
+                mapOf(
+                    ServiceDefinition.SERVICE_META_PATH, "/a/path",
+                    ServiceDefinition.SERVICE_META_ZONE, "myNamespace"))
+        ));
+
+        KnativeComponent component = context.getComponent("knative", KnativeComponent.class);
+        component.setEnvironment(env);
+
+        context.start();
+
+        //
+        // Endpoint with context path derived from service definition
+        //
+
+        KnativeEndpoint e1 = context.getEndpoint("knative:endpoint/myEndpoint", KnativeEndpoint.class);
+
+        assertThat(e1).isNotNull();
+        assertThat(e1.getService()).isNotNull();
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("name", "myEndpoint");
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("type", Knative.Type.endpoint);
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("protocol", Knative.Protocol.http);
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("path", "/a/path");
+        assertThat(e1.getEndpoint()).isInstanceOf(NettyEndpoint.class);
+        assertThat(e1.getEndpoint()).hasFieldOrPropertyWithValue("endpointUri", "http://myEndpoint.myNamespace/a/path");
+    }
+
+    @Test
+    void testCreateEndpointWithComputedHostAndNamespaceWithProperty() throws Exception {
+        KnativeEnvironment env = new KnativeEnvironment(Arrays.asList(
+            new KnativeEnvironment.KnativeServiceDefinition(
+                Knative.Type.endpoint,
+                Knative.Protocol.http,
+                "myEndpoint",
+                "",
+                -1,
+                mapOf(
+                    ServiceDefinition.SERVICE_META_PATH, "/a/path",
+                    ServiceDefinition.SERVICE_META_ZONE, "{{myNamespaceKey}}"))
+        ));
+
+        Properties properties = new Properties();
+        properties.setProperty("myNamespaceKey", "myNamespace");
+
+        PropertiesComponent pc = context.getComponent("properties", PropertiesComponent.class);
+        pc.setInitialProperties(properties);
+
+        KnativeComponent component = context.getComponent("knative", KnativeComponent.class);
+        component.setEnvironment(env);
+
+        context.start();
+
+        //
+        // Endpoint with context path derived from service definition
+        //
+
+        KnativeEndpoint e1 = context.getEndpoint("knative:endpoint/myEndpoint", KnativeEndpoint.class);
+
+        assertThat(e1).isNotNull();
+        assertThat(e1.getService()).isNotNull();
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("name", "myEndpoint");
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("type", Knative.Type.endpoint);
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("protocol", Knative.Protocol.http);
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("path", "/a/path");
+        assertThat(e1.getEndpoint()).isInstanceOf(NettyEndpoint.class);
+        assertThat(e1.getEndpoint()).hasFieldOrPropertyWithValue("endpointUri", "http://myEndpoint.myNamespace/a/path");
+    }
+
+    @Test
+    void testCreateEndpointWithDefaults() throws Exception {
+        KnativeEnvironment env = new KnativeEnvironment(Collections.emptyList());
+
+        KnativeComponent component = context.getComponent("knative", KnativeComponent.class);
+        component.setEnvironment(env);
+
+        context.start();
+
+        //
+        // Endpoint with context path derived from service definition
+        //
+
+        KnativeEndpoint e1 = context.getEndpoint("knative:endpoint/myEndpoint/my/path", KnativeEndpoint.class);
+
+        assertThat(e1).isNotNull();
+        assertThat(e1.getService()).isNotNull();
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("name", "myEndpoint");
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("type", Knative.Type.endpoint);
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("protocol", Knative.Protocol.http);
+        assertThat(e1.getService()).hasFieldOrPropertyWithValue("path", "/my/path");
+        assertThat(e1.getEndpoint()).isInstanceOf(NettyEndpoint.class);
+        assertThat(e1.getEndpoint()).hasFieldOrPropertyWithValue("endpointUri", "http://myEndpoint/my/path");
+    }
+
+    @Test
     void testInvokeEndpoint() throws Exception {
         final int port = AvailablePortFinder.getNextAvailable();
 
@@ -326,7 +463,7 @@ public class KnativeComponentTest {
     }
 
     @Test
-    void testConsumeContentFithFilter() throws Exception {
+    void testConsumeContentWithFilter() throws Exception {
         final int port = AvailablePortFinder.getNextAvailable();
 
         KnativeEnvironment env = new KnativeEnvironment(Arrays.asList(
diff --git a/runtime/camel-knative/src/test/resources/log4j2-test.xml b/runtime/camel-knative/src/test/resources/log4j2-test.xml
index 403c946..b31e8b4 100644
--- a/runtime/camel-knative/src/test/resources/log4j2-test.xml
+++ b/runtime/camel-knative/src/test/resources/log4j2-test.xml
@@ -9,10 +9,10 @@
 
   <Loggers>
     <Root level="INFO">
-      <AppenderRef ref="STDOUT"/>
       <!--
-      <AppenderRef ref="NONE"/>
+      <AppenderRef ref="STDOUT"/>
       -->
+      <AppenderRef ref="NONE"/>
     </Root>
   </Loggers>