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-jbang-examples.git
The following commit(s) were added to refs/heads/main by this push:
new 9e819b6 CAMEL-24744: write the examples in the canonical YAML format,
not the deprecated compact notation (#74)
9e819b6 is described below
commit 9e819b6ff6780042e012ae36517f3cffbd450101
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Sep 15 06:54:44 2026 +0200
CAMEL-24744: write the examples in the canonical YAML format, not the
deprecated compact notation (#74)
The compact notation (setBody: {simple: "..."}, log: "...", to: "...", a
when
item with - simple:, script: {groovy: ...}, toD: "...") is deprecated in
Camel
4.23: camel run warns about it and camel validate yaml --canonical reports
it.
Every route file, and the YAML snippets in the READMEs, now use the
canonical
form with the expression under expression: and a step as a map of its
options,
so a user or an AI agent starting from an example starts from the
recommended
form. The three bundled examples (tui-hello-world, content-based-router,
message-size) are byte-identical to the copies shipped in camel-jbang.
AGENTS.md documents the convention and the validate command.
Signed-off-by: Claus Ibsen <[email protected]>
Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
---
AGENTS.md | 10 +-
ai/docling-langchain4j-rag/README.md | 4 +-
.../comprehensive-analysis.camel.yaml | 4 +-
.../sentiment-analysis.camel.yaml | 4 +-
.../text-analysis-api.camel.yaml | 12 +-
beginner/tui-hello-world/tui-hello-world.yaml | 14 +-
cloud/kubernetes-secrets/news-service.camel.yaml | 4 +-
cloud/kubernetes-service/news-service.camel.yaml | 4 +-
.../content-based-router.camel.yaml | 10 +-
observability/message-size/orders.camel.yaml | 40 +++--
security/keycloak-introspection-rest/README.md | 10 +-
.../rest-api.camel.yaml | 199 ++++++++++++---------
security/keycloak-security-rest/README.md | 16 +-
.../keycloak-security-rest/rest-api.camel.yaml | 59 +++---
security/ocsf/README.md | 8 +-
.../pqc-document-signing/pqc-document-signing.yaml | 96 ++++++----
16 files changed, 308 insertions(+), 186 deletions(-)
diff --git a/AGENTS.md b/AGENTS.md
index 6eef9e9..a651fc5 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -85,6 +85,13 @@ example. If your example ships a `test/`, add it to that
workflow.
`<name>.citrus.it.yaml`; Java package `camel.example.*`.
- **License headers**: required on `application.properties` and `*.java`
(ASF header). YAML route files do not carry a header.
+- **YAML format**: write routes in the canonical YAML DSL format — an
expression
+ under `expression:` and a step as a map of its options
+ (`setBody: {expression: {simple: {expression: "..."}}}`, `log: {message:
"..."}`,
+ `to: {uri: "..."}`). The compact notation (`setBody: {simple: "..."}`,
+ `log: "..."`, `- simple:` in a `when` item) is deprecated and `camel run`
warns
+ about it. Check with `camel validate yaml --canonical <file>` (Camel 4.23+);
+ `camel validate normalize` rewrites a file but drops its comments.
- **README**: follow the existing examples — title, description, install CLI,
start infra, how to run, stop/cleanup, integration testing, community footer.
@@ -95,7 +102,8 @@ example. If your example ships a `test/`, add it to that
workflow.
and a correct `metadata.json`.
3. Add `compose.yaml` if infra is required; add `test/` Citrus tests where it
makes sense and wire them into `.github/workflows/build.yml`.
-4. Run it locally with `camel run` and verify the README's expected output.
+4. Run it locally with `camel run` and verify the README's expected output;
+ `camel validate yaml --canonical` must report nothing.
5. Open the PR from your fork, link the JIRA ticket, and request review from
active committers.
diff --git a/ai/docling-langchain4j-rag/README.md
b/ai/docling-langchain4j-rag/README.md
index 9f270b7..7d90f85 100644
--- a/ai/docling-langchain4j-rag/README.md
+++ b/ai/docling-langchain4j-rag/README.md
@@ -500,7 +500,9 @@ ollama.timeout=300
# Add to routes
- setHeader:
name: Authorization
- constant: "Bearer ${env:API_TOKEN}"
+ expression:
+ constant:
+ expression: "Bearer ${env:API_TOKEN}"
```
**2. Input Validation**
diff --git a/ai/ibm-watson-language/comprehensive-analysis.camel.yaml
b/ai/ibm-watson-language/comprehensive-analysis.camel.yaml
index 68313b0..7c8c4c8 100644
--- a/ai/ibm-watson-language/comprehensive-analysis.camel.yaml
+++ b/ai/ibm-watson-language/comprehensive-analysis.camel.yaml
@@ -23,7 +23,9 @@
repeatCount: "2"
steps:
- setBody:
- constant: "Apple Inc. announced record-breaking profits in its
latest quarterly earnings. The company's CEO praised the innovative team for
their groundbreaking work on artificial intelligence and sustainable
technology. Investors are optimistic about the future growth potential."
+ expression:
+ constant:
+ expression: "Apple Inc. announced record-breaking profits in its
latest quarterly earnings. The company's CEO praised the innovative team for
their groundbreaking work on artificial intelligence and sustainable
technology. Investors are optimistic about the future growth potential."
- log:
message: "Analyzing comprehensive text: ${body}"
- to:
diff --git a/ai/ibm-watson-language/sentiment-analysis.camel.yaml
b/ai/ibm-watson-language/sentiment-analysis.camel.yaml
index bef390f..6b9b373 100644
--- a/ai/ibm-watson-language/sentiment-analysis.camel.yaml
+++ b/ai/ibm-watson-language/sentiment-analysis.camel.yaml
@@ -23,7 +23,9 @@
repeatCount: "3"
steps:
- setBody:
- constant: "I love this product! It's absolutely amazing and exceeded
all my expectations. The customer service was outstanding!"
+ expression:
+ constant:
+ expression: "I love this product! It's absolutely amazing and
exceeded all my expectations. The customer service was outstanding!"
- log:
message: "Analyzing text: ${body}"
- to:
diff --git a/ai/ibm-watson-language/text-analysis-api.camel.yaml
b/ai/ibm-watson-language/text-analysis-api.camel.yaml
index e072fb5..af1f5f2 100644
--- a/ai/ibm-watson-language/text-analysis-api.camel.yaml
+++ b/ai/ibm-watson-language/text-analysis-api.camel.yaml
@@ -36,7 +36,9 @@
analyzeKeywords: "false"
- setHeader:
name: "Content-Type"
- constant: "application/json"
+ expression:
+ constant:
+ expression: "application/json"
- marshal:
json: {}
@@ -61,7 +63,9 @@
analyzeKeywords: "true"
- setHeader:
name: "Content-Type"
- constant: "application/json"
+ expression:
+ constant:
+ expression: "application/json"
- marshal:
json: {}
@@ -87,6 +91,8 @@
analyzeConcepts: "true"
- setHeader:
name: "Content-Type"
- constant: "application/json"
+ expression:
+ constant:
+ expression: "application/json"
- marshal:
json: {}
diff --git a/beginner/tui-hello-world/tui-hello-world.yaml
b/beginner/tui-hello-world/tui-hello-world.yaml
index 28db173..b5bce65 100644
--- a/beginner/tui-hello-world/tui-hello-world.yaml
+++ b/beginner/tui-hello-world/tui-hello-world.yaml
@@ -6,14 +6,20 @@
repeatCount: 1
steps:
- setBody:
- constant: "Welcome! Open the TUI (camel tui) and press F2 → Send
Message to say hello."
- - log: "${body}"
+ expression:
+ constant:
+ expression: "Welcome! Open the TUI (camel tui) and press F2 →
Send Message to say hello."
+ - log:
+ message: "${body}"
- route:
id: greet
from:
uri: direct:greet
steps:
- - log: "Received: ${body}"
+ - log:
+ message: "Received: ${body}"
- setBody:
- simple: "Hello ${body}!"
+ expression:
+ simple:
+ expression: "Hello ${body}!"
diff --git a/cloud/kubernetes-secrets/news-service.camel.yaml
b/cloud/kubernetes-secrets/news-service.camel.yaml
index 1705c4d..b5c4246 100644
--- a/cloud/kubernetes-secrets/news-service.camel.yaml
+++ b/cloud/kubernetes-secrets/news-service.camel.yaml
@@ -22,7 +22,9 @@
httpMethodRestrict: GET
steps:
- setBody:
- constant: "{{news.headline}}"
+ expression:
+ constant:
+ expression: "{{news.headline}}"
- to:
uri: "log:info"
parameters:
diff --git a/cloud/kubernetes-service/news-service.camel.yaml
b/cloud/kubernetes-service/news-service.camel.yaml
index 289d0b1..0c7a9e6 100644
--- a/cloud/kubernetes-service/news-service.camel.yaml
+++ b/cloud/kubernetes-service/news-service.camel.yaml
@@ -22,7 +22,9 @@
httpMethodRestrict: GET
steps:
- setBody:
- constant: "Hello from Camel"
+ expression:
+ constant:
+ expression: "Hello from Camel"
- to:
uri: "log:info"
parameters:
diff --git a/eip/content-based-router/content-based-router.camel.yaml
b/eip/content-based-router/content-based-router.camel.yaml
index 698c2b1..d451fcf 100644
--- a/eip/content-based-router/content-based-router.camel.yaml
+++ b/eip/content-based-router/content-based-router.camel.yaml
@@ -14,8 +14,9 @@
type: int
- choice:
when:
- - simple:
- expression: "${body} >= 30"
+ - expression:
+ simple:
+ expression: "${body} >= 30"
steps:
- setHeader:
name: level
@@ -24,8 +25,9 @@
expression: hot
- log:
message: "Hot alert: ${body} C"
- - simple:
- expression: "${body} >= 15"
+ - expression:
+ simple:
+ expression: "${body} >= 15"
steps:
- setHeader:
name: level
diff --git a/observability/message-size/orders.camel.yaml
b/observability/message-size/orders.camel.yaml
index 1093006..c7d84fa 100644
--- a/observability/message-size/orders.camel.yaml
+++ b/observability/message-size/orders.camel.yaml
@@ -8,10 +8,14 @@
steps:
- setHeader:
name: Content-Length
- simple: "${random(100,1023)}"
+ expression:
+ simple:
+ expression: "${random(100,1023)}"
- setHeader:
name: source
- simple: small-producer
+ expression:
+ simple:
+ expression: small-producer
- to:
uri: seda:small
@@ -24,13 +28,19 @@
steps:
- setHeader:
name: Content-Length
- simple: "${random(8192,18432)}"
+ expression:
+ simple:
+ expression: "${random(8192,18432)}"
- setHeader:
name: source
- simple: medium-producer
+ expression:
+ simple:
+ expression: medium-producer
- setHeader:
name: tracking-id
- simple: "TRK-${random(10000,99999)}"
+ expression:
+ simple:
+ expression: "TRK-${random(10000,99999)}"
- to:
uri: seda:medium
@@ -43,19 +53,29 @@
steps:
- setHeader:
name: Content-Length
- simple: "${random(10485760,20971520)}"
+ expression:
+ simple:
+ expression: "${random(10485760,20971520)}"
- setHeader:
name: source
- simple: large-producer
+ expression:
+ simple:
+ expression: large-producer
- setHeader:
name: tracking-id
- simple: "TRK-${random(10000,99999)}"
+ expression:
+ simple:
+ expression: "TRK-${random(10000,99999)}"
- setHeader:
name: batch-id
- simple: "BATCH-${random(100,999)}"
+ expression:
+ simple:
+ expression: "BATCH-${random(100,999)}"
- setHeader:
name: priority
- simple: "${random(1,5)}"
+ expression:
+ simple:
+ expression: "${random(1,5)}"
- to:
uri: seda:large
diff --git a/security/keycloak-introspection-rest/README.md
b/security/keycloak-introspection-rest/README.md
index cb1381c..329d3e4 100644
--- a/security/keycloak-introspection-rest/README.md
+++ b/security/keycloak-introspection-rest/README.md
@@ -496,10 +496,12 @@ Routes are protected by referencing the appropriate
policy:
- policy:
ref: keycloakIntrospectionPolicy
- setBody:
- simple: |
- {
- "message": "Protected with introspection"
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "message": "Protected with introspection"
+ }
```
### Introspection Flow
diff --git a/security/keycloak-introspection-rest/rest-api.camel.yaml
b/security/keycloak-introspection-rest/rest-api.camel.yaml
index a29fae2..93bfd22 100644
--- a/security/keycloak-introspection-rest/rest-api.camel.yaml
+++ b/security/keycloak-introspection-rest/rest-api.camel.yaml
@@ -23,22 +23,29 @@
exception:
- "org.apache.camel.CamelAuthorizationException"
handled:
- constant: true
+ constant:
+ expression: true
steps:
- setHeader:
name: CamelHttpResponseCode
- constant: 403
+ expression:
+ constant:
+ expression: 403
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- setBody:
- simple: |
- {
- "error": "Forbidden",
- "message": "Access denied. ${exception.message}",
- "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
- "status": 403
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "error": "Forbidden",
+ "message": "Access denied. ${exception.message}",
+ "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
+ "status": 403
+ }
- log:
message: "Authorization failed: ${exception.message}"
@@ -79,15 +86,19 @@
uri: "platform-http:/api/public"
steps:
- setBody:
- simple: |
- {
- "message": "This is a public endpoint, no authentication
required",
- "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
- "security": "none"
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "message": "This is a public endpoint, no authentication
required",
+ "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
+ "security": "none"
+ }
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- log:
message: "Public API called"
@@ -102,22 +113,26 @@
- policy:
ref: keycloakIntrospectionPolicy
- setBody:
- simple: |
- {
- "message": "This is a protected endpoint using Token
Introspection (RFC 7662)",
- "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
- "security": "introspection",
- "role_required": "admin",
- "validation": "real-time via Keycloak introspection endpoint",
- "features": [
- "Detects revoked tokens before expiration",
- "Centralized validation",
- "Caching enabled (TTL:
{{keycloak.introspection.cache.ttl}}s)"
- ]
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "message": "This is a protected endpoint using Token
Introspection (RFC 7662)",
+ "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
+ "security": "introspection",
+ "role_required": "admin",
+ "validation": "real-time via Keycloak introspection
endpoint",
+ "features": [
+ "Detects revoked tokens before expiration",
+ "Centralized validation",
+ "Caching enabled (TTL:
{{keycloak.introspection.cache.ttl}}s)"
+ ]
+ }
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- log:
message: "Protected API with Introspection called successfully"
@@ -131,22 +146,26 @@
- policy:
ref: keycloakStandardPolicy
- setBody:
- simple: |
- {
- "message": "This is a protected endpoint using standard JWT
validation",
- "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
- "security": "local-jwt",
- "role_required": "admin",
- "validation": "local JWT signature verification",
- "features": [
- "Fast offline validation",
- "No network calls to Keycloak",
- "Cannot detect revoked tokens before expiration"
- ]
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "message": "This is a protected endpoint using standard
JWT validation",
+ "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
+ "security": "local-jwt",
+ "role_required": "admin",
+ "validation": "local JWT signature verification",
+ "features": [
+ "Fast offline validation",
+ "No network calls to Keycloak",
+ "Cannot detect revoked tokens before expiration"
+ ]
+ }
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- log:
message: "Protected API with standard JWT called successfully"
@@ -157,51 +176,55 @@
uri: "platform-http:/api/info"
steps:
- setBody:
- simple: |
- {
- "example": "Keycloak Token Introspection REST API",
- "endpoints": {
- "public": {
- "path": "/api/public",
- "security": "none",
- "description": "Public endpoint, no authentication
required"
- },
- "protected_introspection": {
- "path": "/api/protected-introspection",
- "security": "token_introspection",
- "role": "admin",
- "description": "Real-time token validation via Keycloak
introspection endpoint (RFC 7662)",
- "features": [
- "Detects revoked tokens",
- "Centralized validation",
- "Caching enabled"
- ]
- },
- "protected_standard": {
- "path": "/api/protected-standard",
- "security": "local_jwt",
- "role": "admin",
- "description": "Local JWT signature verification without
introspection",
- "features": [
- "Fast offline validation",
- "No network overhead",
- "Cannot detect token revocation"
- ]
+ expression:
+ simple:
+ expression: |
+ {
+ "example": "Keycloak Token Introspection REST API",
+ "endpoints": {
+ "public": {
+ "path": "/api/public",
+ "security": "none",
+ "description": "Public endpoint, no authentication
required"
+ },
+ "protected_introspection": {
+ "path": "/api/protected-introspection",
+ "security": "token_introspection",
+ "role": "admin",
+ "description": "Real-time token validation via
Keycloak introspection endpoint (RFC 7662)",
+ "features": [
+ "Detects revoked tokens",
+ "Centralized validation",
+ "Caching enabled"
+ ]
+ },
+ "protected_standard": {
+ "path": "/api/protected-standard",
+ "security": "local_jwt",
+ "role": "admin",
+ "description": "Local JWT signature verification
without introspection",
+ "features": [
+ "Fast offline validation",
+ "No network overhead",
+ "Cannot detect token revocation"
+ ]
+ }
+ },
+ "introspection_config": {
+ "enabled": "{{keycloak.introspection.enabled}}",
+ "cache_enabled":
"{{keycloak.introspection.cache.enabled}}",
+ "cache_ttl_seconds":
"{{keycloak.introspection.cache.ttl}}"
+ },
+ "keycloak_config": {
+ "server_url": "{{keycloak.server.url}}",
+ "realm": "{{keycloak.realm}}",
+ "client_id": "{{keycloak.client.id}}"
+ }
}
- },
- "introspection_config": {
- "enabled": "{{keycloak.introspection.enabled}}",
- "cache_enabled": "{{keycloak.introspection.cache.enabled}}",
- "cache_ttl_seconds": "{{keycloak.introspection.cache.ttl}}"
- },
- "keycloak_config": {
- "server_url": "{{keycloak.server.url}}",
- "realm": "{{keycloak.realm}}",
- "client_id": "{{keycloak.client.id}}"
- }
- }
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- log:
message: "Info API called"
diff --git a/security/keycloak-security-rest/README.md
b/security/keycloak-security-rest/README.md
index 987eb96..79af561 100644
--- a/security/keycloak-security-rest/README.md
+++ b/security/keycloak-security-rest/README.md
@@ -290,14 +290,18 @@ Routes are protected by adding a policy reference. The
policy will validate the
- policy:
ref: keycloakPolicy
- setBody:
- simple: |
- {
- "message": "This is a protected endpoint, admin role required",
- "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}"
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "message": "This is a protected endpoint, admin role
required",
+ "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}"
+ }
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- log:
message: "Protected API called"
```
diff --git a/security/keycloak-security-rest/rest-api.camel.yaml
b/security/keycloak-security-rest/rest-api.camel.yaml
index 55c1714..9d48099 100644
--- a/security/keycloak-security-rest/rest-api.camel.yaml
+++ b/security/keycloak-security-rest/rest-api.camel.yaml
@@ -23,22 +23,29 @@
exception:
- "org.apache.camel.CamelAuthorizationException"
handled:
- constant: true
+ constant:
+ expression: true
steps:
- setHeader:
name: CamelHttpResponseCode
- constant: 403
+ expression:
+ constant:
+ expression: 403
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- setBody:
- simple: |
- {
- "error": "Forbidden",
- "message": "Access denied. ${exception.message}",
- "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
- "status": 403
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "error": "Forbidden",
+ "message": "Access denied. ${exception.message}",
+ "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}",
+ "status": 403
+ }
- log:
message: "Authorization failed: ${exception.message}"
@@ -60,14 +67,18 @@
uri: "platform-http:/api/public"
steps:
- setBody:
- simple: |
- {
- "message": "This is a public endpoint, no authentication
required",
- "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}"
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "message": "This is a public endpoint, no authentication
required",
+ "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}"
+ }
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- log:
message: "Public API called"
@@ -80,13 +91,17 @@
- policy:
ref: keycloakPolicy
- setBody:
- simple: |
- {
- "message": "This is a protected endpoint, admin role required",
- "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}"
- }
+ expression:
+ simple:
+ expression: |
+ {
+ "message": "This is a protected endpoint, admin role
required",
+ "timestamp": "${date:now:yyyy-MM-dd'T'HH:mm:ss}"
+ }
- setHeader:
name: Content-Type
- constant: application/json
+ expression:
+ constant:
+ expression: application/json
- log:
message: "Protected API called"
diff --git a/security/ocsf/README.md b/security/ocsf/README.md
index ec5f3ca..0e451a2 100644
--- a/security/ocsf/README.md
+++ b/security/ocsf/README.md
@@ -208,10 +208,14 @@ After unmarshalling, you can access fields directly:
```yaml
- setHeader:
name: severity
- simple: "${body.additionalProperties[severity]}"
+ expression:
+ simple:
+ expression: "${body.additionalProperties[severity]}"
- setHeader:
name: findingTitle
- simple: "${body.findingInfo.title}"
+ expression:
+ simple:
+ expression: "${body.findingInfo.title}"
```
Some fields are direct properties on the Java class (like `findingInfo`,
`vulnerabilities`), while others are in `additionalProperties` (like
`severity`, `time_dt`). Check the generated model classes in `camel-ocsf` if
you need to know which is which.
diff --git a/security/pqc-document-signing/pqc-document-signing.yaml
b/security/pqc-document-signing/pqc-document-signing.yaml
index d1e680a..3b2c64f 100644
--- a/security/pqc-document-signing/pqc-document-signing.yaml
+++ b/security/pqc-document-signing/pqc-document-signing.yaml
@@ -62,12 +62,14 @@
- log:
message: "PQC signing key initialized successfully"
- script:
- groovy: |
- // Register the KeyPair bean
- def keyManager =
camelContext.registry.lookupByNameAndType('keyLifecycleManager',
-
org.apache.camel.component.pqc.lifecycle.HashicorpVaultKeyLifecycleManager.class)
- def keyPair = keyManager.getKey('document-signing-key')
- camelContext.registry.bind('signingKey', keyPair)
+ expression:
+ groovy:
+ expression: |
+ // Register the KeyPair bean
+ def keyManager =
camelContext.registry.lookupByNameAndType('keyLifecycleManager',
+
org.apache.camel.component.pqc.lifecycle.HashicorpVaultKeyLifecycleManager.class)
+ def keyPair = keyManager.getKey('document-signing-key')
+ camelContext.registry.bind('signingKey', keyPair)
- to:
uri: direct:get-key-metadata
@@ -83,15 +85,18 @@
expression:
simple:
expression: "${body}"
- - toD:
"pqc:sign?operation=sign&signatureAlgorithm=DILITHIUM&keyPair=#signingKey"
+ - toD:
+ uri:
"pqc:sign?operation=sign&signatureAlgorithm=DILITHIUM&keyPair=#signingKey"
- script:
- groovy: |
- // Convert binary signature to base64
- def signature = exchange.message.getHeader('CamelPQCSignature',
byte[].class)
- if (signature != null) {
- def base64Signature =
java.util.Base64.encoder.encodeToString(signature)
- exchange.message.setHeader('CamelPQCSignature',
base64Signature)
- }
+ expression:
+ groovy:
+ expression: |
+ // Convert binary signature to base64
+ def signature =
exchange.message.getHeader('CamelPQCSignature', byte[].class)
+ if (signature != null) {
+ def base64Signature =
java.util.Base64.encoder.encodeToString(signature)
+ exchange.message.setHeader('CamelPQCSignature',
base64Signature)
+ }
- log:
message: "Document signed with quantum-resistant signature"
- to:
@@ -112,7 +117,9 @@
}
- setHeader:
name: Content-Type
- constant: "application/json"
+ expression:
+ constant:
+ expression: "application/json"
- log:
message: "Response: ${body}"
@@ -124,20 +131,23 @@
- log:
message: "Received document verification request: ${body}"
- script:
- groovy: |
- // Get signature from X-Signature header
- def base64Signature = exchange.getIn().getHeader('X-Signature',
String.class)
- if (base64Signature == null || base64Signature.isEmpty()) {
- throw new IllegalArgumentException('X-Signature header is
missing or empty')
- }
- def signature = java.util.Base64.decoder.decode(base64Signature)
- exchange.getIn().setHeader('CamelPQCSignature', signature)
- exchange.getIn().setHeader('signatureLength', signature.length)
+ expression:
+ groovy:
+ expression: |
+ // Get signature from X-Signature header
+ def base64Signature =
exchange.getIn().getHeader('X-Signature', String.class)
+ if (base64Signature == null || base64Signature.isEmpty()) {
+ throw new IllegalArgumentException('X-Signature header
is missing or empty')
+ }
+ def signature =
java.util.Base64.decoder.decode(base64Signature)
+ exchange.getIn().setHeader('CamelPQCSignature', signature)
+ exchange.getIn().setHeader('signatureLength',
signature.length)
- log:
message: "Verifying signature of length: ${header.signatureLength}
bytes"
- doTry:
steps:
- - toD:
"pqc:verify?operation=verify&signatureAlgorithm=DILITHIUM&keyPair=#signingKey"
+ - toD:
+ uri:
"pqc:verify?operation=verify&signatureAlgorithm=DILITHIUM&keyPair=#signingKey"
- log:
message: "Verification completed. Result:
${header.CamelPQCVerification}"
doCatch:
@@ -148,7 +158,9 @@
message: "ERROR during verification:
${exception.message}"
- setHeader:
name: CamelPQCVerification
- constant: false
+ expression:
+ constant:
+ expression: false
- choice:
when:
- expression:
@@ -181,7 +193,9 @@
}
- setHeader:
name: Content-Type
- constant: "application/json"
+ expression:
+ constant:
+ expression: "application/json"
- log:
message: "Verification result: ${body}"
@@ -214,7 +228,9 @@
}
- setHeader:
name: Content-Type
- constant: "application/json"
+ expression:
+ constant:
+ expression: "application/json"
- log:
message: "Keys listed: ${body}"
@@ -242,7 +258,9 @@
}
- setHeader:
name: Content-Type
- constant: "application/json"
+ expression:
+ constant:
+ expression: "application/json"
- route:
id: check-rotation-schedule
@@ -287,13 +305,15 @@
simple:
expression: "${body}"
- script:
- groovy: |
- // Update last used timestamp and increment usage count
- def metadata = exchange.getProperty('metadata')
- if (metadata != null) {
-
metadata.getClass().getMethod('updateLastUsed').invoke(metadata)
- exchange.message.setBody(metadata)
- }
+ expression:
+ groovy:
+ expression: |
+ // Update last used timestamp and increment usage count
+ def metadata = exchange.getProperty('metadata')
+ if (metadata != null) {
+
metadata.getClass().getMethod('updateLastUsed').invoke(metadata)
+ exchange.message.setBody(metadata)
+ }
- bean:
ref: keyLifecycleManager
method: "updateKeyMetadata('document-signing-key', ${body})"
@@ -327,7 +347,9 @@
}
- setHeader:
name: Content-Type
- constant: "application/json"
+ expression:
+ constant:
+ expression: "application/json"
- log:
message: "Key metadata: ${body}"