Listens on http port 8080
or https port 9090
and will correlate requests and responses over the items-requests
and items-responses
topics in Kafka, synchronously.
- Docker 20.10+
- curl
- kcat
- jq
Requires Kafka client, such as kcat
.
$ brew install kcat
$ docker stack deploy -c stack.yml example --resolve-image never
Creating network example_net0
Creating service example_zilla
Creating service example_kafka
When example_kafka
service has finished starting up, execute the following commands to create the topics if they do not already exist:
$ docker exec -it $(docker ps -q -f name=example_kafka) \
/opt/bitnami/kafka/bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--create \
--topic items-requests \
--if-not-exists
docker exec -it $(docker ps -q -f name=example_kafka) /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic items-requests --if-not-exists
Created topic items-requests.
$ docker exec -it $(docker ps -q -f name=example_kafka) \
/opt/bitnami/kafka/bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--create \
--topic items-responses \
--if-not-exists
docker exec -it $(docker ps -q -f name=example_kafka) /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic items-responses --if-not-exists
Created topic items-responses.
Send a PUT
request for a specific item.
Note that the response will not return until you complete the following step to produce the response with kcat
.
$ curl -v \
-X "PUT" "http://localhost:8080/items/5cf7a1d5-3772-49ef-86e7-ba6f2c7d7d07" \
-H "Idempotency-Key: 1" \
-H "Content-Type: application/json" \
-d "{\"greeting\":\"Hello, world\"}"
curl -v -X PUT "http://localhost:8080/items/5cf7a1d5-3772-49ef-86e7-ba6f2c7d7d07" -H "Idempotency-Key: 1" -H "Content-Type: application/json" -d '{"greeting":"Hello, world"}'
...
> PUT /items/5cf7a1d5-3772-49ef-86e7-ba6f2c7d7d07 HTTP/1.1
> Idempotency-Key: 1
> Content-Type: application/json
...
< HTTP/1.1 200 OK
...
{"greeting":"Hello, world ..."}
Verify the request, then send the correlated response via the kafka items-responses
topic.
curl -v "http://localhost:8080/items-res" -H "Idempotency-Key: 1" -H "Content-Type: application/json"
curl -v "http://localhost:8080/items-req" -H "Idempotency-Key: 1" -H "Content-Type: application/json"
$ docker run -it --network=host edenhill/kcat:1.7.1 -C -b localhost:9092 -t items-requests -J -u | jq .
{
"topic": "items-requests",
"partition": 0,
"offset": 0,
"tstype": "create",
"ts": 1652465273281,
"broker": 1001,
"headers": [
":scheme",
"http",
":method",
"PUT",
":path",
"/items/5cf7a1d5-3772-49ef-86e7-ba6f2c7d7d07",
":authority",
"localhost:8080",
"user-agent",
"curl/7.79.1",
"accept",
"*/*",
"idempotency-key",
"1",
"content-type",
"application/json",
"zilla:reply-to",
"items-responses",
"zilla:correlation-id",
"1-e75a4e507cc0dc66a28f5a9617392fe8"
],
"key": "5cf7a1d5-3772-49ef-86e7-ba6f2c7d7d07",
"payload": "{\"greeting\":\"Hello, world\"}"
}
% Reached end of topic items-requests [0] at offset 1
Make sure to propagate the request message zilla:correlation-id
header verbatim as a response message zilla:correlation-id
header.
$ echo "{\"greeting\":\"Hello, world `date`\"}" | \
docker run -it --network=host edenhill/kcat:1.7.1 -P \
-b localhost:9092 \
-t items-responses \
-k "5cf7a1d5-3772-49ef-86e7-ba6f2c7d7d07" \
-H ":status=200" \
-H "zilla:correlation-id=1-e75a4e507cc0dc66a28f5a9617392fe8"
Optionally delete the topics to clean up, otherwise they will still be present when the stack is deployed again next time.
$ docker exec -it $(docker ps -q -f name=example_kafka) \
/opt/bitnami/kafka/bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--delete \
--topic items-requests \
--if-exists
$ docker exec -it $(docker ps -q -f name=example_kafka) \
/opt/bitnami/kafka/bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--delete \
--topic items-responses \
--if-exists
$ docker stack rm example
Removing service example_kafka
Removing service example_zilla
Removing network example_net0