You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2020/01/03 09:56:50 UTC

[camel-k] branch master updated: Auto detect Camel components via FQN classnames

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

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


The following commit(s) were added to refs/heads/master by this push:
     new bd6d9cf  Auto detect Camel components via FQN classnames
     new e26a775  Merge pull request #1177 from jamesnetherton/auto-type-deps
bd6d9cf is described below

commit bd6d9cfb57c78e2adbda7fec8b9bdecdadcbf923
Author: James Netherton <ja...@gmail.com>
AuthorDate: Fri Jan 3 07:19:29 2020 +0000

    Auto detect Camel components via FQN classnames
    
    fixes #1095
---
 pkg/apis/camel/v1/camelcatalog_types.go    |  1 +
 pkg/apis/camel/v1/zz_generated.deepcopy.go |  5 +++++
 pkg/metadata/metadata_dependencies_test.go | 15 ++++++++++++---
 pkg/util/camel/camel_runtime_catalog.go    | 20 +++++++++++++++-----
 pkg/util/camel/camel_util.go               |  8 ++++++++
 pkg/util/source/inspector.go               |  9 +++++++++
 6 files changed, 50 insertions(+), 8 deletions(-)

diff --git a/pkg/apis/camel/v1/camelcatalog_types.go b/pkg/apis/camel/v1/camelcatalog_types.go
index 1c5556e..27b3844 100644
--- a/pkg/apis/camel/v1/camelcatalog_types.go
+++ b/pkg/apis/camel/v1/camelcatalog_types.go
@@ -49,6 +49,7 @@ type CamelArtifact struct {
 	Languages               []string        `json:"languages,omitempty" yaml:"languages,omitempty"`
 	DataFormats             []string        `json:"dataformats,omitempty" yaml:"dataformats,omitempty"`
 	Dependencies            []CamelArtifact `json:"dependencies,omitempty" yaml:"dependencies,omitempty"`
+	JavaTypes               []string        `json:"javaTypes,omitempty" yaml:"javaTypes,omitempty"`
 }
 
 // CamelCatalogSpec defines the desired state of CamelCatalog
diff --git a/pkg/apis/camel/v1/zz_generated.deepcopy.go b/pkg/apis/camel/v1/zz_generated.deepcopy.go
index 9f80a6a..74c59dd 100644
--- a/pkg/apis/camel/v1/zz_generated.deepcopy.go
+++ b/pkg/apis/camel/v1/zz_generated.deepcopy.go
@@ -275,6 +275,11 @@ func (in *CamelArtifact) DeepCopyInto(out *CamelArtifact) {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
 	}
+	if in.JavaTypes != nil {
+		in, out := &in.JavaTypes, &out.JavaTypes
+		*out = make([]string, len(*in))
+		copy(*out, *in)
+	}
 	return
 }
 
