This lab shows a common async implementation drift problem: the AsyncAPI contract already describes retry and dead-letter behavior, but the service does not fully handle the retry and DLQ behavior.
Your job is to fix the service so it matches the retry and DLQ behavior already described in the contract and examples.
Run the async contract tests, observe the intentional failure, update the Python provider so it handles retry and DLQ correctly, and verify a passing run.
15-20 minutes.
- Docker is installed and running.
- You are in
labs/kafka-sqs-retry-dlq. - Ports
4566,9092,9000, and9001are free.
.specmatic/repos/labs-contracts/asyncapi/kafka-sqs-retry-dlq/order-service-sqs-kafka.yaml- AsyncAPI contract that already declares success, retry, and DLQ behaviorspec/order-service-sqs-kafka_examples/- externalized examples for success, retry-success, retry-to-DLQ, and direct-to-DLQ flowsservice/app.py- Python provider implementation with an intentional retry bugspecmatic.yaml- Specmatic async test configurationdocker-compose.yaml- LocalStack, Kafka, provider, contract test runner, and optional Studio
- Do not edit: the contract in
.specmatic/repos/labs-contracts/asyncapi/kafka-sqs-retry-dlq/order-service-sqs-kafka.yaml,specmatic.yaml,docker-compose.yaml, or any file underspec/order-service-sqs-kafka_examples/. - Edit only:
service/app.py. - Do not change the contract or the examples. In this lab, the service behavior is incomplete and must be fixed.
- Contract test runner:
contract-test - Provider under test:
provider - Supporting components: Kafka and LocalStack SQS
Flow:
- Specmatic publishes a message to
place-order-topicbased on thereceivepayload in the examples. - The python service transforms successful messages and emits another message on the
place-order-queue. - Some messages intentionally fail once, always fail, or fail non-retryably.
- Failed messages are published to
place-order-retry-topicorplace-order-dlq-topic. - Based on the scenario, Specmatic validates if correct numbers of messages with the right schema validations have
arrived on required channels to ensure the actual async flow matches the declared behavior in the AsyncAPI contract.
Why the baseline fails:
- The contract and examples already describe the retry and DLQ flows.
- The python service handles the normal success path and the direct-to-DLQ path.
- The retry pipeline is incomplete, so messages published to the retry topic are never reprocessed.
- Because of that, the retry-success and retry-to-DLQ scenarios fail at runtime.
docker compose up contract-test --build --abort-on-container-exitExpected failure shape:
- The normal success scenarios pass.
- The direct-to-DLQ scenario also passes.
- The retry-success and retry-to-DLQ scenarios fail because the provider never consumes retry messages.
Preferred failure summary:
Tests run: 6, Successes: 4, Failures: 2, Errors: 0
The failing scenarios should be:
Retry_Scenario_Standard_OrderReceive_Retry_DLQ_Scenario_Priority_Order
Clean up before making changes:
docker compose down -vUpdate service/app.py so the provider matches the retry and DLQ behavior already declared in the contract.
You need to fix one behavior:
- retry messages published to
place-order-retry-topicmust actually be consumed and reprocessed
In service/app.py, inspect the bridge startup code.
What to look for:
- the app should start both the main consumer and the retry consumer threads
- there is a lab hint comment above the disabled retry-consumer thread
- the intended fix is to uncomment the
RetryConsumerthread entry inself.threads
Do not change the contract, examples, or Compose wiring.
Re-run:
docker compose up contract-test --build --abort-on-container-exitExpected passing output:
Tests run: 6, Successes: 6, Failures: 0, Errors: 0
The message count report should show:
| Topic/queue name | Actual | Expected |
| place-order-topic | 6 | 6 |
| place-order-queue | 4 | 4 |
| place-order-retry-topic | 2 | 2 |
| place-order-dlq-topic | 2 | 2 |
Clean up:
docker compose down -vdocker compose --profile studio up studio --buildOpen Studio, load specmatic.yaml, and run the suite. The contract will be checked out under .specmatic/repos/labs-contracts/asyncapi/kafka-sqs-retry-dlq/order-service-sqs-kafka.yaml if you want to inspect it in the left panel.
Stop Studio:
docker compose --profile studio down -vport is already allocated: Free4566,9092,9000, and9001, then retry.- The suite still fails after fixing
app.py: Bring the stack down withdocker compose down -vand run again so Kafka and LocalStack state is reset. - Retry scenario still never reaches SQS:
Check that the retry consumer thread is started and polling
place-order-retry-topic. - First run is slow: The initial image pull and container startup can take longer than later runs.
If you are doing this lab as part of an eLearning course, return to the eLearning site and continue with the next module.
