Fix #1549: auto-detect json in YAML
diff --git a/pkg/util/camel/camel_runtime_catalog.go b/pkg/util/camel/camel_runtime_catalog.go
index 8153299..2482eff 100644
--- a/pkg/util/camel/camel_runtime_catalog.go
+++ b/pkg/util/camel/camel_runtime_catalog.go
@@ -28,6 +28,7 @@
catalog := RuntimeCatalog{}
catalog.CamelCatalogSpec = spec
catalog.artifactByScheme = make(map[string]string)
+ catalog.artifactByDataFormat = make(map[string]string)
catalog.schemesByID = make(map[string]v1.CamelScheme)
catalog.languageDependencies = make(map[string]string)
catalog.javaTypeDependencies = make(map[string]string)
@@ -38,6 +39,10 @@
catalog.artifactByScheme[scheme.ID] = id
catalog.schemesByID[scheme.ID] = scheme
}
+ for _, dataFormat := range artifact.DataFormats {
+ dataFormat := dataFormat
+ catalog.artifactByDataFormat[dataFormat] = id
+ }
for _, language := range artifact.Languages {
// Skip languages in common dependencies since they are always available to integrations
if artifact.ArtifactID != "camel-base" {
@@ -60,6 +65,7 @@
v1.CamelCatalogSpec
artifactByScheme map[string]string
+ artifactByDataFormat map[string]string
schemesByID map[string]v1.CamelScheme
languageDependencies map[string]string
javaTypeDependencies map[string]string
@@ -86,6 +92,16 @@
return nil
}
+// GetArtifactByDataFormat returns the artifact corresponding to the given data format
+func (c *RuntimeCatalog) GetArtifactByDataFormat(dataFormat string) *v1.CamelArtifact {
+ if id, ok := c.artifactByDataFormat[dataFormat]; ok {
+ if artifact, present := c.Artifacts[id]; present {
+ return &artifact
+ }
+ }
+ return nil
+}
+
// GetScheme returns the scheme definition for the given scheme id
func (c *RuntimeCatalog) GetScheme(id string) (v1.CamelScheme, bool) {
scheme, ok := c.schemesByID[id]
diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go
index 94b8951..90a0051 100644
--- a/pkg/util/source/inspector.go
+++ b/pkg/util/source/inspector.go
@@ -29,6 +29,10 @@
type catalog2deps func(*camel.RuntimeCatalog) []string
+const (
+ defaultJsonDataformat = "json-jackson"
+)
+
var (
singleQuotedFrom = regexp.MustCompile(`from\s*\(\s*'([a-zA-Z0-9-]+:[^']+)'`)
doubleQuotedFrom = regexp.MustCompile(`from\s*\(\s*"([a-zA-Z0-9-]+:[^"]+)"`)
@@ -59,11 +63,19 @@
}
sourceDependencies = map[*regexp.Regexp]catalog2deps{
- jsonLibraryRegexp: func(_ *camel.RuntimeCatalog) []string {
- return []string{"camel:jackson"}
+ jsonLibraryRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ res := make([]string, 0)
+ if jsonDF := catalog.GetArtifactByDataFormat(defaultJsonDataformat); jsonDF != nil {
+ res = append(res, jsonDF.GetDependencyID())
+ }
+ return res
},
- jsonLanguageRegexp: func(_ *camel.RuntimeCatalog) []string {
- return []string{"camel:jackson"}
+ jsonLanguageRegexp: func(catalog *camel.RuntimeCatalog) []string {
+ res := make([]string, 0)
+ if jsonDF := catalog.GetArtifactByDataFormat(defaultJsonDataformat); jsonDF != nil {
+ res = append(res, jsonDF.GetDependencyID())
+ }
+ return res
},
restConfigurationRegexp: func(catalog *camel.RuntimeCatalog) []string {
deps := make([]string, 0)
diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go
index a981049..bcfa6cf 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -19,6 +19,7 @@
import (
"fmt"
+ "strings"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
yaml2 "gopkg.in/yaml.v2"
@@ -61,6 +62,22 @@
meta.RequiredCapabilities.Add(v1.CapabilityRest)
case "circuitBreaker":
meta.RequiredCapabilities.Add(v1.CapabilityCircuitBreaker)
+ case "unmarshal":
+ fallthrough
+ case "marshal":
+ if cm, ok := content.(map[interface{}]interface{}); ok {
+ if js, jsOk := cm["json"]; jsOk {
+ dataFormatID := defaultJsonDataformat
+ if jsContent, jsContentOk := js.(map[interface{}]interface{}); jsContentOk {
+ if lib, libOk := jsContent["library"]; libOk {
+ dataFormatID = strings.ToLower(fmt.Sprintf("json-%s", lib))
+ }
+ }
+ if dfDep := i.catalog.GetArtifactByDataFormat(dataFormatID); dfDep != nil {
+ i.addDependency(dfDep.GetDependencyID(), meta)
+ }
+ }
+ }
}
var maybeURI string
diff --git a/pkg/util/source/inspector_yaml_test.go b/pkg/util/source/inspector_yaml_test.go
index c7ed024..518b938 100644
--- a/pkg/util/source/inspector_yaml_test.go
+++ b/pkg/util/source/inspector_yaml_test.go
@@ -18,6 +18,7 @@
package source
import (
+ "fmt"
"testing"
v1 "github.com/apache/camel-k/pkg/apis/camel/v1"
@@ -104,3 +105,81 @@
})
}
}
+
+const YAMLJSONMarshal = `
+- from:
+ uri: timer:tick
+ steps:
+ - marshal:
+ json: {}
+`
+
+const YAMLJSONUnmarshal = `
+- from:
+ uri: timer:tick
+ steps:
+ - unmarshal:
+ json: {}
+`
+
+const YAMLJSONGsonMarshal = `
+- from:
+ uri: timer:tick
+ steps:
+ - marshal:
+ json:
+ library: Gson
+`
+
+const YAMLJSONUnknownMarshal = `
+- from:
+ uri: timer:tick
+ steps:
+ - marshal:
+ json:
+ library: Unknown
+`
+
+func TestYAMLJson(t *testing.T) {
+ tc := []struct {
+ source string
+ dependency string
+ }{
+ {
+ source: YAMLJSONMarshal,
+ dependency: "camel-quarkus:jackson",
+ },
+ {
+ source: YAMLJSONUnmarshal,
+ dependency: "camel-quarkus:jackson",
+ },
+ {
+ source: YAMLJSONGsonMarshal,
+ dependency: "camel-quarkus:gson",
+ },
+ {
+ source: YAMLJSONUnknownMarshal,
+ dependency: "camel-quarkus:timer",
+ },
+ }
+
+ for i, test := range tc {
+ t.Run(fmt.Sprintf("%s-%d", test.dependency, i), func(t *testing.T) {
+ code := v1.SourceSpec{
+ DataSpec: v1.DataSpec{
+ Name: "route.yaml",
+ Content: test.source,
+ },
+ Language: v1.LanguageYaml,
+ }
+
+ meta := NewMetadata()
+ inspector := NewtestYAMLInspector(t)
+
+ err := inspector.Extract(code, &meta)
+ assert.Nil(t, err)
+ assert.True(t, meta.RequiredCapabilities.IsEmpty())
+ assert.Contains(t, meta.Dependencies.List(), test.dependency)
+ })
+ }
+}