Class project
To run with Docker:
docker-compose up -d
- visit http://localhost:5015
To run using Aspire, also requires docker, and .net 9.0 (all platforms):
% dotnet workload restore
(only once)% dotnet build
% dotnet test
% dotnet run --project Applications/commute-planner.AppHost
CI/CD deployed to:
(https://github.com/joshwyant/commute-planner/actions/workflows/azure-dev.yml)
Apps:
- Orchestrated through Docker, Aspire (AppHost), or Azure
- Web App: Home page - select a popular route, see a description and whether transit or driving is faster; Routes - see the featured routes
- DataFetcher app collects data from https://511.org and Google Maps REST APIs, upon a freshness request message.
- DataProcessor app periodically sends message to DataFetcher app, which then sends message with the fresh data recieved. DataProcessor analyzes, combines, and persists the transformed data to be efficiently retrieved.
- ApiService provides a REST API for the Web front-end to consume, acting as an interface to the database.
- AppHost - handles Aspire orchestration and deployment, as well as a dashboard, logs, and graphs. Provides interfaces to Azure Insights and OpenTelemetry for production monitoring and instrumenting used by logging throughout.
- RabbitMQ is deployed and connected by the Aspire library as a container for messaging.
- PostgreSQL is deployed and connected by the Aspire library as a container for the data store, which is an ACID database, since the data is small, structured, and transactional.
Components:
- ApiClient - used by the Web app as a model and interface to the REST API.
- DataCollection - the logic for how to fetch new third party transportation data, along with communication with the data processor app.
- DataProcessing - the logic for how to analyze, combine, and store the transformed data, as well as for signaling to the DataFetcher app.
- EventCollaboration - Tools and extensions used to handle the bulk of the message queueing work and interfaces with RabbitMQ.
- MapsApiClient - An implementation of the interface to the Routes REST API that Google Maps exposes.
- ServiceDefaults - Configures the orchestration of the distributed app using Aspire.
- TransitApiClient - An implementation of the interface to the part of the 511 Transit REST API that is exposed and used by the app.
- TransitApiModels - Models shared by the data fetcher and transit API.
Tests:
- Integrated into the build and deploy process. Uses Nunit for Unit tests, Moq for mocks and spies, and Aspire to handle the orchestration for integration testing
- Fake Google Maps server
- Fake Transit API server
- Separate folders
Database
- Uses Entity Framework for the Object Relational Mapping, Aspire for orchestration, and PostgreSQL for persistence.
Continuous integration/Continuous Delivery
- On each commit to main, triggers GitHub Actions (.github/) to prepare .NET environment, install build tools, build, test, and deploy to Azure as a cohesive Web App composed of containerized apps and services. Uses Azure Secrets to store real API keys, production passwords, etc.