.Net 6, RabbitMq, MsSQL, MediatR, Swagger, Docker, Redis Cache
React, Material UI, React-Redux, Redux, Redux-Thunk
Kubernetes, Azure AKS, EKS, Azure SQL Server
Microservices architecture, event driven architecture, CQRS, event sourcing, clean architecture, unit tests
- The football clubs do not have a permanent home stadiums and can be reassigned to a new stadium before the beginning of each season.
- Multiple events will be generated and possibly the event processors / consumers might take long to process hence why the use of an event bus.
- An Event is generated when a football player is transferred between teams.
- An Event is generated when linking a football team to a stadium.
- Update documentation (On going)
- Distributed Caching with Redis Cache (95% complete)
- The PlayerTransferCreatedEvent and LinkToStadiumCreatedEvent implementation was added as an example of event sourcing. The PlayerAddedEvent, StadiumAddedEvent and FootballClubAddedEvent events implementation is still outstanding.
- Configure frontend client application and bff to communicate via https.
- Add a security micro service
- Add Kubernetes support
- Add centralised logging and health checks
- Create pipelines on GitLab.
- Make use of Azure SQL Server, AWS MS SQL Server
- Deploy to Azure AKS and AWS EKS
- Add more unit tests
- Add functional tests and integration tests
Redis is an in-memory data structure store, used as a distributed, in-memory key–value database, cache and message broker, with optional durability[4]. Redis supports different kinds of abstract data structures, such as strings, lists, maps, sets, sorted sets, HyperLogLogs, bitmaps, streams, and spatial indices[4].
Kubernetes is an open-source container-orchestration system for automating computer application deployment, scaling, and management[5]. It was originally designed by Google and is now maintained by the Cloud Native Computing Foundation[5].
The way states are managed in a web application (session persistence) has an impact on the load balancing configuration and scalability.
Non sticky persistence: in the case that the session state is saved in a distributed cache or database (e.g. Redis Cache). The load balancer can route requests to any web server that has access to that distributed cache.
Sticky persistence: in the case that the session state is saved in an in-memory cache which is an in-process memory state in the web server. The load balancer must route the requests or traffic from the client to a specific web server that saved its session state.
A distributed cache service was added to keep track of each application client's state. Only the current state of the client is saved in Redis cache.
The entities FootballClubStadium and PlayerTransfer are actually event logs or history data and are not meant to be deleted. Each event must have a date occurred or CreatedDate property.
A property IsCurrent will also be added to each event and therefore another update old event implementation is needed to set IsCurrent to false before adding a new event.
public class FootballClubStadium
{
...
public DateTime DateCreated { get; set;}
public bool IsCurrent { get; set; }
}
public class PlayerTransfer
{
...
public DateTime DateCreated { get; set;}
public bool IsCurrent { get; set; }
}
docker tag soccafootballclubstadium mandavadev/soccafootballclubstadium:1.0.0
- Simply click the run button in Visual Studio 2019. Please see button encircled in an orange oval in the image below.
FootballClub: https://localhost:44301/swagger/index.html
Players: https://localhost:44328/swagger/index.html
FootballClubStadium: https://localhost:44350/swagger/index.html
PlayerTransfers: https://localhost:44370/swagger/index.html
Stadium: https://localhost:44309/swagger/index.html
Distributed Cache: https://localhost:44305/swagger/index.html
UI Web: https://localhost:44358/
Migrations have already been created for you however to create migration (from the directory src/Microservices/FootballClub/Api/Socca.FootballClub.Api)run the following command:
dotnet ef migrations add InitialMigration --context footballclubdbcontext -p ../../Data/Socca.FootballClub.Data/Socca.FootballClub.Data.csproj -s Socca.FootballClub.Api.csproj -o Migrations
Migrations have already been created for you however to create migration (from the directory src/Microservices/FootballClubStadium/Api/Socca.FootballClubStadium.Api) run the following command:
dotnet ef migrations add InitialMigration --context footballclubstadiumdbcontext -p ../../Data/Socca.FootballClubStadium.Data/Socca.FootballClubStadium.Data.csproj -s Socca.FootballClubStadium.Api.csproj -o Migrations
Migrations have already been created for you however to create migration (from the directory src/Microservices/Players/Api/Socca.Players.Api) and run the following command:
dotnet ef migrations add InitialMigration --context playerdbcontext -p ../../Data/Socca.Players.Data/Socca.Players.Data.csproj -s Socca.Players.Api.csproj -o Migrations
Migrations have already been created for you however to create migration (from the directory src/Microservices/PlayerTransfers/Api/Socca.PlayerTransfers.Api) and run the following command:
dotnet ef migrations add InitialMigration --context playertransferdbcontext -p ../../Data/Socca.PlayerTransfers.Data/Socca.PlayerTransfers.Data.csproj -s Socca.PlayerTransfers.Api.csproj -o Migrations
Migrations have already been created for you however to create migration (from the directory src/Microservices/Stadium/Api/Socca.Stadium.Api) run the following command:
dotnet ef migrations add InitialMigration --context stadiumdbcontext -p ../../Data/Socca.Stadium.Data/Socca.Stadium.Data.csproj -s Socca.Stadium.Api.csproj -o Migrations
<!-- REMOVE OR COMMENT OUT THE CLIENT APP TAGS BELOW DURING DOCKERINZING -->
<ItemGroup>
<None Remove="ClientApp\src\constants\" />
</ItemGroup>
<Target Name="DebugEnsureNodeEnv" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('$(SpaRoot)node_modules') ">
<!-- Ensure Node.js is installed -->
<Exec Command="node --version" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
</Exec>
<Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
</Target>
<Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run build" />
<!-- Include the newly-built files in the publish output -->
<ItemGroup>
<DistFiles Include="$(SpaRoot)build\**" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
rabbitmqctl stop_app
rabbitmqctl start_app
rabbitmqctl reset
rabbitmqctl add_user test test
rabbitmqctl set_user_tags test administrator
rabbitmqctl set_permissions -p / test "." "." ".*"
List all images:
docker images
List all containers:
docker ps
Delete every Docker containers:
docker-compose down
Remove all docker containers:
docker rm -f $(docker ps -a -q)
Delete a docker container with CONTAINER ID 10e62ea29d83:
docker rm –f 10e62ea29d83
Delete all docker images:
docker rmi -f $(docker images -q)
Delete a docker image with IMAGE ID 870fda08c907:
docker rmi –f 870fda08c907
Build your application:
docker-compose build
Run your application: docker-compose up
You might be prompted to create a network. Create a network by running the following command:
docker network create soccanet
To use secretes run the following command in the project directory
dotnet user-secrets init
docker pull rabbitmq
docker run --name rediscache -p 5090:6379 -d redis
docker start rediscache
docker exec -it rediscache redis-cli
Pull MSSQL docker image:
sudo docker pull mcr.microsoft.com/mssql/server:2019-latest
Run MSSQL docker image:
sudo docker run -d --name Mssqldb -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Password2021' -p 1433:1433 mcr.microsoft.com/mssql/server:2019-latest
- Introducing CQRS, The Microsoft Press Store by Pearson [https://www.microsoftpressstore.com/articles/article.aspx?p=2248809&seqNum=3]
- [https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-docker-container-deployment?view=sql-server-ver15&pivots=cs1-bash]
- [https://www.nginx.com/resources/glossary/load-balancing/]
- [https://en.wikipedia.org/wiki/Redis]
- [https://en.wikipedia.org/wiki/Kubernetes]
- [https://www.freecodecamp.org/news/how-to-deploy-react-apps-to-production/]