This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch CAMEL-25755-jms-request-reply
in repository https://gitbox.apache.org/repos/asf/camel-jbang-examples.git

commit fe873eed97068d7cf7e9afd0e2250e24b766603a
Author: Claus Ibsen <[email protected]>
AuthorDate: Sun Oct 18 13:09:20 2026 +0200

    CAMEL-25755: connect-service/jms-request-reply - request-reply, a dead 
letter queue and a topic on Artemis
    
    Traditional messaging beyond a queue: each order asks a stock service over
    JMS request-reply (InOut, the answer kept in a variable), ORD-1003 cannot
    be reserved and goes to orders.dead after three redeliveries, and the
    reserved orders are published on a topic with two subscribers. Placed
    after artemis in the group, with a Citrus YAML test in the CI matrix.
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
---
 .github/workflows/build.yml                        |   2 +
 README.md                                          |   1 +
 camel-jbang-example-catalog.json                   |  65 +++++++++-
 connect-service/README.md                          |   1 +
 connect-service/camel-1-tribute/metadata.json      |   2 +-
 connect-service/ftp/metadata.json                  |   2 +-
 connect-service/jms-request-reply/README.md        | 104 ++++++++++++++++
 .../jms-request-reply/application.properties       |  23 ++++
 .../jms-request-reply/jms-request-reply.camel.yaml | 134 +++++++++++++++++++++
 connect-service/jms-request-reply/metadata.json    |  46 +++++++
 .../jms-request-reply/orders/order-1001.json       |   2 +
 .../jms-request-reply/orders/order-1002.json       |   2 +
 .../jms-request-reply/orders/order-1003.json       |   2 +
 connect-service/jms-request-reply/stock.json       |   5 +
 .../test/jms-request-reply.citrus.it.yaml          |  41 +++++++
 connect-service/kafka-orders/metadata.json         |   2 +-
 connect-service/mqtt/metadata.json                 |   2 +-
 17 files changed, 428 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 05cc0cd..1c615e0 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -44,6 +44,8 @@ jobs:
             path: connect-service/kafka-orders
           - name: Artemis queue
             path: connect-service/artemis
+          - name: JMS request-reply
+            path: connect-service/jms-request-reply
           - name: FTP courier
             path: connect-service/ftp
           - name: Camel 1.0 tribute
diff --git a/README.md b/README.md
index 290139b..93d7cba 100644
--- a/README.md
+++ b/README.md
@@ -103,6 +103,7 @@ SQL, JMS, MQTT, Kafka and FTP against a service the Camel 
CLI starts for you wit
 |---|---|---|
 | [SQL database](connect-service/sql/) | Against a Postgres started with camel 
infra, a customers table is created, the three orders register their customers 
with an insert that counts orders on conflict, and every ten seconds a select 
lists the customers; run it twice and the order counts go up. | `camel infra 
run postgres` |
 | [Artemis queue](connect-service/artemis/) | The three orders are put on the 
orders queue of an ActiveMQ Artemis broker started with camel infra, and a 
consumer route takes them off and logs the customer and line count; the 
connection factory is declared in application.properties. | `camel infra run 
artemis` |
+| [JMS request-reply](connect-service/jms-request-reply/) | The three orders 
go on a queue of an ActiveMQ Artemis broker started with camel infra; a 
consumer asks a stock service over JMS request-reply for each, publishes the 
reserved ones on a topic that shipping and invoicing both subscribe to, and 
ORD-1003, which the stock service cannot reserve, is redelivered three times 
and then moved to a dead letter queue. | `camel infra run artemis` |
 | [MQTT sensors](connect-service/mqtt/) | Temperature sensors in the 
warehouse's cold rooms publish JSON readings on an MQTT topic of a Mosquitto 
broker started with camel infra; a consumer logs each reading and raises a 
warning when a room is above 8 degrees. | `camel infra run mosquitto` |
 | [Kafka orders](connect-service/kafka-orders/) | The three orders go through 
a shared validation route to a Kafka topic on a broker started with camel 
infra; the pending one is stopped, the paid ones are dispatched to the 
fulfilment and notifications topics, whose consumers log the picking and the 
email; camel cmd route-topology draws the flow. | `camel infra run kafka` |
 | [FTP courier](connect-service/ftp/) | Each order on the shipments queue of 
