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 64dc4fcce fix(trait): cron replace only related components
64dc4fcce is described below

commit 64dc4fccef812bd20b70b6f5b24d33d2cad4960d
Author: Pasquale Congiusti <pasquale.congiu...@gmail.com>
AuthorDate: Thu Jun 19 18:26:40 2025 +0200

    fix(trait): cron replace only related components
    
    Closes #6161
---
 pkg/util/source/inspector_groovy.go           | 52 ++++++++++++---------
 pkg/util/source/inspector_groovy_test.go      | 18 ++++++++
 pkg/util/source/inspector_java_script.go      | 24 +---------
 pkg/util/source/inspector_java_script_test.go | 18 ++++++++
 pkg/util/source/inspector_java_source.go      | 21 +--------
 pkg/util/source/inspector_java_source_test.go | 18 ++++++++
 pkg/util/source/inspector_kotlin.go           | 22 +--------
 pkg/util/source/inspector_kotlin_test.go      | 18 ++++++++
 pkg/util/source/inspector_xml.go              |  4 +-
 pkg/util/source/inspector_xml_test.go         | 66 ++++++++++++++++++++++++++-
 pkg/util/source/inspector_yaml.go             |  8 +++-
 pkg/util/source/inspector_yaml_test.go        | 64 +++++++++++++++++++++-----
 12 files changed, 230 insertions(+), 103 deletions(-)

diff --git a/pkg/util/source/inspector_groovy.go 
b/pkg/util/source/inspector_groovy.go
index 57ecba6c7..bd85c53a4 100644
--- a/pkg/util/source/inspector_groovy.go
+++ b/pkg/util/source/inspector_groovy.go
@@ -18,12 +18,20 @@ limitations under the License.
 package source
 
 import (
-       "strings"
+       "fmt"
+       "regexp"
 
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
        "github.com/apache/camel-k/v2/pkg/util"
 )
 
