You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2026/10/18 12:41:40 UTC
(camel-performance-tests) branch main updated (981c7a2 -> 7f09ad7)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel-performance-tests.git
from 981c7a2 ai-benchmark: the sql upsert check accepts doTry/doCatch
new fa6f787 ai-benchmark: a new set in steps-new/, with connect-service/kafka-orders as its first example
new 7f09ad7 ai-benchmark: connect-service/jms-request-reply in the new set
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
ai-benchmark/.gitignore | 1 +
ai-benchmark/gen_stepwise.py | 125 ++++++++++++++++++++-
ai-benchmark/run-stepwise-ladder.sh | 7 +-
.../orders/order-1001.json | 0
.../orders/order-1002.json | 0
.../orders/order-1003.json | 0
.../stock.json | 0
.../orders/order-1001.json | 0
.../orders/order-1002.json | 0
.../orders/order-1003.json | 0
10 files changed, 129 insertions(+), 4 deletions(-)
copy ai-benchmark/seed/{connect-http-client => connect-service-jms-request-reply}/orders/order-1001.json (100%)
copy ai-benchmark/seed/{connect-http-client => connect-service-jms-request-reply}/orders/order-1002.json (100%)
copy ai-benchmark/seed/{connect-http-client => connect-service-jms-request-reply}/orders/order-1003.json (100%)
copy ai-benchmark/seed/{_peer-openapi-server => connect-service-jms-request-reply}/stock.json (100%)
copy ai-benchmark/seed/{connect-http-client => connect-service-kafka-orders}/orders/order-1001.json (100%)
copy ai-benchmark/seed/{connect-http-client => connect-service-kafka-orders}/orders/order-1002.json (100%)
copy ai-benchmark/seed/{connect-http-client => connect-service-kafka-orders}/orders/order-1003.json (100%)
(camel-performance-tests) 01/02: ai-benchmark: a new set in steps-new/, with connect-service/kafka-orders as its first example
Posted by da...@apache.org.
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-performance-tests.git
commit fa6f787f6afc83f9e4d95825899f9b617da3ba3b
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Oct 18 11:04:40 2026 +0200
ai-benchmark: a new set in steps-new/, with connect-service/kafka-orders as its first example
The ladder's 71 steps stay in steps-ladder/ for comparison. The new examples (Oct 18: messaging, the EIPs the ladder
never uses, code-first REST, AI) are written to steps-new/ through steps_dir, and run with
BENCH_STEPS_DIR=steps-new run-stepwise-ladder.sh <tag> [k].
kafka-orders: Kafka from camel infra, the three README steps after the first: a validation route with choice and
stop, a multicast to two more topics with a consumer each, and the order id as the record key (the dispatch log
prints CamelKafkaKey, so the log proves it). Reference pass 3/3 in four runs.
The project sets camel.component.kafka.pollTimeoutMs=500: a camel-kafka consumer stops only after its current poll,
up to 5 s each and one route after another, and the 5 s shutdown timeout of camel run --dev is then exceeded on a
reload with two or more Kafka routes; the forced shutdown logs ERRORs from the interrupted Kafka clients.
Co-Authored-By: Claude Opus 5.5 (1M context) <no...@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
---
ai-benchmark/.gitignore | 1 +
ai-benchmark/gen_stepwise.py | 64 +++++++++++++++++++++-
ai-benchmark/run-stepwise-ladder.sh | 7 ++-
.../orders/order-1001.json | 2 +
.../orders/order-1002.json | 2 +
.../orders/order-1003.json | 2 +
6 files changed, 74 insertions(+), 4 deletions(-)
diff --git a/ai-benchmark/.gitignore b/ai-benchmark/.gitignore
index 46712c1..ef85329 100644
--- a/ai-benchmark/.gitignore
+++ b/ai-benchmark/.gitignore
@@ -8,6 +8,7 @@ local/
__pycache__/
# generated by gen_stepwise.py from its own step definitions: the steps files and the starting projects
steps-ladder/
+steps-new/
stepwise-ladder/
stepwise-project/
# generated by gen_kamelet.py: the Kamelet side check
diff --git a/ai-benchmark/gen_stepwise.py b/ai-benchmark/gen_stepwise.py
index 34bc0f9..fd7ba4d 100644
--- a/ai-benchmark/gen_stepwise.py
+++ b/ai-benchmark/gen_stepwise.py
@@ -777,6 +777,66 @@ EXAMPLES.append({
]})
+# ================================================================ the new set (2026-10-18), written to steps-new/
+# Claus, Oct 18: messaging, the EIPs the ladder never uses, code-first REST and AI. Kept out of steps-ladder/ so the
+# nightly 71 steps stay comparable; run with BENCH_STEPS_DIR=steps-new run-stepwise-ladder.sh <tag> [k].
+NEW = "steps-new"
+
+# ---------------------------------------------------------------- connect-service/kafka-orders (Kafka started with camel infra)
+KO = "kafka-orders.camel.yaml"
+# pollTimeoutMs 500: a camel-kafka consumer stops only after its current poll returns (the poll loop holds the lock that
+# stop() waits for before it wakes the consumer), up to the default 5000 ms per consumer and one route after another;
+# the 5 s shutdown timeout of camel run --dev is then exceeded on a reload with two or more Kafka routes, and the
+# forced shutdown logs ERRORs from the interrupted Kafka clients (kref1, Oct 18). Remove once CAMEL-25753 is fixed.
+KO_PROPS = "camel.component.kafka.brokers=localhost:9092\ncamel.component.kafka.pollTimeoutMs=500\n"
+def kafka_from(topic):
+ # earliest: every reload starts the consumers in a new random group, which then reads the topic from the start
+ return " uri: kafka\n parameters:\n topic: " + topic + "\n autoOffsetReset: earliest\n"
+def kafka_to(topic, ind=" "):
+ return ind + "- to:\n" + ind + " uri: kafka\n" + ind + " parameters:\n" + ind + " topic: " + topic + "\n"
+KO_VALIDATE = route("validate-order", DIRECT("validate-order"),
+ " - choice:\n when:\n - expression:\n simple:\n"
+ " expression: \"${header.status} != 'paid'\"\n steps:\n"
+ + log("Order ${header.orderId} is ${header.status}, not published", " ")
+ + " - stop: {}\n otherwise:\n steps:\n"
+ + log("Order ${header.orderId} validated", " "))
+def ko_incoming(validate, key):
+ return route("incoming-orders", FILE_ORDERS,
+ set_header("orderId", "jsonpath", "\"$.orderId\"") + set_header("status", "jsonpath", "\"$.status\"")
+ + (" - to:\n uri: direct:validate-order\n" if validate else "")
+ + (set_header("CamelKafkaKey", "simple", "\"${header.orderId}\"") if key else "")
+ + kafka_to("orders") + log("Published ${header.orderId} to the orders topic"))
+def ko_dispatch(fan_out, key):
+ return route("dispatch", kafka_from("orders"),
+ (log("Dispatching ${header.CamelKafkaKey} from partition ${header.CamelKafkaPartition} offset ${header.CamelKafkaOffset}")
+ if key else log("Received ${header.orderId} from the orders topic"))
+ + (" - multicast:\n steps:\n" + kafka_to("fulfilment", " ")
+ + kafka_to("notifications", " ") if fan_out else ""))
+KO_DEPARTMENTS = ("\n" + route("fulfilment", kafka_from("fulfilment"),
+ UNMARSHAL + log("Fulfilment: ${body[lines].size()} line(s) of ${body[orderId]} to the warehouse"))
+ + "\n" + route("notification", kafka_from("notifications"),
+ UNMARSHAL + log("Notification: email to customer ${body[customer]} about ${body[orderId]}")))
+ko_s1 = ko_incoming(False, False) + "\n" + ko_dispatch(False, False)
+ko_s2 = ko_incoming(True, False) + "\n" + KO_VALIDATE + "\n" + ko_dispatch(False, False)
+ko_s3 = ko_incoming(True, False) + "\n" + KO_VALIDATE + "\n" + ko_dispatch(True, False) + KO_DEPARTMENTS
+ko_s4 = ko_incoming(True, True) + "\n" + KO_VALIDATE + "\n" + ko_dispatch(True, True) + KO_DEPARTMENTS
+EXAMPLES.append({
+ "name": "connect-service-kafka-orders", "route_file": KO, "props_file": "application.properties", "wait_seconds": 20,
+ "seed": "connect-service-kafka-orders", "infra": ["kafka"], "steps_dir": NEW,
+ "initial": {KO: ko_s1, "application.properties": KO_PROPS},
+ "steps": [
+ {"request": "Only paid orders may be published to Kafka. Add a route validate-order from direct:validate-order with a choice: when the status header is not paid, log \"Order ${header.orderId} is ${header.status}, not published\" and stop the message; otherwise log \"Order ${header.orderId} validated\". Call it from incoming-orders before the order is sent to the orders topic.",
+ "check": {"file_regex": "validate-order", "log_regex": ["Order ORD-1003 is pending, not published", "Order ORD-1001 validated", "Published ORD-1001 to the orders topic"], "log_not_regex": "Published ORD-1003"},
+ "reference": {KO: ko_s2}},
+ {"request": "Fan out the orders in dispatch: send each one with a multicast to two more topics, fulfilment and notifications. Add a route fulfilment that consumes the fulfilment topic from the earliest offset, unmarshals the JSON with Jackson and logs \"Fulfilment: ${body[lines].size()} line(s) of ${body[orderId]} to the warehouse\", and a route notification that consumes the notifications topic the same way and logs \"Notification: email to customer ${body[customer]} about ${bod [...]
+ "check": {"file_regex": "multicast", "log_regex": ["Fulfilment: 2 line\\(s\\) of ORD-1001 to the warehouse", "Notification: email to customer C-482 about ORD-1001"]},
+ "reference": {KO: ko_s3}},
+ {"request": "Publish each order with its order id as the Kafka record key, and change the log of dispatch to \"Dispatching ${header.CamelKafkaKey} from partition ${header.CamelKafkaPartition} offset ${header.CamelKafkaOffset}\".",
+ "check": {"log_regex": "Dispatching ORD-1001 from partition \\d+ offset \\d+"},
+ "reference": {KO: ko_s4}},
+ ]})
+
+
def write_project(ex):
d = os.path.join(PROJECTS, ex["name"])
shutil.rmtree(d, ignore_errors=True)
@@ -814,7 +874,9 @@ def main():
pd = os.path.join(HERE, ex["peer"]["project"])
shutil.rmtree(pd, ignore_errors=True)
shutil.copytree(os.path.join(SEEDS, ex["peer"]["seed"]), pd)
- with open(os.path.join(STEPS_DIR, ex["name"] + ".json"), "w") as f:
+ steps_dir = os.path.join(HERE, ex["steps_dir"]) if ex.get("steps_dir") else STEPS_DIR
+ os.makedirs(steps_dir, exist_ok=True)
+ with open(os.path.join(steps_dir, ex["name"] + ".json"), "w") as f:
json.dump(cfg, f, indent=1)
write_project(ex)
print(f"{ex['name']}: {len(steps)} steps, project stepwise-ladder/{ex['name']}")
diff --git a/ai-benchmark/run-stepwise-ladder.sh b/ai-benchmark/run-stepwise-ladder.sh
index 5eba143..849c90a 100755
--- a/ai-benchmark/run-stepwise-ladder.sh
+++ b/ai-benchmark/run-stepwise-ladder.sh
@@ -3,6 +3,7 @@
# Usage: run-stepwise-ladder.sh <tag> [k] Results: stepwise/<tag>-<i>/<name>/ (results.json, run.log, traces)
# BENCH_REFERENCE=1 applies the reference files instead of asking the model (the reference pass of the steps files).
# BENCH_ONLY="<name> [<name> ...]" runs only those examples.
+# BENCH_STEPS_DIR=steps-new runs the new set (2026-10-18) instead of the ladder in steps-ladder/.
set -u
TAG="${1:?usage: run-stepwise-ladder.sh <tag> [k]}"
K="${2:-1}"
@@ -12,7 +13,7 @@ command -v caffeinate > /dev/null && caffeinate -i -s -w $$ &
for i in $(seq 1 "$K"); do
if (( K > 1 )); then T="$TAG-$i"; else T="$TAG"; fi
: > "stepwise-$T.log" # a fresh log per run, so a later wait on its DONE line cannot see an earlier run's
- for f in steps-ladder/*.json; do
+ for f in ${BENCH_STEPS_DIR:-steps-ladder}/*.json; do
name=$(basename "$f" .json)
if [[ -n "${BENCH_ONLY:-}" && " $BENCH_ONLY " != *" $name "* ]]; then continue; fi
python3 gen_stepwise.py "$name" > /dev/null
@@ -30,9 +31,9 @@ for i in $(seq 1 "$K"); do
done
# the services an example needed stay up across its passes; stop them once the run is over
for svc in $(python3 -c "
-import glob, json
+import glob, json, os
out = set()
-for f in glob.glob('steps-ladder/*.json'):
+for f in glob.glob(os.environ.get('BENCH_STEPS_DIR', 'steps-ladder') + '/*.json'):
try: out.update(json.load(open(f)).get('infra') or [])
except Exception: pass
print(' '.join(sorted(out)))"); do camel infra stop "$svc" > /dev/null 2>&1 || true; done
diff --git a/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1001.json b/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1001.json
new file mode 100644
index 0000000..3eb5f03
--- /dev/null
+++ b/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1001.json
@@ -0,0 +1,2 @@
+{"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.50}]}
diff --git a/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1002.json b/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1002.json
new file mode 100644
index 0000000..bb7aa0e
--- /dev/null
+++ b/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1002.json
@@ -0,0 +1,2 @@
+{"orderId": "ORD-1002", "customer": "C-207", "country": "DE", "status": "paid",
+ "lines": [{"sku": "CAMEL-MUG", "qty": 3, "price": 9.50}]}
diff --git a/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1003.json b/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1003.json
new file mode 100644
index 0000000..9edab76
--- /dev/null
+++ b/ai-benchmark/seed/connect-service-kafka-orders/orders/order-1003.json
@@ -0,0 +1,2 @@
+{"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.00}, {"sku": "CAMEL-MUG", "qty": 2, "price": 9.50}]}
(camel-performance-tests) 02/02: ai-benchmark: connect-service/jms-request-reply in the new set
Posted by da...@apache.org.
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-performance-tests.git
commit 7f09ad765e37b233d535a3b3946c6c40b2505b1c
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Oct 18 13:11:44 2026 +0200
ai-benchmark: connect-service/jms-request-reply in the new set
Traditional messaging (Claus, Oct 18): the start has no broker connection, so the first request is connecting to
Artemis and a queue with a consumer; then a stock service asked with request-reply, redelivery with a dead letter
queue (ORD-1003: not enough CAMEL-CAP), and a topic with two subscribers. The final reference is the example's route
file (apache/camel-jbang-examples#115). Reference pass pending: the camel infra Artemis blocks producers on a Docker
disk over 90% full (CAMEL-25754, apache/camel#28056).
Co-Authored-By: Claude Opus 5.5 (1M context) <no...@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
---
ai-benchmark/gen_stepwise.py | 61 ++++++++++++++++++++++
.../orders/order-1001.json | 2 +
.../orders/order-1002.json | 2 +
.../orders/order-1003.json | 2 +
.../connect-service-jms-request-reply/stock.json | 5 ++
5 files changed, 72 insertions(+)
diff --git a/ai-benchmark/gen_stepwise.py b/ai-benchmark/gen_stepwise.py
index fd7ba4d..1d4da6b 100644
--- a/ai-benchmark/gen_stepwise.py
+++ b/ai-benchmark/gen_stepwise.py
@@ -837,6 +837,67 @@ EXAMPLES.append({
]})
+# ---------------------------------------------------------------- connect-service/jms-request-reply (Artemis started with camel infra)
+# Claus, Oct 18: "we need traditional messaging also". The start has no broker connection: connecting to Artemis is
+# the first request (in September the model reached for amqp with inline credentials there).
+JR = "jms-request-reply.camel.yaml"
+JR_CF = ("# The broker started by: camel infra run artemis\n"
+ "camel.beans.artemisCF = #class:org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory\n"
+ "camel.beans.artemisCF.brokerURL = tcp://localhost:61616\ncamel.beans.artemisCF.user = artemis\n"
+ "camel.beans.artemisCF.password = artemis\ncamel.component.jms.connection-factory = #bean:artemisCF\n")
+def jms_from(kind, name):
+ return " uri: jms\n parameters:\n destinationType: " + kind + "\n destinationName: " + name + "\n"
+def jms_to(kind, name, ind=" ", more=""):
+ return (ind + "- to:\n" + ind + " uri: jms\n" + ind + " parameters:\n" + ind + " destinationType: " + kind + "\n"
+ + ind + " destinationName: " + name + "\n" + more)
+JR_HEADERS = set_header("orderId", "jsonpath", "\"$.orderId\"") + set_header("customer", "jsonpath", "\"$.customer\"")
+def jr_intake(queue):
+ return route("order-intake", FILE_ORDERS, JR_HEADERS + (jms_to("queue", "orders") + log("Order ${header.orderId} put on the queue")
+ if queue else log("Order ${header.orderId} received")))
+JR_ASK = (jms_to("queue", "stock", more=" exchangePattern: InOut\n variableReceive: answer\n")
+ + log("Stock service answered for ${header.orderId}: ${variable.answer}"))
+JR_FAIL = (" - filter:\n expression:\n simple:\n expression: \"${variable.answer} != 'reserved'\"\n"
+ " steps:\n - throwException:\n exceptionType: java.lang.IllegalStateException\n"
+ " message: \"${variable.answer} for ${header.orderId}\"\n")
+JR_DLC = (" errorHandler:\n deadLetterChannel:\n deadLetterUri: \"jms:queue:orders.dead\"\n useOriginalMessage: true\n"
+ " redeliveryPolicy:\n maximumRedeliveries: 3\n redeliveryDelay: 1000\n")
+def jr_reserve(ask, dlc, topic):
+ steps = (log("Reserving ${header.orderId} for customer ${header.customer}") + (JR_ASK if ask else "")
+ + (JR_FAIL if dlc else "") + (jms_to("topic", "orders.reserved") if topic else ""))
+ return "- route:\n id: reserve-order\n" + (JR_DLC if dlc else "") + " from:\n" + jms_from("queue", "orders") + " steps:\n" + steps
+JR_STOCK = route("stock-service", jms_from("queue", "stock"),
+ UNMARSHAL + " - setVariable:\n name: order\n expression:\n simple:\n expression: \"${body}\"\n"
+ + " - setBody:\n expression:\n constant:\n expression: \"resource:file:stock.json\"\n"
+ + UNMARSHAL + " - setBody:\n expression:\n groovy:\n expression: \"def missing = variables.order.lines.find "
+ "{ line -> (body.find { it.sku == line.sku }?.qty ?: 0) < line.qty }; missing ? 'not enough ' + missing.sku : 'reserved'\"\n")
+JR_DEAD = route("dead-orders", jms_from("queue", "orders.dead"), log("Dead order ${header.orderId}"))
+JR_TOPIC = (route("shipping", jms_from("topic", "orders.reserved"), log("Shipping ${header.orderId}")) + "\n"
+ + route("invoicing", jms_from("topic", "orders.reserved"), log("Invoicing ${header.orderId}")))
+jr_s1 = jr_intake(False)
+jr_s2 = jr_intake(True) + "\n" + jr_reserve(False, False, False)
+jr_s3 = jr_intake(True) + "\n" + jr_reserve(True, False, False) + "\n" + JR_STOCK
+jr_s4 = jr_intake(True) + "\n" + jr_reserve(True, True, False) + "\n" + JR_STOCK + "\n" + JR_DEAD
+jr_s5 = jr_intake(True) + "\n" + jr_reserve(True, True, True) + "\n" + JR_STOCK + "\n" + JR_DEAD + "\n" + JR_TOPIC
+EXAMPLES.append({
+ "name": "connect-service-jms-request-reply", "route_file": JR, "props_file": "application.properties", "wait_seconds": 15,
+ "seed": "connect-service-jms-request-reply", "infra": ["artemis"], "steps_dir": NEW,
+ "initial": {JR: jr_s1, "application.properties": "# application properties\n"},
+ "steps": [
+ {"request": "Connect to the ActiveMQ Artemis broker that camel infra started (tcp://localhost:61616, user artemis, password artemis) and send each order to the queue orders with the jms component, logging \"Order ${header.orderId} put on the queue\" instead of received. Add a route reserve-order that takes the orders off the queue and logs \"Reserving ${header.orderId} for customer ${header.customer}\".",
+ "check": {"log_regex": ["Order ORD-1001 put on the queue", "Reserving ORD-1001 for customer C-482"]},
+ "reference": {JR: jr_s2, "application.properties": JR_CF}},
+ {"request": "Add a route stock-service on the queue stock that answers whether an order (the JSON body) can be reserved: \"reserved\" when stock.json has enough of every line, otherwise \"not enough <sku>\" for the first line that is short. In reserve-order, ask the stock service with request-reply, keep the order as the body, and log \"Stock service answered for ${header.orderId}: <the answer>\".",
+ "check": {"log_regex": ["Stock service answered for ORD-1001: reserved", "Stock service answered for ORD-1003: not enough CAMEL-CAP"]},
+ "reference": {JR: jr_s3}},
+ {"request": "An order the stock service cannot reserve must fail: redeliver it 3 times, one second apart, and then move the original order to the queue orders.dead, where a route dead-orders logs \"Dead order ${header.orderId}\".",
+ "check": {"file_regex": "maximumRedeliveries", "log_regex": "Dead order ORD-1003", "errors_ok": True},
+ "reference": {JR: jr_s4}},
+ {"request": "Publish each reserved order to the topic orders.reserved, and add two routes, shipping and invoicing, that subscribe to it and log \"Shipping ${header.orderId}\" and \"Invoicing ${header.orderId}\".",
+ "check": {"log_regex": ["Shipping ORD-1001", "Invoicing ORD-1001"], "log_not_regex": "Shipping ORD-1003", "errors_ok": True},
+ "reference": {JR: jr_s5}},
+ ]})
+
+
def write_project(ex):
d = os.path.join(PROJECTS, ex["name"])
shutil.rmtree(d, ignore_errors=True)
diff --git a/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1001.json b/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1001.json
new file mode 100644
index 0000000..3eb5f03
--- /dev/null
+++ b/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1001.json
@@ -0,0 +1,2 @@
+{"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.50}]}
diff --git a/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1002.json b/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1002.json
new file mode 100644
index 0000000..bb7aa0e
--- /dev/null
+++ b/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1002.json
@@ -0,0 +1,2 @@
+{"orderId": "ORD-1002", "customer": "C-207", "country": "DE", "status": "paid",
+ "lines": [{"sku": "CAMEL-MUG", "qty": 3, "price": 9.50}]}
diff --git a/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1003.json b/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1003.json
new file mode 100644
index 0000000..9edab76
--- /dev/null
+++ b/ai-benchmark/seed/connect-service-jms-request-reply/orders/order-1003.json
@@ -0,0 +1,2 @@
+{"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.00}, {"sku": "CAMEL-MUG", "qty": 2, "price": 9.50}]}
diff --git a/ai-benchmark/seed/connect-service-jms-request-reply/stock.json b/ai-benchmark/seed/connect-service-jms-request-reply/stock.json
new file mode 100644
index 0000000..efab5de
--- /dev/null
+++ b/ai-benchmark/seed/connect-service-jms-request-reply/stock.json
@@ -0,0 +1,5 @@
+[
+ {"sku": "CAMEL-TSHIRT", "qty": 120},
+ {"sku": "CAMEL-MUG", "qty": 42},
+ {"sku": "CAMEL-CAP", "qty": 0}
+]