Camel CLI - Validation
The camel validate commands check Camel source files for mistakes without running them: the YAML DSL schema, endpoint URIs, Simple expressions, bean references and camel.* configuration keys, against the Camel catalog. They are provided by the validate plugin:
camel plugin add validate | Command | What it checks |
|---|---|
| YAML routes: the YAML DSL schema, and the endpoint URIs, Simple expressions and bean references against the catalog. |
| Any file |
| The |
| Not a check: rewrites YAML routes in the canonical (explicit) form. |
Validating YAML routes
$ camel validate yaml cheese.yaml bad.yaml
Validation error detected (errors:1)
File: bad.yaml
/0/from: required property 'steps' not found When all files pass:
$ camel validate yaml cheese.yaml
Validation success (files:1) After the YAML DSL schema, the endpoint URIs, Simple expressions and bean references are checked against the Camel catalog; use --catalog=false to check the schema only. --canonical validates against the canonical schema and reports the deprecated compact notation (see Normalizing YAML routes).
Validating any source file
camel validate source validates any file camel run would load: YAML routes, .properties files (the camel.* keys), Java (compiles it), XSLT and XML:
camel validate source orders.yaml OrderRoute.java application.properties Java and XML routes
The routes of a Java or XML DSL file are also read into the Camel model, without compiling or running them, and checked as YAML routes are:
-
the endpoint URIs, with the endpoint DSL and constants resolved;
-
Simple expressions;
-
a
towhose URI holds${...}and should be atoD.
These are what the Java compiler cannot see inside the strings. A part of a Java route the parser cannot work out (a value computed at runtime) is left unchecked.
Endpoints no route consumes
As the routes of an application are spread over the files of its directory, camel validate source also reports a direct:, seda: or disruptor: endpoint that a route sends to, but that no YAML, Java or XML route in the directory (and its subdirectories) consumes. With direct: sending a message to it fails; with seda: and disruptor: the messages would be queued and never read.
A route sends to an endpoint with to, a toD without an expression, wireTap, enrich, a rest verb, or the dead letter channel of an error handler. A route consumes an endpoint with its from, or with a poll or pollEnrich. camel overview reports the same endpoints, by the same rules.
The check stays quiet when it cannot be certain: a route that consumes an endpoint only known at runtime (a property placeholder, an expression), route templates, Kamelets and Pipes, and a directory that is only a part of a Maven or Gradle project, such as src/main/resources/camel.
Validating configuration properties
camel validate properties checks every camel.* key of application.properties (or any .properties file) against the Camel catalog. A wrong key, such as camel.main.log-level or camel.main.streamCaching, is reported before the application fails to start:
camel validate properties application.properties application-prod.properties camel validate source runs the same check on the .properties files it is given.
Normalizing YAML routes
The YAML DSL accepts compact shorthands, such as from: at the top level or an expression without its expression: wrapper. camel validate normalize rewrites YAML routes in the canonical, explicit form, which is what the documentation and the canonical schema use:
camel validate normalize orders.yaml
camel validate normalize orders.yaml --output=orders-canonical.yaml Without --output the result is printed. The routes are loaded (not run) to write them, so property placeholders are kept as they are. Use camel validate yaml --canonical to report the shorthands instead of rewriting them.
Normalizing several files
When --output is a directory (an existing one, or a name ending with /), each input file is normalized into a file of its own in that directory, with the name of the input file:
camel validate normalize a.yaml b.yaml --output=out/ writes out/a.yaml and out/b.yaml. A top-level onException applies to the routes of its own file only, and so it does in the normalized files. A Kamelet is written back to a file of its own name too, with only its template normalized.
The files of the output directory are named as follows:
-
an input file keeps its name;
-
input files with the same name in different directories get the name of their parent directory in front:
orders/routes.yamlandbilling/routes.yamlare written asorders-routes.yamlandbilling-routes.yaml; -
when these names are the same too (
x/orders/routes.yamlandy/orders/routes.yaml), the input files are numbered in the order they are given, before the extension:routes-1.yaml,routes-2.yaml(action-1.kamelet.yamlforaction.kamelet.yaml); -
a generated name is never the name of another input file or of another output file: a number already in use is skipped (with an input file named
routes-1.yaml, the tworoutes.yamlbecomeroutes-2.yamlandroutes-3.yaml).
Beans, data formats, rests, route configurations and route templates go to the file they were loaded from. What was not loaded from one of the input files goes to normalized.yaml in the output directory (normalized-1.yaml if an input file is named normalized.yaml).
The command refuses to write over one of its input files, for example with --output=. in the directory of the routes: the normalized files go to another directory.
With --output set to a file, or without --output, the routes of all the files are merged into one YAML document. A top-level onException of one file then applies to the routes of all the files when the result is loaded, so the command prints a warning to the standard error when this happens (the standard output keeps only the YAML, so it can be redirected to a file):
WARN: the top-level onException of b.yaml applies to the routes of a.yaml too, as the routes of all the files are written together: use --output with a directory to write one file per input file Validating against another Camel version or runtime
Both commands validate against the CLI’s own Camel version. A project that runs another version, or Camel Spring Boot or Camel Quarkus, is validated against the catalog and the YAML DSL schema of that version with --camel-version and --runtime, the same options camel catalog and camel doc take:
$ camel validate yaml --camel-version=4.18.0 orders.yaml
$ camel validate source --runtime=quarkus --quarkus-version=3.30.1 orders.yaml application.properties
Validation error detected (errors:1)
File: orders.yaml
line 4: atmosphere-websocket: Camel Quarkus has no extension for this component (no camel-quarkus-atmosphere-websocket); pick a component that has one, camel_catalog_find lists them The catalog of that version is downloaded as for camel catalog, and the schema is read from the camel-yaml-dsl jar of that version (--repos and --download=false apply to both). With --runtime=quarkus the Quarkus platform is resolved from the Camel version through the Quarkus extension registry (the response is cached for a day under ~/.camel, and the platform resolved for a released Camel version that the platform carries exactly is cached for 7 days; a -SNAPSHOT version is never cached, and --fresh clears both), or given with --quarkus-version; a component of the route that has no Camel Quarkus extension, or no Camel Spring Boot starter with --runtime=spring-boot, is an error. --canonical needs Camel 4.22 or later, the first version with the canonical schema.
The Simple expressions are parsed by the CLI’s own Simple language (the catalog of the other version supplies its functions), and the Java, XSLT and XML checks of camel validate source use the CLI’s classpath.
The camel_validate_source tool of the MCP servers (Camel MCP Server) does the same when it is given a camelVersion: the catalog and the schema of that version.