diff --git a/pkg/metadata/metadata_dependencies_test.go b/pkg/metadata/metadata_dependencies_test.go
index 96d6d0b..c8b605e 100644
--- a/pkg/metadata/metadata_dependencies_test.go
+++ b/pkg/metadata/metadata_dependencies_test.go
@@ -31,6 +31,8 @@ func TestDependenciesJavaSource(t *testing.T) {
 		DataSpec: v1.DataSpec{
 			Name: "Request.java",
 			Content: `
+			    import org.apache.camel.component.activemq.ActiveMQComponent;
+
 			    from("telegram:bots/cippa").to("log:stash");
 			    from("timer:tick").to("amqp:queue");
 			    from("ine:xistent").to("amqp:queue");
@@ -46,7 +48,7 @@ func TestDependenciesJavaSource(t *testing.T) {
 
 	meta := Extract(catalog, code)
 
-	assert.ElementsMatch(t, []string{"camel:amqp", "camel:log", "camel:telegram", "camel:timer", "camel:twitter"}, meta.Dependencies.List())
+	assert.ElementsMatch(t, []string{"camel:activemq", "camel:amqp", "camel:log", "camel:telegram", "camel:timer", "camel:twitter"}, meta.Dependencies.List())
 }
 
 func TestDependenciesJavaScript(t *testing.T) {
@@ -54,6 +56,8 @@ func TestDependenciesJavaScript(t *testing.T) {
 		DataSpec: v1.DataSpec{
 			Name: "source.js",
 			Content: `
+			    var component = Java.type("org.apache.camel.component.activemq.ActiveMQComponent");
+
 			    from('telegram:bots/cippa').to("log:stash");
 			    from('timer:tick').to("amqp:queue");
 			    from("ine:xistent").to("amqp:queue");
@@ -68,7 +72,7 @@ func TestDependenciesJavaScript(t *testing.T) {
 
 	meta := Extract(catalog, code)
 
-	assert.ElementsMatch(t, []string{"camel:amqp", "camel:log", "camel:telegram", "camel:timer"}, meta.Dependencies.List())
+	assert.ElementsMatch(t, []string{"camel:activemq", "camel:amqp", "camel:log", "camel:telegram", "camel:timer"}, meta.Dependencies.List())
 }
 
 func TestDependenciesGroovy(t *testing.T) {
@@ -76,6 +80,8 @@ func TestDependenciesGroovy(t *testing.T) {
 		DataSpec: v1.DataSpec{
 			Name: "source.groovy",
 			Content: `
+			    import org.apache.camel.component.activemq.ActiveMQComponent;
+
 			    from('telegram:bots/cippa').to("log:stash");
 			    from('timer:tick').to("amqp:queue");
 			    from("ine:xistent").to("amqp:queue");
@@ -92,7 +98,7 @@ func TestDependenciesGroovy(t *testing.T) {
 
 	meta := Extract(catalog, code)
 
-	assert.ElementsMatch(t, []string{"camel:amqp", "camel:log", "camel:telegram", "camel:timer", "camel:twitter"}, meta.Dependencies.List())
+	assert.ElementsMatch(t, []string{"camel:activemq", "camel:amqp", "camel:log", "camel:telegram", "camel:timer", "camel:twitter"}, meta.Dependencies.List())
 }
 
 func TestDependencies(t *testing.T) {
@@ -121,6 +127,8 @@ func TestDependenciesQuarkus(t *testing.T) {
 		DataSpec: v1.DataSpec{
 			Name: "Request.java",
 			Content: `
+			    import org.apache.camel.component.timer.TimerComponent;
+
 			    from("http:test").to("log:end");
 			    from("https4:test").to("log:end");
 			    from("twitter-timeline:test").to("mock:end");
@@ -138,6 +146,7 @@ func TestDependenciesQuarkus(t *testing.T) {
 	assert.ElementsMatch(t,
 		[]string{
 			"camel-quarkus:log",
+			"camel-quarkus:timer",
 			"camel-quarkus:twitter",
 		},
 		meta.Dependencies.List())
diff --git a/pkg/util/camel/camel_runtime_catalog.go b/pkg/util/camel/camel_runtime_catalog.go
index 38bee12..b0d4a67 100644
--- a/pkg/util/camel/camel_runtime_catalog.go
+++ b/pkg/util/camel/camel_runtime_catalog.go
@@ -30,6 +30,7 @@ func NewRuntimeCatalog(spec v1.CamelCatalogSpec) *RuntimeCatalog {
 	catalog.artifactByScheme = make(map[string]string)
 	catalog.schemesByID = make(map[string]v1.CamelScheme)
 	catalog.languageDependencies = make(map[string]string)
+	catalog.javaTypeDependencies = make(map[string]string)
 
 	for id, artifact := range catalog.Artifacts {
 		for _, scheme := range artifact.Schemes {
@@ -40,11 +41,13 @@ func NewRuntimeCatalog(spec v1.CamelCatalogSpec) *RuntimeCatalog {
 		for _, language := range artifact.Languages {
 			// Skip languages in common dependencies since they are always available to integrations
 			if artifact.ArtifactID != "camel-base" {
-				if catalog.RuntimeProvider != nil && catalog.RuntimeProvider.Quarkus != nil {
-					catalog.languageDependencies[language] = strings.Replace(artifact.ArtifactID, "camel-quarkus-", "camel-quarkus:", 1)
-				} else {
-					catalog.languageDependencies[language] = strings.Replace(artifact.ArtifactID, "camel-", "camel:", 1)
-				}
+				catalog.languageDependencies[language] = getDependency(artifact, catalog.RuntimeProvider)
+			}
+		}
+		for _, javaType := range artifact.JavaTypes {
+			// Skip types in common dependencies since they are always available to integrations
+			if artifact.ArtifactID != "camel-base" {
+				catalog.javaTypeDependencies[javaType] = getDependency(artifact, catalog.RuntimeProvider)
 			}
 		}
 	}
@@ -59,6 +62,7 @@ type RuntimeCatalog struct {
 	artifactByScheme     map[string]string
 	schemesByID          map[string]v1.CamelScheme
 	languageDependencies map[string]string
+	javaTypeDependencies map[string]string
 }
 
 // HasArtifact --
@@ -94,6 +98,12 @@ func (c *RuntimeCatalog) GetLanguageDependency(language string) (string, bool) {
 	return language, ok
 }
 
+// GetJavaTypeDependency returns the maven dependency for the given type name
+func (c *RuntimeCatalog) GetJavaTypeDependency(camelType string) (string, bool) {
+	javaType, ok := c.javaTypeDependencies[camelType]
+	return javaType, ok
+}
+
 // VisitArtifacts --
 func (c *RuntimeCatalog) VisitArtifacts(visitor func(string, v1.CamelArtifact) bool) {
 	for id, artifact := range c.Artifacts {
diff --git a/pkg/util/camel/camel_util.go b/pkg/util/camel/camel_util.go
index a6510a3..a9a7055 100644
--- a/pkg/util/camel/camel_util.go
+++ b/pkg/util/camel/camel_util.go
@@ -19,6 +19,7 @@ package camel
 
 import (
 	"sort"
+	"strings"
 
 	"github.com/Masterminds/semver"
 
@@ -130,3 +131,10 @@ func newCatalogVersionCollection(catalogs []v1.CamelCatalog) CatalogVersionColle
 
 	return answer
 }
+
+func getDependency(artifact v1.CamelArtifact, runtimeProvider *v1.RuntimeProvider) string {
+	if runtimeProvider != nil && runtimeProvider.Quarkus != nil {
+		return strings.Replace(artifact.ArtifactID, "camel-quarkus-", "camel-quarkus:", 1)
+	}
+	return strings.Replace(artifact.ArtifactID, "camel-", "camel:", 1)
+}
diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go
index 06f4071..2faac01 100644
--- a/pkg/util/source/inspector.go
+++ b/pkg/util/source/inspector.go
@@ -36,6 +36,7 @@ var (
 	doubleQuotedToD  = regexp.MustCompile(`\.toD\s*\(\s*"([a-zA-Z0-9-]+:[^"]+)"`)
 	doubleQuotedToF  = regexp.MustCompile(`\.toF\s*\(\s*"([a-zA-Z0-9-]+:[^"]+)"`)
 	languageRegexp   = regexp.MustCompile(`language\s*\(\s*["|']([a-zA-Z0-9-]+[^"|']+)["|']\s*,.*\)`)
+	camelTypeRegexp  = regexp.MustCompile(`.*(org.apache.camel.*Component|DataFormat|Language)`)
 
 	sourceDependencies = struct {
 		main    map[string]string
@@ -153,6 +154,14 @@ func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta *Metadat
 			}
 		}
 	}
+
+	for _, match := range camelTypeRegexp.FindAllStringSubmatch(source.Content, -1) {
+		if len(match) > 1 {
+			if dependency, ok := i.catalog.GetJavaTypeDependency(match[1]); ok {
+				meta.Dependencies.Add(dependency)
+			}
+		}
+	}
 }
 
 func (i *baseInspector) decodeComponent(uri string) string {