Repository: apache/camel-k
Pull request #1411 (2020-04-17 15:35:09)

Properly handle platform-http component in routes
<!-- Description -->




<!--
Enter your extended release note in the below block. If the PR requires
additional action from users switching to the new release, include the string
"action required". If no release note is required, write "NONE". 

You can (optionally) mark this PR with labels "kind/bug" or "kind/feature" to make sure
the text is added to the right section of the release notes. 
-->

**Release Note**
```release-note
NONE
```


Patch:
diff --git a/pkg/install/optional.go b/pkg/install/optional.go
index f3fe873fc..185ac7851 100644
--- a/pkg/install/optional.go
+++ b/pkg/install/optional.go
@@ -1,7 +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
+
+   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 install
 
 import (
 	"context"
+
 	"github.com/apache/camel-k/pkg/client"
 	"github.com/go-logr/logr"
 )
diff --git a/pkg/metadata/metadata.go b/pkg/metadata/metadata.go
index 2c8dd8e88..27a2c8df6 100644
--- a/pkg/metadata/metadata.go
+++ b/pkg/metadata/metadata.go
@@ -44,8 +44,6 @@ func ExtractAll(catalog *camel.RuntimeCatalog, sources []v1.SourceSpec) Integrat
 }
 
 func merge(m1 src.Metadata, m2 src.Metadata) src.Metadata {
-	d := strset.Union(m1.Dependencies, m2.Dependencies)
-
 	f := make([]string, 0, len(m1.FromURIs)+len(m2.FromURIs))
 	f = append(f, m1.FromURIs...)
 	f = append(f, m2.FromURIs...)
@@ -55,11 +53,12 @@ func merge(m1 src.Metadata, m2 src.Metadata) src.Metadata {
 	t = append(t, m2.ToURIs...)
 
 	return src.Metadata{
-		FromURIs:            f,
-		ToURIs:              t,
-		Dependencies:        d,
-		ExposesHTTPServices: m1.ExposesHTTPServices || m2.ExposesHTTPServices,
-		PassiveEndpoints:    m1.PassiveEndpoints && m2.PassiveEndpoints,
+		FromURIs:             f,
+		ToURIs:               t,
+		Dependencies:         strset.Union(m1.Dependencies, m2.Dependencies),
+		RequiredCapabilities: strset.Union(m1.RequiredCapabilities, m2.RequiredCapabilities),
+		ExposesHTTPServices:  m1.ExposesHTTPServices || m2.ExposesHTTPServices,
+		PassiveEndpoints:     m1.PassiveEndpoints && m2.PassiveEndpoints,
 	}
 }
 
diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go
index a8b690a63..25347d398 100644
--- a/pkg/util/source/inspector.go
+++ b/pkg/util/source/inspector.go
@@ -199,6 +199,17 @@ func (i baseInspector) Extract(v1.SourceSpec, *Metadata) error {
 	return nil
 }
 
+// discoverDependencies returns a list of dependencies required by the given source code
+func (i *baseInspector) discoverCapabilities(_ v1.SourceSpec, meta *Metadata) {
+	uris := util.StringSliceJoin(meta.FromURIs, meta.ToURIs)
+
+	for _, uri := range uris {
+		if i.getURIPrefix(uri) == "platform-http" {
+			meta.RequiredCapabilities.Add(v1.CapabilityPlatformHTTP)
+		}
+	}
+}
+
 // discoverDependencies returns a list of dependencies required by the given source code
 func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta *Metadata) {
 	uris := util.StringSliceJoin(meta.FromURIs, meta.ToURIs)
diff --git a/pkg/util/source/inspector_groovy.go b/pkg/util/source/inspector_groovy.go
index 9f705c324..b6db6e959 100644
--- a/pkg/util/source/inspector_groovy.go
+++ b/pkg/util/source/inspector_groovy.go
@@ -47,6 +47,7 @@ func (i GroovyInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 	meta.FromURIs = append(meta.FromURIs, from...)
 	meta.ToURIs = append(meta.ToURIs, to...)
 
+	i.discoverCapabilities(source, meta)
 	i.discoverDependencies(source, meta)
 
 	hasRest := restRegexp.MatchString(source.Content) || restClosureRegexp.MatchString(source.Content)
diff --git a/pkg/util/source/inspector_java_script.go b/pkg/util/source/inspector_java_script.go
index dc5be4100..00dba9a47 100644
--- a/pkg/util/source/inspector_java_script.go
+++ b/pkg/util/source/inspector_java_script.go
@@ -47,6 +47,7 @@ func (i JavaScriptInspector) Extract(source v1.SourceSpec, meta *Metadata) error
 	meta.FromURIs = append(meta.FromURIs, from...)
 	meta.ToURIs = append(meta.ToURIs, to...)
 
+	i.discoverCapabilities(source, meta)
 	i.discoverDependencies(source, meta)
 
 	hasRest := restRegexp.MatchString(source.Content)
diff --git a/pkg/util/source/inspector_java_source.go b/pkg/util/source/inspector_java_source.go
index e54826731..6e0386f4c 100644
--- a/pkg/util/source/inspector_java_source.go
+++ b/pkg/util/source/inspector_java_source.go
@@ -43,6 +43,7 @@ func (i JavaSourceInspector) Extract(source v1.SourceSpec, meta *Metadata) error
 	meta.FromURIs = append(meta.FromURIs, from...)
 	meta.ToURIs = append(meta.ToURIs, to...)
 
+	i.discoverCapabilities(source, meta)
 	i.discoverDependencies(source, meta)
 
 	hasRest := restRegexp.MatchString(source.Content)
diff --git a/pkg/util/source/inspector_kotlin.go b/pkg/util/source/inspector_kotlin.go
index 4a405ce8f..7dab24a0e 100644
--- a/pkg/util/source/inspector_kotlin.go
+++ b/pkg/util/source/inspector_kotlin.go
@@ -43,6 +43,7 @@ func (i KotlinInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 	meta.FromURIs = append(meta.FromURIs, from...)
 	meta.ToURIs = append(meta.ToURIs, to...)
 
+	i.discoverCapabilities(source, meta)
 	i.discoverDependencies(source, meta)
 
 	hasRest := restRegexp.MatchString(source.Content) || restClosureRegexp.MatchString(source.Content)
diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go
index f9f2ab64d..4d4f39e71 100644
--- a/pkg/util/source/inspector_xml.go
+++ b/pkg/util/source/inspector_xml.go
@@ -76,6 +76,7 @@ func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 		}
 	}
 
+	i.discoverCapabilities(source, meta)
 	i.discoverDependencies(source, meta)
 
 	meta.ExposesHTTPServices = meta.ExposesHTTPServices || i.containsHTTPURIs(meta.FromURIs)
diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go
index d05b2e823..f705b6286 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -30,38 +30,37 @@ type YAMLInspector struct {
 }
 
 // Extract --
-func (inspector YAMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
+func (i YAMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error {
 	definitions := make([]map[string]interface{}, 0)
 
 	if err := yaml2.Unmarshal([]byte(source.Content), &definitions); err != nil {
 		return err
 	}
 
-	for i := range definitions {
-		definition := definitions[i]
-
+	for _, definition := range definitions {
 		for k, v := range definition {
-			if err := inspector.parseStep(k, v, meta); err != nil {
+			if err := i.parseStep(k, v, meta); err != nil {
 				return err
 			}
 		}
 	}
 
-	inspector.discoverDependencies(source, meta)
+	i.discoverCapabilities(source, meta)
+	i.discoverDependencies(source, meta)
 
-	meta.ExposesHTTPServices = meta.ExposesHTTPServices || inspector.containsHTTPURIs(meta.FromURIs)
-	meta.PassiveEndpoints = inspector.hasOnlyPassiveEndpoints(meta.FromURIs)
+	meta.ExposesHTTPServices = meta.ExposesHTTPServices || i.containsHTTPURIs(meta.FromURIs)
+	meta.PassiveEndpoints = i.hasOnlyPassiveEndpoints(meta.FromURIs)
 
 	return nil
 }
 
-func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *Metadata) error {
+func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata) error {
 	switch key {
 	case "rest":
 		meta.ExposesHTTPServices = true
 		meta.RequiredCapabilities.Add(v1.CapabilityRest)
 	case "circuitBreaker":
-		inspector.addDependency("camel:hystrix", meta)
+		i.addDependency("camel:hystrix", meta)
 	}
 
 	var maybeURI string
@@ -71,14 +70,14 @@ func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *
 		maybeURI = t
 	case map[interface{}]interface{}:
 		if u, ok := t["rest"]; ok {
-			return inspector.parseStep("rest", u, meta)
+			return i.parseStep("rest", u, meta)
 		} else if u, ok := t["from"]; ok {
-			return inspector.parseStep("from", u, meta)
+			return i.parseStep("from", u, meta)
 		} else if u, ok := t["steps"]; ok {
 			steps := u.([]interface{})
 
-			for i := range steps {
-				step := steps[i].(map[interface{}]interface{})
+			for _, raw := range steps {
+				step := raw.(map[interface{}]interface{})
 
 				if len(step) != 1 {
 					return fmt.Errorf("unable to parse step: %v", step)
@@ -87,11 +86,11 @@ func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *
 				for k, v := range step {
 					switch kt := k.(type) {
 					case fmt.Stringer:
-						if err := inspector.parseStep(kt.String(), v, meta); err != nil {
+						if err := i.parseStep(kt.String(), v, meta); err != nil {
 							return err
 						}
 					case string:
-						if err := inspector.parseStep(kt, v, meta); err != nil {
+						if err := i.parseStep(kt, v, meta); err != nil {
 							return err
 						}
 					default:
@@ -107,11 +106,11 @@ func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *
 
 		if _, ok := t["language"]; ok {
 			if s, ok := t["language"].(string); ok {
-				if dependency, ok := inspector.catalog.GetLanguageDependency(s); ok {
-					inspector.addDependency(dependency, meta)
+				if dependency, ok := i.catalog.GetLanguageDependency(s); ok {
+					i.addDependency(dependency, meta)
 				}
 			} else if m, ok := t["language"].(map[interface{}]interface{}); ok {
-				if err := inspector.parseStep("language", m, meta); err != nil {
+				if err := i.parseStep("language", m, meta); err != nil {
 					return err
 				}
 			}
@@ -119,8 +118,8 @@ func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *
 
 		for k := range t {
 			if s, ok := k.(string); ok {
-				if dependency, ok := inspector.catalog.GetLanguageDependency(s); ok {
-					inspector.addDependency(dependency, meta)
+				if dependency, ok := i.catalog.GetLanguageDependency(s); ok {
+					i.addDependency(dependency, meta)
 				}
 			}
 		}


Test patch:
diff --git a/pkg/metadata/metadata_capabilities_test.go b/pkg/metadata/metadata_capabilities_test.go
new file mode 100644
index 000000000..349e4850e
--- /dev/null
+++ b/pkg/metadata/metadata_capabilities_test.go
@@ -0,0 +1,57 @@
+/*
+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 metadata
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+
+	v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
+	"github.com/apache/camel-k/pkg/util/camel"
+)
+
+func TestPlatformHttpCapabilities(t *testing.T) {
+	code := v1.SourceSpec{
+		DataSpec: v1.DataSpec{
+			Name:    "Request.java",
+			Content: `from("platform-http:/test").to("log:test");`,
+		},
+		Language: v1.LanguageJavaSource,
+	}
+
+	catalog, err := camel.DefaultCatalog()
+	assert.Nil(t, err)
+
+	meta := Extract(catalog, code)
+
+	assert.ElementsMatch(
+		t,
+		[]string{
+			"camel:platform-http",
+			"camel:log",
+		},
+		meta.Dependencies.List())
+
+	assert.ElementsMatch(
+		t,
+		[]string{
+			v1.CapabilityPlatformHTTP,
+		},
+		meta.RequiredCapabilities.List())
+}