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 865199f chore: find the SKU in stock.json with Groovy instead of a
jsonpath filter (#95)
865199f is described below
commit 865199f82e06a999992544ce1f87fef3df962528
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Oct 2 20:11:00 2026 +0200
chore: find the SKU in stock.json with Groovy instead of a jsonpath filter
(#95)
stock-api, http-client, openapi-server and mcp-server looked up one SKU with
a jsonpath filter returning a list, then a size check and ${body[0]}. They
now
unmarshal the file and run body.find { it.sku == headers.sku }, which gives
the item or null in one line. READMEs, metadata and the catalog follow.
Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
ai/mcp-server/README.md | 2 +-
ai/mcp-server/mcp-server.camel.yaml | 13 ++++++-----
ai/mcp-server/metadata.json | 2 +-
camel-jbang-example-catalog.json | 9 ++++----
connect/http-client/http-client.camel.yaml | 15 ++++++-------
connect/http-client/metadata.json | 2 +-
connect/stock-api/README.md | 10 ++++-----
connect/stock-api/metadata.json | 3 ++-
connect/stock-api/stock-api.camel.yaml | 15 ++++++-------
contracts/openapi-server/README.md | 4 ++--
contracts/openapi-server/metadata.json | 2 +-
contracts/openapi-server/openapi-server.camel.yaml | 25 ++++++----------------
12 files changed, 46 insertions(+), 56 deletions(-)
diff --git a/ai/mcp-server/README.md b/ai/mcp-server/README.md
index 2170f2f..9eb62a7 100644
--- a/ai/mcp-server/README.md
+++ b/ai/mcp-server/README.md
@@ -74,7 +74,7 @@ The MCP server is a preview feature since Camel 4.22.
1. One `ai-tool` route that answers a fixed text, with the four
`camel.server.mcp-*` properties; run it and see
the server line in the log, then `initialize` and `tools/list` with `curl`.
2. Add a parameter and use `${header.sku}` in the answer; call it with
`tools/call`.
-3. Answer from `stock.json` with `jsonpath` and add the unknown case.
+3. Answer from `stock.json`: unmarshal it, find the SKU with Groovy and add
the unknown case.
4. Add the second tool and connect a real agent.
## Try changing
diff --git a/ai/mcp-server/mcp-server.camel.yaml
b/ai/mcp-server/mcp-server.camel.yaml
index 02834fb..55a7399 100644
--- a/ai/mcp-server/mcp-server.camel.yaml
+++ b/ai/mcp-server/mcp-server.camel.yaml
@@ -17,16 +17,19 @@
expression:
constant:
expression: resource:file:stock.json
+ - unmarshal:
+ json:
+ library: Jackson
+ # the item of that SKU as a map, or null when there is none
- setBody:
expression:
- jsonpath:
- expression: "$[?(@.sku == '${header.sku}')]"
- resultType: java.util.List
+ groovy:
+ expression: "body.find { it.sku == headers.sku }"
- choice:
when:
- expression:
simple:
- expression: "${body.size()} == 0"
+ expression: "${body} == null"
steps:
- setBody:
expression:
@@ -37,7 +40,7 @@
- setBody:
expression:
simple:
- expression: "${body[0][qty]} ${header.sku} in stock"
+ expression: "${body[qty]} ${header.sku} in stock"
- log:
message: "Tool stock_level(${header.sku}): ${body}"
diff --git a/ai/mcp-server/metadata.json b/ai/mcp-server/metadata.json
index f5134f5..3ccae52 100644
--- a/ai/mcp-server/metadata.json
+++ b/ai/mcp-server/metadata.json
@@ -16,7 +16,7 @@
],
"languages": [
"simple",
- "jsonpath",
+ "groovy",
"constant"
],
"dataformats": [
diff --git a/camel-jbang-example-catalog.json b/camel-jbang-example-catalog.json
index dbabdbe..3991ceb 100644
--- a/camel-jbang-example-catalog.json
+++ b/camel-jbang-example-catalog.json
@@ -112,7 +112,7 @@
],
"languages": [
"simple",
- "jsonpath",
+ "groovy",
"constant"
],
"dataformats": [
@@ -548,7 +548,7 @@
],
"languages": [
"simple",
- "jsonpath"
+ "groovy"
],
"dataformats": [
"json"
@@ -589,11 +589,12 @@
"setBody",
"setHeader",
"choice",
+ "unmarshal",
"marshal"
],
"languages": [
"constant",
- "jsonpath",
+ "groovy",
"simple"
],
"dataformats": [
@@ -728,7 +729,7 @@
],
"languages": [
"simple",
- "jsonpath",
+ "groovy",
"constant"
],
"dataformats": [
diff --git a/connect/http-client/http-client.camel.yaml
b/connect/http-client/http-client.camel.yaml
index 79f40db..a73f67e 100644
--- a/connect/http-client/http-client.camel.yaml
+++ b/connect/http-client/http-client.camel.yaml
@@ -19,16 +19,19 @@
expression:
constant:
expression: resource:file:stock.json
+ - unmarshal:
+ json:
+ library: Jackson
+ # the item of that SKU as a map, or null when there is none
- setBody:
expression:
- jsonpath:
- expression: "$[?(@.sku == '${header.sku}')]"
- resultType: java.util.List
+ groovy:
+ expression: "body.find { it.sku == headers.sku }"
- choice:
when:
- expression:
simple:
- expression: "${body.size()} == 0"
+ expression: "${body} == null"
steps:
- setHeader:
name: CamelHttpResponseCode
@@ -41,10 +44,6 @@
expression: '{"error": "unknown sku ${header.sku}"}'
otherwise:
steps:
- - setBody:
- expression:
- simple:
- expression: "${body[0]}"
- marshal:
json:
library: Jackson
diff --git a/connect/http-client/metadata.json
b/connect/http-client/metadata.json
index 07a2492..2487795 100644
--- a/connect/http-client/metadata.json
+++ b/connect/http-client/metadata.json
@@ -22,7 +22,7 @@
],
"languages": [
"simple",
- "jsonpath"
+ "groovy"
],
"dataformats": [
"json"
diff --git a/connect/stock-api/README.md b/connect/stock-api/README.md
index 10cbd83..6cf1cf0 100644
--- a/connect/stock-api/README.md
+++ b/connect/stock-api/README.md
@@ -40,17 +40,17 @@ Then, in another terminal, call it with `curl` as above.
Stop it with `ctrl` + `
item. Each operation hands over to a `direct` route. The CLI starts the HTTP
server on port 8080 because the
file uses the REST DSL; `application.properties` sets the port.
- The list route sets the body to `resource:file:stock.json`, the file next to
the route, and the content type.
-- The item route loads the same file and picks the item with a `jsonpath`
filter, `$[?(@.sku == '...')]`, in which
- the `{sku}` path parameter arrives as the header `sku`. The result is a
list: empty means 404 with a small error
- body, otherwise the first element is marshalled back to JSON.
+- The item route loads the same file, unmarshals it into a list of maps, and
picks the item with one line of Groovy,
+ `body.find { it.sku == headers.sku }`, in which the `{sku}` path parameter
arrives as the header `sku`. The result is
+ the item or null: null means 404 with a small error body, otherwise the item
is marshalled back to JSON.
- `CamelHttpResponseCode` is the header that sets the status code; 200 is the
default.
## Build it step by step
1. A `rest` with one `get` that answers `resource:file:stock.json`; run it and
`curl localhost:8080/stock`.
2. Add the `/{sku}` operation and log `${header.sku}` to see the path
parameter arrive.
-3. Filter the file with `jsonpath` and return the first element; `curl` a
known SKU.
-4. Add the `choice` for the empty result and the 404.
+3. Unmarshal the file and find the item with Groovy, `body.find { it.sku ==
headers.sku }`; `curl` a known SKU.
+4. Add the `choice` for the null result and the 404.
## Try changing
diff --git a/connect/stock-api/metadata.json b/connect/stock-api/metadata.json
index cf02c8c..e5ec94b 100644
--- a/connect/stock-api/metadata.json
+++ b/connect/stock-api/metadata.json
@@ -13,11 +13,12 @@
"setBody",
"setHeader",
"choice",
+ "unmarshal",
"marshal"
],
"languages": [
"constant",
- "jsonpath",
+ "groovy",
"simple"
],
"dataformats": [
diff --git a/connect/stock-api/stock-api.camel.yaml
b/connect/stock-api/stock-api.camel.yaml
index b5464b8..94fafe5 100644
--- a/connect/stock-api/stock-api.camel.yaml
+++ b/connect/stock-api/stock-api.camel.yaml
@@ -37,16 +37,19 @@
expression:
constant:
expression: resource:file:stock.json
+ - unmarshal:
+ json:
+ library: Jackson
+ # the item of that SKU as a map, or null when there is none
- setBody:
expression:
- jsonpath:
- expression: "$[?(@.sku == '${header.sku}')]"
- resultType: java.util.List
+ groovy:
+ expression: "body.find { it.sku == headers.sku }"
- choice:
when:
- expression:
simple:
- expression: "${body.size()} == 0"
+ expression: "${body} == null"
steps:
- setHeader:
name: CamelHttpResponseCode
@@ -59,10 +62,6 @@
expression: '{"error": "unknown sku ${header.sku}"}'
otherwise:
steps:
- - setBody:
- expression:
- simple:
- expression: "${body[0]}"
- marshal:
json:
library: Jackson
diff --git a/contracts/openapi-server/README.md
b/contracts/openapi-server/README.md
index 04fbb10..746aaa9 100644
--- a/contracts/openapi-server/README.md
+++ b/contracts/openapi-server/README.md
@@ -48,8 +48,8 @@ Stop it with `ctrl` + `c`.
`apiContextPath: openapi` serves the contract.
- Each operation is a `direct` route named after its `operationId`:
`listStock`, `getStock`, `reserveStock`.
Path parameters arrive as headers, `sku` here; the request body is the
message body.
-- `lookup` is a helper route the two SKU operations share: it filters the
stock file with `jsonpath` and
- leaves the item, or null, as the body.
+- `lookup` is a helper route the two SKU operations share: it unmarshals the
stock file and finds the SKU
+ with Groovy, `body.find { it.sku == headers.sku }`, which leaves the item,
or null, as the body.
- The contract check does not look at the values, so `reserveStock` runs
`validate` on them and an
`onException` turns the failed predicate into a 400 with an error body, the
status the contract promises.
- `CamelHttpResponseCode` sets 404 and 409; the bodies are the JSON the
contract's `Error` schema describes.
diff --git a/contracts/openapi-server/metadata.json
b/contracts/openapi-server/metadata.json
index 2983f8b..07a2707 100644
--- a/contracts/openapi-server/metadata.json
+++ b/contracts/openapi-server/metadata.json
@@ -21,7 +21,7 @@
],
"languages": [
"simple",
- "jsonpath",
+ "groovy",
"constant"
],
"dataformats": [
diff --git a/contracts/openapi-server/openapi-server.camel.yaml
b/contracts/openapi-server/openapi-server.camel.yaml
index 23d364e..d2f497b 100644
--- a/contracts/openapi-server/openapi-server.camel.yaml
+++ b/contracts/openapi-server/openapi-server.camel.yaml
@@ -139,24 +139,11 @@
expression:
constant:
expression: resource:file:stock.json
+ - unmarshal:
+ json:
+ library: Jackson
+ # the item of that SKU as a map, or null when there is none
- setBody:
expression:
- jsonpath:
- expression: "$[?(@.sku == '${header.sku}')]"
- resultType: java.util.List
- - choice:
- when:
- - expression:
- simple:
- expression: "${body.size()} == 0"
- steps:
- - setBody:
- expression:
- simple:
- expression: "${null}"
- otherwise:
- steps:
- - setBody:
- expression:
- simple:
- expression: "${body[0]}"
+ groovy:
+ expression: "body.find { it.sku == headers.sku }"