This is an automated email from the ASF dual-hosted git repository. pcongiusti pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/main by this push: new a91f56963 feat: support Error Handler a91f56963 is described below commit a91f5696355ba5d8c4e9b69ec965e489efdacfe1 Author: Pasquale Congiusti <pasquale.congiu...@gmail.com> AuthorDate: Sat Jan 11 09:57:52 2025 +0100 feat: support Error Handler --- pkg/util/source/inspector.go | 18 ++++++++- pkg/util/source/inspector_java_source_test.go | 21 +++++++++++ pkg/util/source/inspector_xml.go | 16 +++++++- pkg/util/source/inspector_xml_test.go | 19 ++++++++++ pkg/util/source/inspector_yaml.go | 16 ++++++-- pkg/util/source/inspector_yaml_test.go | 54 +++++++++++++++++++++++++++ 6 files changed, 137 insertions(+), 7 deletions(-) diff --git a/pkg/util/source/inspector.go b/pkg/util/source/inspector.go index 8d58602a2..101fbd91e 100644 --- a/pkg/util/source/inspector.go +++ b/pkg/util/source/inspector.go @@ -31,6 +31,7 @@ type catalog2deps func(*camel.RuntimeCatalog) []string const ( defaultJSONDataFormat = "jackson" + kamelet = "kamelet" ) var ( @@ -51,6 +52,7 @@ var ( jsonLibraryRegexp = regexp.MustCompile(`.*JsonLibrary\.Jackson.*`) jsonLanguageRegexp = regexp.MustCompile(`.*\.json\(\).*`) beanRegexp = regexp.MustCompile(`.*\.bean\(.*\).*`) + errorHandlerRegexp = regexp.MustCompile(`errorHandler\s*\(\s*deadLetterChannel\s*\(\s*["|']([a-zA-Z0-9-]+:[^"|']+)["|']\s*\).*`) circuitBreakerRegexp = regexp.MustCompile(`.*\.circuitBreaker\(\).*`) restConfigurationRegexp = regexp.MustCompile(`.*restConfiguration\(\).*`) restRegexp = regexp.MustCompile(`.*rest\s*\([^)]*\).*`) @@ -253,7 +255,7 @@ func (i *baseInspector) extract(source v1.SourceSpec, meta *Metadata, meta.ToURIs = append(meta.ToURIs, to...) for _, k := range kameletEips { - AddKamelet(meta, "kamelet:"+k) + AddKamelet(meta, kamelet+":"+k) } if err := i.discoverCapabilities(source, meta); err != nil { @@ -350,6 +352,18 @@ func (i *baseInspector) discoverDependencies(source v1.SourceSpec, meta *Metadat } } + for _, match := range errorHandlerRegexp.FindAllStringSubmatch(source.Content, -1) { + if len(match) > 1 { + _, scheme := i.catalog.DecodeComponent(match[1]) + if dfDep := i.catalog.GetArtifactByScheme(scheme.ID); dfDep != nil { + meta.AddDependency(dfDep.GetDependencyID()) + } + if scheme.ID == kamelet { + AddKamelet(meta, match[1]) + } + } + } + return nil } @@ -430,7 +444,7 @@ func (i *baseInspector) hasOnlyPassiveEndpoints(fromURIs []string) bool { func (i *baseInspector) containsOnlyURIsIn(fromURI []string, allowed map[string]bool) bool { for _, uri := range fromURI { - if uri == "kamelet:source" { + if uri == kamelet+":source" { continue } prefix := i.getURIPrefix(uri) diff --git a/pkg/util/source/inspector_java_source_test.go b/pkg/util/source/inspector_java_source_test.go index 4d52c9864..0ecc4b5c3 100644 --- a/pkg/util/source/inspector_java_source_test.go +++ b/pkg/util/source/inspector_java_source_test.go @@ -206,3 +206,24 @@ func TestJavaBeanDependencies(t *testing.T) { assert.Contains(t, meta.Dependencies.List(), "camel:log") }) } + +func TestErrorHandlerDependencies(t *testing.T) { + inspector := newTestJavaSourceInspector(t) + + sourceSpec := &v1.SourceSpec{ + DataSpec: v1.DataSpec{ + Name: "test.java", + Content: ` + public void configure() throws Exception { + errorHandler(deadLetterChannel("seda:error")); + from("timer:foo").to("log:bar"); + } + `, + }, + } + assertExtract(t, inspector, sourceSpec.Content, func(meta *Metadata) { + assert.Contains(t, meta.Dependencies.List(), "camel:timer") + assert.Contains(t, meta.Dependencies.List(), "camel:seda") + assert.Contains(t, meta.Dependencies.List(), "camel:log") + }) +} diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go index 2604a5944..521f96242 100644 --- a/pkg/util/source/inspector_xml.go +++ b/pkg/util/source/inspector_xml.go @@ -77,6 +77,18 @@ func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error { } } } + case "deadLetterChannel": + for _, a := range se.Attr { + if a.Name.Local == "deadLetterUri" { + _, scheme := i.catalog.DecodeComponent(a.Value) + if dfDep := i.catalog.GetArtifactByScheme(scheme.ID); dfDep != nil { + meta.AddDependency(dfDep.GetDependencyID()) + } + if scheme.ID == kamelet { + AddKamelet(meta, a.Value) + } + } + } case "from", "fromF": for _, a := range se.Attr { if a.Name.Local == URI { @@ -89,10 +101,10 @@ func (i XMLInspector) Extract(source v1.SourceSpec, meta *Metadata) error { meta.ToURIs = append(meta.ToURIs, a.Value) } } - case "kamelet": + case kamelet: for _, a := range se.Attr { if a.Name.Local == "name" { - AddKamelet(meta, "kamelet:"+a.Value) + AddKamelet(meta, kamelet+":"+a.Value) } } } diff --git a/pkg/util/source/inspector_xml_test.go b/pkg/util/source/inspector_xml_test.go index a8de69477..1b770141a 100644 --- a/pkg/util/source/inspector_xml_test.go +++ b/pkg/util/source/inspector_xml_test.go @@ -238,3 +238,22 @@ func TestXMLBeanDependencies(t *testing.T) { assert.Contains(t, meta.Dependencies.List(), "camel:log") }) } + +func TestXMLErrorHandlerDependencies(t *testing.T) { + xmlCode := ` + <errorHandler> + <deadLetterChannel deadLetterUri="seda:dead"> + <redeliveryPolicy maximumRedeliveries="3" redeliveryDelay="250"/> + </deadLetterChannel> + </errorHandler> + <from uri="timer:foo"/> + <to uri="log:bar"></to> + ` + inspector := newTestXMLInspector(t) + + assertExtract(t, inspector, xmlCode, func(meta *Metadata) { + assert.Contains(t, meta.Dependencies.List(), "camel:timer") + assert.Contains(t, meta.Dependencies.List(), "camel:seda") + assert.Contains(t, meta.Dependencies.List(), "camel:log") + }) +} diff --git a/pkg/util/source/inspector_yaml.go b/pkg/util/source/inspector_yaml.go index 3b280fc7f..840aaaf10 100644 --- a/pkg/util/source/inspector_yaml.go +++ b/pkg/util/source/inspector_yaml.go @@ -111,13 +111,13 @@ func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata } } } - case "kamelet": + case kamelet: switch t := content.(type) { case string: - AddKamelet(meta, "kamelet:"+t) + AddKamelet(meta, kamelet+":"+t) case map[interface{}]interface{}: if name, ok := t["name"].(string); ok { - AddKamelet(meta, "kamelet:"+name) + AddKamelet(meta, kamelet+":"+name) } } } @@ -170,6 +170,16 @@ func (i YAMLInspector) parseStep(key string, content interface{}, meta *Metadata return err } } + case "deadLetterUri": + if s, ok := v.(string); ok { + _, scheme := i.catalog.DecodeComponent(s) + if dfDep := i.catalog.GetArtifactByScheme(scheme.ID); dfDep != nil { + meta.AddDependency(dfDep.GetDependencyID()) + } + if scheme.ID == kamelet { + AddKamelet(meta, s) + } + } default: // Always follow children because from/to uris can be nested if ks, ok := k.(string); ok { diff --git a/pkg/util/source/inspector_yaml_test.go b/pkg/util/source/inspector_yaml_test.go index fbe8c286e..a94c25491 100644 --- a/pkg/util/source/inspector_yaml_test.go +++ b/pkg/util/source/inspector_yaml_test.go @@ -776,3 +776,57 @@ func TestYamlBeanDependencies(t *testing.T) { assert.Contains(t, meta.Dependencies.List(), "camel:log") }) } + +func TestYAMLErrorHandler(t *testing.T) { + yamlContractFirst := ` +- errorHandler: + deadLetterChannel: + deadLetterUri: kafka:my-dlc +- route: + id: route1 + from: + uri: "timer:tick" + parameters: + period: "5000" + steps: + - setBody: + constant: "Hello Yaml !!!" + - transform: + simple: "${body.toUpperCase()}" + - to: "{{url}}" +` + + inspector := newTestYAMLInspector(t) + t.Run("TestYAMLErrorHandler", func(t *testing.T) { + assertExtractYAML(t, inspector, yamlContractFirst, func(meta *Metadata) { + assert.Contains(t, meta.Dependencies.List(), "camel:kafka") + }) + }) +} + +func TestYAMLErrorHandlerKamelet(t *testing.T) { + yamlContractFirst := ` +- errorHandler: + deadLetterChannel: + deadLetterUri: kamelet:my-kamelet/errorHandler +- route: + id: route1 + from: + uri: "timer:tick" + parameters: + period: "5000" + steps: + - setBody: + constant: "Hello Yaml !!!" + - transform: + simple: "${body.toUpperCase()}" + - to: "{{url}}" +` + + inspector := newTestYAMLInspector(t) + t.Run("TestYAMLErrorHandler", func(t *testing.T) { + assertExtractYAML(t, inspector, yamlContractFirst, func(meta *Metadata) { + assert.Contains(t, meta.Kamelets, "my-kamelet/error") + }) + }) +}