From 4dcdeda3695540eed9fc5578914efa747c7e8d11 Mon Sep 17 00:00:00 2001 From: AJ Date: Fri, 8 Nov 2024 16:08:07 -0500 Subject: [PATCH] implement tests --- amqp.reflect/README.md | 1 - asyncapi.http.kafka.proxy/README.md | 2 +- asyncapi.http.kafka.proxy/test.sh | 2 +- asyncapi.mqtt.proxy/README.md | 1 - grpc.kafka.fanout/README.md | 2 +- http.json.schema/README.md | 1 - http.jwt/README.md | 2 - http.kafka.async/README.md | 2 +- http.kafka.async/compose.yaml | 2 +- http.kafka.avro.json/README.md | 10 +-- http.kafka.avro.json/compose.yaml | 3 +- http.kafka.avro.json/test.sh | 73 +++++++++++++++ http.kafka.cache/README.md | 1 - http.kafka.cache/test.sh | 65 ++++++++++++++ http.kafka.crud/README.md | 9 +- http.kafka.crud/test.sh | 34 +++++++ http.kafka.oneway/README.md | 7 +- http.kafka.oneway/compose.yaml | 3 +- http.kafka.oneway/test.sh | 32 +++++++ http.kafka.proto.json/README.md | 14 +-- http.kafka.proto.json/test.sh | 58 ++++++++++++ mqtt.jwt/README.md | 118 +++++++++++++++++++------ mqtt.jwt/compose.yaml | 4 +- mqtt.jwt/private.pem | 27 ++++++ mqtt.jwt/tls/localhost.p12 | Bin 0 -> 5632 bytes mqtt.jwt/zilla.yaml | 34 +++++-- mqtt.kafka.broker/README.md | 31 ------- mqtt.kafka.broker/compose.yaml | 87 ------------------ mqtt.kafka.broker/setup.sh | 9 -- mqtt.kafka.broker/teardown.sh | 4 - mqtt.kafka.broker/zilla.yaml | 62 ------------- openapi.asyncapi.kakfa.proxy/README.md | 4 +- openapi.asyncapi.kakfa.proxy/test.sh | 34 +++++++ openapi.proxy/README.md | 2 +- sse.jwt/README.md | 2 +- sse.kafka.fanout/README.md | 1 - tcp.echo/README.md | 2 +- tcp.reflect/README.md | 2 +- tls.echo/README.md | 1 - tls.reflect/README.md | 1 - ws.echo/README.md | 1 - ws.reflect/README.md | 1 - 42 files changed, 475 insertions(+), 276 deletions(-) create mode 100755 http.kafka.avro.json/test.sh create mode 100755 http.kafka.cache/test.sh create mode 100755 http.kafka.crud/test.sh create mode 100755 http.kafka.oneway/test.sh create mode 100755 http.kafka.proto.json/test.sh create mode 100644 mqtt.jwt/private.pem create mode 100644 mqtt.jwt/tls/localhost.p12 delete mode 100644 mqtt.kafka.broker/README.md delete mode 100644 mqtt.kafka.broker/compose.yaml delete mode 100755 mqtt.kafka.broker/setup.sh delete mode 100755 mqtt.kafka.broker/teardown.sh delete mode 100644 mqtt.kafka.broker/zilla.yaml create mode 100755 openapi.asyncapi.kakfa.proxy/test.sh diff --git a/amqp.reflect/README.md b/amqp.reflect/README.md index f61b7a20..dd7ea6f3 100644 --- a/amqp.reflect/README.md +++ b/amqp.reflect/README.md @@ -5,7 +5,6 @@ Listens on amqps port `7171` and will echo back whatever is sent to the server, ## Requirements -- jq, nc - Compose compatible host - cli-rhea diff --git a/asyncapi.http.kafka.proxy/README.md b/asyncapi.http.kafka.proxy/README.md index d7900bc1..a6ec6a54 100644 --- a/asyncapi.http.kafka.proxy/README.md +++ b/asyncapi.http.kafka.proxy/README.md @@ -55,7 +55,7 @@ output: List all the pets using `GET` request for the `/pets` endpoint ```bash -curl --location 'http://localhost:7114/pets' \ +curl 'http://localhost:7114/pets' \ --header 'Accept: application/json' ``` diff --git a/asyncapi.http.kafka.proxy/test.sh b/asyncapi.http.kafka.proxy/test.sh index 09f70796..5dbbf950 100755 --- a/asyncapi.http.kafka.proxy/test.sh +++ b/asyncapi.http.kafka.proxy/test.sh @@ -43,7 +43,7 @@ echo EXPECTED="$EXPECTED" echo # WHEN -OUTPUT=$(curl --location "http://localhost:$PORT/pets" \ +OUTPUT=$(curl "http://localhost:$PORT/pets" \ --header 'Content-Type: application/json') RESULT=$? echo RESULT="$RESULT" diff --git a/asyncapi.mqtt.proxy/README.md b/asyncapi.mqtt.proxy/README.md index 3474856c..655035bd 100644 --- a/asyncapi.mqtt.proxy/README.md +++ b/asyncapi.mqtt.proxy/README.md @@ -4,7 +4,6 @@ Listens on mqtt port `7183` and will forward mqtt publish messages and proxies s ## Requirements -- jq, nc - Compose compatible host - mosquitto diff --git a/grpc.kafka.fanout/README.md b/grpc.kafka.fanout/README.md index 1aa45fde..bb500dcd 100644 --- a/grpc.kafka.fanout/README.md +++ b/grpc.kafka.fanout/README.md @@ -4,7 +4,7 @@ Listens on https port `7151` and fanout messages from `messages` topic in Kafka. ## Requirements -- jq, protoc +- protoc - Compose compatible host - [grpcurl](https://github.com/fullstorydev/grpcurl) diff --git a/http.json.schema/README.md b/http.json.schema/README.md index 6d4a8ce9..99239ce1 100644 --- a/http.json.schema/README.md +++ b/http.json.schema/README.md @@ -4,7 +4,6 @@ Listens on https port `7114` and will response back whatever is hosted in `nginx ## Requirements -- jq, nc - Compose compatible host ## Setup diff --git a/http.jwt/README.md b/http.jwt/README.md index 4955a0f0..9fd18e3d 100644 --- a/http.jwt/README.md +++ b/http.jwt/README.md @@ -5,10 +5,8 @@ Listens on https port `7143` and will echo back whatever is sent to the server f ## Requirements -- jq, nc - Compose compatible host - jwt-cli -- curl ### Install jwt-cli client diff --git a/http.kafka.async/README.md b/http.kafka.async/README.md index 6bd462bd..628ba2af 100644 --- a/http.kafka.async/README.md +++ b/http.kafka.async/README.md @@ -5,7 +5,7 @@ and `items-responses` topics in Kafka, asynchronously. ## Requirements -- jq, nc +- jq - Compose compatible host\ ## Setup diff --git a/http.kafka.async/compose.yaml b/http.kafka.async/compose.yaml index 9eedbce6..d7cb7e1e 100644 --- a/http.kafka.async/compose.yaml +++ b/http.kafka.async/compose.yaml @@ -57,7 +57,7 @@ services: - | echo -e "Creating kafka topic"; /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic items-requests - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic items-responses --config cleanup.policy=compact + /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic items-responses echo -e "Successfully created the following topics:"; /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --list; diff --git a/http.kafka.avro.json/README.md b/http.kafka.avro.json/README.md index 14375e9f..bc873530 100644 --- a/http.kafka.avro.json/README.md +++ b/http.kafka.avro.json/README.md @@ -23,7 +23,7 @@ docker compose up -d ### Register Schema ```bash -curl 'http://localhost:8081/subjects/core-paymenthub-simple-pay-ipn-request-value/versions' \ +curl 'http://localhost:8081/subjects/items-snapshots-value/versions' \ --header 'Content-Type: application/json' \ --data '{ "schema": @@ -53,7 +53,7 @@ curl 'http://localhost:8081/subjects/items-snapshots-value/versions/latest' `POST` request ```bash -curl -k -v -X POST http://localhost:7114/items -H 'Idempotency-Key: 1' -H 'Content-Type: application/json' -d '{"id": "123","status": "OK"}' +curl -k -v http://localhost:7114/items -H 'Idempotency-Key: 1' -H 'Content-Type: application/json' -d '{"id": "123","status": "OK"}' ``` output: @@ -75,7 +75,7 @@ output: `GET` request to fetch specific item. ```bash -curl -k -v http://localhost7114/items/1 +curl -k http://localhost:7114/items/1 ``` output: @@ -96,7 +96,7 @@ output: `POST` request. ```bash -curl -k -v -X POST http://localhost7114/items -H 'Idempotency-Key: 2' -H 'Content-Type: application/json' -d '{"id": 123,"status": "OK"}' +curl -k -v http://localhost:7114/items -H 'Idempotency-Key: 2' -H 'Content-Type: application/json' -d '{"id": 123,"status": "OK"}' ``` output: @@ -118,7 +118,7 @@ output: `GET` request to verify whether Invalid event is produced ```bash -curl -k -v http://localhost7114/items/2 +curl -k -v http://localhost:7114/items/2 ``` output: diff --git a/http.kafka.avro.json/compose.yaml b/http.kafka.avro.json/compose.yaml index ca02c86d..8b7d2316 100644 --- a/http.kafka.avro.json/compose.yaml +++ b/http.kafka.avro.json/compose.yaml @@ -86,8 +86,7 @@ services: command: - | echo -e "Creating kafka topic"; - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic items-requests - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic items-responses --config cleanup.policy=compact + /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic items-snapshots --config cleanup.policy=compact echo -e "Successfully created the following topics:"; /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --list; diff --git a/http.kafka.avro.json/test.sh b/http.kafka.avro.json/test.sh new file mode 100755 index 00000000..6f56a71a --- /dev/null +++ b/http.kafka.avro.json/test.sh @@ -0,0 +1,73 @@ +#!/bin/sh +set -x + +EXIT=0 + +# create schema +curl 'http://localhost:8081/subjects/items-snapshots-value/versions' \ +--header 'Content-Type: application/json' \ +--data '{ + "schema": + "{\"fields\":[{\"name\":\"id\",\"type\":\"string\"},{\"name\":\"status\",\"type\":\"string\"}],\"name\":\"Event\",\"namespace\":\"io.aklivity.example\",\"type\":\"record\"}", + "schemaType": "AVRO" +}' + +# GIVEN +PORT="7114" +INPUT='{"id": "123", "status": "OK"}' +EXPECTED='{"id":"123","status":"OK"}' +echo \# Testing http.kafka.avro.json/valid +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +# send message +curl -k http://localhost:7114/items -H 'Idempotency-Key: 1' -H 'Content-Type: application/json' -d "$INPUT" + +# WHEN +OUTPUT=$(curl -k http://localhost:$PORT/items/1) +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + +# GIVEN +PORT="7114" +INPUT='{"id": 123,"status": "OK"}' +EXPECTED='404' +echo \# Testing http.kafka.avro.json/invalid +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +# send message +curl -k http://localhost:7114/items -H 'Idempotency-Key: 2' -H 'Content-Type: application/json' -d "$INPUT" + +# WHEN +OUTPUT=$(curl -w "%{http_code}" http://localhost:$PORT/items/2) +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + +exit $EXIT diff --git a/http.kafka.cache/README.md b/http.kafka.cache/README.md index 16c1164c..07432470 100644 --- a/http.kafka.cache/README.md +++ b/http.kafka.cache/README.md @@ -4,7 +4,6 @@ Listens on http port `7114` or https port `7114` and will serve cached responses ## Requirements -- jq, nc - Compose compatible host ## Setup diff --git a/http.kafka.cache/test.sh b/http.kafka.cache/test.sh new file mode 100755 index 00000000..4513c40c --- /dev/null +++ b/http.kafka.cache/test.sh @@ -0,0 +1,65 @@ +#!/bin/sh +set -x + +EXIT=0 + +# GIVEN +PORT="7114" +EXPECTED="[]" +echo \# Testing http.kafka.cache/ +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +# WHEN +OUTPUT=$(curl http://localhost:$PORT/items) +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + + +# GIVEN +PORT="7114" +INPUT='{"message":"Hello World"}' +EXPECTED='[{"message":"Hello World"}]' +echo \# Testing http.kafka.cache/ +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +echo "$INPUT" | docker compose -p zilla-http-kafka-cache exec -T kafkacat \ + kafkacat -P \ + -b kafka:29092 \ + -t items-snapshots \ + -k "5cf7a1d5-3772-49ef-86e7-ba6f2c7d7d07" \ + -H "content-type=application/json" + +# WHEN +OUTPUT=$(curl http://localhost:$PORT/items) +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + +exit $EXIT diff --git a/http.kafka.crud/README.md b/http.kafka.crud/README.md index 95927891..a0c01af6 100644 --- a/http.kafka.crud/README.md +++ b/http.kafka.crud/README.md @@ -5,7 +5,6 @@ deletes and reads messages in `items-snapshots` log-compacted Kafka topic acting ## Requirements -- jq, nc - Compose compatible host ## Setup @@ -39,7 +38,7 @@ docker compose up -d Note: You can remove `-H 'Idempotency-Key: 1'` to generate random key. ```bash -curl -k -v -X POST http://localhost7114/items -H 'Idempotency-Key: 1' -H 'Content-Type: application/json' -d '{"greeting":"Hello, world1"}' +curl -k -v -X POST http://localhost:7114/items -H 'Idempotency-Key: 1' -H 'Content-Type: application/json' -d '{"greeting":"Hello, world1"}' ``` output: @@ -61,7 +60,7 @@ HTTP/2 204 `GET` request to fetch specific item. ```bash -curl -k -v http://localhost7114/items/1 +curl -k -v http://localhost:7114/items/1 ``` output: @@ -81,7 +80,7 @@ output: `PUT` request to update specific item. ```bash -curl -k -v -X PUT http://localhost7114/items/1 -H 'Content-Type: application/json' -d '{"greeting":"Hello, world2"}' +curl -k -v -X PUT http://localhost:7114/items/1 -H 'Content-Type: application/json' -d '{"greeting":"Hello, world2"}' ``` output: @@ -103,7 +102,7 @@ HTTP/2 204 `DELETE` request to delete specific item. ```bash -curl -k -v -X DELETE http://localhost7114/items/1 +curl -k -v -X DELETE http://localhost:7114/items/1 ``` output: diff --git a/http.kafka.crud/test.sh b/http.kafka.crud/test.sh new file mode 100755 index 00000000..ef726462 --- /dev/null +++ b/http.kafka.crud/test.sh @@ -0,0 +1,34 @@ +#!/bin/sh +set -x + +EXIT=0 + +# GIVEN +PORT="7114" +INPUT='{"greeting":"Hello, world1"}' +EXPECTED='{"greeting":"Hello, world1"}' +echo \# Testing http.kafka.crud/ +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +curl -k -v -X POST http://localhost:$PORT/items -H 'Idempotency-Key: 1' -H 'Content-Type: application/json' -d "$INPUT" + +# WHEN +OUTPUT=$(curl -k http://localhost:$PORT/items/1) +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + +exit $EXIT diff --git a/http.kafka.oneway/README.md b/http.kafka.oneway/README.md index 3e91e40a..d6f8fa6d 100644 --- a/http.kafka.oneway/README.md +++ b/http.kafka.oneway/README.md @@ -4,7 +4,7 @@ Listens on http port `7114` or https port `7114` and will produce messages to th ## Requirements -- jq, nc +- jq - Compose compatible host ## Setup @@ -26,10 +26,7 @@ docker compose up -d Send a `POST` request with an event body. ```bash -curl -v \ - -X "POST" http://localhost:7114/events \ - -H "Content-Type: application/json" \ - -d "{\"greeting\":\"Hello, world\"}" +curl -v http://localhost:7114/events -H "Content-Type: application/json" -d '{"greeting":"Hello, world"}' ``` output: diff --git a/http.kafka.oneway/compose.yaml b/http.kafka.oneway/compose.yaml index 5255f24b..cd22e224 100644 --- a/http.kafka.oneway/compose.yaml +++ b/http.kafka.oneway/compose.yaml @@ -56,8 +56,7 @@ services: command: - | echo -e "Creating kafka topic"; - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic items-requests - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic items-responses --config cleanup.policy=compact + /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic events echo -e "Successfully created the following topics:"; /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --list; diff --git a/http.kafka.oneway/test.sh b/http.kafka.oneway/test.sh new file mode 100755 index 00000000..9b8aed24 --- /dev/null +++ b/http.kafka.oneway/test.sh @@ -0,0 +1,32 @@ +#!/bin/sh +set -x + +EXIT=0 + +# GIVEN +PORT="7114" +INPUT='{"greeting":"Hello, world"}' +EXPECTED="204" +echo \# Testing http.kafka.oneway/ +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +# WHEN +OUTPUT=$(curl -w "%{http_code}" http://localhost:$PORT/events -H "Content-Type: application/json" -d "$INPUT") +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + +exit $EXIT diff --git a/http.kafka.proto.json/README.md b/http.kafka.proto.json/README.md index 30375f73..673cbdc2 100644 --- a/http.kafka.proto.json/README.md +++ b/http.kafka.proto.json/README.md @@ -1,6 +1,6 @@ # http.kafka.proto.json -This example allows a protobuf object to be sent to a REST edpoint as JSON that gets validated and converted to the protobuf when it is produced onto Kafka. +This example allows a protobuf object to be sent to a REST endpoint as JSON that gets validated and converted to the protobuf when it is produced onto Kafka. ## Setup @@ -25,7 +25,7 @@ Each of the below scenarios are run from a fresh install of zilla and kafka 1. `POST` a valid request getting a `204` back ```bash -curl --location 'http://localhost:7114/requests' \ +curl 'http://localhost:7114/requests' \ --header 'Content-Type: application/json' \ --data '{ "message": "hello world", @@ -36,7 +36,7 @@ curl --location 'http://localhost:7114/requests' \ 1. `POST` an invalid request getting a `400` back and logs `MODEL_PROTOBUF_VALIDATION_FAILED A message payload failed validation. Cannot find field: invalid in message Request.` to stdout ```bash -curl --location 'http://localhost:7114/requests' \ +curl 'http://localhost:7114/requests' \ --header 'Content-Type: application/json' \ --data '{ "message": "hello world", @@ -48,7 +48,7 @@ curl --location 'http://localhost:7114/requests' \ 1. `POST` a valid request getting a `400` back and logs `MODEL_PROTOBUF_VALIDATION_FAILED A message payload failed validation. Field Request.message has already been set..` to stdout ```bash -curl --location 'http://localhost:7114/requests' \ +curl 'http://localhost:7114/requests' \ --header 'Content-Type: application/json' \ --data '{ "message": "hello world", @@ -63,7 +63,7 @@ Sending an invalid `message` field causes subsequent requests to take ~10 min to 1. `POST` a valid request getting a `204` back ```bash -curl --location 'http://localhost:7114/requests' \ +curl 'http://localhost:7114/requests' \ --header 'Content-Type: application/json' \ --data '{ "message": "hello message", @@ -74,13 +74,13 @@ curl --location 'http://localhost:7114/requests' \ 1. `POST` an invalid `"messages"` field request getting a `400` back and immediately post the correct payload after. Run both curl commands at the same time and sometimes the second one works and other times it will hang until it gets a `204` back after ~10min and the message is not on the Kafka topic ```bash -curl --location 'http://localhost:7114/requests' \ +curl 'http://localhost:7114/requests' \ --header 'Content-Type: application/json' \ --data '{ "messages": "hello messages", "count": 10 }' -v -curl --location 'http://localhost:7114/requests' \ +curl 'http://localhost:7114/requests' \ --header 'Content-Type: application/json' \ --data '{ "message": "hello messages", diff --git a/http.kafka.proto.json/test.sh b/http.kafka.proto.json/test.sh new file mode 100755 index 00000000..9e196e0c --- /dev/null +++ b/http.kafka.proto.json/test.sh @@ -0,0 +1,58 @@ +#!/bin/sh +set -x + +EXIT=0 + +# GIVEN +PORT="7114" +INPUT='{ "message": "hello world", "count": 10 }' +EXPECTED="204" +echo \# Testing http.kafka.proto.json/valid +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +# WHEN +OUTPUT=$(curl -w "%{http_code}" http://localhost:$PORT/requests -H "Content-Type: application/json" -d "$INPUT") +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + +# GIVEN +PORT="7114" +INPUT='{ "message": "hello world", "count": 10, "invalid": "field" }' +EXPECTED="400" +echo \# Testing http.kafka.proto.json/invalid +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +# WHEN +OUTPUT=$(curl -w "%{http_code}" http://localhost:$PORT/requests -H "Content-Type: application/json" -d "$INPUT") +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + +exit $EXIT diff --git a/mqtt.jwt/README.md b/mqtt.jwt/README.md index 616c5e35..66e10ef0 100644 --- a/mqtt.jwt/README.md +++ b/mqtt.jwt/README.md @@ -1,6 +1,6 @@ # mqtt.jwt -Listens on mqtt port `7183` and will forward mqtt publish messages and proxies subscribes to mosquitto MQTT broker listening on `1883` for topic `smartylighting/streetlights/1/0/event/+/lighting/measured`. +Listens on mqtt port `7183` and `7883` forwarding mqtt publish messages and proxies subscribes to mosquitto MQTT broker listening on `1883`. ## Requirements @@ -23,61 +23,127 @@ The `setup.sh` script will install the Open Source Zilla image in a Compose stac docker compose up -d ``` +### Install jwt-cli client + +Requires JWT command line client, such as `jwt-cli` version `2.0.0` or higher. + +```bash +brew install mike-engel/jwt-cli/jwt-cli +``` + ### Verify behavior -Connect a subscribing client to mosquitto broker to port `1883`. Using mosquitto_pub client publish `{"id":"1","status":"on"}` to Zilla on port `7183`. Verify that the message arrived to on the first client. +Create a token without `mqtt:stream` scope. ```bash -docker compose -p zilla-mqtt-proxy exec -T mosquitto-cli \ -mosquitto_sub --url mqtt://zilla:7183/smartylighting/streetlights/1/0/event/+/lighting/measured --debug +export MQTT_USERNAME="Bearer $(jwt encode \ + --alg "RS256" \ + --kid "example" \ + --iss "https://auth.example.com" \ + --aud "https://api.example.com" \ + --exp=+1d \ + --no-iat \ + --secret @private.pem)" ``` -output: +Create a token that is valid until 2032, with `mqtt:stream` scope. + +See the signed JWT token, without `mqtt:stream` scope, print the `MQTT_USERNAME` var. +```bash +$ jwt encode \ +echo $MQTT_USERNAME ``` + +Use the signed JWT token, without `mqtt:stream` scope, to attempt an authorized request. Provide the JWT token in the MQTT_USERNAME field. + +```bash +docker compose -p zilla-mqtt-jwt exec mosquitto-cli \ + mosquitto_sub --url mqtt://zilla:7183/zilla --debug -u $MQTT_USERNAME +``` + +The request is rejected as expected, and without leaking any information about failed security checks. + +```text +Client null sending CONNECT +Client null sending CONNECT Client null sending CONNECT -Client auto-5A1C0A41-0D16-497D-6C3B-527A93E421E6 received CONNACK (0) -Client auto-5A1C0A41-0D16-497D-6C3B-527A93E421E6 sending SUBSCRIBE (Mid: 1, Topic: smartylighting/streetlights/1/0/event/+/lighting/measured, QoS: 0, Options: 0x00) -Client auto-5A1C0A41-0D16-497D-6C3B-527A93E421E6 received SUBACK -Subscribed (mid: 1): 0 -{"id":"1","status":"on"} ``` +Create a token with the `mqtt:stream` scope. + ```bash -docker compose -p zilla-mqtt-proxy exec -T mosquitto-cli \ -mosquitto_sub --url mqtt://zilla:7183/smartylighting/streetlights/1/0/event/1/lighting/measured --message '{"id":"1","status":"on"}' --debug +export MQTT_USERNAME="Bearer $(jwt encode \ + --alg "RS256" \ + --kid "example" \ + --iss "https://auth.example.com" \ + --aud "https://api.example.com" \ + --exp=+1d \ + --no-iat \ + --payload "scope=mqtt:stream" \ + --secret @private.pem)" ``` -output: +See the signed JWT token with `mqtt:stream` scope print the `MQTT_USERNAME` var. +```bash +echo $MQTT_USERNAME +``` + +Use the signed JWT token, with `mqtt:stream` scope, to attempt an authorized request. + +```bash +docker compose -p zilla-mqtt-jwt exec mosquitto-cli \ + mosquitto_sub --url mqtt://zilla:7183/zilla --debug -u $MQTT_USERNAME ``` + +The connection is authorized. + +```text Client null sending CONNECT -Client 244684c7-fbaf-4e08-b382-a1a2329cf9ec received CONNACK (0) -Client 244684c7-fbaf-4e08-b382-a1a2329cf9ec sending PUBLISH (d0, q0, r0, m1, 'smartylighting/streetlights/1/0/event/1/lighting/measured', ... (24 bytes)) -Client 244684c7-fbaf-4e08-b382-a1a2329cf9ec sending DISCONNECT +Client a0b72aaa-3d12-4d1d-8fc3-4971d1973763 received CONNACK (0) +Client a0b72aaa-3d12-4d1d-8fc3-4971d1973763 sending SUBSCRIBE (Mid: 1, Topic: zilla, QoS: 0, Options: 0x00) +Client a0b72aaa-3d12-4d1d-8fc3-4971d1973763 received SUBACK +Subscribed (mid: 1): 0 +Client 2b77314a-163f-4f18-908c-2913645e4f56 received PUBLISH (d0, q0, r0, m0, 'zilla', ... (12 bytes)) +Hello, world ``` -Now attempt to publish an invalid message, with property `stat` instead of `status`. +Use the signed JWT token, with `mqtt:stream` scope, publish a message. ```bash -mosquitto_pub -V '5' -t 'smartylighting/streetlights/1/0/event/1/lighting/measured' -m '{"id":"1","stat":"off"}' -p 7183 --repeat 2 --repeat-delay 3 --debug +docker compose -p zilla-mqtt-jwt exec mosquitto-cli \ + mosquitto_pub --url mqtt://zilla:7183/zilla --message 'Hello, world' --debug -u $MQTT_USERNAME ``` output: -``` +```text Client null sending CONNECT -Client e7e9ddb0-f8c9-43a0-840f-dab9981a9de3 received CONNACK (0) -Client e7e9ddb0-f8c9-43a0-840f-dab9981a9de3 sending PUBLISH (d0, q0, r0, m1, 'smartylighting/streetlights/1/0/event/1/lighting/measured', ... (23 bytes)) -Received DISCONNECT (153) -Error: The client is not currently connected. +Client 44181407-f1bc-4a6b-b94d-9f37d37ea395 received CONNACK (0) +Client 44181407-f1bc-4a6b-b94d-9f37d37ea395 sending PUBLISH (d0, q0, r0, m1, 'zilla', ... (12 bytes)) +Client 44181407-f1bc-4a6b-b94d-9f37d37ea395 sending DISCONNECT +``` + +### Note + +The `private.pem` key was generated using `openssl` as follows. + +```bash +openssl genrsa -out private.pem 2048 +``` + +Then the RSA key modulus is extracted in base64 format. + +```bash +openssl rsa -in private.pem -pubout -noout -modulus | cut -h 'localhost' -p 7183 --debug= -f2 | xxd -r -p | base64 ``` -Note that the invalid message is rejected with error code `153` `payload format invalid`, and therefore not received by the subscriber. +The resulting base64 modulus is used to configure the `jwt` guard in `zilla.yaml` to validate the integrity of signed JWT tokens. -## Teardown +### Teardown -The `teardown.sh` script stops the compose stack. +The `teardown.sh` script stops port forwarding, uninstalls Zilla and deletes the namespace. ```bash ./teardown.sh diff --git a/mqtt.jwt/compose.yaml b/mqtt.jwt/compose.yaml index 9e5df0d1..76ccdcca 100644 --- a/mqtt.jwt/compose.yaml +++ b/mqtt.jwt/compose.yaml @@ -1,4 +1,4 @@ -name: ${NAMESPACE:-zilla-mqtt-proxy} +name: ${NAMESPACE:-zilla-mqtt-jwt} services: zilla: image: ghcr.io/aklivity/zilla:${ZILLA_VERSION:-latest} @@ -15,7 +15,7 @@ services: MOSQUITTO_BROKER_PORT: 1883 volumes: - ./zilla.yaml:/etc/zilla/zilla.yaml - - ./mqtt-asyncapi.yaml:/etc/zilla/specs/mqtt-asyncapi.yaml + - ./tls:/etc/zilla/tls command: start -v -e mosquitto: diff --git a/mqtt.jwt/private.pem b/mqtt.jwt/private.pem new file mode 100644 index 00000000..dbf9178b --- /dev/null +++ b/mqtt.jwt/private.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAqqEu50hX+43Bx4W1UYWnAVKwFm+vDbP0kuIOSLVNa+HKQdHT +f+3Sei5UCnkskn796izA29D0DdCy3ET9oaKRHIJyKbqFl0rv6f516QzOoXKC6N01 +sXBHBE/ovs0wwDvlaW+gFGPgkzdcfUlyrWLDnLV7LcuQymhTND2uH0oR3wJnNENN +/OFgM1KGPPDOe19YsIKdLqARgxrhZVsh06OurEviZTXOBFI5r+yac7haDwOQhLHX +Nv+Y9MNvxs5QLWPFIM3bNUWfYrJnLrs4hGJS+y/KDM9Si+HL30QAFXy4YNO33J8D +HjZ7ddG5n8/FqplOKvRtUgjcKWlxoGY4VdVaDQIDAQABAoIBAQCU5nnO3UPiQs+S +9SzIynB16BnASpAhziOlNl4utwCsH2roS1pdLkXZ16oBRcNOyEF+5LUcXllL4Q7k +x9PqBLrLfU5w+dNwtrVspmFxEXsUSqDQ45HimU9wBOff8aIUb3CAtSemA47MCajN +sJXBlwmLLJgk25sr9yR810KnDXVQ/RQXWGnRiyVvgHjYyrhQEam22z95+60yJPbQ +hFphWPGDj4O1kOkuQil/ciD5Br1IcrftNp32UZE1c5TyBL9kyLH0iYGELt+UR4ht +kbkBYF4ai0tiDRSpi1M0yd+5EDbi7kK5qI/XKZiDFptKXFkb49hln6mYpzuumzxh +W7MqNswlAoGBANLAXpLmcLm5IqvjGRT3V34O1C1ztQzR9h8Vor0hpfVZEcUTjQ8i +HwzkIfIBQqfOpxCrutbPSC9gOQIrjPS4O04B6qI/n1xY8n2bm7xEN0w68cjeS+Aa +duB8NmXGW3iTCWkZ8LntKKiijY/qM4DNTJwOHNnx/gEoccSJBX7eQdVrAoGBAM9D +lEv2A6+AwQP19kiN+PVGtzQx/VD8URCe8b5FOxEY42Cfic13ZUK2o35cZKrWgw5T +gO+PtrLGg6iHYv6Igib2urHJrX8bv4GhuUk3e4ZUDfBvQEctb+3ziDIH+dz1idxG +3NBm3YIyROrvV4sZknziPAxSSs0nsRO99LKC7HRnAoGABfL8OHVc1UFOoz+D472f +sKVGhAnyIGyE4BfCQkiC4Mwk3kVRBA5YhgqikqxKb2Y7/RJ78bhkN0ImGdOU5QuW +UPto3i+hlf/EyJrt6ICcdwBq9tqflbHpjSi0eGcDCgJMj7T1wKnbLfd4u4lG7unc +scMMOXLFUs8LdxrPFue7QAUCgYAmVIEgaybTViRb7yjU0iywb5uB85y9VWxIfpyG +a5c42jlyrQ53CRWY+N3TiJK1ZWZnR9oYc6N9/GhsylzsZaJsQkTUjE+hqigIeTgi +6jfV58WMKYbhou2IO/l8By2WR3JvYkuD3wIoCdPk/s5Z0yjcH5qrTKy4tBZzaDXQ +rZW9EQKBgEpfuGRtsUE+FUEqLcqfI3w5aYMKb0pEsG4zbvxB/4QeHdAawNEqeSrS +TC0boMRlZ3Mf6GpZ9No/qVvfsW45PghmT77b4nsR2Sh0mdPMbBzdoqOOTwgNAoKP +RHsZtVdb9Gk7Jf2UHTEZY5NLKyXGH/qj4/7ajxixtHNvlD3oI14F +-----END RSA PRIVATE KEY----- diff --git a/mqtt.jwt/tls/localhost.p12 b/mqtt.jwt/tls/localhost.p12 new file mode 100644 index 0000000000000000000000000000000000000000..a0db8587be04a4b29127be825906501ba7f3281e GIT binary patch literal 5632 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 Ie}wM;0593D;s5{u literal 0 HcmV?d00001 diff --git a/mqtt.jwt/zilla.yaml b/mqtt.jwt/zilla.yaml index 9ce3b1cf..5c46216c 100644 --- a/mqtt.jwt/zilla.yaml +++ b/mqtt.jwt/zilla.yaml @@ -1,7 +1,13 @@ --- name: zilla-mqtt-jwt ---- -name: example +vaults: + my_servers: + type: filesystem + options: + keys: + store: tls/localhost.p12 + type: pkcs12 + password: ${{env.KEYSTORE_PASSWORD}} guards: authn_jwt: type: jwt @@ -22,10 +28,24 @@ bindings: host: 0.0.0.0 port: - 7183 + - 7883 routes: - - when: - - port: 7183 - exit: north_mqtt_server + - when: + - port: 7183 + exit: north_mqtt_server + - when: + - port: 7883 + exit: north_tls_server + north_tls_server: + type: tls + kind: server + vault: my_servers + options: + keys: + - localhost + sni: + - localhost + exit: north_mqtt_server north_mqtt_server: type: mqtt kind: server @@ -39,8 +59,8 @@ bindings: - guarded: authn_jwt: - mqtt:stream - exit: north_mqtt_kafka_mapping - north_mqtt_kafka_mapping: + exit: north_mqtt_client + north_mqtt_client: type: mqtt kind: client exit: south_tcp_client diff --git a/mqtt.kafka.broker/README.md b/mqtt.kafka.broker/README.md deleted file mode 100644 index 0994002b..00000000 --- a/mqtt.kafka.broker/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# mqtt.kafka.broker - -This is the resource folder for the running the [MQTT Kafka broker guide](https://docs.aklivity.io/zilla/latest/how-tos/mqtt/mqtt.kafka.broker.html) found on our docs. - -## Setup - -The `setup.sh` script will install the Open Source Zilla image in a Compose stack along with any necessary services defined in the [compose.yaml](compose.yaml) file. - -- create an MQTT broker at `mqtt://localhost:7183` - -```bash -./setup.sh -``` - -- alternatively with the docker compose command: - -```bash -docker compose up -d -``` - -### Using this example - -Follow the steps on our [MQTT Kafka broker guide](https://docs.aklivity.io/zilla/latest/how-tos/mqtt/mqtt.kafka.broker.html#send-a-greeting) - -## Teardown - -The `teardown.sh` script will remove any resources created. - -```bash -./teardown.sh -``` diff --git a/mqtt.kafka.broker/compose.yaml b/mqtt.kafka.broker/compose.yaml deleted file mode 100644 index 69195530..00000000 --- a/mqtt.kafka.broker/compose.yaml +++ /dev/null @@ -1,87 +0,0 @@ -name: ${NAMESPACE:-zilla-mqtt-kafka-broker} -services: - zilla: - image: ghcr.io/aklivity/zilla:${ZILLA_VERSION:-latest} - restart: unless-stopped - ports: - - 7114:7114 - - 7183:7183 - healthcheck: - interval: 5s - timeout: 3s - retries: 5 - test: ["CMD", "bash", "-c", "echo -n '' > /dev/tcp/127.0.0.1/7183"] - environment: - KAFKA_BOOTSTRAP_SERVER: kafka:29092 - volumes: - - ./zilla.yaml:/etc/zilla/zilla.yaml - command: start -v -e - - kafka: - image: bitnami/kafka:3.5 - restart: unless-stopped - ports: - - 9092:9092 - healthcheck: - test: /opt/bitnami/kafka/bin/kafka-cluster.sh cluster-id --bootstrap-server kafka:29092 || exit 1 - interval: 1s - timeout: 60s - retries: 60 - environment: - ALLOW_PLAINTEXT_LISTENER: "yes" - KAFKA_CFG_NODE_ID: "1" - KAFKA_CFG_BROKER_ID: "1" - KAFKA_CFG_GROUP_INITIAL_REBALANCE_DELAY_MS: "0" - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: "1@127.0.0.1:9093" - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: "CLIENT:PLAINTEXT,INTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT" - KAFKA_CFG_CONTROLLER_LISTENER_NAMES: "CONTROLLER" - KAFKA_CFG_LOG_DIRS: "/tmp/logs" - KAFKA_CFG_PROCESS_ROLES: "broker,controller" - KAFKA_CFG_LISTENERS: "CLIENT://:9092,INTERNAL://:29092,CONTROLLER://:9093" - KAFKA_CFG_INTER_BROKER_LISTENER_NAME: "INTERNAL" - KAFKA_CFG_ADVERTISED_LISTENERS: "CLIENT://localhost:9092,INTERNAL://kafka:29092" - KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: "true" - - kafka-init: - image: bitnami/kafka:3.5 - user: root - depends_on: - kafka: - condition: service_healthy - restart: true - deploy: - restart_policy: - condition: none - max_attempts: 0 - entrypoint: ["/bin/sh", "-c"] - command: - - | - echo -e "Creating kafka topic"; - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic mqtt-messages - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic mqtt-retained --config cleanup.policy=compact - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --create --if-not-exists --topic mqtt-sessions --config cleanup.policy=compact - echo -e "Successfully created the following topics:"; - /opt/bitnami/kafka/bin/kafka-topics.sh --bootstrap-server kafka:29092 --list; - - kafka-ui: - image: ghcr.io/kafbat/kafka-ui:v1.0.0 - restart: unless-stopped - ports: - - 8080:8080 - depends_on: - kafka: - condition: service_healthy - restart: true - environment: - KAFKA_CLUSTERS_0_NAME: local - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:29092 - - kafkacat: - image: confluentinc/cp-kafkacat:7.1.9 - command: "bash" - stdin_open: true - tty: true - -networks: - default: - driver: bridge diff --git a/mqtt.kafka.broker/setup.sh b/mqtt.kafka.broker/setup.sh deleted file mode 100755 index 80375039..00000000 --- a/mqtt.kafka.broker/setup.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/sh -set -e - -# Start or restart Zilla -if [ -z "$(docker compose ps -q zilla)" ]; then -docker compose up -d -else -docker compose up -d --force-recreate --no-deps zilla -fi diff --git a/mqtt.kafka.broker/teardown.sh b/mqtt.kafka.broker/teardown.sh deleted file mode 100755 index 1358056d..00000000 --- a/mqtt.kafka.broker/teardown.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -set -e - -docker compose -p "${NAMESPACE:-zilla-mqtt-kafka-broker}" down --remove-orphans diff --git a/mqtt.kafka.broker/zilla.yaml b/mqtt.kafka.broker/zilla.yaml deleted file mode 100644 index e5371a72..00000000 --- a/mqtt.kafka.broker/zilla.yaml +++ /dev/null @@ -1,62 +0,0 @@ ---- -name: zilla-mqtt-kafka-broker -bindings: - # Proxy service entrypoint - north_tcp_server: - type: tcp - kind: server - options: - host: 0.0.0.0 - port: - - 7183 - routes: - - when: - - port: 7183 - exit: north_mqtt_server - - # MQTT server - north_mqtt_server: - type: mqtt - kind: server - exit: north_mqtt_kafka_mapping - - # MQTT messages to Kafka topics - north_mqtt_kafka_mapping: - type: mqtt-kafka - kind: proxy - options: - topics: - sessions: mqtt-sessions - messages: mqtt-messages - retained: mqtt-retained - exit: north_kafka_cache_client - - # Kafka sync layer - north_kafka_cache_client: - type: kafka - kind: cache_client - exit: south_kafka_cache_server - south_kafka_cache_server: - type: kafka - kind: cache_server - options: - bootstrap: - - mqtt-messages - - mqtt-retained - exit: south_kafka_client - - # Connect to Kafka - south_kafka_client: - type: kafka - kind: client - options: - servers: - - ${{env.KAFKA_BOOTSTRAP_SERVER}} - exit: south_tcp_client - south_tcp_client: - type: tcp - kind: client -telemetry: - exporters: - stdout_logs_exporter: - type: stdout diff --git a/openapi.asyncapi.kakfa.proxy/README.md b/openapi.asyncapi.kakfa.proxy/README.md index 79226425..7cf88a69 100644 --- a/openapi.asyncapi.kakfa.proxy/README.md +++ b/openapi.asyncapi.kakfa.proxy/README.md @@ -19,7 +19,7 @@ docker compose up -d #### Create Pet ```bash -curl -X POST --location 'http://localhost:7114/pets' \ +curl 'http://localhost:7114/pets' \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: 1' \ --data '{ "id": 1, "name": "Spike" }' @@ -28,7 +28,7 @@ curl -X POST --location 'http://localhost:7114/pets' \ #### Retrieve Pets ```bash -curl --location 'http://localhost:7114/pets' --header 'Accept: application/json' +curl 'http://localhost:7114/pets' --header 'Accept: application/json' ``` ## Teardown diff --git a/openapi.asyncapi.kakfa.proxy/test.sh b/openapi.asyncapi.kakfa.proxy/test.sh new file mode 100755 index 00000000..06805226 --- /dev/null +++ b/openapi.asyncapi.kakfa.proxy/test.sh @@ -0,0 +1,34 @@ +#!/bin/sh +set -x + +EXIT=0 + +# GIVEN +PORT="7114" +INPUT='{"id": 1, "name": "Spike"}' +EXPECTED='[{"id": 1, "name": "Spike"}]' +echo \# Testing openapi.asyncapi.kakfa.proxy/ +echo PORT="$PORT" +echo INPUT="$INPUT" +echo EXPECTED="$EXPECTED" +echo + +curl "http://localhost:$PORT/pets" --header 'Content-Type: application/json' --header 'Idempotency-Key: 1' --data "$INPUT" + +# WHEN +OUTPUT=$(curl "http://localhost:$PORT/pets") +RESULT=$? +echo RESULT="$RESULT" + +# THEN +echo OUTPUT="$OUTPUT" +echo EXPECTED="$EXPECTED" +echo +if [ "$RESULT" -eq 0 ] && [ "$OUTPUT" = "$EXPECTED" ]; then + echo ✅ +else + echo ❌ + EXIT=1 +fi + +exit $EXIT diff --git a/openapi.proxy/README.md b/openapi.proxy/README.md index 835536bd..23bb3ec3 100644 --- a/openapi.proxy/README.md +++ b/openapi.proxy/README.md @@ -19,7 +19,7 @@ docker compose up -d ## Test ```bash -curl --location 'http://localhost:7114/pets' --header 'Accept: application/json' +curl 'http://localhost:7114/pets' --header 'Accept: application/json' ``` ## Teardown diff --git a/sse.jwt/README.md b/sse.jwt/README.md index ee85fe05..76d875fc 100644 --- a/sse.jwt/README.md +++ b/sse.jwt/README.md @@ -4,7 +4,7 @@ Listens on https port `7143` and will stream back whatever is published to `sse_ ## Requirements -- jq, nc +- nc - Compose compatible host - [jwt-cli](https://github.com/mike-engel/jwt-cli) diff --git a/sse.kafka.fanout/README.md b/sse.kafka.fanout/README.md index ed1d6d32..f4a430db 100644 --- a/sse.kafka.fanout/README.md +++ b/sse.kafka.fanout/README.md @@ -4,7 +4,6 @@ Listens on http port `7114` or https port `7114` and will stream back whatever i ## Requirements -- jq, nc - Compose compatible host - sse-cat diff --git a/tcp.echo/README.md b/tcp.echo/README.md index e2e91aa0..74415b35 100644 --- a/tcp.echo/README.md +++ b/tcp.echo/README.md @@ -4,7 +4,7 @@ Listens on tcp port `12345` and will echo back whatever is sent to the server. ## Requirements -- jq, nc +- nc - Compose compatible host ## Setup diff --git a/tcp.reflect/README.md b/tcp.reflect/README.md index d98ba991..a62e5c8c 100644 --- a/tcp.reflect/README.md +++ b/tcp.reflect/README.md @@ -4,7 +4,7 @@ Listens on tcp port `12345` and will echo back whatever is sent to the server, b ## Requirements -- jq, nc +- nc - Compose compatible host ## Setup diff --git a/tls.echo/README.md b/tls.echo/README.md index 906886f8..6426cceb 100644 --- a/tls.echo/README.md +++ b/tls.echo/README.md @@ -4,7 +4,6 @@ Listens on tls port `23456` and will echo back whatever is sent to the server. ## Requirements -- jq, nc - Compose compatible host - openssl diff --git a/tls.reflect/README.md b/tls.reflect/README.md index e5b961e1..6e3c697c 100644 --- a/tls.reflect/README.md +++ b/tls.reflect/README.md @@ -4,7 +4,6 @@ Listens on tls port `23456` and will echo back whatever is sent to the server, b ## Requirements -- jq, nc - Compose compatible host - openssl diff --git a/ws.echo/README.md b/ws.echo/README.md index f1bbf89e..eeba0e84 100644 --- a/ws.echo/README.md +++ b/ws.echo/README.md @@ -5,7 +5,6 @@ Listens on wss port `7114` and will echo back whatever is sent to the server. ## Requirements -- jq, nc - Compose compatible host - wscat diff --git a/ws.reflect/README.md b/ws.reflect/README.md index e07d32f8..af3b793f 100644 --- a/ws.reflect/README.md +++ b/ws.reflect/README.md @@ -4,7 +4,6 @@ Listens on ws port `7114` and will echo back whatever is sent to the server, bro ## Requirements -- jq, nc - Compose compatible host - wscat