The traffic-control application architecture consists of four microservices:
/entrycam
and /exitcam
./collectfine
for collecting fines./getvehicleinfo/{license-number}
for retrieving vehicle and owner information of a vehicle.These services compose together to simulate a traffic control scenario.
The following sequence diagram describes how the application works:
Simulation
generates a random license plate number and sends a VehicleRegistered message (containing this license plate number, a random entry-lane (1-3) and the timestamp) to the /entrycam
endpoint of the TrafficControlService
.TrafficControlService
stores the VehicleState (license plate number and entry-timestamp).Simulation
sends a follow-up VehicleRegistered message to the /exitcam
endpoint of the TrafficControlService
. It contains the license plate number generated in step 1, a random exit-lane (1-3), and the exit timestamp.TrafficControlService
retrieves the previously-stored VehicleState.TrafficControlService
calculates the average speed of the vehicle using the entry and exit timestamp. It also stores the VehicleState with the exit timestamp for audit purposes, which is left out of the sequence diagram for clarity.TrafficControlService
calls the /collectfine
endpoint of the FineCollectionService
. The request payload will be a SpeedingViolation containing the license plate number of the vehicle, the identifier of the road, the speeding-violation in KMh, and the timestamp of the violation.FineCollectionService
calculates the fine for the speeding-violation.FineCollectionService
calls the /vehicleinfo/{license-number}
endpoint of the VehicleRegistrationService
with the license plate number of the speeding vehicle to retrieve vehicle and owner information.FineCollectionService
sends a fine notice to the owner of the vehicle by email.All actions described in the previous sequence are logged to the console during execution so you can follow the flow.
Your coach will provide you with a Resources.zip
package file that contains the starting projects for the WhatTheHack. It contains a version of the services that use plain HTTP communication and store state in memory. With each challenge, you’ll add a Dapr building block to enhance this application architecture.
It’s important to understand that all calls between services are direct, synchronous HTTP calls using the HttpClient library in .NET Core. While sometimes necessary, this type of synchronous communication isn’t considered a best practice for distributed microservice applications. When possible, you should consider decoupling microservices using asynchronous messaging. However, decoupling communication can dramatically increase the architectural and operational complexity of an application. You’ll soon see how Dapr reduces the inherent complexity of distributed microservice applications.
As you complete the challenges, you’ll evolve the application architecture to work with Dapr and consume Azure-based backing services:
The following diagram shows the end-state of the application:
FineCollectionService
and VehicleRegistrationService
, you’ll implement the Dapr service invocation building block.FineCollectionService
, you’ll implement the Dapr publish and subscribe building block (asynchronous communication) with the Dapr Azure Service Bus component.TrafficControlService
, you’ll use the Dapr input binding for MQTT using Dapr Azure IoT Hub component as the MQTT broker.The following sequence diagram shows how the solution will work after implementing Dapr:
It’s helpful to refer back to the preceding sequence diagram as you progress through the challenges.
For most of the challenges, you’ll run the microservices in the solution on your local machine. To prevent port collisions, all services will listen on a different HTTP port. When running with Dapr, you need additional ports for HTTP and gRPC communication between the sidecar services. By default, these ports are 3500
and 50001
. However, you’ll use different port numbers for each service to prevent collisions. Please closely follow the instructions so that your microservices use the following ports for their Dapr sidecars:
Service | Application Port | Dapr sidecar HTTP port | Dapr sidecar gRPC port |
---|---|---|---|
TrafficControlService | 6000 | 3600 | 60000 |
FineCollectionService | 6001 | 3601 | 60001 |
VehicleRegistrationService | 6002 | 3602 | 60002 |
Use the ports specified in the preceding table whether using the DIY or step-by-step approach.
You’ll specify the ports from the command-line when starting a service with the Dapr CLI using the following command-line arguments:
--app-port
--dapr-http-port
--dapr-grpc-port