Croway commented on PR #27447:
URL: https://github.com/apache/camel/pull/27447#issuecomment-6019737773

   Thanks, the Kamelet checks are a useful addition. I ran reproducers against 
the PR branch, and three issues fail there:
   
   **1. Crash on unknown names that repeat a word** 
(`KameletDefinitions.suggest`)
   
   `Set.of(lower.split("[-_.]"))` throws when a word appears twice:
   
   ```yaml
   - to: kamelet:aws-s3-to-aws-sqs
   ```
   
   This gives `IllegalArgumentException: duplicate element: aws`, thrown from 
`KameletChecks.validateYaml`, from `SourceValidator.validate` and from 
`CatalogDocs.catalogDoc("kafka-to-kafka")`. So a made-up name crashes the 
write/validate tool instead of returning "did you mean". Changing it to `new 
HashSet<>(Arrays.asList(...))` fixes it.
   
   **2. The kamelet component's own endpoint options are reported as unknown 
properties** (`KameletChecks.check`)
   
   ```yaml
   - to: kamelet:log-sink?routeId=myLog&noErrorHandler=false
   ```
   
   This is reported as `unknown property 'routeId'` and `unknown property 
'noErrorHandler'`. `location` and `timeout` under `parameters:` are reported 
the same way. A runtime test in `camel-kamelet` with the same URI passes and 
creates the route `myLog`, so the validator rejects a valid route. The endpoint 
options (`templateId`, `routeId`, `location`, `uuid`, `block`, `timeout`, 
`failIfNoConsumers`, `noErrorHandler`, `bridgeErrorHandler`, 
`lazyStartProducer`, `exchangePattern`, `exceptionHandler`) could be skipped. 
They could be taken from the catalog's `kamelet` component model rather than 
hard-coded.
   
   **3. Required properties set in other valid ways are reported as missing** 
(`projectProperties` / `inProperties`)
   
   Both of these still give "the required property message is missing":
   - `camel.kamelet.timer-source.message: hello` (`:` is a valid 
`java.util.Properties` separator)
   - `camel.component.kamelet.template-properties[timer-source].message=hello`, 
which `KameletComponent` reads
   
   Loading the files with `java.util.Properties` would cover the separators. 
Matching `template-properties[<name>]` / `route-properties[...]` would cover 
the component form.
   
   The reproducer tests are below, if useful for the PR.
   
   <details><summary>KameletChecksReproducerTest (all fail on the PR 
branch)</summary>
   
   ```java
   @Test
   void unknownNameWithRepeatedWordDoesNotCrashValidator() {
       String yaml = """
               - route:
                   from:
                     uri: timer:tick
                     steps:
                       - to: kamelet:aws-s3-to-aws-sqs
               """;
       assertThatCode(() -> KameletChecks.validateYaml(yaml, 
null)).doesNotThrowAnyException();
   }
   
   @Test
   void catalogDocWithRepeatedWordDoesNotCrash() {
       assertThatCode(() -> CatalogDocs.catalogDoc(new DefaultCamelCatalog(), 
"kafka-to-kafka", null, null, null, null,
               false, false, null)).doesNotThrowAnyException();
   }
   
   @Test
   void kameletComponentOptionsAreNotUnknownProperties() {
       String yaml = """
               - route:
                   from:
                     uri: timer:tick
                     steps:
                       - to: kamelet:log-sink?routeId=myLog&noErrorHandler=false
                       - to:
                           uri: kamelet:log-sink
                           parameters:
                             location: file:/k/log-sink.kamelet.yaml
                             timeout: 5000
               """;
       assertThat(KameletChecks.validateYaml(yaml, null)).isEmpty();
   }
   
   @Test
   void requiredPropertyWithColonSeparator(@TempDir Path dir) throws Exception {
       Files.writeString(dir.resolve("application.properties"), 
"camel.kamelet.timer-source.message: hello\n");
       String yaml = """
               - route:
                   from:
                     uri: kamelet:timer-source
                     steps:
                       - to: kamelet:log-sink
               """;
       assertThat(KameletChecks.validateYaml(yaml, dir)).isEmpty();
   }
   
   @Test
   void requiredPropertyFromComponentTemplateProperties(@TempDir Path dir) 
throws Exception {
       Files.writeString(dir.resolve("application.properties"),
               
"camel.component.kamelet.template-properties[timer-source].message=hello\n");
       // same route as above
       assertThat(KameletChecks.validateYaml(yaml, dir)).isEmpty();
   }
   ```
   
   </details>
   
   <details><summary>Runtime check in camel-kamelet (passes: routeId / 
noErrorHandler as query parameters are valid)</summary>
   
   ```java
   class KameletRouteIdQueryParamReproducerTest extends CamelTestSupport {
   
       @Test
       void routeIdQueryParamIsAcceptedAtRuntime() {
           assertThat(context.getRoute("myLog")).isNotNull();
           
assertThat(fluentTemplate.toF("direct:start").withBody("hi").request(String.class)).isEqualTo("hi");
       }
   
       @Override
       protected RoutesBuilder createRouteBuilder() {
           return new RouteBuilder() {
               @Override
               public void configure() {
                   routeTemplate("log-sink").templateParameter("showHeaders", 
"false")
                           .from("kamelet:source").log("${body}");
                   
from("direct:start").to("kamelet:log-sink?routeId=myLog&noErrorHandler=false");
               }
           };
       }
   }
   ```
   
   </details>
   
   _Claude Code on behalf of Croway_
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to