Federico Mariani created CAMEL-25490:
----------------------------------------

             Summary: camel-jbang - camel validate normalize writes a top-level 
onException into the steps of every route, which the YAML DSL schema rejects
                 Key: CAMEL-25490
                 URL: https://issues.apache.org/jira/browse/CAMEL-25490
             Project: Camel
          Issue Type: Bug
          Components: camel-jbang, camel-yaml-dsl
    Affects Versions: 4.22.1
            Reporter: Federico Mariani


{{camel validate normalize}} turns a valid YAML file with a top-level 
{{onException}} into a file that {{camel validate yaml}} rejects: the 
{{onException}} is written as the first step of every route.

Since {{camel validate yaml}} and the YAML DSL compact notation warning 
recommend {{camel validate normalize}}, users (and AI agents) run it and copy 
its output over their routes, which turns valid files into invalid ones. The 
Camel runtime still loads the result, but it is no longer valid for the YAML 
DSL schema, and the error handling silently changes from "all routes of the 
file" to a per-route copy.

h3. Reproduction (Camel CLI 4.22.0 and 4.22.1)

{code:yaml|title=in.yaml}
- onException:
    exception:
      - java.lang.Exception
    handled:
      constant: "true"
    steps:
      - log:
          message: "Failed: ${exception.message}"
- route:
    id: myRoute
    from:
      uri: timer:tick
      steps:
        - log:
            message: "Hello"
{code}

{noformat}
$ camel validate yaml in.yaml
Validation success (files:1)
$ camel validate normalize in.yaml --output=out.yaml
{noformat}

{code:yaml|title=out.yaml}
- route:
    id: myRoute
    from:
      uri: timer
      parameters:
        timerName: tick
      steps:
        - onException:
            exception:
              - java.lang.Exception
            handled:
              constant:
                expression: "true"
            steps:
              - log:
                  message: "Failed: ${exception.message}"
        - log:
            message: Hello
{code}

{noformat}
$ camel validate yaml out.yaml
Validation error detected (errors:1)
        File: out.yaml
                /0/route/from/steps/0: property 'onException' is not defined in 
the schema and the schema does not allow additional properties
{noformat}

With several routes in the file, the {{onException}} is copied into the steps 
of each of them.

The same happens to the {{onException}} of a {{routeConfiguration}} that is 
loaded before the routes (for example {{camel validate normalize a-config.yaml 
b-routes.yaml}}): it is dumped in the {{routeConfiguration}} and again as a 
step of each route.

h3. Cause

{{camel validate normalize}} runs the files with 
{{camel.main.dumpRoutes=yaml}}. When a route is prepared 
({{RoutesDefinition.prepareRoute}} -> {{RouteDefinitionHelper.prepareRoute}} / 
{{initOnExceptions}}), the context scoped onExceptions (the top-level ones of 
the YAML file, and those of the route configurations that apply) are added to 
the outputs of the route, marked with {{routeScoped=false}}. 
{{LwModelToYAMLDumper.dumpModelAsYaml}} (core/camel-yaml-io) then writes all 
the outputs of the route as steps, including these onExceptions, and the YAML 
DSL schema has no {{onException}} among the steps of a route (route scoped 
onException is not supported in YAML, see CAMEL-25207).

h3. Fix

In {{LwModelToYAMLDumper}}, leave the context scoped onExceptions 
({{routeScoped=false}}) out of the steps of the routes, and write those that do 
not belong to a route configuration once, as top-level {{onException}} entries 
before the routes. The dump then loads back with the same scope and passes the 
schema validation.

h3. Related findings (not part of this fix)

While checking the other top-level elements with {{camel validate normalize}} 
4.22.1:
* top-level {{onCompletion}} and {{interceptFrom}} are also written into the 
steps of each (matching) route, which the schema rejects (they are added to the 
route outputs the same way, but have no marker to tell them from route scoped 
ones);
* top-level {{intercept}}, {{interceptSendToEndpoint}} and {{errorHandler}} are 
dropped from the output;
* {{routeConfiguration.onException}} items are written without the 
{{onException:}} wrapper the schema requires;
* {{rest}} verbs are written as {{verbs:}} instead of {{get:}}/{{post:}}..., 
which the schema rejects;
* {{beans}} are kept as they are.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to