+var (
+       replaceURISingleQuotedFrom  = 
regexp.MustCompile(`from\s*\(\s*'(?:timer|cron|quartz)[^']*'\s*\)`)
+       replaceURISingleQuotedFromF = 
regexp.MustCompile(`fromF\s*\(\s*'(?:timer|cron|quartz)[^']*'\s*\)`)
+       replaceURIDoubleQuotedFrom  = 
regexp.MustCompile(`from\s*\(\s*"(?:timer|cron|quartz)[^"]*"\s*\)`)
+       replaceURIDoubleQuotedFromF = 
regexp.MustCompile(`fromF\s*\(\s*"(?:timer|cron|quartz)[^"]*"\s*\)`)
+)
+
 // GroovyInspector inspects Groovy DSL spec.
 type GroovyInspector struct {
        baseInspector
@@ -61,25 +69,25 @@ func (i GroovyInspector) Extract(source v1.SourceSpec, meta 
*Metadata) error {
 
 // ReplaceFromURI parses the source content and replace the `from` URI 
configuration with the a new URI. Returns true if it applies a replacement.
 func (i GroovyInspector) ReplaceFromURI(source *v1.SourceSpec, newFromURI 
string) (bool, error) {
-       froms := util.FindAllDistinctStringSubmatch(
-               source.Content,
-               singleQuotedFrom,
-               doubleQuotedFrom,
-               singleQuotedFromF,
-               doubleQuotedFromF,
-       )
-       newContent := source.Content
-       if froms == nil {
-               return false, nil
-       }
-       for _, from := range froms {
-               newContent = strings.ReplaceAll(newContent, from, newFromURI)
-       }
-       replaced := newContent != source.Content
-
-       if replaced {
-               source.Content = newContent
-       }
-
-       return replaced, nil
+       return replaceFromURI(source, newFromURI)
+}
+
+func replaceFromURI(source *v1.SourceSpec, newFromURI string) (bool, error) {
+       originalContent := source.Content
+
+       source.Content = 
replaceURISingleQuotedFrom.ReplaceAllString(source.Content, 
fmt.Sprintf("from('%s')", newFromURI))
+       source.Content = 
replaceURISingleQuotedFromF.ReplaceAllString(source.Content, 
fmt.Sprintf("fromF('%s')", newFromURI))
+       source.Content = 
replaceURIDoubleQuotedFrom.ReplaceAllString(source.Content, 
fmt.Sprintf(`from("%s")`, newFromURI))
+       source.Content = 
replaceURIDoubleQuotedFromF.ReplaceAllString(source.Content, 
fmt.Sprintf(`fromF('%s')`, newFromURI))
+
+       return originalContent != source.Content, nil
+}
+
+func replaceFromURIDoubleQuotesOnly(source *v1.SourceSpec, newFromURI string) 
(bool, error) {
+       originalContent := source.Content
+
+       source.Content = 
replaceURIDoubleQuotedFrom.ReplaceAllString(source.Content, 
fmt.Sprintf(`from("%s")`, newFromURI))
+       source.Content = 
replaceURIDoubleQuotedFromF.ReplaceAllString(source.Content, 
fmt.Sprintf(`fromF('%s')`, newFromURI))
+
+       return originalContent != source.Content, nil
 }
diff --git a/pkg/util/source/inspector_groovy_test.go 
b/pkg/util/source/inspector_groovy_test.go
index c89e1c5dc..f595936fc 100644
--- a/pkg/util/source/inspector_groovy_test.go
+++ b/pkg/util/source/inspector_groovy_test.go
@@ -203,3 +203,21 @@ func TestGroovyReplaceURI(t *testing.T) {
        assert.Nil(t, err)
        assert.Equal(t, "from(\"direct:newURI?hello=world\").to(\"log:info\")", 
sourceSpec.Content)
 }
+
+func TestGroovyMultiReplaceURI(t *testing.T) {
+       inspector := newTestGroovyInspector(t)
+
+       sourceSpec := &v1.SourceSpec{
+               DataSpec: v1.DataSpec{
+                       Name:    "test.groovy",
+                       Content: "from('quartz:trigger?cron=0 0/1 * * * 
?').to('direct:d1');from('direct:d1').to('log:info')",
+               },
+       }
+       replaced, err := inspector.ReplaceFromURI(
+               sourceSpec,
+               "direct:newURI?hello=world",
+       )
+       assert.Nil(t, err)
+       assert.True(t, replaced)
+       assert.Equal(t, 
"from('direct:newURI?hello=world').to('direct:d1');from('direct:d1').to('log:info')",
 sourceSpec.Content)
+}
diff --git a/pkg/util/source/inspector_java_script.go 
b/pkg/util/source/inspector_java_script.go
index c54b18881..cef88834f 100644
--- a/pkg/util/source/inspector_java_script.go
+++ b/pkg/util/source/inspector_java_script.go
@@ -18,8 +18,6 @@ limitations under the License.
 package source
 
 import (
-       "strings"
-
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
        "github.com/apache/camel-k/v2/pkg/util"
 )
@@ -61,25 +59,5 @@ func (i JavaScriptInspector) Extract(source v1.SourceSpec, 
meta *Metadata) error
 
 // ReplaceFromURI parses the source content and replace the `from` URI 
configuration with the a new URI. Returns true if it applies a replacement.
 func (i JavaScriptInspector) ReplaceFromURI(source *v1.SourceSpec, newFromURI 
string) (bool, error) {
-       froms := util.FindAllDistinctStringSubmatch(
-               source.Content,
-               singleQuotedFrom,
-               doubleQuotedFrom,
-               singleQuotedFromF,
-               doubleQuotedFromF,
-       )
-       newContent := source.Content
-       if froms == nil {
-               return false, nil
-       }
-       for _, from := range froms {
-               newContent = strings.ReplaceAll(newContent, from, newFromURI)
-       }
-       replaced := newContent != source.Content
-
-       if replaced {
-               source.Content = newContent
-       }
-
-       return replaced, nil
+       return replaceFromURI(source, newFromURI)
 }
diff --git a/pkg/util/source/inspector_java_script_test.go 
b/pkg/util/source/inspector_java_script_test.go
index 8c860acfb..c777d0279 100644
--- a/pkg/util/source/inspector_java_script_test.go
+++ b/pkg/util/source/inspector_java_script_test.go
@@ -185,3 +185,21 @@ func TestJavascriptReplaceURI(t *testing.T) {
        assert.True(t, replaced)
        assert.Equal(t, "from(\"direct:newURI?hello=world\").to(\"log:info\")", 
sourceSpec.Content)
 }
+
+func TestJavascriptMultiReplaceURI(t *testing.T) {
+       inspector := newTestJavaScriptInspector(t)
+
+       sourceSpec := &v1.SourceSpec{
+               DataSpec: v1.DataSpec{
+                       Name:    "test.js",
+                       Content: "from('quartz:trigger?cron=0 0/1 * * * 
?').to('direct:d1');from('direct:d1').to('log:info')",
+               },
+       }
+       replaced, err := inspector.ReplaceFromURI(
+               sourceSpec,
+               "direct:newURI?hello=world",
+       )
+       assert.Nil(t, err)
+       assert.True(t, replaced)
+       assert.Equal(t, 
"from('direct:newURI?hello=world').to('direct:d1');from('direct:d1').to('log:info')",
 sourceSpec.Content)
+}
diff --git a/pkg/util/source/inspector_java_source.go 
b/pkg/util/source/inspector_java_source.go
index 6486bdcef..74b4bd9f7 100644
--- a/pkg/util/source/inspector_java_source.go
+++ b/pkg/util/source/inspector_java_source.go
@@ -18,8 +18,6 @@ limitations under the License.
 package source
 
 import (
-       "strings"
-
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
        "github.com/apache/camel-k/v2/pkg/util"
 )
@@ -55,22 +53,5 @@ func (i JavaSourceInspector) Extract(source v1.SourceSpec, 
meta *Metadata) error
 
 // ReplaceFromURI parses the source content and replace the `from` URI 
configuration with the a new URI. Returns true if it applies a replacement.
 func (i JavaSourceInspector) ReplaceFromURI(source *v1.SourceSpec, newFromURI 
string) (bool, error) {
-       froms := util.FindAllDistinctStringSubmatch(
-               source.Content,
-               doubleQuotedFrom,
-               doubleQuotedFromF,
-       )
-       newContent := source.Content
-       if froms == nil {
-               return false, nil
-       }
-       for _, from := range froms {
-               newContent = strings.ReplaceAll(newContent, from, newFromURI)
-       }
-       replaced := newContent != source.Content
-       if replaced {
-               source.Content = newContent
-       }
-
-       return replaced, nil
+       return replaceFromURIDoubleQuotesOnly(source, newFromURI)
 }
diff --git a/pkg/util/source/inspector_java_source_test.go 
b/pkg/util/source/inspector_java_source_test.go
index 0ecc4b5c3..24f7241b4 100644
--- a/pkg/util/source/inspector_java_source_test.go
+++ b/pkg/util/source/inspector_java_source_test.go
@@ -172,6 +172,24 @@ func TestJavaReplaceURI(t *testing.T) {
        assert.Equal(t, "from(\"direct:newURI?hello=world\").to(\"log:info\")", 
sourceSpec.Content)
 }
 
+func TestJavaReplaceMultiURI(t *testing.T) {
+       inspector := newTestJavaSourceInspector(t)
+
+       sourceSpec := &v1.SourceSpec{
+               DataSpec: v1.DataSpec{
+                       Name:    "test.java",
+                       Content: "from(\"quartz:trigger?cron=0 0/1 * * * 
?\").to(\"direct:d1\");from(\"direct:d1\").to(\"log:info\");",
+               },
+       }
+       replaced, err := inspector.ReplaceFromURI(
+               sourceSpec,
+               "direct:newURI?hello=world",
+       )
+       assert.Nil(t, err)
+       assert.True(t, replaced)
+       assert.Equal(t, 
"from(\"direct:newURI?hello=world\").to(\"direct:d1\");from(\"direct:d1\").to(\"log:info\");",
 sourceSpec.Content)
+}
+
 func TestJavaRestOpenapiFirst(t *testing.T) {
        inspector := newTestJavaSourceInspector(t)
 
diff --git a/pkg/util/source/inspector_kotlin.go 
b/pkg/util/source/inspector_kotlin.go
index bdf57afe7..14eff39ad 100644
--- a/pkg/util/source/inspector_kotlin.go
+++ b/pkg/util/source/inspector_kotlin.go
@@ -18,8 +18,6 @@ limitations under the License.
 package source
 
 import (
-       "strings"
-
        v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
        "github.com/apache/camel-k/v2/pkg/util"
 )
@@ -55,23 +53,5 @@ func (i KotlinInspector) Extract(source v1.SourceSpec, meta 
*Metadata) error {
 
 // ReplaceFromURI parses the source content and replace the `from` URI 
configuration with the a new URI. Returns true if it applies a replacement.
 func (i KotlinInspector) ReplaceFromURI(source *v1.SourceSpec, newFromURI 
string) (bool, error) {
-       froms := util.FindAllDistinctStringSubmatch(
-               source.Content,
-               doubleQuotedFrom,
-               doubleQuotedFromF,
-       )
-       newContent := source.Content
-       if froms == nil {
-               return false, nil
-       }
-       for _, from := range froms {
-               newContent = strings.ReplaceAll(newContent, from, newFromURI)
-       }
-       replaced := newContent != source.Content
-
-       if replaced {
-               source.Content = newContent
-       }
-
-       return replaced, nil
+       return replaceFromURIDoubleQuotesOnly(source, newFromURI)
 }
diff --git a/pkg/util/source/inspector_kotlin_test.go 
b/pkg/util/source/inspector_kotlin_test.go
index 3e5b9c3b0..a332ad950 100644
--- a/pkg/util/source/inspector_kotlin_test.go
+++ b/pkg/util/source/inspector_kotlin_test.go
@@ -171,3 +171,21 @@ func TestKotlinReplaceURI(t *testing.T) {
        assert.True(t, replaced)
        assert.Equal(t, "from(\"direct:newURI?hello=world\").to(\"log:info\")", 
sourceSpec.Content)
 }
+
+func TestKotlinReplaceMultiURI(t *testing.T) {
+       inspector := newTestKotlinInspector(t)
+
+       sourceSpec := &v1.SourceSpec{
+               DataSpec: v1.DataSpec{
+                       Name:    "test.java",
+                       Content: "from(\"quartz:trigger?cron=0 0/1 * * * 
?\").to(\"direct:d1\");from(\"direct:d1\").to(\"log:info\");",
+               },
+       }
+       replaced, err := inspector.ReplaceFromURI(
+               sourceSpec,
+               "direct:newURI?hello=world",
+       )
+       assert.Nil(t, err)
+       assert.True(t, replaced)
+       assert.Equal(t, 
"from(\"direct:newURI?hello=world\").to(\"direct:d1\");from(\"direct:d1\").to(\"log:info\");",
 sourceSpec.Content)
+}
diff --git a/pkg/util/source/inspector_xml.go b/pkg/util/source/inspector_xml.go
index 521f96242..91ebf98f3 100644
--- a/pkg/util/source/inspector_xml.go
+++ b/pkg/util/source/inspector_xml.go
@@ -140,7 +140,9 @@ func (i XMLInspector) ReplaceFromURI(source *v1.SourceSpec, 
newFromURI string) (
                return false, nil
        }
        for _, from := range metadata.FromURIs {
-               newContent = strings.ReplaceAll(newContent, from, newFromURI)
+               if strings.HasPrefix(from, "timer") || strings.HasPrefix(from, 
"cron") || strings.HasPrefix(from, "quartz") {
+                       newContent = strings.ReplaceAll(newContent, from, 
newFromURI)
+               }
        }
        replaced := newContent != source.Content
 
diff --git a/pkg/util/source/inspector_xml_test.go 
b/pkg/util/source/inspector_xml_test.go
index 1b770141a..182228851 100644
--- a/pkg/util/source/inspector_xml_test.go
+++ b/pkg/util/source/inspector_xml_test.go
@@ -112,6 +112,50 @@ const xmlJSONEip = `
 </camelContext>
 `
 
+const xmlReplaceURI = `
+<camelContext xmlns="http://camel.apache.org/schema/spring";>
+  <route>
+    <from uri="timer:start"/>
+    <to uri="log:info"/>
+  </route>
+</camelContext>
+`
+
+const expectedXmlReplaceURI = `
+<camelContext xmlns="http://camel.apache.org/schema/spring";>
+  <route>
+    <from uri="direct:newURI?hello=world"/>
+    <to uri="log:info"/>
+  </route>
+</camelContext>
+`
+
+const xmlReplaceMultiURI = `
+<camelContext xmlns="http://camel.apache.org/schema/spring";>
+  <route>
+    <from uri="cron:tab"/>
+    <to uri="direct:d1"/>
+  </route>
+  <route>
+    <from uri="direct:d1"/>
+    <to uri="log:info"/>
+  </route>
+</camelContext>
+`
+
+const expectedXmlReplaceMultiURI = `
+<camelContext xmlns="http://camel.apache.org/schema/spring";>
+  <route>
+    <from uri="direct:newURI?hello=world"/>
+    <to uri="direct:d1"/>
+  </route>
+  <route>
+    <from uri="direct:d1"/>
+    <to uri="log:info"/>
+  </route>
+</camelContext>
+`
+
 const xmlJSONJacksonEip = `
 <camelContext xmlns="http://camel.apache.org/schema/spring";>
   <route>
@@ -194,7 +238,25 @@ func TestXMLReplaceURI(t *testing.T) {
        sourceSpec := &v1.SourceSpec{
                DataSpec: v1.DataSpec{
                        Name:    "test.xml",
-                       Content: xmlJSONEip,
+                       Content: xmlReplaceURI,
+               },
+       }
+       replaced, err := inspector.ReplaceFromURI(
+               sourceSpec,
+               "direct:newURI?hello=world",
+       )
+       assert.Nil(t, err)
+       assert.True(t, replaced)
+       assert.Equal(t, expectedXmlReplaceURI, sourceSpec.Content)
+}
+
+func TestXMLReplaceMultiURI(t *testing.T) {
+       inspector := newTestXMLInspector(t)
+
+       sourceSpec := &v1.SourceSpec{
+               DataSpec: v1.DataSpec{
+                       Name:    "test.xml",
+                       Content: xmlReplaceMultiURI,
                },
        }
        replaced, err := inspector.ReplaceFromURI(
@@ -203,7 +265,7 @@ func TestXMLReplaceURI(t *testing.T) {
        )
        assert.Nil(t, err)
        assert.True(t, replaced)
-       assert.Contains(t, sourceSpec.Content, "<from 
uri=\"direct:newURI?hello=world\"/>")
+       assert.Equal(t, expectedXmlReplaceMultiURI, sourceSpec.Content)
 }
 
 func TestXMLRestOpenapiFirst(t *testing.T) {
diff --git a/pkg/util/source/inspector_yaml.go 
b/pkg/util/source/inspector_yaml.go
index 840aaaf10..9d83879b4 100644
--- a/pkg/util/source/inspector_yaml.go
+++ b/pkg/util/source/inspector_yaml.go
@@ -238,7 +238,8 @@ func (i YAMLInspector) parseStepsParam(steps []interface{}, 
meta *Metadata) erro
        return nil
 }
 
-// ReplaceFromURI parses the source content and replace the `from` URI 
configuration with the a new URI. Returns true if it applies a replacement.
+// ReplaceFromURI parses the source content and replace the `from` URI 
configuration with the a new URI.
+// Returns true if it applies a replacement.
 func (i YAMLInspector) ReplaceFromURI(source *v1.SourceSpec, newFromURI 
string) (bool, error) {
        definitions := make([]map[string]interface{}, 0)
 
@@ -264,7 +265,10 @@ func (i YAMLInspector) ReplaceFromURI(source 
*v1.SourceSpec, newFromURI string)
                        }
                }
                delete(from, "parameters")
-               from["uri"] = newFromURI
+               oldURI, ok := from["uri"].(string)
+               if ok && (strings.HasPrefix(oldURI, "timer") || 
strings.HasPrefix(oldURI, "cron") || strings.HasPrefix(oldURI, "quartz")) {
+                       from["uri"] = newFromURI
+               }
        }
 
        newContentRaw, err := yaml2.Marshal(definitions)
diff --git a/pkg/util/source/inspector_yaml_test.go 
b/pkg/util/source/inspector_yaml_test.go
index a94c25491..af688756e 100644
--- a/pkg/util/source/inspector_yaml_test.go
+++ b/pkg/util/source/inspector_yaml_test.go
@@ -672,24 +672,45 @@ const yamlFromCronReplacement = `
     - to: "{{url}}"
 `
 
-const expectedYamlFromCronReplacement = `from:
+const yamlFromMultiCronReplacement = `
+- from:
+    uri: "cron:tab"
+    parameters:
+      schedule: "* * * * ?"
+    steps:
+    - to: "direct:hello"
+- from:
+    uri: "direct:hello"
+    steps:
+    - setBody:
+        constant: "Hello Yaml !!!"
+    - transform:
+        simple: "${body.toUpperCase()}"
+    - to: "{{url}}"
+`
+
+const expectedYamlFromMultiCronReplacement = `- from:
+    steps:
+    - to: direct:hello
+    uri: direct:newURI?hello=world
+- from:
     steps:
     - setBody:
         constant: Hello Yaml !!!
     - transform:
         simple: ${body.toUpperCase()}
     - to: '{{url}}'
-    uri: direct:newURI?hello=world
+    uri: direct:hello
 `
 
-const expectedYamlRouteCronReplacement = `from:
-      steps:
-      - setBody:
-          constant: Hello Yaml !!!
-      - transform:
-          simple: ${body.toUpperCase()}
-      - to: '{{url}}'
-      uri: direct:newURI?hello=world
+const expectedYamlFromCronReplacement = `from:
+    steps:
+    - setBody:
+        constant: Hello Yaml !!!
+    - transform:
+        simple: ${body.toUpperCase()}
+    - to: '{{url}}'
+    uri: direct:newURI?hello=world
 `
 
 func TestYAMLFromReplaceURI(t *testing.T) {
@@ -717,7 +738,7 @@ func TestYAMLRouteReplaceURI(t *testing.T) {
        sourceSpec := &v1.SourceSpec{
                DataSpec: v1.DataSpec{
                        Name:    "test.yaml",
-                       Content: yamlRouteCronReplacement,
+                       Content: yamlFromCronReplacement,
                },
        }
        replaced, err := inspector.ReplaceFromURI(
@@ -727,7 +748,26 @@ func TestYAMLRouteReplaceURI(t *testing.T) {
        assert.Nil(t, err)
        assert.True(t, replaced)
        // Assert changed uri and removed parameters
-       assert.Contains(t, sourceSpec.Content, expectedYamlRouteCronReplacement)
+       assert.Contains(t, sourceSpec.Content, expectedYamlFromCronReplacement)
+}
+
+func TestYAMLFromWithMultiRouteReplaceURI(t *testing.T) {
+       inspector := newTestYAMLInspector(t)
+
+       sourceSpec := &v1.SourceSpec{
+               DataSpec: v1.DataSpec{
+                       Name:    "test.yaml",
+                       Content: yamlFromMultiCronReplacement,
+               },
+       }
+       replaced, err := inspector.ReplaceFromURI(
+               sourceSpec,
+               "direct:newURI?hello=world",
+       )
+       assert.Nil(t, err)
+       assert.True(t, replaced)
+       // Assert changed cron uri only
+       assert.Equal(t, expectedYamlFromMultiCronReplacement, 
sourceSpec.Content)
 }
 
 func TestYAMLRESTContractFirst(t *testing.T) {

Reply via email to