-
Install
protoc
compiler# brew install protoc
-
Install go plugins for protoc
Make sure to call the following command in this directory (to make sure the protoc generators are installed globally and not added to a
go.mod
file of an individual microservice):# go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28 # go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3
After that, follow the individual development instructions for each microservice.
Build and run the docker containers:
# docker compose up --build
Shut down the docker containers:
# docker compose down
First, you have to get an Auth token by calling:
payload="{\"client_id\":\"9l4Fp3tK9mtRGSdS8WdSVHiE8QFToMOD\",\"client_secret\":\"$CLIENT_SECRET\",\"audience\":\"http://localhost:8000\",\"grant_type\":\"password\",\"username\":\"$API_USERNAME\",\"password\":\"$API_PASSWORD\"}"
TOKEN=$(curl --request POST --url https://dev-elymxg0u.us.auth0.com/oauth/token --header 'content-type: application/json' --data "$payload" | jq -r .access_token)
The token that will be returned, has to be used in the private API calls below.
To get the credentials, you have to configure an application in your Auth0 account.
# curl -H "Content-Type: application/json" -d '{"name":"Covid","organizerName":"Martin","donationMinimum":2,"targetAmount":100,"account":{"name":"Martin","bankName":"DKB","number":"123456"}}' localhost:8000/campaign --header "authorization: Bearer $TOKEN"
To check if the campaign was persisted, call:
# docker exec -it myaktion-go_mariadb_1 mysql -uroot -proot -e 'USE myaktion; SELECT * FROM campaigns'
To retrieve all the persisted campaign objects, send this GET request:
# curl localhost:8000/campaigns
For retrieving just a specific campaign, append the campaign's ID. E.g. for retrieving the campaign with ID 1, call:
# curl localhost:8000/campaigns/1
The following command deletes the campaign with ID 1:
# curl -X DELETE localhost:8000/campaigns/1 --header "authorization: Bearer $TOKEN"
The following command updates the campaign with ID 1:
# curl -X PUT -H "Content-Type: application/json" -d '{"name":"Corona","organizerName":"Marcus","donationMinimum":2,"targetAmount":100,"Account":{"Name":"Marcus","BankName":"DKB","Number":"123456"}}' localhost:8000/campaigns/1 --header "authorization: Bearer $TOKEN"
This command adds a donation to the campaign with ID 1:
# curl -H "Content-Type: application/json" -d '{"Amount":20,"donorName":"Martin","receiptRequested":true,"status":"IN_PROCESS","account":{"name":"Martin","bankName":"DKB","number":"123456"}}' localhost:8000/campaigns/1/donation
To test the retry mechanism, we have to send a lot of transactions. In one terminal run:
# docker compose down && docker compose up --build > compose.log
In another just show the error logs of docker compose:
# tail -f compose.log | grep "level=error"
And in a third terminal, first create a new campaign:
# curl -H "Content-Type: application/json" -d '{"name":"Covid","organizerName":"Martin","donationMinimum":2,"targetAmount":100,"account":{"name":"Martin","bankName":"DKB","number":"123456"}}' localhost:8000/campaign
And then continuously send new donations to it:
# while sleep 0.1; do curl -H "Content-Type: application/json" -d '{"Amount":20,"donorName":"Martin","receiptRequested":true,"status":"IN_PROCESS","account":{"name":"Martin","bankName":"DKB","number":"123456"}}' localhost:8000/campaigns/1/donation; done
Look for the strings "Requeuing transaction" and "Requeued transaction"
Now, we're scaling the banktransfer service:
# docker compose down && docker compose up --build --scale banktransfer=2
After adding a campaign:
# curl -H "Content-Type: application/json" -d '{"name":"Covid","organizerName":"Martin","donationMinimum":2,"targetAmount":100,"account":{"name":"Martin","bankName":"DKB","number":"123456"}}' localhost:8000/campaign
We do a couple of donations by calling:
# curl -H "Content-Type: application/json" -d '{"Amount":20,"donorName":"Martin","receiptRequested":true,"status":"IN_PROCESS","account":{"name":"Martin","bankName":"DKB","number":"123456"}}' localhost:8000/campaigns/1/donation
If we're using the Kafka version, all donations are processed as the messages are shared between banktransfer instances.
If we're using the version based on Go channels, the result is that only about half of all donations are processed.
This happens if the transaction monitor (myaktion/monitor.go
) is connected to another instance of the banktransfer service
as the AddDonation
method (maktion/service/donation.go
).
Then the goroutine in the processTransaction
method (banktransfer/service/banktransfer.go
) is waiting endlessly for
the goroutine in ProcessTransactions
to receive the transaction. That won't happen as the goroutine is running
in another service instance.
-
Locally build the docker images
# docker compose build
-
Install application on K8S
# kubectl apply -f ./kubernetes-manifests
-
Forward port 8000 of myaktion to local port 8000
# kubectl -n myaktion port-forward service/myaktion 8000
-
Watch logs of banktransfer service (dedicated terminal)
# kubectl logs -f -n myaktion -l run=banktransfer
-
Watch logs of myaktion service (dedicated terminal)
# kubectl logs -f -n myaktion -l run=myaktion
Then you can use curl to test the application as described above. Once you're finished, you can delete the application by calling:
# kubectl delete ns myaktion