This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new 9a6721628ea8 CAMEL-23981: Fix 12 camel-yaml-dsl bugs
9a6721628ea8 is described below
commit 9a6721628ea83274a9624cd303b908340a53d3c8
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Jul 11 19:32:47 2026 +0200
CAMEL-23981: Fix 12 camel-yaml-dsl bugs
Fix 12 YAML DSL bugs reported by Federico Mariani (CAMEL-23981 through
CAMEL-23992):
- springTransactionErrorHandler creating wrong definition type
- Bean cache cleared too early when loading multiple YAML files
- @YamlProperty flag emission swapped required/deprecated, isSecret used
wrong accessor
- Unsupported top-level YAML mappings silently ignored without warning
- Pipe handling lacked validation for unsupported ref kinds, missing sink,
empty errorHandler
- routeConfiguration lost line number, source location, and resource
metadata
- Missing note property on from, routeConfiguration, and kamelet
deserializers
- MultiValue endpoint parameters not flattened when URI has a path
- nodeAt() matched later pointer segments at wrong depth
- MessageFormat crash when error messages contain curly braces
- ValidateMojo ignored application.yaml only and used static field for
per-instance state
- Inverted $ref check in extractRequiredFromComposition
Closes #24599
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
.../dsl/yaml/common/YamlDeserializerSupport.java | 9 +-
.../apache/camel/dsl/yaml/common/YamlSupport.java | 14 +++
.../apache/camel/dsl/yaml/common/NodeAtTest.groovy | 107 +++++++++++++++++++++
.../dsl/yaml/deserializers/ModelDeserializers.java | 36 +++----
.../deserializers/ErrorHandlerDeserializer.java | 5 +-
.../yaml/deserializers/KameletDeserializer.java | 8 ++
.../OutputAwareFromDefinitionDeserializer.java | 8 ++
.../RouteConfigurationDefinitionDeserializer.java | 10 ++
.../dsl/yaml/GenerateYamlDeserializersMojo.java | 28 +++---
.../maven/dsl/yaml/GenerateYamlSchemaMojo.java | 2 +-
.../maven/dsl/yaml/support/YamlProperties.java | 2 +-
.../camel/dsl/yaml/validator/ValidateMojo.java | 7 +-
.../camel/dsl/yaml/validator/CamelYamlParser.java | 4 +-
.../camel/dsl/yaml/validator/YamlParser.java | 4 +-
.../camel/dsl/yaml/validator/YamlValidator.java | 4 +-
.../resources/schema/camelYamlDsl-canonical.json | 61 ++++++++----
.../generated/resources/schema/camelYamlDsl.json | 60 ++++++++----
.../camel/dsl/yaml/YamlRoutesBuilderLoader.java | 32 +++++-
.../apache/camel/dsl/yaml/ErrorHandlerTest.groovy | 16 +++
.../org/apache/camel/dsl/yaml/KameletTest.groovy | 39 ++++++++
.../apache/camel/dsl/yaml/PipeLoaderTest.groovy | 31 ++++++
.../org/apache/camel/dsl/yaml/RestTest.groovy | 3 +-
.../camel/dsl/yaml/RouteConfigurationTest.groovy | 59 ++++++++++++
.../org/apache/camel/dsl/yaml/RoutesTest.groovy | 26 +++++
24 files changed, 487 insertions(+), 88 deletions(-)
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerSupport.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerSupport.java
index 0c661f570e2c..4b2bef9d6b5d 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerSupport.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlDeserializerSupport.java
@@ -418,17 +418,24 @@ public class YamlDeserializerSupport {
MappingNode mn = asMappingNode(root);
for (String path : pointer.split("/")) {
+ if (path.isEmpty()) {
+ continue;
+ }
for (NodeTuple child : mn.getValue()) {
if (child.getKeyNode() instanceof ScalarNode) {
ScalarNode scalar = (ScalarNode) child.getKeyNode();
if (scalar.getValue().equals(path)) {
- String next = pointer.substring(path.length() + 1);
+ String next = pointer.substring(pointer.indexOf(path)
+ path.length());
+ if (next.startsWith("/")) {
+ next = next.substring(1);
+ }
return ObjectHelper.isEmpty(next)
? child.getValueNode()
: nodeAt(child.getValueNode(), next);
}
}
}
+ return null;
}
return null;
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java
index ed59e13806fd..aebd4bbda4fd 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/main/java/org/apache/camel/dsl/yaml/common/YamlSupport.java
@@ -119,6 +119,20 @@ public final class YamlSupport {
}
}
+ // flatten multiValue map parameters
+ for (Map.Entry<String, String> multi :
factory.multiValuePrefixes().entrySet()) {
+ Object val = options.get(multi.getKey());
+ if (val instanceof Map<?, ?> m) {
+ String prefix = multi.getValue();
+ for (var entry : m.entrySet()) {
+ if (entry.getValue() != null) {
+ options.put(prefix + entry.getKey(),
entry.getValue());
+ }
+ }
+ options.remove(multi.getKey());
+ }
+ }
+
answer += "?" + URISupport.createQueryString(options,
false);
}
} else {
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/test/groovy/org/apache/camel/dsl/yaml/common/NodeAtTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/test/groovy/org/apache/camel/dsl/yaml/common/NodeAtTest.groovy
new file mode 100644
index 000000000000..9df80f30ca8a
--- /dev/null
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-common/src/test/groovy/org/apache/camel/dsl/yaml/common/NodeAtTest.groovy
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.yaml.common
+
+import org.snakeyaml.engine.v2.common.FlowStyle
+import org.snakeyaml.engine.v2.common.ScalarStyle
+import org.snakeyaml.engine.v2.nodes.MappingNode
+import org.snakeyaml.engine.v2.nodes.NodeTuple
+import org.snakeyaml.engine.v2.nodes.ScalarNode
+import org.snakeyaml.engine.v2.nodes.Tag
+import spock.lang.Specification
+
+class NodeAtTest extends Specification {
+
+ private static ScalarNode scalar(String value) {
+ return new ScalarNode(Tag.STR, value, ScalarStyle.PLAIN)
+ }
+
+ private static MappingNode mapping(Map<String, Object> entries) {
+ def tuples = entries.collect { k, v ->
+ def valNode = v instanceof Map ? mapping(v as Map<String, Object>)
: scalar(v.toString())
+ new NodeTuple(scalar(k), valNode)
+ }
+ return new MappingNode(Tag.MAP, tuples, FlowStyle.BLOCK)
+ }
+
+ def "nodeAt with leading slash"() {
+ given:
+ def root = mapping(foo: [bar: 'hello'])
+ when:
+ def result = YamlDeserializerSupport.nodeAt(root, "/foo/bar")
+ then:
+ result instanceof ScalarNode
+ (result as ScalarNode).value == 'hello'
+ }
+
+ def "nodeAt without leading slash"() {
+ given:
+ def root = mapping(foo: [bar: 'hello'])
+ when:
+ def result = YamlDeserializerSupport.nodeAt(root, "foo/bar")
+ then:
+ result instanceof ScalarNode
+ (result as ScalarNode).value == 'hello'
+ }
+
+ def "nodeAt single segment"() {
+ given:
+ def root = mapping(foo: 'hello')
+ when:
+ def result = YamlDeserializerSupport.nodeAt(root, "/foo")
+ then:
+ result instanceof ScalarNode
+ (result as ScalarNode).value == 'hello'
+ }
+
+ def "nodeAt returns null for missing path"() {
+ given:
+ def root = mapping(foo: [bar: 'hello'])
+ when:
+ def result = YamlDeserializerSupport.nodeAt(root, "/foo/missing")
+ then:
+ result == null
+ }
+
+ def "nodeAt with empty pointer returns root"() {
+ given:
+ def root = mapping(foo: 'hello')
+ when:
+ def result = YamlDeserializerSupport.nodeAt(root, "")
+ then:
+ result == root
+ }
+
+ def "nodeAt three levels deep"() {
+ given:
+ def root = mapping(a: [b: [c: 'deep']])
+ when:
+ def result = YamlDeserializerSupport.nodeAt(root, "/a/b/c")
+ then:
+ result instanceof ScalarNode
+ (result as ScalarNode).value == 'deep'
+ }
+
+ def "nodeAt stops at first missing segment"() {
+ given:
+ def root = mapping(a: [b: [c: 'deep']])
+ when:
+ def result = YamlDeserializerSupport.nodeAt(root, "/a/missing/c")
+ then:
+ result == null
+ }
+}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index 9100e8858fd7..49e692108309 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -1605,7 +1605,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "defaultValueStringAsNull", type =
"boolean", defaultValue = "false", description = "To change the default value
for string types to be null instead of an empty string.", displayName =
"Default Value String As Null"),
@YamlProperty(name = "id", type = "string", description =
"The id of this node", displayName = "Id"),
@YamlProperty(name = "locale", type = "string",
description = "To configure a default locale to use, such as us for united
states. To use the JVM platform default locale then use the name default.",
displayName = "Locale"),
- @YamlProperty(name = "type", type =
"enum:Csv,Fixed,KeyValue", description = "Whether to use Csv, Fixed, or
KeyValue.", displayName = "Type"),
+ @YamlProperty(name = "type", type =
"enum:Csv,Fixed,KeyValue", required = true, description = "Whether to use Csv,
Fixed, or KeyValue.", displayName = "Type"),
@YamlProperty(name = "unwrapSingleInstance", type =
"boolean", defaultValue = "true", description = "When unmarshalling should a
single instance be unwrapped and returned instead of wrapped in a
java.util.List.", displayName = "Unwrap Single Instance")
}
)
@@ -2107,7 +2107,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "id", type = "string", description =
"The id of this node", displayName = "Id"),
@YamlProperty(name = "key", type = "string", description =
"The unique claim check key to use for Get, GetAndRemove, and Set operations.",
displayName = "Key"),
@YamlProperty(name = "note", type = "string", description
= "The note for this node", displayName = "Note"),
- @YamlProperty(name = "operation", type =
"enum:Get,GetAndRemove,Set,Push,Pop", description = "The claim check operation
to use. Get=retrieve, GetAndRemove=retrieve and remove, Set=store with key,
Push=store on stack, Pop=retrieve from stack.", displayName = "Operation")
+ @YamlProperty(name = "operation", type =
"enum:Get,GetAndRemove,Set,Push,Pop", required = true, description = "The claim
check operation to use. Get=retrieve, GetAndRemove=retrieve and remove,
Set=store with key, Push=store on stack, Pop=retrieve from stack.", displayName
= "Operation")
}
)
public static class ClaimCheckDefinitionDeserializer extends
YamlDeserializerBase<ClaimCheckDefinition> {
@@ -4510,7 +4510,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "security", type =
"array:org.apache.camel.model.rest.SecurityDefinition", description = "Security
settings for this REST operation", displayName = "Security"),
@YamlProperty(name = "skipBindingOnErrorCode", type =
"boolean", defaultValue = "false", description = "Whether to skip binding on
output if there is a custom HTTP error code header. This allows to build custom
error messages that do not bind to json / xml etc, as success messages
otherwise will do. This option will override what may be configured on a parent
level.", displayName = "Skip Binding On Error Code"),
@YamlProperty(name = "streamCache", type = "boolean",
defaultValue = "false", description = "Whether stream caching is enabled on
this rest operation.", displayName = "Stream Cache"),
- @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", description = "The Camel endpoint
this REST service will call, such as a direct endpoint to link to an existing
route that handles this REST call.", displayName = "To"),
+ @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", required = true, description =
"The Camel endpoint this REST service will call, such as a direct endpoint to
link to an existing route that handles this REST call.", displayName = "To"),
@YamlProperty(name = "type", type = "string", description
= "Sets the class name to use for binding from input to POJO for the incoming
data. This option will override what may be configured on a parent level.",
displayName = "Type")
}
)
@@ -6010,7 +6010,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "security", type =
"array:org.apache.camel.model.rest.SecurityDefinition", description = "Security
settings for this REST operation", displayName = "Security"),
@YamlProperty(name = "skipBindingOnErrorCode", type =
"boolean", defaultValue = "false", description = "Whether to skip binding on
output if there is a custom HTTP error code header. This allows to build custom
error messages that do not bind to json / xml etc, as success messages
otherwise will do. This option will override what may be configured on a parent
level.", displayName = "Skip Binding On Error Code"),
@YamlProperty(name = "streamCache", type = "boolean",
defaultValue = "false", description = "Whether stream caching is enabled on
this rest operation.", displayName = "Stream Cache"),
- @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", description = "The Camel endpoint
this REST service will call, such as a direct endpoint to link to an existing
route that handles this REST call.", displayName = "To"),
+ @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", required = true, description =
"The Camel endpoint this REST service will call, such as a direct endpoint to
link to an existing route that handles this REST call.", displayName = "To"),
@YamlProperty(name = "type", type = "string", description
= "Sets the class name to use for binding from input to POJO for the incoming
data. This option will override what may be configured on a parent level.",
displayName = "Type")
}
)
@@ -6582,7 +6582,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "security", type =
"array:org.apache.camel.model.rest.SecurityDefinition", description = "Security
settings for this REST operation", displayName = "Security"),
@YamlProperty(name = "skipBindingOnErrorCode", type =
"boolean", defaultValue = "false", description = "Whether to skip binding on
output if there is a custom HTTP error code header. This allows to build custom
error messages that do not bind to json / xml etc, as success messages
otherwise will do. This option will override what may be configured on a parent
level.", displayName = "Skip Binding On Error Code"),
@YamlProperty(name = "streamCache", type = "boolean",
defaultValue = "false", description = "Whether stream caching is enabled on
this rest operation.", displayName = "Stream Cache"),
- @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", description = "The Camel endpoint
this REST service will call, such as a direct endpoint to link to an existing
route that handles this REST call.", displayName = "To"),
+ @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", required = true, description =
"The Camel endpoint this REST service will call, such as a direct endpoint to
link to an existing route that handles this REST call.", displayName = "To"),
@YamlProperty(name = "type", type = "string", description
= "Sets the class name to use for binding from input to POJO for the incoming
data. This option will override what may be configured on a parent level.",
displayName = "Type")
}
)
@@ -8529,7 +8529,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "maxOverlap", type = "number",
required = true, description = "The maximum number of tokens that can overlap
in each segment.", displayName = "Max Overlap"),
@YamlProperty(name = "maxTokens", type = "number",
required = true, description = "The maximum number of tokens on each segment.",
displayName = "Max Tokens"),
@YamlProperty(name = "modelName", type = "string",
description = "The underlying model name used by the tokenizer. Providing this
switches to computing segment sizes in terms of tokens.", displayName = "Model
Name"),
- @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", description = "The tokenizer type. Must be one of
OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
+ @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", required = true, description = "The tokenizer type.
Must be one of OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
}
)
public static class LangChain4jCharacterTokenizerDefinitionDeserializer
extends YamlDeserializerBase<LangChain4jCharacterTokenizerDefinition> {
@@ -8592,7 +8592,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "maxOverlap", type = "number",
required = true, description = "The maximum number of tokens that can overlap
in each segment.", displayName = "Max Overlap"),
@YamlProperty(name = "maxTokens", type = "number",
required = true, description = "The maximum number of tokens on each segment.",
displayName = "Max Tokens"),
@YamlProperty(name = "modelName", type = "string",
description = "The underlying model name used by the tokenizer. Providing this
switches to computing segment sizes in terms of tokens.", displayName = "Model
Name"),
- @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", description = "The tokenizer type. Must be one of
OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
+ @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", required = true, description = "The tokenizer type.
Must be one of OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
}
)
public static class LangChain4jLineTokenizerDefinitionDeserializer extends
YamlDeserializerBase<LangChain4jLineTokenizerDefinition> {
@@ -8655,7 +8655,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "maxOverlap", type = "number",
required = true, description = "The maximum number of tokens that can overlap
in each segment.", displayName = "Max Overlap"),
@YamlProperty(name = "maxTokens", type = "number",
required = true, description = "The maximum number of tokens on each segment.",
displayName = "Max Tokens"),
@YamlProperty(name = "modelName", type = "string",
description = "The underlying model name used by the tokenizer. Providing this
switches to computing segment sizes in terms of tokens.", displayName = "Model
Name"),
- @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", description = "The tokenizer type. Must be one of
OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
+ @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", required = true, description = "The tokenizer type.
Must be one of OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
}
)
public static class LangChain4jParagraphTokenizerDefinitionDeserializer
extends YamlDeserializerBase<LangChain4jParagraphTokenizerDefinition> {
@@ -8718,7 +8718,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "maxOverlap", type = "number",
required = true, description = "The maximum number of tokens that can overlap
in each segment.", displayName = "Max Overlap"),
@YamlProperty(name = "maxTokens", type = "number",
required = true, description = "The maximum number of tokens on each segment.",
displayName = "Max Tokens"),
@YamlProperty(name = "modelName", type = "string",
description = "The underlying model name used by the tokenizer. Providing this
switches to computing segment sizes in terms of tokens.", displayName = "Model
Name"),
- @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", description = "The tokenizer type. Must be one of
OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
+ @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", required = true, description = "The tokenizer type.
Must be one of OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
}
)
public static class LangChain4jSentenceTokenizerDefinitionDeserializer
extends YamlDeserializerBase<LangChain4jSentenceTokenizerDefinition> {
@@ -8777,7 +8777,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "maxOverlap", type = "number",
required = true),
@YamlProperty(name = "maxTokens", type = "number",
required = true),
@YamlProperty(name = "modelName", type = "string"),
- @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN")
+ @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", required = true)
}
)
public static class LangChain4jTokenizerDefinitionDeserializer extends
YamlDeserializerBase<LangChain4jTokenizerDefinition> {
@@ -8840,7 +8840,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "maxOverlap", type = "number",
required = true, description = "The maximum number of tokens that can overlap
in each segment.", displayName = "Max Overlap"),
@YamlProperty(name = "maxTokens", type = "number",
required = true, description = "The maximum number of tokens on each segment.",
displayName = "Max Tokens"),
@YamlProperty(name = "modelName", type = "string",
description = "The underlying model name used by the tokenizer. Providing this
switches to computing segment sizes in terms of tokens.", displayName = "Model
Name"),
- @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", description = "The tokenizer type. Must be one of
OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
+ @YamlProperty(name = "tokenizerType", type =
"enum:OPEN_AI,AZURE,QWEN", required = true, description = "The tokenizer type.
Must be one of OPEN_AI, AZURE or QWEN.", displayName = "Tokenizer Type")
}
)
public static class LangChain4jWordTokenizerDefinitionDeserializer extends
YamlDeserializerBase<LangChain4jWordTokenizerDefinition> {
@@ -11393,7 +11393,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "examples", type =
"array:org.apache.camel.model.rest.RestPropertyDefinition", description =
"Examples of the parameter.", displayName = "Examples"),
@YamlProperty(name = "name", type = "string", required =
true, description = "The parameter name.", displayName = "Name"),
@YamlProperty(name = "required", type = "boolean",
defaultValue = "true", description = "Sets the parameter required flag.",
displayName = "Required"),
- @YamlProperty(name = "type", type =
"enum:body,formData,header,path,query", defaultValue = "path", description =
"Sets the parameter type such as body, form, header, path, or query.",
displayName = "Type")
+ @YamlProperty(name = "type", type =
"enum:body,formData,header,path,query", required = true, defaultValue = "path",
description = "Sets the parameter type such as body, form, header, path, or
query.", displayName = "Type")
}
)
public static class ParamDefinitionDeserializer extends
YamlDeserializerBase<ParamDefinition> {
@@ -11564,7 +11564,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "security", type =
"array:org.apache.camel.model.rest.SecurityDefinition", description = "Security
settings for this REST operation", displayName = "Security"),
@YamlProperty(name = "skipBindingOnErrorCode", type =
"boolean", defaultValue = "false", description = "Whether to skip binding on
output if there is a custom HTTP error code header. This allows to build custom
error messages that do not bind to json / xml etc, as success messages
otherwise will do. This option will override what may be configured on a parent
level.", displayName = "Skip Binding On Error Code"),
@YamlProperty(name = "streamCache", type = "boolean",
defaultValue = "false", description = "Whether stream caching is enabled on
this rest operation.", displayName = "Stream Cache"),
- @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", description = "The Camel endpoint
this REST service will call, such as a direct endpoint to link to an existing
route that handles this REST call.", displayName = "To"),
+ @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", required = true, description =
"The Camel endpoint this REST service will call, such as a direct endpoint to
link to an existing route that handles this REST call.", displayName = "To"),
@YamlProperty(name = "type", type = "string", description
= "Sets the class name to use for binding from input to POJO for the incoming
data. This option will override what may be configured on a parent level.",
displayName = "Type")
}
)
@@ -12155,7 +12155,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "security", type =
"array:org.apache.camel.model.rest.SecurityDefinition", description = "Security
settings for this REST operation", displayName = "Security"),
@YamlProperty(name = "skipBindingOnErrorCode", type =
"boolean", defaultValue = "false", description = "Whether to skip binding on
output if there is a custom HTTP error code header. This allows to build custom
error messages that do not bind to json / xml etc, as success messages
otherwise will do. This option will override what may be configured on a parent
level.", displayName = "Skip Binding On Error Code"),
@YamlProperty(name = "streamCache", type = "boolean",
defaultValue = "false", description = "Whether stream caching is enabled on
this rest operation.", displayName = "Stream Cache"),
- @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", description = "The Camel endpoint
this REST service will call, such as a direct endpoint to link to an existing
route that handles this REST call.", displayName = "To"),
+ @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", required = true, description =
"The Camel endpoint this REST service will call, such as a direct endpoint to
link to an existing route that handles this REST call.", displayName = "To"),
@YamlProperty(name = "type", type = "string", description
= "Sets the class name to use for binding from input to POJO for the incoming
data. This option will override what may be configured on a parent level.",
displayName = "Type")
}
)
@@ -12459,7 +12459,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
deprecated = false,
properties = {
@YamlProperty(name = "__extends", type =
"object:org.apache.camel.model.language.ExpressionDefinition", oneOf =
"expression"),
- @YamlProperty(name = "expression", type =
"object:org.apache.camel.model.language.ExpressionDefinition", description =
"The property value as an expression.", displayName = "Expression", oneOf =
"expression"),
+ @YamlProperty(name = "expression", type =
"object:org.apache.camel.model.language.ExpressionDefinition", required = true,
description = "The property value as an expression.", displayName =
"Expression", oneOf = "expression"),
@YamlProperty(name = "key", type = "string", required =
true, description = "The property key.", displayName = "Key")
}
)
@@ -12704,7 +12704,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "security", type =
"array:org.apache.camel.model.rest.SecurityDefinition", description = "Security
settings for this REST operation", displayName = "Security"),
@YamlProperty(name = "skipBindingOnErrorCode", type =
"boolean", defaultValue = "false", description = "Whether to skip binding on
output if there is a custom HTTP error code header. This allows to build custom
error messages that do not bind to json / xml etc, as success messages
otherwise will do. This option will override what may be configured on a parent
level.", displayName = "Skip Binding On Error Code"),
@YamlProperty(name = "streamCache", type = "boolean",
defaultValue = "false", description = "Whether stream caching is enabled on
this rest operation.", displayName = "Stream Cache"),
- @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", description = "The Camel endpoint
this REST service will call, such as a direct endpoint to link to an existing
route that handles this REST call.", displayName = "To"),
+ @YamlProperty(name = "to", type =
"object:org.apache.camel.model.ToDefinition", required = true, description =
"The Camel endpoint this REST service will call, such as a direct endpoint to
link to an existing route that handles this REST call.", displayName = "To"),
@YamlProperty(name = "type", type = "string", description
= "Sets the class name to use for binding from input to POJO for the incoming
data. This option will override what may be configured on a parent level.",
displayName = "Type")
}
)
@@ -13793,7 +13793,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "batchConfig", type =
"object:org.apache.camel.model.config.BatchResequencerConfig", oneOf =
"resequencerConfig"),
@YamlProperty(name = "description", type = "string",
description = "The description for this node", displayName = "Description"),
@YamlProperty(name = "disabled", type = "boolean",
defaultValue = "false", description = "Whether to disable this EIP from the
route during build time. Once an EIP has been disabled then it cannot be
enabled later at runtime.", displayName = "Disabled"),
- @YamlProperty(name = "expression", type =
"object:org.apache.camel.model.language.ExpressionDefinition", description =
"Expression to use for re-ordering the messages, such as a header with a
sequence number.", displayName = "Expression", oneOf = "expression"),
+ @YamlProperty(name = "expression", type =
"object:org.apache.camel.model.language.ExpressionDefinition", required = true,
description = "Expression to use for re-ordering the messages, such as a header
with a sequence number.", displayName = "Expression", oneOf = "expression"),
@YamlProperty(name = "id", type = "string", description =
"The id of this node", displayName = "Id"),
@YamlProperty(name = "note", type = "string", description
= "The note for this node", displayName = "Note"),
@YamlProperty(name = "steps", type =
"array:org.apache.camel.model.ProcessorDefinition"),
@@ -16153,7 +16153,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "disabled", type = "boolean",
defaultValue = "false", description = "Whether to disable this EIP from the
route during build time. Once an EIP has been disabled then it cannot be
enabled later at runtime.", displayName = "Disabled"),
@YamlProperty(name = "id", type = "string", description =
"The id of this node", displayName = "Id"),
@YamlProperty(name = "note", type = "string", description
= "The note for this node", displayName = "Note"),
- @YamlProperty(name = "pattern", type =
"enum:InOnly,InOut", description = "The new exchange pattern to use from this
point forward.", displayName = "Pattern")
+ @YamlProperty(name = "pattern", type =
"enum:InOnly,InOut", required = true, description = "The new exchange pattern
to use from this point forward.", displayName = "Pattern")
}
)
public static class SetExchangePatternDefinitionDeserializer extends
YamlDeserializerBase<SetExchangePatternDefinition> {
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerDeserializer.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerDeserializer.java
index 8d76392b74d7..4aab6dafd507 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerDeserializer.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/ErrorHandlerDeserializer.java
@@ -28,6 +28,7 @@ import
org.apache.camel.model.errorhandler.DefaultErrorHandlerDefinition;
import
org.apache.camel.model.errorhandler.JtaTransactionErrorHandlerDefinition;
import org.apache.camel.model.errorhandler.NoErrorHandlerDefinition;
import org.apache.camel.model.errorhandler.RefErrorHandlerDefinition;
+import
org.apache.camel.model.errorhandler.SpringTransactionErrorHandlerDefinition;
import org.apache.camel.spi.CamelContextCustomizer;
import org.apache.camel.spi.annotations.YamlIn;
import org.apache.camel.spi.annotations.YamlProperty;
@@ -110,9 +111,11 @@ public class ErrorHandlerDeserializer implements
ConstructNode {
factory = asType(val, DefaultErrorHandlerDefinition.class);
break;
case "jtaTransactionErrorHandler":
- case "springTransactionErrorHandler":
factory = asType(val,
JtaTransactionErrorHandlerDefinition.class);
break;
+ case "springTransactionErrorHandler":
+ factory = asType(val,
SpringTransactionErrorHandlerDefinition.class);
+ break;
case "noErrorHandler":
factory = asType(val, NoErrorHandlerDefinition.class);
break;
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/KameletDeserializer.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/KameletDeserializer.java
index 59bf9a8dda12..04821dac494c 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/KameletDeserializer.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/KameletDeserializer.java
@@ -37,6 +37,8 @@ import org.snakeyaml.engine.v2.nodes.NodeTuple;
nodes = "kamelet",
properties = {
@YamlProperty(name = "name", type = "string", required =
true),
+ @YamlProperty(name = "description", type = "string"),
+ @YamlProperty(name = "note", type = "string"),
@YamlProperty(name = "parameters", type = "object"),
@YamlProperty(name = "steps", type =
"array:org.apache.camel.model.ProcessorDefinition")
})
@@ -76,6 +78,12 @@ public class KameletDeserializer extends
YamlDeserializerBase<KameletDefinition>
case "id":
target.setId(asText(val));
break;
+ case "description":
+ target.setDescription(asText(val));
+ break;
+ case "note":
+ target.setNote(asText(val));
+ break;
case "name":
name = asText(val);
break;
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/OutputAwareFromDefinitionDeserializer.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/OutputAwareFromDefinitionDeserializer.java
index e587b71ef4a0..12850af756e0 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/OutputAwareFromDefinitionDeserializer.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/OutputAwareFromDefinitionDeserializer.java
@@ -40,6 +40,7 @@ import org.snakeyaml.engine.v2.nodes.NodeTuple;
@YamlProperty(name = "variableReceive", type = "string"),
@YamlProperty(name = "id", type = "string"),
@YamlProperty(name = "description", type = "string"),
+ @YamlProperty(name = "note", type = "string"),
@YamlProperty(name = "parameters", type = "object"),
@YamlProperty(name = "steps", type =
"array:org.apache.camel.model.ProcessorDefinition", required = true)
})
@@ -71,6 +72,7 @@ public class OutputAwareFromDefinitionDeserializer extends
YamlDeserializerBase<
String uri = null;
String id = null;
String desc = null;
+ String note = null;
String variableReceive = null;
Map<String, Object> parameters = null;
@@ -88,6 +90,9 @@ public class OutputAwareFromDefinitionDeserializer extends
YamlDeserializerBase<
case "description":
desc = asText(val);
break;
+ case "note":
+ note = asText(val);
+ break;
case "uri":
uri = asText(val);
break;
@@ -120,6 +125,9 @@ public class OutputAwareFromDefinitionDeserializer extends
YamlDeserializerBase<
if (desc != null) {
from.setDescription(desc);
}
+ if (note != null) {
+ from.setNote(note);
+ }
if (variableReceive != null) {
from.setVariableReceive(variableReceive);
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteConfigurationDefinitionDeserializer.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteConfigurationDefinitionDeserializer.java
index 45f0dbdab21c..e6614cc28909 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteConfigurationDefinitionDeserializer.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/main/java/org/apache/camel/dsl/yaml/deserializers/RouteConfigurationDefinitionDeserializer.java
@@ -44,6 +44,7 @@ import org.snakeyaml.engine.v2.nodes.NodeTuple;
properties = {
@YamlProperty(name = "id", type = "string"),
@YamlProperty(name = "description", type = "string"),
+ @YamlProperty(name = "note", type = "string"),
@YamlProperty(name = "precondition", type = "string"),
@YamlProperty(name = "errorHandler", type =
"object:org.apache.camel.model.ErrorHandlerDefinition"),
@YamlProperty(name = "intercept", wrapItem = true,
@@ -76,6 +77,12 @@ public class RouteConfigurationDefinitionDeserializer
extends YamlDeserializerBa
final MappingNode bn = asMappingNode(node);
setDeserializationContext(node, dc);
+ int line = -1;
+ if (node.getStartMark().isPresent()) {
+ line = node.getStartMark().get().getLine();
+ }
+ onNewTarget(node, target, line);
+
for (NodeTuple tuple : bn.getValue()) {
String key = asText(tuple.getKeyNode());
Node val = tuple.getValueNode();
@@ -88,6 +95,9 @@ public class RouteConfigurationDefinitionDeserializer extends
YamlDeserializerBa
case "description":
target.setDescription(asText(val));
break;
+ case "note":
+ target.setNote(asText(val));
+ break;
case "precondition":
target.setPrecondition(asText(val));
break;
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java
index e83a2766ec34..d0d60ae00fa9 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlDeserializersMojo.java
@@ -909,7 +909,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
.withDescription(descriptor.description(name))
.withDisplayName(descriptor.displayName(name))
.withDefaultValue(descriptor.defaultValue(name))
-
.withIsSecret(descriptor.defaultValue(name))
+
.withIsSecret(descriptor.isSecret(name))
.build());
}
return true;
@@ -948,7 +948,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
.withDescription(descriptor.description(name))
.withDisplayName(descriptor.displayName(name))
.withDefaultValue(descriptor.defaultValue(name))
-
.withIsSecret(descriptor.defaultValue(name))
+
.withIsSecret(descriptor.isSecret(name))
.build());
}
return true;
@@ -1024,7 +1024,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "enum:" +
String.join(",", values))
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1039,7 +1039,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "enum:" +
getEnums(field))
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1057,13 +1057,11 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
YamlProperties.annotation(fieldName, "string")
.withFormat("binary")
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
.withIsSecret(descriptor.isSecret(fieldName))
-
.withDefaultValue(descriptor.defaultValue(fieldName))
-
.withIsSecret(descriptor.isSecret(fieldName))
.build());
break;
case "Z":
@@ -1075,7 +1073,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "boolean")
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1091,7 +1089,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "number")
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1107,7 +1105,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "number")
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1123,7 +1121,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "number")
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1187,7 +1185,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "string")
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1213,7 +1211,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "number")
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1229,7 +1227,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
annotations.add(
YamlProperties.annotation(fieldName, "boolean")
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
@@ -1247,7 +1245,7 @@ public class GenerateYamlDeserializersMojo extends
GenerateYamlSupportMojo {
YamlProperties.annotation(fieldName, "object")
.withSubType(field.type().name().toString())
.withRequired(isRequired(field))
- .withRequired(isDeprecated(field))
+ .withDeprecated(isDeprecated(field))
.withDescription(descriptor.description(fieldName))
.withDisplayName(descriptor.displayName(fieldName))
.withDefaultValue(descriptor.defaultValue(fieldName))
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java
index 3ddafcf93a06..2fd42f59817f 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/GenerateYamlSchemaMojo.java
@@ -578,7 +578,7 @@ public class GenerateYamlSchemaMojo extends
GenerateYamlSupportMojo {
}
composition.forEach(compositionEntry -> {
- if (!compositionEntry.has("$ref")) {
+ if (compositionEntry.has("$ref")) {
String parentName =
StringHelper.after(compositionEntry.get("$ref").asText(), "/definitions/");
ObjectNode referredObject = definitions.withObject("/" +
parentName);
extractRequiredFromComposition(negations, referredObject);
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/support/YamlProperties.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/support/YamlProperties.java
index 5bbd442855cc..377d97767f0d 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/support/YamlProperties.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-maven-plugin/src/main/java/org/apache/camel/maven/dsl/yaml/support/YamlProperties.java
@@ -142,7 +142,7 @@ public final class YamlProperties {
if (node.isMissingNode()) {
return this;
}
- if (!node.isTextual()) {
+ if (!node.isTextual() && !node.isBoolean()) {
return this;
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator-maven-plugin/src/main/java/org/apache/camel/dsl/yaml/validator/ValidateMojo.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator-maven-plugin/src/main/java/org/apache/camel/dsl/yaml/validator/ValidateMojo.java
index a9e239972926..4cac71a01fb7 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator-maven-plugin/src/main/java/org/apache/camel/dsl/yaml/validator/ValidateMojo.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator-maven-plugin/src/main/java/org/apache/camel/dsl/yaml/validator/ValidateMojo.java
@@ -45,7 +45,7 @@ public class ValidateMojo extends AbstractMojo {
private final YamlValidator validator = new YamlValidator();
- private static final String IGNORE_FILE = "application.yml";
+ private static final String IGNORE_FILE = "application";
/**
* The maven project.
@@ -103,10 +103,7 @@ public class ValidateMojo extends AbstractMojo {
@Parameter(property = "camel.excludes")
private String excludes;
- /**
- * yamlFiles in memory cache, useful for multi modules maven projects
- */
- private static final Set<File> yamlFiles = new LinkedHashSet<>();
+ private final Set<File> yamlFiles = new LinkedHashSet<>();
private final RepositorySystem repositorySystem;
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/CamelYamlParser.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/CamelYamlParser.java
index e396aa06e5e1..9977323b38f3 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/CamelYamlParser.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/CamelYamlParser.java
@@ -98,9 +98,11 @@ public class CamelYamlParser {
return Collections.emptyList();
}
} catch (Exception e) {
+ String msg = e.getClass().getName() + ": " + e.getMessage();
Error error = Error.builder()
.messageKey("parser")
- .format(new MessageFormat(e.getClass().getName() + ": " +
e.getMessage()))
+ .format(new MessageFormat("{0}"))
+ .arguments(msg)
.build();
return List.of(error);
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlParser.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlParser.java
index 16142ce61b62..6b0753c0c8b1 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlParser.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlParser.java
@@ -40,9 +40,11 @@ public class YamlParser {
mapper.readTree(file);
return Collections.emptyList();
} catch (Exception e) {
+ String msg = e.getClass().getName() + ": " + e.getMessage();
Error error = Error.builder()
.messageKey("parser")
- .format(new MessageFormat(e.getClass().getName() + ": " +
e.getMessage()))
+ .format(new MessageFormat("{0}"))
+ .arguments(msg)
.build();
return List.of(error);
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlValidator.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlValidator.java
index a55c58e10a13..91770407d318 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlValidator.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/main/java/org/apache/camel/dsl/yaml/validator/YamlValidator.java
@@ -66,9 +66,11 @@ public class YamlValidator {
var target = mapper.readTree(file);
return new ArrayList<>(schema.validate(target));
} catch (Exception e) {
+ String msg = e.getClass().getName() + ": " + e.getMessage();
Error error = Error.builder()
.messageKey("parser")
- .format(new MessageFormat(e.getClass().getName() + ": " +
e.getMessage()))
+ .format(new MessageFormat("{0}"))
+ .arguments(msg)
.build();
return List.of(error);
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
index b255cbe5f0a2..5d39e4465d8b 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
@@ -260,6 +260,9 @@
"id" : {
"type" : "string"
},
+ "note" : {
+ "type" : "string"
+ },
"parameters" : {
"type" : "object"
},
@@ -288,6 +291,9 @@
"id" : {
"type" : "string"
},
+ "note" : {
+ "type" : "string"
+ },
"parameters" : {
"type" : "object"
},
@@ -882,7 +888,8 @@
"description" : "The claim check operation to use. Get=retrieve,
GetAndRemove=retrieve and remove, Set=store with key, Push=store on stack,
Pop=retrieve from stack.",
"enum" : [ "Get", "GetAndRemove", "Set", "Push", "Pop" ]
}
- }
+ },
+ "required" : [ "operation" ]
},
"org.apache.camel.model.ContextScanDefinition" : {
"title" : "Context Scan",
@@ -1872,9 +1879,15 @@
"type" : "object",
"additionalProperties" : false,
"properties" : {
+ "description" : {
+ "type" : "string"
+ },
"name" : {
"type" : "string"
},
+ "note" : {
+ "type" : "string"
+ },
"parameters" : {
"type" : "object"
},
@@ -3077,7 +3090,7 @@
"description" : "The property key."
}
},
- "required" : [ "key" ]
+ "required" : [ "expression", "key" ]
},
"org.apache.camel.model.RecipientListDefinition" : {
"title" : "Recipient List",
@@ -3584,7 +3597,8 @@
"streamConfig" : {
"$ref" :
"#/items/definitions/org.apache.camel.model.config.StreamResequencerConfig"
}
- }
+ },
+ "required" : [ "expression" ]
},
"org.apache.camel.model.Resilience4jConfigurationDefinition" : {
"title" : "Resilience4j Configuration",
@@ -3929,6 +3943,9 @@
}
}
},
+ "note" : {
+ "type" : "string"
+ },
"onCompletion" : {
"type" : "array",
"items" : {
@@ -4381,7 +4398,8 @@
"description" : "The new exchange pattern to use from this point
forward.",
"enum" : [ "InOnly", "InOut" ]
}
- }
+ },
+ "required" : [ "pattern" ]
},
"org.apache.camel.model.SetHeaderDefinition" : {
"title" : "Set Header",
@@ -6411,7 +6429,8 @@
"description" : "When unmarshalling should a single instance be
unwrapped and returned instead of wrapped in a java.util.List.",
"default" : true
}
- }
+ },
+ "required" : [ "type" ]
},
"org.apache.camel.model.dataformat.CBORDataFormat" : {
"title" : "CBOR",
@@ -10886,7 +10905,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.GetDefinition" : {
"title" : "Get",
@@ -11029,7 +11049,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.HeadDefinition" : {
"title" : "Head",
@@ -11172,7 +11193,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.MutualTLSDefinition" : {
"title" : "Mutual TLS",
@@ -11398,7 +11420,7 @@
"enum" : [ "body", "formData", "header", "path", "query" ]
}
},
- "required" : [ "name" ]
+ "required" : [ "name", "type" ]
},
"org.apache.camel.model.rest.PatchDefinition" : {
"title" : "Patch",
@@ -11541,7 +11563,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.PostDefinition" : {
"title" : "Post",
@@ -11684,7 +11707,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.PutDefinition" : {
"title" : "Put",
@@ -11827,7 +11851,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.ResponseHeaderDefinition" : {
"title" : "Response Header",
@@ -12491,7 +12516,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jLineTokenizerDefinition" : {
"title" : "LangChain4J Tokenizer with line splitter",
@@ -12526,7 +12551,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jParagraphTokenizerDefinition" : {
"title" : "LangChain4J Tokenizer with paragraph splitter",
@@ -12561,7 +12586,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jSentenceTokenizerDefinition" : {
"title" : "LangChain4J Tokenizer with sentence splitter",
@@ -12596,7 +12621,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jTokenizerDefinition" : {
"type" : "object",
@@ -12619,7 +12644,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jWordTokenizerDefinition" : {
"title" : "LangChain4J Tokenizer with word splitter",
@@ -12654,7 +12679,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.transformer.CustomTransformerDefinition" : {
"title" : "Custom Transformer",
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index f97e7cb55df1..291c8c66db81 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -314,6 +314,9 @@
"id" : {
"type" : "string"
},
+ "note" : {
+ "type" : "string"
+ },
"parameters" : {
"type" : "object"
},
@@ -343,6 +346,9 @@
"id" : {
"type" : "string"
},
+ "note" : {
+ "type" : "string"
+ },
"parameters" : {
"type" : "object"
},
@@ -941,7 +947,8 @@
"description" : "The claim check operation to use. Get=retrieve,
GetAndRemove=retrieve and remove, Set=store with key, Push=store on stack,
Pop=retrieve from stack.",
"enum" : [ "Get", "GetAndRemove", "Set", "Push", "Pop" ]
}
- }
+ },
+ "required" : [ "operation" ]
},
"org.apache.camel.model.ContextScanDefinition" : {
"title" : "Context Scan",
@@ -2691,9 +2698,15 @@
"type" : "object",
"additionalProperties" : false,
"properties" : {
+ "description" : {
+ "type" : "string"
+ },
"name" : {
"type" : "string"
},
+ "note" : {
+ "type" : "string"
+ },
"parameters" : {
"type" : "object"
},
@@ -4638,8 +4651,6 @@
}, {
"not" : {
"anyOf" : [ {
- "required" : [ "expression" ]
- }, {
"required" : [ "constant" ]
}, {
"required" : [ "csimple" ]
@@ -5328,8 +5339,6 @@
}, {
"not" : {
"anyOf" : [ {
- "required" : [ "expression" ]
- }, {
"required" : [ "constant" ]
}, {
"required" : [ "csimple" ]
@@ -5839,6 +5848,9 @@
}
}
},
+ "note" : {
+ "type" : "string"
+ },
"onCompletion" : {
"type" : "array",
"items" : {
@@ -6592,7 +6604,8 @@
"enum" : [ "InOnly", "InOut" ]
}
}
- } ]
+ } ],
+ "required" : [ "pattern" ]
},
"org.apache.camel.model.SetHeaderDefinition" : {
"title" : "Set Header",
@@ -9834,7 +9847,8 @@
"description" : "When unmarshalling should a single instance be
unwrapped and returned instead of wrapped in a java.util.List.",
"default" : true
}
- }
+ },
+ "required" : [ "type" ]
},
"org.apache.camel.model.dataformat.CBORDataFormat" : {
"title" : "CBOR",
@@ -14607,7 +14621,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.GetDefinition" : {
"title" : "Get",
@@ -14750,7 +14765,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.HeadDefinition" : {
"title" : "Head",
@@ -14893,7 +14909,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.MutualTLSDefinition" : {
"title" : "Mutual TLS",
@@ -15119,7 +15136,7 @@
"enum" : [ "body", "formData", "header", "path", "query" ]
}
},
- "required" : [ "name" ]
+ "required" : [ "name", "type" ]
},
"org.apache.camel.model.rest.PatchDefinition" : {
"title" : "Patch",
@@ -15262,7 +15279,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.PostDefinition" : {
"title" : "Post",
@@ -15405,7 +15423,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.PutDefinition" : {
"title" : "Put",
@@ -15548,7 +15567,8 @@
"title" : "Type",
"description" : "Sets the class name to use for binding from input
to POJO for the incoming data. This option will override what may be configured
on a parent level."
}
- }
+ },
+ "required" : [ "to" ]
},
"org.apache.camel.model.rest.ResponseHeaderDefinition" : {
"title" : "Response Header",
@@ -16212,7 +16232,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jLineTokenizerDefinition" : {
"title" : "LangChain4J Tokenizer with line splitter",
@@ -16247,7 +16267,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jParagraphTokenizerDefinition" : {
"title" : "LangChain4J Tokenizer with paragraph splitter",
@@ -16282,7 +16302,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jSentenceTokenizerDefinition" : {
"title" : "LangChain4J Tokenizer with sentence splitter",
@@ -16317,7 +16337,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jTokenizerDefinition" : {
"type" : "object",
@@ -16340,7 +16360,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.tokenizer.LangChain4jWordTokenizerDefinition" : {
"title" : "LangChain4J Tokenizer with word splitter",
@@ -16375,7 +16395,7 @@
"enum" : [ "OPEN_AI", "AZURE", "QWEN" ]
}
},
- "required" : [ "maxOverlap", "maxTokens" ]
+ "required" : [ "maxOverlap", "maxTokens", "tokenizerType" ]
},
"org.apache.camel.model.transformer.CustomTransformerDefinition" : {
"title" : "Custom Transformer",
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java
index feab814755ab..de4298dc917b 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/main/java/org/apache/camel/dsl/yaml/YamlRoutesBuilderLoader.java
@@ -160,7 +160,13 @@ public class YamlRoutesBuilderLoader extends
YamlRoutesBuilderLoaderSupport {
}
}
} else {
- doConfigure(target);
+ boolean accepted = doConfigure(target);
+ if (!accepted) {
+ String loc = ctx.getResource() != null ?
ctx.getResource().getLocation() : "";
+ LOG.warn(
+ "Unsupported top-level YAML node in
resource: {}. Ensure the YAML file uses a sequence (list) of route
definitions.",
+ loc);
+ }
}
}
@@ -171,7 +177,9 @@ public class YamlRoutesBuilderLoader extends
YamlRoutesBuilderLoaderSupport {
if (resource != null) {
preparseDone.remove(resource.getLocation());
}
- beansDeserializer.clearCache();
+ if (preparseDone.isEmpty()) {
+ beansDeserializer.clearCache();
+ }
}
private boolean doConfigure(Object item) throws Exception {
@@ -324,7 +332,13 @@ public class YamlRoutesBuilderLoader extends
YamlRoutesBuilderLoaderSupport {
}
}
} else {
- doConfiguration(target);
+ boolean accepted = doConfiguration(target);
+ if (!accepted) {
+ String loc = ctx.getResource() != null ?
ctx.getResource().getLocation() : "";
+ LOG.warn(
+ "Unsupported top-level YAML node in
resource: {}. Ensure the YAML file uses a sequence (list) of route
definitions.",
+ loc);
+ }
}
}
}
@@ -506,7 +520,7 @@ public class YamlRoutesBuilderLoader extends
YamlRoutesBuilderLoaderSupport {
// is there any error handler?
MappingNode errorHandler = asMappingNode(nodeAt(root,
"/spec/errorHandler"));
- if (errorHandler != null) {
+ if (errorHandler != null &&
!errorHandler.getValue().isEmpty()) {
// there are 5 different error handlers, which one is it
NodeTuple nt = errorHandler.getValue().get(0);
String ehName = asText(nt.getKeyNode());
@@ -516,6 +530,10 @@ public class YamlRoutesBuilderLoader extends
YamlRoutesBuilderLoaderSupport {
// a sink is a dead letter queue
DeadLetterChannelDefinition dlcd = new
DeadLetterChannelDefinition();
MappingNode endpoint =
asMappingNode(nodeAt(nt.getValueNode(), "/endpoint"));
+ if (endpoint == null) {
+ throw new IllegalArgumentException(
+ "Pipe errorHandler sink must have an
endpoint defined");
+ }
String dlq = extractCamelEndpointUri(endpoint);
dlcd.setDeadLetterUri(dlq);
ehf = dlcd;
@@ -590,6 +608,12 @@ public class YamlRoutesBuilderLoader extends
YamlRoutesBuilderLoaderSupport {
uri = extractTupleValue(mn.getValue(), "name");
} else {
uri = extractTupleValue(node.getValue(), "uri");
+ if (uri == null && mn != null) {
+ String kind = extractTupleValue(mn.getValue(), "kind");
+ String apiVersion = extractTupleValue(mn.getValue(),
"apiVersion");
+ throw new IllegalArgumentException(
+ "Unsupported Pipe ref kind: " + kind + " (apiVersion:
" + apiVersion + ")");
+ }
}
// properties
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ErrorHandlerTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ErrorHandlerTest.groovy
index 0cbeaddfdf54..39cdaba9fda8 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ErrorHandlerTest.groovy
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/ErrorHandlerTest.groovy
@@ -23,6 +23,7 @@ import
org.apache.camel.model.errorhandler.DeadLetterChannelDefinition
import org.apache.camel.model.errorhandler.DefaultErrorHandlerDefinition
import org.apache.camel.model.errorhandler.NoErrorHandlerDefinition
import org.apache.camel.model.errorhandler.RefErrorHandlerDefinition
+import
org.apache.camel.model.errorhandler.SpringTransactionErrorHandlerDefinition
import org.junit.jupiter.api.Assertions
class ErrorHandlerTest extends YamlTestSupport {
@@ -172,6 +173,21 @@ class ErrorHandlerTest extends YamlTestSupport {
}
}
+ def "errorHandler (springTransactionErrorHandler)"() {
+ setup:
+ loadRoutesNoValidate """
+ - errorHandler:
+ springTransactionErrorHandler:
+ transactedPolicyRef: "myTxPolicy"
+ """
+ when:
+ context.start()
+ then:
+ with(context.getCamelContextExtension().getErrorHandlerFactory(),
SpringTransactionErrorHandlerDefinition) {
+ transactedPolicyRef == 'myTxPolicy'
+ }
+ }
+
def "Error: duplicate errorHandler"() {
when:
var route = """
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletTest.groovy
index 05b913beeebc..6bb97540ec6e 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletTest.groovy
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/KameletTest.groovy
@@ -21,6 +21,7 @@ import
org.apache.camel.dsl.yaml.common.YamlDeserializationMode
import org.apache.camel.dsl.yaml.support.YamlTestSupport
import org.apache.camel.dsl.yaml.support.model.MySetBody
import org.apache.camel.dsl.yaml.support.model.MyUppercaseProcessor
+import org.apache.camel.model.KameletDefinition
import org.apache.camel.processor.aggregate.UseLatestAggregationStrategy
import org.apache.camel.spi.Resource
@@ -421,4 +422,42 @@ class KameletTest extends YamlTestSupport {
then:
MockEndpoint.assertIsSatisfied(context)
}
+
+ def "kamelet (note property)"() {
+ setup:
+ addTemplate('setPayload') {
+ from('kamelet:source')
+ .setBody().simple('${body}: {{payload}}')
+ }
+
+ loadRoutesNoValidate '''
+ - from:
+ uri: "direct:start"
+ steps:
+ - kamelet:
+ name: "setPayload"
+ description: "calls setPayload template"
+ note: "a developer note"
+ parameters:
+ payload: 1
+ - to: "mock:kamelet"
+ '''
+
+ withMock('mock:kamelet') {
+ expectedMessageCount 1
+ expectedBodiesReceived 'a: 1'
+ }
+ when:
+ withTemplate {
+ to('direct:start').withBody('a').send()
+ }
+
+ then:
+ MockEndpoint.assertIsSatisfied(context)
+
+ with(context.routeDefinitions[0].outputs[0], KameletDefinition) {
+ description == 'calls setPayload template'
+ note == 'a developer note'
+ }
+ }
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
index 66af9b152ab6..5087d7c2b0b4 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/PipeLoaderTest.groovy
@@ -20,6 +20,7 @@ import org.apache.camel.dsl.yaml.support.YamlTestSupport
import org.apache.camel.model.KameletDefinition
import org.apache.camel.model.ToDefinition
import org.apache.camel.model.TransformDataTypeDefinition
+import org.junit.jupiter.api.Assertions
class PipeLoaderTest extends YamlTestSupport {
@Override
@@ -823,4 +824,34 @@ class PipeLoaderTest extends YamlTestSupport {
}
}
+ def "Error: Pipe with unsupported ref kind"() {
+ when:
+ var pipe = '''
+ apiVersion: camel.apache.org/v1
+ kind: Pipe
+ metadata:
+ name: bad-ref-pipe
+ spec:
+ source:
+ ref:
+ kind: Kamelet
+ apiVersion: camel.apache.org/v1
+ name: timer-source
+ properties:
+ message: "Hello"
+ sink:
+ ref:
+ kind: UnknownKind
+ apiVersion: unknown/v1
+ name: bad-sink
+ '''
+ then:
+ try {
+ loadBindings(pipe)
+ Assertions.fail("Should have thrown exception")
+ } catch (e) {
+ assert e.message.contains("Unsupported Pipe ref kind")
+ }
+ }
+
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RestTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RestTest.groovy
index 6abf2b68d121..340777e1c559 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RestTest.groovy
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RestTest.groovy
@@ -189,7 +189,8 @@ class RestTest extends YamlTestSupport {
def rloc = 'classpath:/rest-dsl/generated-rest-dsl.yaml'
def rdsl =
PluginHelper.getResourceLoader(context).resolveResource(rloc)
when:
- loadRoutes rdsl
+ // skip schema validation: generated REST DSL may omit 'type' on
params (CAMEL-24004)
+ loadRoutes([rdsl], false)
then:
context.restDefinitions != null
!context.restDefinitions.isEmpty()
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteConfigurationTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteConfigurationTest.groovy
index fb8ae9e65a5c..3e237f9024af 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteConfigurationTest.groovy
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RouteConfigurationTest.groovy
@@ -26,6 +26,9 @@ import org.junit.jupiter.api.Assertions
import static org.apache.camel.util.PropertiesHelper.asProperties
+import org.apache.camel.spi.Resource
+import org.apache.camel.support.PluginHelper
+
class RouteConfigurationTest extends YamlTestSupport {
def "routeConfiguration"() {
setup:
@@ -401,4 +404,60 @@ class RouteConfigurationTest extends YamlTestSupport {
MockEndpoint.assertIsSatisfied(context)
}
+ def "routeConfiguration note"() {
+ when:
+ loadRoutesNoValidate """
+ - routeConfiguration:
+ id: myConfig
+ description: my route config
+ note: a developer note
+ onException:
+ - onException:
+ handled:
+ constant: "true"
+ exception:
+ - ${MyException.name}
+ steps:
+ - transform:
+ constant: "Sorry"
+ - to: "mock:on-exception"
+ """
+ then:
+ context.routeConfigurationDefinitions.size() == 1
+
+ with(context.routeConfigurationDefinitions[0],
RouteConfigurationDefinition) {
+ id == 'myConfig'
+ description == 'my route config'
+ note == 'a developer note'
+ }
+ }
+
+ def "routeConfiguration has line number"() {
+ when:
+ Resource res = asResource('route-config-line',
+ '''
+ - routeConfiguration:
+ id: myConfig
+ onException:
+ - onException:
+ handled:
+ constant: "true"
+ exception:
+ - java.lang.Exception
+ steps:
+ - to: "mock:on-exception"
+ '''
+ )
+ PluginHelper.getRoutesLoader(context).loadRoutes(res)
+
+ then:
+ context.routeConfigurationDefinitions.size() == 1
+
+ with(context.routeConfigurationDefinitions[0],
RouteConfigurationDefinition) {
+ id == 'myConfig'
+ lineNumber >= 0
+ location != null
+ }
+ }
+
}
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RoutesTest.groovy
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RoutesTest.groovy
index 9811203fe2bd..eadf95a40c0c 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RoutesTest.groovy
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/groovy/org/apache/camel/dsl/yaml/RoutesTest.groovy
@@ -365,6 +365,32 @@ class RoutesTest extends YamlTestSupport {
}
}
+ def "load from note"() {
+ when:
+ loadRoutes '''
+ - from:
+ id: from-demo
+ description: from something cool
+ note: a developer note
+ uri: "direct:info"
+ steps:
+ - log: "message"
+ '''
+ then:
+ context.routeDefinitions.size() == 1
+
+ with(context.routeDefinitions[0], RouteDefinition) {
+ input.id == 'from-demo'
+ input.description == 'from something cool'
+ input.note == 'a developer note'
+ input.endpointUri == 'direct:info'
+
+ with (outputs[0], LogDefinition) {
+ message == 'message'
+ }
+ }
+ }
+
def "load route with from description"() {
when:
loadRoutes '''