an Artemis broker becomes a file on the courier's FTP server, both started with 
camel infra; the log shows each shipment uploaded and camel infra get ftp shows 
where the files landed. | `camel infra run artemis ftp` |
diff --git a/camel-jbang-example-catalog.json b/camel-jbang-example-catalog.json
index 0be9e36..fda1cd7 100644
--- a/camel-jbang-example-catalog.json
+++ b/camel-jbang-example-catalog.json
@@ -299,7 +299,7 @@
         "infraServices": [
             "artemis"
         ],
-        "order": 6
+        "order": 7
     },
     {
         "name": "connect-service/ftp",
@@ -343,7 +343,64 @@
             "artemis",
             "ftp"
         ],
-        "order": 5
+        "order": 6
+    },
+    {
+        "name": "connect-service/jms-request-reply",
+        "title": "JMS request-reply",
+        "description": "The three orders go on a queue of an ActiveMQ Artemis 
broker started with camel infra; a consumer asks a stock service over JMS 
request-reply for each, publishes the reserved ones on a topic that shipping 
and invoicing both subscribe to, and ORD-1003, which the stock service cannot 
reserve, is redelivered three times and then moved to a dead letter queue.",
+        "level": "connect-service",
+        "teaches": {
+            "components": [
+                "jms",
+                "file",
+                "log"
+            ],
+            "eips": [
+                "errorHandler",
+                "deadLetterChannel",
+                "redeliveryPolicy",
+                "filter",
+                "throwException",
+                "setVariable",
+                "setHeader",
+                "unmarshal"
+            ],
+            "languages": [
+                "simple",
+                "jsonpath",
+                "groovy"
+            ],
+            "dataformats": [
+                "json"
+            ]
+        },
+        "tags": [
+            "shop",
+            "jms",
+            "artemis",
+            "queue",
+            "topic",
+            "request-reply",
+            "dead-letter",
+            "messaging"
+        ],
+        "bundled": false,
+        "requiresDocker": true,
+        "hasCitrusTests": true,
+        "files": [
+            "README.md",
+            "application.properties",
+            "jms-request-reply.camel.yaml",
+            "orders/order-1001.json",
+            "orders/order-1002.json",
+            "orders/order-1003.json",
+            "stock.json"
+        ],
+        "infraServices": [
+            "artemis"
+        ],
+        "order": 3
     },
     {
         "name": "connect-service/kafka-orders",
@@ -392,7 +449,7 @@
         "infraServices": [
             "kafka"
         ],
-        "order": 4
+        "order": 5
     },
     {
         "name": "connect-service/mqtt",
@@ -433,7 +490,7 @@
         "infraServices": [
             "mosquitto"
         ],
-        "order": 3
+        "order": 4
     },
     {
         "name": "connect-service/sql",
diff --git a/connect-service/README.md b/connect-service/README.md
index a03f15c..83d71ab 100644
--- a/connect-service/README.md
+++ b/connect-service/README.md
@@ -7,6 +7,7 @@ SQL, JMS, MQTT, Kafka and FTP against a service the Camel CLI 
starts for you wit
 |---|---|---|
 | [SQL database](sql/) | Against a Postgres started with camel infra, a 
customers table is created, the three orders register their customers with an 
insert that counts orders on conflict, and every ten seconds a select lists the 
customers; run it twice and the order counts go up. | `camel infra run 
postgres` |
 | [Artemis queue](artemis/) | The three orders are put on the orders queue of 
an ActiveMQ Artemis broker started with camel infra, and a consumer route takes 
them off and logs the customer and line count; the connection factory is 
declared in application.properties. | `camel infra run artemis` |
+| [JMS request-reply](jms-request-reply/) | The three orders go on a queue of 
an ActiveMQ Artemis broker started with camel infra; a consumer asks a stock 
service over JMS request-reply for each, publishes the reserved ones on a topic 
that shipping and invoicing both subscribe to, and ORD-1003, which the stock 
service cannot reserve, is redelivered three times and then moved to a dead 
letter queue. | `camel infra run artemis` |
 | [MQTT sensors](mqtt/) | Temperature sensors in the warehouse's cold rooms 
publish JSON readings on an MQTT topic of a Mosquitto broker started with camel 
infra; a consumer logs each reading and raises a warning when a room is above 8 
degrees. | `camel infra run mosquitto` |
 | [Kafka orders](kafka-orders/) | The three orders go through a shared 
validation route to a Kafka topic on a broker started with camel infra; the 
pending one is stopped, the paid ones are dispatched to the fulfilment and 
notifications topics, whose consumers log the picking and the email; camel cmd 
route-topology draws the flow. | `camel infra run kafka` |
 | [FTP courier](ftp/) | Each order on the shipments queue of an Artemis broker 
becomes a file on the courier's FTP server, both started with camel infra; the 
log shows each shipment uploaded and camel infra get ftp shows where the files 
landed. | `camel infra run artemis ftp` |
diff --git a/connect-service/camel-1-tribute/metadata.json 
b/connect-service/camel-1-tribute/metadata.json
index 0d90ac0..7b307c6 100644
--- a/connect-service/camel-1-tribute/metadata.json
+++ b/connect-service/camel-1-tribute/metadata.json
@@ -2,7 +2,7 @@
     "title": "Camel 1.0 tribute",
     "description": "The very first Camel example of 2007, JMS to file: a timer 
sends ten messages to a queue on an Artemis broker started with camel infra, 
and the consumer writes each message to a file in outbox; the log shows both 
sides.",
     "level": "connect-service",
-    "order": 6,
+    "order": 7,
     "teaches": {
         "components": [
             "jms",
diff --git a/connect-service/ftp/metadata.json 
b/connect-service/ftp/metadata.json
index 79b0da1..22d3318 100644
--- a/connect-service/ftp/metadata.json
+++ b/connect-service/ftp/metadata.json
@@ -2,7 +2,7 @@
     "title": "FTP courier",
     "description": "Each order on the shipments queue of an Artemis broker 
becomes a file on the courier's FTP server, both started with camel infra; the 
log shows each shipment uploaded and camel infra get ftp shows where the files 
landed.",
     "level": "connect-service",
-    "order": 5,
+    "order": 6,
     "teaches": {
         "components": [
             "ftp",
diff --git a/connect-service/jms-request-reply/README.md 
b/connect-service/jms-request-reply/README.md
new file mode 100644
index 0000000..e0067bb
--- /dev/null
+++ b/connect-service/jms-request-reply/README.md
@@ -0,0 +1,104 @@
+# JMS request-reply
+
+Traditional messaging with a broker. The orders go on a queue, each order asks 
a stock service for a reservation
+and waits for the answer, and a reserved order is published on a topic that 
two departments subscribe to. An order
+that cannot be reserved is tried three more times and then moved to a dead 
letter queue.
+
+## What you will see
+
+```text
+INFO ... jms-request-reply.camel.yaml:28 : Order ORD-1001 put on the queue
+INFO ... jms-request-reply.camel.yaml:47 : Reserving ORD-1001 for customer 
C-482
+INFO ... jms-request-reply.camel.yaml:56 : Stock service answered for 
ORD-1001: reserved
+INFO ... jms-request-reply.camel.yaml:122 : Shipping ORD-1001
+INFO ... jms-request-reply.camel.yaml:133 : Invoicing ORD-1001
+...
+INFO ... jms-request-reply.camel.yaml:56 : Stock service answered for 
ORD-1003: not enough CAMEL-CAP
+INFO ... jms-request-reply.camel.yaml:110 : Dead order ORD-1003
+```
+
+## Install Camel CLI
+
+Install [JBang](https://www.jbang.dev/download/) and the Camel CLI as 
described in the
+[root README](../../README.md#install-the-camel-cli); `camel --version` 
confirms the install.
+
+## Run it
+
+The example needs a running artemis, which the Camel CLI starts for you in a 
container
+(Docker or Podman must be running). In one terminal:
+
+```shell
+camel infra run artemis
+```
+
+It prints the connection details as JSON; they match `application.properties`. 
In another terminal:
+
+```shell
+camel run *
+```
+
+The broker's web console is at http://localhost:8161 (user `artemis`, password 
`artemis`). It shows the queues
+`orders`, `stock` and `orders.dead`, and the topic `orders.reserved`.
+
+Stop the example with `ctrl` + `c` and the service with `camel infra stop 
artemis`.
+
+## How it works
+
+- `application.properties` declares the connection factory as a bean, as in 
the [artemis](../artemis/) example,
+  and wires it into the `jms` component.
+- `order-intake` reads each order, puts the order id and the customer in 
headers (JMS headers travel with the
+  message), and sends the order to the `orders` queue.
+- `reserve-order` takes the orders off the queue and asks the stock service. 
`exchangePattern: InOut` makes it a
+  request-reply: the `jms` producer sends to the `stock` queue with a 
temporary reply queue and waits for the
+  answer (20 seconds by default, the `requestTimeout` option). 
`variableReceive: answer` keeps the answer in a
+  variable, so the order stays the body.
+- `stock-service` is an ordinary consumer of the `stock` queue. Its answer is 
the body the route ends with, which
+  the `jms` consumer sends to the reply queue the request named.
+- An order the stock service cannot reserve throws an exception. The route's 
`deadLetterChannel` redelivers it
+  three times, one second apart, and then sends the original order 
(`useOriginalMessage`) to the `orders.dead`
+  queue, where `dead-orders` logs it.
+- A reserved order goes to the topic `orders.reserved`. Unlike a queue, a 
topic gives every subscriber a copy, so
+  `shipping` and `invoicing` both get it.
+
+## Build it step by step
+
+Ask your assistant, or type it yourself, one step at a time, and run after 
each:
+
+1. A file route on `orders` that puts the order id and the customer in headers 
and logs each order.
+2. Connect to the broker with the connection factory in 
`application.properties`, put the orders on the
+   `orders` queue, and add a route `reserve-order` that takes them off and 
logs the customer.
+3. Add the stock service on the `stock` queue, and ask it from `reserve-order` 
with request-reply.
+4. Fail an order the stock service cannot reserve: redeliver it three times, 
then move it to the dead letter
+   queue `orders.dead`, with a route that logs it.
+5. Publish the reserved orders on the topic `orders.reserved`, with two 
subscriber routes.
+
+## Try changing
+
+- Give `CAMEL-CAP` a stock of 5 in `stock.json`: ORD-1003 is reserved and 
shipped.
+- Stop the stock service with `camel cmd stop-route stock-service` and drop in 
a new order: the request waits
+  for the `requestTimeout`, fails, and the order goes to the dead letter queue 
after the redeliveries.
+- Remove the `dead-orders` route and restart: ORD-1003 stays on `orders.dead` 
in the console, as the broker keeps
+  what no one has taken.
+- Add a third subscriber to the topic.
+
+## Integration testing
+
+The example comes with a test in the [Citrus](https://citrusframework.org/) 
YAML DSL,
+`test/jms-request-reply.citrus.it.yaml`, which the Camel CLI runs. The test 
starts the service itself
+with the same `camel infra` mechanism, so nothing must be running beforehand:
+
+```shell
+camel test run test/jms-request-reply.citrus.it.yaml
+```
+
+The test starts Artemis, runs the routes and verifies the answers of the stock 
service and the dead letter queue.
+
+## Help and contributions
+
+If you hit any problem using Camel or have some feedback, then please
+[let us know](https://camel.apache.org/community/support/).
+
+We also love contributors, so
+[get involved](https://camel.apache.org/community/contributing/) :-)
+
+The Camel riders!
diff --git a/connect-service/jms-request-reply/application.properties 
b/connect-service/jms-request-reply/application.properties
new file mode 100644
index 0000000..18969e7
--- /dev/null
+++ b/connect-service/jms-request-reply/application.properties
@@ -0,0 +1,23 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# The broker started by: camel infra run artemis
+camel.beans.artemisCF = 
#class:org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory
+camel.beans.artemisCF.brokerURL = tcp://localhost:61616
+camel.beans.artemisCF.user = artemis
+camel.beans.artemisCF.password = artemis
+camel.component.jms.connection-factory = #bean:artemisCF
diff --git a/connect-service/jms-request-reply/jms-request-reply.camel.yaml 
b/connect-service/jms-request-reply/jms-request-reply.camel.yaml
new file mode 100644
index 0000000..f4e34da
--- /dev/null
+++ b/connect-service/jms-request-reply/jms-request-reply.camel.yaml
@@ -0,0 +1,134 @@
+# Each order asks a stock service over JMS request-reply whether its lines can 
be reserved. An order that cannot be
+# reserved is redelivered and then moved to a dead letter queue; a reserved 
order is published on a topic, where
+# shipping and invoicing each get a copy. Start the broker with: camel infra 
run artemis
+- route:
+    id: order-intake
+    from:
+      uri: file
+      parameters:
+        directoryName: orders
+        noop: true
+        sortBy: "file:name"
+      steps:
+        - setHeader:
+            name: orderId
+            expression:
+              jsonpath:
+                expression: "$.orderId"
+        - setHeader:
+            name: customer
+            expression:
+              jsonpath:
+                expression: "$.customer"
+        - to:
+            uri: jms
+            parameters:
+              destinationType: queue
+              destinationName: orders
+        - log:
+            message: "Order ${header.orderId} put on the queue"
+
+# Takes the orders off the queue and asks the stock service; the reply goes to 
a variable, so the order stays the body
+- route:
+    id: reserve-order
+    errorHandler:
+      deadLetterChannel:
+        deadLetterUri: "jms:queue:orders.dead"
+        useOriginalMessage: true
+        redeliveryPolicy:
+          maximumRedeliveries: 3
+          redeliveryDelay: 1000
+    from:
+      uri: jms
+      parameters:
+        destinationType: queue
+        destinationName: orders
+      steps:
+        - log:
+            message: "Reserving ${header.orderId} for customer 
${header.customer}"
+        - to:
+            uri: jms
+            parameters:
+              destinationType: queue
+              destinationName: stock
+              exchangePattern: InOut
+            variableReceive: answer
+        - log:
+            message: "Stock service answered for ${header.orderId}: 
${variable.answer}"
+        - filter:
+            expression:
+              simple:
+                expression: "${variable.answer} != 'reserved'"
+            steps:
+              - throwException:
+                  exceptionType: java.lang.IllegalStateException
+                  message: "${variable.answer} for ${header.orderId}"
+        - to:
+            uri: jms
+            parameters:
+              destinationType: topic
+              destinationName: orders.reserved
+
+# Answers "reserved" when stock.json has enough of every line of the order, or 
"not enough <sku>"
+- route:
+    id: stock-service
+    from:
+      uri: jms
+      parameters:
+        destinationType: queue
+        destinationName: stock
+      steps:
+        - unmarshal:
+            json:
+              library: Jackson
+        - setVariable:
+            name: order
+            expression:
+              simple:
+                expression: "${body}"
+        - setBody:
+            expression:
+              constant:
+                expression: "resource:file:stock.json"
+        - unmarshal:
+            json:
+              library: Jackson
+        - setBody:
+            expression:
+              groovy:
+                expression: "def missing = variables.order.lines.find { line 
-> (body.find { it.sku == line.sku }?.qty ?: 0) < line.qty }; missing ? 'not 
enough ' + missing.sku : 'reserved'"
+
+# The orders that could not be reserved, after three redeliveries
+- route:
+    id: dead-orders
+    from:
+      uri: jms
+      parameters:
+        destinationType: queue
+        destinationName: orders.dead
+      steps:
+        - log:
+            message: "Dead order ${header.orderId}"
+
+# Every subscriber of the topic gets each reserved order
+- route:
+    id: shipping
+    from:
+      uri: jms
+      parameters:
+        destinationType: topic
+        destinationName: orders.reserved
+      steps:
+        - log:
+            message: "Shipping ${header.orderId}"
+
+- route:
+    id: invoicing
+    from:
+      uri: jms
+      parameters:
+        destinationType: topic
+        destinationName: orders.reserved
+      steps:
+        - log:
+            message: "Invoicing ${header.orderId}"
diff --git a/connect-service/jms-request-reply/metadata.json 
b/connect-service/jms-request-reply/metadata.json
new file mode 100644
index 0000000..b77cd6b
--- /dev/null
+++ b/connect-service/jms-request-reply/metadata.json
@@ -0,0 +1,46 @@
+{
+    "title": "JMS request-reply",
+    "description": "The three orders go on a queue of an ActiveMQ Artemis 
broker started with camel infra; a consumer asks a stock service over JMS 
request-reply for each, publishes the reserved ones on a topic that shipping 
and invoicing both subscribe to, and ORD-1003, which the stock service cannot 
reserve, is redelivered three times and then moved to a dead letter queue.",
+    "level": "connect-service",
+    "order": 3,
+    "teaches": {
+        "components": [
+            "jms",
+            "file",
+            "log"
+        ],
+        "eips": [
+            "errorHandler",
+            "deadLetterChannel",
+            "redeliveryPolicy",
+            "filter",
+            "throwException",
+            "setVariable",
+            "setHeader",
+            "unmarshal"
+        ],
+        "languages": [
+            "simple",
+            "jsonpath",
+            "groovy"
+        ],
+        "dataformats": [
+            "json"
+        ]
+    },
+    "tags": [
+        "shop",
+        "jms",
+        "artemis",
+        "queue",
+        "topic",
+        "request-reply",
+        "dead-letter",
+        "messaging"
+    ],
+    "infraServices": [
+        "artemis"
+    ],
+    "requiresDocker": true,
+    "bundled": false
+}
diff --git a/connect-service/jms-request-reply/orders/order-1001.json 
b/connect-service/jms-request-reply/orders/order-1001.json
new file mode 100644
index 0000000..3eb5f03
--- /dev/null
+++ b/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/connect-service/jms-request-reply/orders/order-1002.json 
b/connect-service/jms-request-reply/orders/order-1002.json
new file mode 100644
index 0000000..bb7aa0e
--- /dev/null
+++ b/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/connect-service/jms-request-reply/orders/order-1003.json 
b/connect-service/jms-request-reply/orders/order-1003.json
new file mode 100644
index 0000000..9edab76
--- /dev/null
+++ b/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/connect-service/jms-request-reply/stock.json 
b/connect-service/jms-request-reply/stock.json
new file mode 100644
index 0000000..efab5de
--- /dev/null
+++ b/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}
+]
diff --git 
a/connect-service/jms-request-reply/test/jms-request-reply.citrus.it.yaml 
b/connect-service/jms-request-reply/test/jms-request-reply.citrus.it.yaml
new file mode 100644
index 0000000..c1312ba
--- /dev/null
+++ b/connect-service/jms-request-reply/test/jms-request-reply.citrus.it.yaml
@@ -0,0 +1,41 @@
+name: jms-request-reply-test
+description: The jms-request-reply example logs what its README promises
+actions:
+  - camel:
+      infra:
+        run:
+          service: artemis
+          fixedPort: true
+  - camel:
+      jbang:
+        run:
+          integration:
+            name: "jms-request-reply"
+            file: "../jms-request-reply.camel.yaml"
+            systemProperties:
+              file: "../application.properties"
+          resources:
+            - "orders/order-1001.json"
+            - "orders/order-1002.json"
+            - "orders/order-1003.json"
+            - "stock.json"
+  - camel:
+      jbang:
+        verify:
+          integration: "jms-request-reply"
+          logMessage: "Stock service answered for ORD-1001: reserved"
+  - camel:
+      jbang:
+        verify:
+          integration: "jms-request-reply"
+          logMessage: "Invoicing ORD-1002"
+  - camel:
+      jbang:
+        verify:
+          integration: "jms-request-reply"
+          logMessage: "Stock service answered for ORD-1003: not enough 
CAMEL-CAP"
+  - camel:
+      jbang:
+        verify:
+          integration: "jms-request-reply"
+          logMessage: "Dead order ORD-1003"
diff --git a/connect-service/kafka-orders/metadata.json 
b/connect-service/kafka-orders/metadata.json
index 48d479f..b6a3521 100644
--- a/connect-service/kafka-orders/metadata.json
+++ b/connect-service/kafka-orders/metadata.json
@@ -2,7 +2,7 @@
     "title": "Kafka orders",
     "description": "The three orders go through a shared validation route to a 
Kafka topic on a broker started with camel infra; the pending one is stopped, 
the paid ones are dispatched to the fulfilment and notifications topics, whose 
consumers log the picking and the email; camel cmd route-topology draws the 
flow.",
     "level": "connect-service",
-    "order": 4,
+    "order": 5,
     "teaches": {
         "components": [
             "kafka",
diff --git a/connect-service/mqtt/metadata.json 
b/connect-service/mqtt/metadata.json
index 1e79ac8..683553d 100644
--- a/connect-service/mqtt/metadata.json
+++ b/connect-service/mqtt/metadata.json
@@ -2,7 +2,7 @@
     "title": "MQTT sensors",
     "description": "Temperature sensors in the warehouse's cold rooms publish 
JSON readings on an MQTT topic of a Mosquitto broker started with camel infra; 
a consumer logs each reading and raises a warning when a room is above 8 
degrees.",
     "level": "connect-service",
-    "order": 3,
+    "order": 4,
     "teaches": {
         "components": [
             "paho-mqtt5",

Reply via email to