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 96921011d3db CAMEL-25820: camel-yaml-dsl-validator - the Kamelet 
schema keeps the schema of the template under definitions, so validating a 
Kamelet logs no warning (#28115)
96921011d3db is described below

commit 96921011d3db2763cc7cedd8e5da803f07be9251
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Oct 19 18:51:35 2026 +0200

    CAMEL-25820: camel-yaml-dsl-validator - the Kamelet schema keeps the schema 
of the template under definitions, so validating a Kamelet logs no warning 
(#28115)
    
    Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
 .../camel/dsl/yaml/validator/YamlValidator.java    | 10 +++--
 .../dsl/yaml/validator/KameletValidationTest.java  | 45 ++++++++++++++++++++++
 2 files changed, 52 insertions(+), 3 deletions(-)

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 6b787a151989..4552f458b1e4 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
@@ -675,8 +675,12 @@ public class YamlValidator {
      * <p/>
      * The envelope is described loosely on purpose. Camel does not own the 
Kamelet CRD, so the parts it does not read
      * are accepted as they come rather than failed for being unknown.
+     * <p/>
+     * The schema of the template is kept under {@code definitions}, where 
draft 4 (the dialect of the route schema)
+     * keeps a schema that is only referenced: under a key of its own at the 
root it is no keyword, and the validator
+     * warns about an unknown keyword each time a JVM loads the schema 
(CAMEL-25820).
      */
-    private JsonNode kameletModel(JsonNode routeModel) {
+    JsonNode kameletModel(JsonNode routeModel) {
         ObjectNode root = mapper.createObjectNode();
         JsonNode dialect = routeModel.get("$schema");
         if (dialect != null) {
@@ -696,14 +700,14 @@ public class YamlValidator {
         specProperties.putObject("types").put("type", "object");
         specProperties.putObject("dataTypes").put("type", "object");
         specProperties.putObject("dependencies").put("type", "array");
-        specProperties.putObject("template").put("$ref", "#/templateEntry");
+        specProperties.putObject("template").put("$ref", 
"#/definitions/templateEntry");
         // an entry of a route file is exactly one of route/from/beans/..., 
which is what maxProperties says. The
         // template of a Kamelet is not: counter-source declares its bean 
beside its from, and 60 of the 250 kamelets
         // of the library do the same. Everything else about an entry still 
holds, and the $refs inside the copy point
         // at #/items/definitions/..., which is why the items node is kept as 
well.
         ObjectNode template = routeModel.get("items").deepCopy();
         template.remove("maxProperties");
-        root.set("templateEntry", template);
+        root.putObject("definitions").set("templateEntry", template);
         root.set("items", routeModel.get("items"));
         return root;
     }
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/KameletValidationTest.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/KameletValidationTest.java
index 0b553fd1b423..22cba4c2d7a6 100644
--- 
a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/KameletValidationTest.java
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/KameletValidationTest.java
@@ -16,9 +16,20 @@
  */
 package org.apache.camel.dsl.yaml.validator;
 
+import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
 import com.networknt.schema.Error;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.Property;
 import org.junit.jupiter.api.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -60,6 +71,40 @@ class KameletValidationTest {
         return YamlValidator.describeAll(content, errors);
     }
 
+    @Test
+    void aKameletIsValidatedWithoutAWarningAboutTheSchema() throws Exception {
+        // CAMEL-25820: the schema of a Kamelet kept the schema of its 
template under a key of its own at the root, which
+        // is no keyword, and the validator warned "Unknown keyword 
templateEntry" each time it loaded the schema
+        List<String> warnings = new CopyOnWriteArrayList<>();
+        LoggerContext context = (LoggerContext) LogManager.getContext(false);
+        Appender appender = new AbstractAppender("kamelet-schema-warnings", 
null, null, true, Property.EMPTY_ARRAY) {
+            @Override
+            public void append(LogEvent event) {
+                if (event.getLevel().isMoreSpecificThan(Level.WARN)) {
+                    warnings.add(event.getLoggerName() + ": " + 
event.getMessage().getFormattedMessage());
+                }
+            }
+        };
+        appender.start();
+        context.getConfiguration().getRootLogger().addAppender(appender, 
Level.ALL, null);
+        context.updateLoggers();
+        try {
+            assertThat(validate(WORKING)).isEmpty();
+        } finally {
+            
context.getConfiguration().getRootLogger().removeAppender(appender.getName());
+            context.updateLoggers();
+            appender.stop();
+        }
+
+        assertThat(warnings).noneMatch(w -> w.contains("Unknown keyword"));
+        // the validator warns once in a JVM, so the schema is checked as 
well: only keywords at its root
+        YamlValidator validator = new YamlValidator();
+        JsonNode model = new 
ObjectMapper().readTree(YamlValidator.class.getResourceAsStream("/schema/camelYamlDsl.json"));
+        List<String> keys = new ArrayList<>();
+        validator.kameletModel(model).fieldNames().forEachRemaining(keys::add);
+        assertThat(keys).containsOnly("$schema", "type", 
"additionalProperties", "properties", "definitions", "items");
+    }
+
     @Test
     void aKameletThatRunsIsValid() throws Exception {
         // this is the file of the issue: camel run logs the filtered body for 
it

Reply via email to