Challenge 3 - Dapr Pub/Sub Messaging
October 10, 2023 ยท View on GitHub
< Previous Challenge - Home - Next Challenge >
Introduction
In this challenge, you're going to add Dapr publish/subscribe messaging to send messages from the TrafficControlService to the FineCollectionService.
Description
In challenge 2, you implemented direct, synchronous communication between two microservices. This pattern is common when an immediate response is required. Communication between services doesn't always require an immediate response.
The publish/subscribe pattern allows your microservices to communicate asynchronously with each other purely by sending messages. In this system, the producer of a message sends it to a topic, with no knowledge of what service(s) will consume the message. A message can even be sent if there's no consumer for it.
Similarly, a subscriber or consumer will receive messages from a topic without knowledge of what producer sent it. This pattern is especially useful when you need to decouple microservices from one another. See the diagram below for an overview of how this pattern works with Dapr:
You will need to modify the services to use the Dapr pub/sub building block.
- Start up a RabbitMQ pub/sub message broker in a Docker container.
- Create a Dapr configuration file for specifying the pub/sub Dapr components.
- Modify the
TrafficControlService(TrafficControllerclass) so it sendsSpeedingViolationmessages using the Dapr pub/sub building block. - Restart all services & run the
Simulationapplication. - Once you have the above working, replace the RabbitMQ message broker with Azure Service Bus (using topics) by only changing the Dapr configuration file.
Optional if re-implementing FineCollectionService using Dapr .NET SDK
- Modify the
FineCollectionService(CollectionControllerclass) so it receivesSpeedingViolationmessages using the Dapr pub/sub building block and unwraps it from the CloudEvents message format.
Success Criteria
This challenge targets the operations labeled as number 2 in the end-state setup:
- Validate that the RabbitMQ message broker is running.
- Validate that messages are being sent from the
TrafficControlServiceto theFineCollectionServiceusing Dapr, not direct service invocation. - Validate that messages are being received & consumed from the Azure Service Bus via topics.
Tips
- Start a container instance of a RabbitMQ message broker by entering the following command:
docker run -d -p 5672:5672 -p 15672:15672 --name dtc-rabbitmq rabbitmq:3-management - RabbitMQ provides a built-in dashboard that presents messaging activity, logging, and performance metrics. Open a browser and navigate to http://localhost:15672/. Both the login name is
guestand the password isguest. Shown below, the dashboard is helpful for troubleshooting RabbitMQ anomalies:
- See the TrafficControl Application & Services Description for the port numbers used by the services.
- Put your Dapr configuration files in the
Resources/dapr/componentsdirectory (you will see some existing files related to the Azure Kubernetes Service deployment in Challenge-08, you can ignore these for now and put your files here as well) - You will need to specify the directory where you provide the custom Dapr configuration files when running the Dapr sidecars.
dapr run ... --resources-path ../dapr/components -- dotnet run - You can either use declarative or `programmatic subscriptions to subscribe to a topic. See the Dapr documentation for more information. Declarative is simpler for this example.
- Use Zipkin to observe the messages flow as specified in Challenge-02.
Specific info for using the Dapr .NET SDK for programmatic subscriptions (not needed unless implementing SpeedingViolation using Dapr .NET SDK)
- Dapr wraps pub/sub messages inside the open-source CloudEvents message format. Upon receipt, the subscriber must transform the message to a CloudEvent. You must manually parse the incoming JSON and convert to a
SpeedingViolationclass.- The parameter type for receiving these CloudEvents message format is:
[FromBody] System.Text.Json.JsonDocument cloudEvent. - Key/value pairs can be extracted from the JSON document by using the following C#:
cloudEvent.RootElement.GetProperty("data").GetProperty("vehicleId").GetString()
- The parameter type for receiving these CloudEvents message format is: