Solution protype: just a couple of .net5.0 console apps:
- DataGenerator simulates your very lucrative upstream system that feeds RabbitMQ broker with a huge amount of PurchaseOrder messages.
- Daemon provides message consuming capbabilities with at-least-once semantics: within its UOW data are atomically persisted to Cassandra host. A pretty common scenario indeed.
For my fellow diagram lovers..
Used LCOW ( linux container on windows ) to keep the a minimal footprint on host resources.
Minimal requirements(for a Windows OS machine):
- .net5.0 sdk
- Docker for windows wsl2 mode
&.\run-demo.ps1
- Prepare environment:
docker network create demo
docker-compose `
-f .\rabbitmq.docker-compose.yml `
-f .\cassandra.docker-compose.yml `
up -d
This will enable:
- a RabbitMQ container [rabbitmq]:
- with admin plugin available at http://localhost:15674/Fulfillment with default credentials( guest:guest )
- listening on [rabbitmq:5672] for tcp connections
- a Cassandra container on [cassandra]
- listening on default port - 9042
- with default credentials ( cassandra:cassandra )
- with the defined fulfillment keyspace
It can take a while for cassandra initialization complete...
- Run consuming application ( scaled to 2 containers to provide competing consuming scenario):
- a few locs consumer
- bound to daemon:purchase-order queue
- with dlx enabled
start powershell {
docker-compose -f .\daemon.docker-compose.yml --compatibility up --scale daemon=2
}
- Run data generator
start powershell {
docker-compose -f .\datagenerator.docker-compose.yml up
}
- View our data on cassandra
docker exec cassandra cqlsh -e "select json * from fulfillment.orders;"
docker-compose `
-f .\rabbitmq.docker-compose.yml `
-f .\cassandra.docker-compose.yml `
-f .\daemon.docker-compose.yml `
-f .\datagenerator.docker-compose.yml `
down
docker network demo rm
Well...
Definitely this was my main goal since the beginning, hence infrastructure dependencies are spun up(setup)/down(teardown) for every test cycle - thanks to FluentDocker creator for such an OSS contribution.
Integration tests run within the CI context and locally - but with a different approach.
- Locally - through looback ip binding:
- Debug from within VS ( 'Local' configuration)
- Run from cli using the following snippet:
dotnet test Demo.sln -c Local
Within a conteinerized contex you have to use the 'Debug' configuration that refers to hostnames - resolved within the network boundaries.
For major convenience I provided a docker-out-of-docker environment where you can play the full CI flow.
run-ci.sh
Refer to Make.ps1 for details on tasks and available options.
Worth to notice, we're creating windows artifacts from a linux box :)