diff --git a/pkg/metadata/metadata_dependencies_test.go b/pkg/metadata/metadata_dependencies_test.go
index f0ad794a53..edaab2113d 100644
--- a/pkg/metadata/metadata_dependencies_test.go
+++ b/pkg/metadata/metadata_dependencies_test.go
@@ -135,6 +135,55 @@ func TestJacksonDependency(t *testing.T) {
assert.ElementsMatch(t, []string{"camel:http4", "camel:jackson", "camel:log"}, meta.Dependencies.List())
}
+func TestLanguageDependencies(t *testing.T) {
+ code := v1alpha1.SourceSpec{
+ DataSpec: v1alpha1.DataSpec{
+ Name: "Languages.java",
+ Content: `
+ from("direct:start")
+ .transform().ognl("request.body.name == 'Camel K'")
+ .transform().simple("${body.toUpperCase()}")
+ .transform().mvel("resource:classpath:script.mvel")
+ .transform().xquery("/ns:foo/bar", String.class, new Namespaces("ns", "http://foo/bar"))
+ .transform().xpath("//foo/bar")
+ .transform().jsonpath("$.foo")
+ .transform().groovy("request.body += 'modified'")
+ .split().xtokenize("/ns:foo/bar", new Namespaces("ns", "http://foo/bar"));
+ `,
+ },
+ Language: v1alpha1.LanguageJavaSource,
+ }
+
+ catalog, err := test.DefaultCatalog()
+ assert.Nil(t, err)
+
+ meta := Extract(catalog, code)
+ assert.ElementsMatch(t, []string{"camel:direct", "camel:bean", "camel:ognl", "camel:saxon", "camel:xpath",
+ "camel:jsonpath", "camel:groovy", "camel:jaxp", "camel:mvel"}, meta.Dependencies.List())
+}
+
+func TestLanguageDependenciesTransformExpression(t *testing.T) {
+ code := v1alpha1.SourceSpec{
+ DataSpec: v1alpha1.DataSpec{
+ Name: "Languages.java",
+ Content: `
+ from("direct:start")
+ .transform(language("ognl", "request.body.name == 'Camel K'"))
+ .transform(simple("${body.toUpperCase()}"))
+ .transform(xpath("//foo/bar"))
+ .transform(jsonpath("$.foo"))
+ `,
+ },
+ Language: v1alpha1.LanguageJavaSource,
+ }
+
+ catalog, err := test.DefaultCatalog()
+ assert.Nil(t, err)
+
+ meta := Extract(catalog, code)
+ assert.ElementsMatch(t, []string{"camel:direct", "camel:bean", "camel:ognl", "camel:xpath", "camel:jsonpath"}, meta.Dependencies.List())
+}
+
func TestHystrixDependency(t *testing.T) {
code := v1alpha1.SourceSpec{
DataSpec: v1alpha1.DataSpec{
@@ -232,7 +281,7 @@ func TestRestClosureDependency(t *testing.T) {
Name: "Request.groovy",
Content: `
rest {
- }
+ }
from("http4:test")
.to("log:info")
`,
@@ -304,19 +353,94 @@ func TestXMLRestDependency(t *testing.T) {
assert.ElementsMatch(t, []string{"camel:direct", "camel:rest", "camel:mock"}, meta.Dependencies.List())
}
+func TestXMLLanguageDependencies(t *testing.T) {
+ code := v1alpha1.SourceSpec{
+ DataSpec: v1alpha1.DataSpec{
+ Name: "routes.xml",
+ Content: `
+
+
+ request.body.name == 'Camel K'
+
+
+ ${body.toUpperCase()}
+
+
+ resource:classpath:script.mvel
+
+
+ $.foo
+
+
+ request.body += 'modified'
+
+
+ request.body += 'modified'
+
+
+ /ns:foo/bar
+
+
+ //foo/bar
+
+
+ //ns:foo/bar
+
+
+
+
+ `,
+ },
+ Language: v1alpha1.LanguageXML,
+ }
+
+ catalog, err := test.DefaultCatalog()
+ assert.Nil(t, err)
+
+ meta := Extract(catalog, code)
+ assert.ElementsMatch(t, []string{"camel:direct", "camel:bean", "camel:ognl", "camel:saxon", "camel:xpath",
+ "camel:jsonpath", "camel:groovy", "camel:jaxp", "camel:mvel"}, meta.Dependencies.List())
+}
+
const yamlWithRest = `
- rest:
path: "/"
steps:
- to: "log:info"
- - to: "direct:hello"
+ - to: "direct:hello"
`
const yamlWithHystrix = `
- from:
uri: "direct:start"
steps:
- hystrix:
- todo: "not implemented"
+ todo: "not implemented"
+`
+
+const yamlWithLanguages = `
+- from:
+ uri: "direct:start"
+ steps:
+ - set-body:
+ constant: "Hello Camel K"
+ - transform:
+ language:
+ language: "ognl"
+ expression: "request.body.name == 'Camel K'"
+ - transform:
+ simple: "${body.toUpperCase()}"
+ - transform:
+ mvel: "resource:classpath:script.mvel"
+ - transform:
+ xquery: "/ns:foo/bar"
+ - transform:
+ xpath: "//foo/bar"
+ - transform:
+ jsonpath: "$.foo"
+ - transform:
+ groovy: "request.body += 'modified'"
+ - split:
+ xtokenize: "/ns:foo/bar"
`
func TestYAMLRestDependency(t *testing.T) {
@@ -354,3 +478,21 @@ func TestYAMLHystrixDependency(t *testing.T) {
assert.ElementsMatch(t, []string{"camel:direct", "camel:hystrix"}, meta.Dependencies.List())
}
+
+func TestYAMLLanguageDependencies(t *testing.T) {
+ code := v1alpha1.SourceSpec{
+ DataSpec: v1alpha1.DataSpec{
+ Name: "routes.yaml",
+ Content: yamlWithLanguages,
+ },
+ Language: v1alpha1.LanguageYaml,
+ }
+
+ catalog, err := test.DefaultCatalog()
+ assert.Nil(t, err)
+
+ meta := Extract(catalog, code)
+
+ assert.ElementsMatch(t, []string{"camel:direct", "camel:bean", "camel:ognl", "camel:saxon", "camel:xpath",
+ "camel:jsonpath", "camel:groovy", "camel:jaxp", "camel:mvel"}, meta.Dependencies.List())
+}
diff --git a/pkg/util/camel/camel_runtime_catalog.go b/pkg/util/camel/camel_runtime_catalog.go
index 8cb90e5fc7..da0ee4dce9 100644
--- a/pkg/util/camel/camel_runtime_catalog.go
+++ b/pkg/util/camel/camel_runtime_catalog.go
@@ -29,6 +29,7 @@ func NewRuntimeCatalog(spec v1alpha1.CamelCatalogSpec) *RuntimeCatalog {
catalog.CamelCatalogSpec = spec
catalog.artifactByScheme = make(map[string]string)
catalog.schemesByID = make(map[string]v1alpha1.CamelScheme)
+ catalog.languageDependencies = make(map[string]string)
for id, artifact := range catalog.Artifacts {
for _, scheme := range artifact.Schemes {
@@ -36,6 +37,12 @@ func NewRuntimeCatalog(spec v1alpha1.CamelCatalogSpec) *RuntimeCatalog {
catalog.artifactByScheme[scheme.ID] = id
catalog.schemesByID[scheme.ID] = scheme
}
+ for _, language := range artifact.Languages {
+ // Skip languages in common dependencies since they are always available to integrations
+ if artifact.ArtifactID != "camel-base" {
+ catalog.languageDependencies[language] = strings.Replace(artifact.ArtifactID, "camel-", "camel:", 1)
+ }
+ }
}
return &catalog
@@ -45,8 +52,9 @@ func NewRuntimeCatalog(spec v1alpha1.CamelCatalogSpec) *RuntimeCatalog {
type RuntimeCatalog struct {
v1alpha1.CamelCatalogSpec
- artifactByScheme map[string]string
- schemesByID map[string]v1alpha1.CamelScheme
+ artifactByScheme map[string]string
+ schemesByID map[string]v1alpha1.CamelScheme
+ languageDependencies map[string]string
}
// HasArtifact --
@@ -76,6 +84,12 @@ func (c *RuntimeCatalog) GetScheme(id string) (v1alpha1.CamelScheme, bool) {
return scheme, ok
}
+// GetLanguageDependency returns the maven dependency for the given language name
+func (c *RuntimeCatalog) GetLanguageDependency(language string) (string, bool) {
+ language, ok := c.languageDependencies[language]
+ return language, ok
+}
+
// VisitArtifacts --
func (c *RuntimeCatalog) VisitArtifacts(visitor func(string, v1alpha1.CamelArtifact) bool) {
for id, artifact := range c.Artifacts {
diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go
index 65263cdb90..942900b513 100644
--- a/pkg/util/source/inspector.go
+++ b/pkg/util/source/inspector.go
@@ -35,13 +35,22 @@ var (
doubleQuotedTo = regexp.MustCompile(`\.to\s*\(\s*"([a-zA-Z0-9-]+:[^"]+)"`)
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*,.*\)`)
additionalDependencies = map[string]string{
- `.*JsonLibrary\.Jackson.*`: "camel:jackson",
- `.*\.hystrix().*`: "camel:hystrix",
- `.*restConfiguration().*`: "camel:rest",
- `.*rest(("[a-zA-Z0-9-/]+")*).*`: "camel:rest",
- `^\s*rest\s*{.*`: "camel:rest",
+ `.*JsonLibrary\.Jackson.*`: "camel:jackson",
+ `.*\.hystrix().*`: "camel:hystrix",
+ `.*restConfiguration().*`: "camel:rest",
+ `.*rest(("[a-zA-Z0-9-/]+")*).*`: "camel:rest",
+ `^\s*rest\s*{.*`: "camel:rest",
+ `.*\.groovy\s*\(.*\).*`: "camel:groovy",
+ `.*\.?(jsonpath|jsonpathWriteAsString)\s*\(.*\).*`: "camel:jsonpath",
+ `.*\.ognl\s*\(.*\).*`: "camel:ognl",
+ `.*\.mvel\s*\(.*\).*`: "camel:mvel",
+ `.*\.?simple\s*\(.*\).*`: "camel:bean",
+ `.*\.xquery\s*\(.*\).*`: "camel:saxon",
+ `.*\.?xpath\s*\(.*\).*`: "camel:xpath",
+ `.*\.xtokenize\s*\(.*\).*`: "camel:jaxp",
}
)
@@ -118,6 +127,14 @@ func (i *baseInspector) discoverDependencies(source v1alpha1.SourceSpec, meta *M
meta.Dependencies.Add(dep)
}
}
+
+ for _, match := range languageRegexp.FindAllStringSubmatch(source.Content, -1) {
+ if len(match) > 1 {
+ if dependency, ok := i.catalog.GetLanguageDependency(match[1]); ok {
+ meta.Dependencies.Add(dependency)
+ }
+ }
+ }
}
func (i *baseInspector) decodeComponent(uri string) string {
diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go
index fbf13a2959..116ed62fa5 100644
--- a/pkg/util/source/inspector_xml.go
+++ b/pkg/util/source/inspector_xml.go
@@ -47,6 +47,16 @@ func (i XMLInspector) Extract(source v1alpha1.SourceSpec, meta *Metadata) error
meta.Dependencies.Add("camel:rest")
case "hystrix":
meta.Dependencies.Add("camel:hystrix")
+ case "simple":
+ meta.Dependencies.Add("camel:bean")
+ case "language":
+ for _, a := range se.Attr {
+ if a.Name.Local == "language" {
+ if dependency, ok := i.catalog.GetLanguageDependency(a.Value); ok {
+ meta.Dependencies.Add(dependency)
+ }
+ }
+ }
case "from", "fromF":
for _, a := range se.Attr {
if a.Name.Local == "uri" {
@@ -60,6 +70,10 @@ func (i XMLInspector) Extract(source v1alpha1.SourceSpec, meta *Metadata) error
}
}
}
+
+ if dependency, ok := i.catalog.GetLanguageDependency(se.Name.Local); ok {
+ meta.Dependencies.Add(dependency)
+ }
}
}
diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go
index 93e8781d3f..7a16d1afab 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -69,6 +69,31 @@ func (inspector YAMLInspector) parseStep(key string, content interface{}, meta *
if u, ok := t["uri"]; ok {
maybeURI = u.(string)
}
+
+ if _, ok := t["simple"]; ok {
+ meta.Dependencies.Add("camel:bean")
+ }
+
+ if _, ok := t["language"]; ok {
+ if s, ok := t["language"].(string); ok {
+ if dependency, ok := inspector.catalog.GetLanguageDependency(s); ok {
+ meta.Dependencies.Add(dependency)
+ }
+ } else if m, ok := t["language"].(map[interface{}]interface{}); ok {
+ if err := inspector.parseStep("language", m, meta); err != nil {
+ return err
+ }
+ }
+ }
+
+ for k := range t {
+ if s, ok := k.(string); ok {
+ if dependency, ok := inspector.catalog.GetLanguageDependency(s); ok {
+ meta.Dependencies.Add(dependency)
+ }
+ }
+ }
+
if u, ok := t["steps"]; ok {
steps := u.([]interface{})