This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch variables-for-temporary-storage in repository https://gitbox.apache.org/repos/asf/camel-jbang-examples.git
commit c5ce84ca23c1418b9d30e94952635d8f24cc6bb1 Author: Claus Ibsen <[email protected]> AuthorDate: Mon Oct 26 10:05:13 2026 +0100 chore: the examples keep a value for the route in a variable, not a header A header is sent on with the message to the next endpoint and becomes part of what it gets. A value the route only keeps for itself - an order id for the logs and the split lines, the aggregation key, the pollEnrich file name, an output file name - goes into a variable: setVariable and ${variable.name}. Split and aggregated messages get the variables as they get the headers, and the file consumer of pollEnrich evaluates fileName with them. Changed: run/order-generator, transform/json-transform, transform/csv-to-json, route/order-lines, route/aggregator, route/enrich-and-dedupe (routes, READMEs, metadata, catalog). Headers an endpoint reads stay headers (CamelFileName, Content-Type, CamelHttpResponseCode, the path parameters of rest-openapi). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- README.md | 4 ++-- camel-jbang-example-catalog.json | 12 ++++++------ route/README.md | 2 +- route/aggregator/README.md | 6 +++--- route/aggregator/aggregator.camel.yaml | 8 ++++---- route/aggregator/metadata.json | 2 +- route/enrich-and-dedupe/README.md | 4 ++-- route/enrich-and-dedupe/audit/ORD-1001.json | 1 + route/enrich-and-dedupe/audit/ORD-1002.json | 1 + route/enrich-and-dedupe/audit/ORD-1003.json | 1 + route/enrich-and-dedupe/enrich-and-dedupe.camel.yaml | 10 +++++----- route/order-lines/README.md | 9 +++++---- route/order-lines/metadata.json | 4 ++-- route/order-lines/order-lines.camel.yaml | 10 +++++----- run/order-generator/README.md | 8 ++++---- run/order-generator/metadata.json | 2 +- run/order-generator/order-generator.camel.yaml | 6 +++--- transform/README.md | 2 +- transform/csv-to-json/README.md | 2 +- transform/csv-to-json/csv-to-json.camel.yaml | 6 +++--- transform/json-transform/README.md | 5 +++-- transform/json-transform/json-transform.camel.yaml | 6 +++--- transform/json-transform/metadata.json | 4 ++-- 23 files changed, 60 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index ebf4869..9822da3 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ JSON, XML and CSV in and out, field-by-field mapping, Groovy and XSLT. | Example | What you will see | Needs | |---|---|---| -| [JSON transform](transform/json-transform/) | The shop's order in order.json is reshaped for the warehouse: jsonpath reads the order id and the number of lines into headers, jq builds the pick list with only sku and quantity per line, and both the order and the pick list are logged. | nothing | +| [JSON transform](transform/json-transform/) | The shop's order in order.json is reshaped for the warehouse: jsonpath reads the order id and the number of lines into variables, jq builds the pick list with only sku and quantity per line, and both the order and the pick list are logged. | nothing | | [XML to JSON](transform/xml-to-json/) | A supplier's XML order dropped in the inbox directory is read with the Jackson XML data format and written out as the shop's JSON with the Jackson JSON data format, both logged; no mapping code, the XML elements and attributes become JSON fields. | nothing | | [CSV to JSON](transform/csv-to-json/) | A CSV of invoices dropped in the inbox directory is read with the CSV data format, its header line naming the fields, split into one message per invoice, and each invoice is logged as JSON and written to the outbox directory as its own file. | nothing | | [Data mapping](transform/data-mapping/) | The shop's order in order.json is mapped field by field to the courier's shipment format, with renamed fields, a nested recipient, one parcel per line, a computed total and a service chosen from the country; the order is parsed to a map, the script shipment-mapping.groovy builds the shipment, and it is logged as JSON. | nothing | @@ -72,7 +72,7 @@ The routing patterns: content-based router, splitter, aggregator, filter and mul | Example | What you will see | Needs | |---|---|---| | [Content-based router](route/content-based-router/) | Three orders from three countries are read from the orders directory and a choice routes each by its country: the Danish order to local delivery, the German order to EU shipping without customs, the US order to export with a customs declaration; each branch logs what it did. | nothing | -| [Order lines](route/order-lines/) | Each order read from the orders directory is split into one message per line, the order id travels along in a header, and the log shows the order, one pick line per line, and the parent's confirmation that all lines went to picking. | nothing | +| [Order lines](route/order-lines/) | Each order read from the orders directory is split into one message per line, the order id travels along in a variable, and the log shows the order, one pick line per line, and the parent's confirmation that all lines went to picking. | nothing | | [Aggregator](route/aggregator/) | The warehouse reports each picked line on its own and the aggregator collects the lines of one order back into a shipment, correlated by the order id and complete when as many lines are in as the order had; each shipment is logged as JSON. | nothing | | [Filter and multicast](route/filter-and-multicast/) | Three orders are read from the orders directory; a filter lets only the paid ones through and a multicast sends each paid order to both the warehouse route and the invoicing route, which log their part; the pending order is logged as received and goes no further. | nothing | | [Enrich and deduplicate](route/enrich-and-dedupe/) | The three orders and a resent copy of ORD-1001 are read; an idempotent consumer accepts each order id once and logs the resent one as a duplicate, each accepted order is enriched with its customer's name and tier from customers/ with pollEnrich, and a wire tap writes a copy to audit/ without holding the order up. | nothing | diff --git a/camel-jbang-example-catalog.json b/camel-jbang-example-catalog.json index f4e34cb..261b291 100644 --- a/camel-jbang-example-catalog.json +++ b/camel-jbang-example-catalog.json @@ -1135,7 +1135,7 @@ "eips": [ "aggregate", "split", - "setHeader", + "setVariable", "marshal", "unmarshal" ], @@ -1352,7 +1352,7 @@ { "name": "route/order-lines", "title": "Order lines", - "description": "Each order read from the orders directory is split into one message per line, the order id travels along in a header, and the log shows the order, one pick line per line, and the parent's confirmation that all lines went to picking.", + "description": "Each order read from the orders directory is split into one message per line, the order id travels along in a variable, and the log shows the order, one pick line per line, and the parent's confirmation that all lines went to picking.", "level": "route", "teaches": { "components": [ @@ -1361,7 +1361,7 @@ ], "eips": [ "split", - "setHeader", + "setVariable", "unmarshal" ], "languages": [ @@ -1433,7 +1433,7 @@ "log" ], "eips": [ - "setHeader", + "setVariable", "setBody" ], "languages": [ @@ -1712,7 +1712,7 @@ { "name": "transform/json-transform", "title": "JSON transform", - "description": "The shop's order in order.json is reshaped for the warehouse: jsonpath reads the order id and the number of lines into headers, jq builds the pick list with only sku and quantity per line, and both the order and the pick list are logged.", + "description": "The shop's order in order.json is reshaped for the warehouse: jsonpath reads the order id and the number of lines into variables, jq builds the pick list with only sku and quantity per line, and both the order and the pick list are logged.", "level": "transform", "teaches": { "components": [ @@ -1721,7 +1721,7 @@ ], "eips": [ "transform", - "setHeader", + "setVariable", "setBody" ], "languages": [ diff --git a/route/README.md b/route/README.md index e957861..a8da5bc 100644 --- a/route/README.md +++ b/route/README.md @@ -6,7 +6,7 @@ The routing patterns: content-based router, splitter, aggregator, filter and mul | Example | What you will see | Needs | |---|---|---| | [Content-based router](content-based-router/) | Three orders from three countries are read from the orders directory and a choice routes each by its country: the Danish order to local delivery, the German order to EU shipping without customs, the US order to export with a customs declaration; each branch logs what it did. | nothing | -| [Order lines](order-lines/) | Each order read from the orders directory is split into one message per line, the order id travels along in a header, and the log shows the order, one pick line per line, and the parent's confirmation that all lines went to picking. | nothing | +| [Order lines](order-lines/) | Each order read from the orders directory is split into one message per line, the order id travels along in a variable, and the log shows the order, one pick line per line, and the parent's confirmation that all lines went to picking. | nothing | | [Aggregator](aggregator/) | The warehouse reports each picked line on its own and the aggregator collects the lines of one order back into a shipment, correlated by the order id and complete when as many lines are in as the order had; each shipment is logged as JSON. | nothing | | [Filter and multicast](filter-and-multicast/) | Three orders are read from the orders directory; a filter lets only the paid ones through and a multicast sends each paid order to both the warehouse route and the invoicing route, which log their part; the pending order is logged as received and goes no further. | nothing | | [Enrich and deduplicate](enrich-and-dedupe/) | The three orders and a resent copy of ORD-1001 are read; an idempotent consumer accepts each order id once and logs the resent one as a duplicate, each accepted order is enriched with its customer's name and tier from customers/ with pollEnrich, and a wire tap writes a copy to audit/ without holding the order up. | nothing | diff --git a/route/aggregator/README.md b/route/aggregator/README.md index 56789ff..c1cd66d 100644 --- a/route/aggregator/README.md +++ b/route/aggregator/README.md @@ -31,9 +31,9 @@ can be repeated. ## How it works -- The first route reads the orders, keeps the order id in a header, splits them into lines, and sends every +- The first route reads the orders, keeps the order id in a variable, splits them into lines, and sends every line to `direct:shipment`, as a warehouse system would report picks one by one. -- The second route aggregates: `correlationExpression` `${header.orderId}` groups lines of the same order, +- The second route aggregates: `correlationExpression` `${variable.orderId}` groups lines of the same order, `completionSizeExpression` `${header.CamelSplitSize}` says how many lines make the order complete, and the `GroupedBodyAggregationStrategy` collects the bodies into a list. - When a shipment completes, the list of lines is written as JSON with `marshal` and logged. @@ -41,7 +41,7 @@ can be repeated. ## Build it step by step 1. Start from `order-lines` and send each line to `direct:shipment` instead of only logging it. -2. Add a route from `direct:shipment` with an `aggregate` correlating on `${header.orderId}` and a fixed +2. Add a route from `direct:shipment` with an `aggregate` correlating on `${variable.orderId}` and a fixed `completionSize: 2`; only the two-line order completes. 3. Replace the fixed size by `completionSizeExpression` with `${header.CamelSplitSize}`. 4. Add `marshal` with `json` and log the shipment. diff --git a/route/aggregator/aggregator.camel.yaml b/route/aggregator/aggregator.camel.yaml index 5148ba5..9d07624 100644 --- a/route/aggregator/aggregator.camel.yaml +++ b/route/aggregator/aggregator.camel.yaml @@ -13,7 +13,7 @@ - unmarshal: json: library: Jackson - - setHeader: + - setVariable: name: orderId expression: simple: @@ -24,7 +24,7 @@ expression: "${body[lines]}" steps: - log: - message: "Picked ${body[qty]} x ${body[sku]} for ${header.orderId}" + message: "Picked ${body[qty]} x ${body[sku]} for ${variable.orderId}" - to: uri: direct parameters: @@ -40,7 +40,7 @@ aggregationStrategy: "#class:org.apache.camel.processor.aggregate.GroupedBodyAggregationStrategy" correlationExpression: simple: - expression: "${header.orderId}" + expression: "${variable.orderId}" completionSizeExpression: simple: expression: "${header.CamelSplitSize}" @@ -49,4 +49,4 @@ json: library: Jackson - log: - message: "Shipment for ${header.orderId} complete: ${body}" + message: "Shipment for ${variable.orderId} complete: ${body}" diff --git a/route/aggregator/metadata.json b/route/aggregator/metadata.json index 3636de3..19d5f94 100644 --- a/route/aggregator/metadata.json +++ b/route/aggregator/metadata.json @@ -12,7 +12,7 @@ "eips": [ "aggregate", "split", - "setHeader", + "setVariable", "marshal", "unmarshal" ], diff --git a/route/enrich-and-dedupe/README.md b/route/enrich-and-dedupe/README.md index 5415943..b684f52 100644 --- a/route/enrich-and-dedupe/README.md +++ b/route/enrich-and-dedupe/README.md @@ -37,8 +37,8 @@ The copies of the accepted orders land in `audit/`. Stop the example with `ctrl` - `idempotentConsumer` computes the order id with Simple and checks it against the repository. With `skipDuplicate: false` a duplicate is not dropped but marked with the exchange property `CamelDuplicateMessage`, so the `choice` can log it. -- `pollEnrich` reads the customer's file. The file name is computed into a header first: the file consumer that - `pollEnrich` uses evaluates `fileName` with the headers of the message, not its body. `variableReceive: customer` +- `pollEnrich` reads the customer's file. The file name is computed into a variable first: the file consumer that + `pollEnrich` uses evaluates `fileName` with the variables and headers of the message, not its body. `variableReceive: customer` keeps the customer in a variable, so the order stays the body, and `unmarshal` with `variableSend` and `variableReceive` parses the variable in place. - `wireTap` sends a copy of the order to the `audit` route and goes on at once: the audit never holds the order up. diff --git a/route/enrich-and-dedupe/audit/ORD-1001.json b/route/enrich-and-dedupe/audit/ORD-1001.json new file mode 100644 index 0000000..dca6842 --- /dev/null +++ b/route/enrich-and-dedupe/audit/ORD-1001.json @@ -0,0 +1 @@ +{"orderId":"ORD-1001","customer":"C-482","country":"DK","status":"paid","lines":[{"sku":"CAMEL-TSHIRT","qty":2,"price":19.95},{"sku":"CAMEL-MUG","qty":1,"price":9.5}]} \ No newline at end of file diff --git a/route/enrich-and-dedupe/audit/ORD-1002.json b/route/enrich-and-dedupe/audit/ORD-1002.json new file mode 100644 index 0000000..c08226a --- /dev/null +++ b/route/enrich-and-dedupe/audit/ORD-1002.json @@ -0,0 +1 @@ +{"orderId":"ORD-1002","customer":"C-207","country":"DE","status":"paid","lines":[{"sku":"CAMEL-MUG","qty":3,"price":9.5}]} \ No newline at end of file diff --git a/route/enrich-and-dedupe/audit/ORD-1003.json b/route/enrich-and-dedupe/audit/ORD-1003.json new file mode 100644 index 0000000..004ac33 --- /dev/null +++ b/route/enrich-and-dedupe/audit/ORD-1003.json @@ -0,0 +1 @@ +{"orderId":"ORD-1003","customer":"C-134","country":"US","status":"pending","lines":[{"sku":"CAMEL-TSHIRT","qty":1,"price":19.95},{"sku":"CAMEL-CAP","qty":1,"price":14.0},{"sku":"CAMEL-MUG","qty":2,"price":9.5}]} \ No newline at end of file diff --git a/route/enrich-and-dedupe/enrich-and-dedupe.camel.yaml b/route/enrich-and-dedupe/enrich-and-dedupe.camel.yaml index f81fb64..b5c058c 100644 --- a/route/enrich-and-dedupe/enrich-and-dedupe.camel.yaml +++ b/route/enrich-and-dedupe/enrich-and-dedupe.camel.yaml @@ -38,10 +38,10 @@ steps: - log: message: "Order ${body[orderId]} accepted" - # the file name goes in a header: the file consumer of pollEnrich evaluates fileName with - # the headers of the message, not its body; the customer goes to a variable, so the order - # stays the body - - setHeader: + # the file name goes in a variable: the file consumer of pollEnrich evaluates fileName with + # the variables and headers of the message, not its body; the customer goes to a variable, + # so the order stays the body + - setVariable: name: customerFile expression: simple: @@ -49,7 +49,7 @@ - pollEnrich: expression: simple: - expression: "file:customers?fileName=${header.customerFile}&noop=true&idempotent=false" + expression: "file:customers?fileName=${variable.customerFile}&noop=true&idempotent=false" timeout: 2000 variableReceive: customer - unmarshal: diff --git a/route/order-lines/README.md b/route/order-lines/README.md index 2659d8d..17b346f 100644 --- a/route/order-lines/README.md +++ b/route/order-lines/README.md @@ -1,7 +1,7 @@ # Order lines An order is one message with several lines; the warehouse picks one line at a time. The splitter turns the order -into one message per line, and the order id travels along in a header. +into one message per line, and the order id travels along in a variable. ## What you will see @@ -32,8 +32,9 @@ can be repeated. - The order is parsed with `unmarshal` and `json`, so `${body[lines]}` is a list and `${body[lines].size()}` its length. -- `setHeader` keeps the order id before the split: headers are copied to every split message, so each pick line - knows its order. +- `setVariable` keeps the order id before the split: every split message gets a copy of the variables, so each pick + line knows its order. A variable, not a header: a header is sent on with the message to the next endpoint, and + the order id is only for the route itself. - `split` with `${body[lines]}` runs its steps once per line with that line as the body; `CamelSplitIndex` and `CamelSplitSize` are available inside if a count is needed. - After the split the route continues with the original order, which logs the confirmation. @@ -42,7 +43,7 @@ can be repeated. 1. A `file` route on `orders` that unmarshals each order and logs the number of lines. 2. Add `split` over `${body[lines]}` and log `${body[sku]}` inside it. -3. Keep the order id in a header before the split and use it in the pick line. +3. Keep the order id in a variable before the split and use it in the pick line. 4. Log the confirmation after the split and notice the body is the whole order again. ## Try changing diff --git a/route/order-lines/metadata.json b/route/order-lines/metadata.json index 2f86c2b..4338dd2 100644 --- a/route/order-lines/metadata.json +++ b/route/order-lines/metadata.json @@ -1,6 +1,6 @@ { "title": "Order lines", - "description": "Each order read from the orders directory is split into one message per line, the order id travels along in a header, and the log shows the order, one pick line per line, and the parent's confirmation that all lines went to picking.", + "description": "Each order read from the orders directory is split into one message per line, the order id travels along in a variable, and the log shows the order, one pick line per line, and the parent's confirmation that all lines went to picking.", "level": "route", "order": 2, "teaches": { @@ -10,7 +10,7 @@ ], "eips": [ "split", - "setHeader", + "setVariable", "unmarshal" ], "languages": [ diff --git a/route/order-lines/order-lines.camel.yaml b/route/order-lines/order-lines.camel.yaml index 9f8c2ad..be0d10d 100644 --- a/route/order-lines/order-lines.camel.yaml +++ b/route/order-lines/order-lines.camel.yaml @@ -1,5 +1,5 @@ # An order is one message with several lines; the warehouse picks one line at a time. The splitter -# turns the order into one message per line, and the split messages keep the order id in a header. +# turns the order into one message per line, and the split messages keep the order id in a variable. - route: id: order-lines from: @@ -12,19 +12,19 @@ - unmarshal: json: library: Jackson - - setHeader: + - setVariable: name: orderId expression: simple: expression: "${body[orderId]}" - log: - message: "Order ${header.orderId} with ${body[lines].size()} line(s)" + message: "Order ${variable.orderId} with ${body[lines].size()} line(s)" - split: expression: simple: expression: "${body[lines]}" steps: - log: - message: " pick ${body[qty]} x ${body[sku]} for ${header.orderId}" + message: " pick ${body[qty]} x ${body[sku]} for ${variable.orderId}" - log: - message: "Order ${header.orderId}: all ${body[lines].size()} line(s) sent to picking" + message: "Order ${variable.orderId}: all ${body[lines].size()} line(s) sent to picking" diff --git a/run/order-generator/README.md b/run/order-generator/README.md index 18fc09f..203a087 100644 --- a/run/order-generator/README.md +++ b/run/order-generator/README.md @@ -27,7 +27,7 @@ Stop it with `ctrl` + `c`, or from another terminal with `camel stop order-gener ## How it works - `order-generator.camel.yaml` is the route: a `timer` fires every `order.period` milliseconds, a - `setHeader` asks the `orderNumber` bean for the next number with a method expression, a `setBody` + `setVariable` asks the `orderNumber` bean for the next number with a method expression, a `setBody` builds the order as JSON with the simple language, and a `log` prints it. - `OrderNumber.java` is a plain Java class next to the route. `beans.yaml` declares it as the bean `orderNumber` and sets its first number from a property. @@ -39,9 +39,9 @@ Stop it with `ctrl` + `c`, or from another terminal with `camel stop order-gener Ask your assistant, or type it yourself, one step at a time, and run after each: 1. A timer route that logs "New order" every five seconds. -2. Set a header `orderId` to a constant `ORD-1001` and log "New order ${header.orderId}". +2. Set a variable `orderId` to a constant `ORD-1001` and log "New order ${variable.orderId}". 3. Add a Java class `OrderNumber` with a method `next()` that returns `ORD-` and a counter, declare it - in `beans.yaml`, and set the header from the bean's method instead of the constant. + in `beans.yaml`, and set the variable from the bean's method instead of the constant. 4. Set the body to a JSON order with the order id, a random customer and one line, and log the body. 5. Move the period and the first order number to `application.properties`. @@ -49,7 +49,7 @@ Ask your assistant, or type it yourself, one step at a time, and run after each: - `order.period=1000` for an order every second. - Add a second line to the order, or pick the sku at random from two products. -- Log only the order id and the number of lines: `${header.orderId} has ${body.lines.size()} line(s)` +- Log only the order id and the number of lines: `${variable.orderId} has ${body.lines.size()} line(s)` needs the body as an object; the `json-transform` example on the next rung shows how. ## Integration testing diff --git a/run/order-generator/metadata.json b/run/order-generator/metadata.json index e009640..e6b5bdf 100644 --- a/run/order-generator/metadata.json +++ b/run/order-generator/metadata.json @@ -9,7 +9,7 @@ "log" ], "eips": [ - "setHeader", + "setVariable", "setBody" ], "languages": [ diff --git a/run/order-generator/order-generator.camel.yaml b/run/order-generator/order-generator.camel.yaml index 514f42b..3bcff45 100644 --- a/run/order-generator/order-generator.camel.yaml +++ b/run/order-generator/order-generator.camel.yaml @@ -8,7 +8,7 @@ timerName: orders period: "{{order.period}}" steps: - - setHeader: + - setVariable: name: orderId expression: method: @@ -18,7 +18,7 @@ expression: simple: expression: |- - {"orderId": "${header.orderId}", "customer": "C-${random(100,999)}", "country": "DK", + {"orderId": "${variable.orderId}", "customer": "C-${random(100,999)}", "country": "DK", "lines": [{"sku": "CAMEL-TSHIRT", "qty": ${random(1,3)}, "price": 19.95}], "status": "paid"} - log: - message: "New order ${header.orderId}: ${body}" + message: "New order ${variable.orderId}: ${body}" diff --git a/transform/README.md b/transform/README.md index f87b719..798626f 100644 --- a/transform/README.md +++ b/transform/README.md @@ -5,7 +5,7 @@ JSON, XML and CSV in and out, field-by-field mapping, Groovy and XSLT. | Example | What you will see | Needs | |---|---|---| -| [JSON transform](json-transform/) | The shop's order in order.json is reshaped for the warehouse: jsonpath reads the order id and the number of lines into headers, jq builds the pick list with only sku and quantity per line, and both the order and the pick list are logged. | nothing | +| [JSON transform](json-transform/) | The shop's order in order.json is reshaped for the warehouse: jsonpath reads the order id and the number of lines into variables, jq builds the pick list with only sku and quantity per line, and both the order and the pick list are logged. | nothing | | [XML to JSON](xml-to-json/) | A supplier's XML order dropped in the inbox directory is read with the Jackson XML data format and written out as the shop's JSON with the Jackson JSON data format, both logged; no mapping code, the XML elements and attributes become JSON fields. | nothing | | [CSV to JSON](csv-to-json/) | A CSV of invoices dropped in the inbox directory is read with the CSV data format, its header line naming the fields, split into one message per invoice, and each invoice is logged as JSON and written to the outbox directory as its own file. | nothing | | [Data mapping](data-mapping/) | The shop's order in order.json is mapped field by field to the courier's shipment format, with renamed fields, a nested recipient, one parcel per line, a computed total and a service chosen from the country; the order is parsed to a map, the script shipment-mapping.groovy builds the shipment, and it is logged as JSON. | nothing | diff --git a/transform/csv-to-json/README.md b/transform/csv-to-json/README.md index 8ed95b6..05635c9 100644 --- a/transform/csv-to-json/README.md +++ b/transform/csv-to-json/README.md @@ -30,7 +30,7 @@ camel run * - `unmarshal` with the `csv` data format reads `inbox/invoices.csv`; `captureHeaderRecord` takes the first line as the field names and `useMaps` makes each following line a map. - `split` turns the list of maps into one message per invoice. -- Inside the split, the invoice id is kept in a header, `marshal` with `json` writes the map as JSON, and the +- Inside the split, the invoice id is kept in a variable, `marshal` with `json` writes the map as JSON, and the `file` producer names the output file after the invoice. - Values are strings, as in the CSV; the `data-mapping` example shows how to compute and type fields. diff --git a/transform/csv-to-json/csv-to-json.camel.yaml b/transform/csv-to-json/csv-to-json.camel.yaml index 4fdf03d..a020cd3 100644 --- a/transform/csv-to-json/csv-to-json.camel.yaml +++ b/transform/csv-to-json/csv-to-json.camel.yaml @@ -18,7 +18,7 @@ simple: expression: "${body}" steps: - - setHeader: + - setVariable: name: invoiceId expression: simple: @@ -27,9 +27,9 @@ json: library: Jackson - log: - message: "Invoice ${header.invoiceId}: ${body}" + message: "Invoice ${variable.invoiceId}: ${body}" - to: uri: file parameters: directoryName: outbox - fileName: "${header.invoiceId}.json" + fileName: "${variable.invoiceId}.json" diff --git a/transform/json-transform/README.md b/transform/json-transform/README.md index f7e3d2c..1ad285f 100644 --- a/transform/json-transform/README.md +++ b/transform/json-transform/README.md @@ -28,7 +28,8 @@ camel run * ## How it works - The order comes from `order.json`; `resource:file:` in a constant expression loads a file as the body. -- `jsonpath` expressions pick the order id and the number of lines into headers. +- `jsonpath` expressions pick the order id and the number of lines into variables, which stay with the route and are + not sent on with the message as headers would be. - `transform` with a `jq` expression builds a new document from the old one: `.orderId` becomes `order`, and `[.lines[] | {sku, qty}]` keeps two fields of every line. - The Camel CLI adds the jq and jsonpath languages on its own. @@ -36,7 +37,7 @@ camel run * ## Build it step by step 1. A one-shot timer route that sets the body from `order.json` and logs it. -2. Read the order id into a header with `jsonpath: $.orderId` and log it. +2. Read the order id into a variable with `jsonpath: $.orderId` and log it. 3. Add the number of lines with `jsonpath: $.lines.length()`. 4. Add a `transform` step with a jq expression that keeps only the order id, and log the result. 5. Extend the jq expression with the country and the pick list of sku and qty per line. diff --git a/transform/json-transform/json-transform.camel.yaml b/transform/json-transform/json-transform.camel.yaml index 933bb41..e17ecdd 100644 --- a/transform/json-transform/json-transform.camel.yaml +++ b/transform/json-transform/json-transform.camel.yaml @@ -12,18 +12,18 @@ expression: constant: expression: "resource:file:order.json" - - setHeader: + - setVariable: name: orderId expression: jsonpath: expression: "$.orderId" - - setHeader: + - setVariable: name: itemCount expression: jsonpath: expression: "$.lines.length()" - log: - message: "Order ${header.orderId} with ${header.itemCount} lines: ${body}" + message: "Order ${variable.orderId} with ${variable.itemCount} lines: ${body}" - transform: expression: jq: diff --git a/transform/json-transform/metadata.json b/transform/json-transform/metadata.json index 07c9264..1f2bb81 100644 --- a/transform/json-transform/metadata.json +++ b/transform/json-transform/metadata.json @@ -1,6 +1,6 @@ { "title": "JSON transform", - "description": "The shop's order in order.json is reshaped for the warehouse: jsonpath reads the order id and the number of lines into headers, jq builds the pick list with only sku and quantity per line, and both the order and the pick list are logged.", + "description": "The shop's order in order.json is reshaped for the warehouse: jsonpath reads the order id and the number of lines into variables, jq builds the pick list with only sku and quantity per line, and both the order and the pick list are logged.", "level": "transform", "order": 1, "teaches": { @@ -10,7 +10,7 @@ ], "eips": [ "transform", - "setHeader", + "setVariable", "setBody" ], "languages": [
