- RabbitMQ
- MassTransit
- Docker / Docker Compose
- Logging - A custom Logger implementation can be found in
./common/loggingwhich provides additional extension methods for theMicrosoft.Extensions.Logging.ILoggerand utilizes the compile time Caller Information Attributes to add the member name, file path and line number to every log. You can configure your own logging provider e.g. Log4Net or Serilog (an example for NLog has been included in./common/logging/MicroService.Logging.NLog). - Encryption Service - To demonstrate an end-to-end example, an encryption service is included and builds upon an idea discussed on StackOverflow to create a random SALT (if ommitted) and append it to the encrypted string. You can of course include a SALT value, or implement your own SALT'ing strategy. An encryption key is always required.
Important
The Encryption service serves as an example and is something I have been experimenting with. Make sure to follow recommended guidance when selecting and using services in your own Micro Service infrastructure.
- Install the 'Docker' extension for VSCode.
- Install the 'C#' extension for VSCode.
- Install the 'C# Dev Kit' extension for VSCode.
- Clone the repository and open with Visual Studio Code.
- If you don't already have a Docker environment set up on your local machine, follow the guide below starting from the
Install Ubuntu on WSL2section through to the end of the ReadMe. - Create a RabbitMQ login following the steps provided below.
- Update the RabbitMQ hostname following the steps provided below.
- Debug and Test using the steps provided in the sections below.
-
Open the repository in VSCode.
-
Build and run the RabbitMQ container image from a VSCode terminal:
docker-compose up -d --build rabbitmq -
Open the Docker pane in the VSCode sidebar.
-
Right click the
microservice.rabbitmq:debugcontainer and click 'Attach Shell'. -
In the terminal window that opens, generate a password hash for the
adminandbrokeruser accounts:rabbitmqctl hash_password <your_unencrypted_password> -
Update the password_hash for the
adminandbrokeruser accounts in./containers/rabbitmq/config/definitions.json. -
Update the RABBITMQ__PASSWORD value with the unencrypted
brokerpassword in the.envfile in the root of the repository.
Important
These passwords are intended for local development only. Take care to avoid committing passwords into public and/or shared repositories and follow recommended guidance when deploying containers to other environments.
- Login to the Ubuntu on Windows application from the start menu e.g.
Ubuntu 22.04.3 LTS. - Get the IPv4 address for the eth0 adapter by running the
ifconfigcommand. - Update the RABBITMQ__HOSTNAME value with the IPv4 address inside the
.envfile in the root of the respository.
- Load the solution in VSCode.
- Switch to the
Run and Debugwindow. - Choose a Launch configuration in the dropdown list.
- Click the play icon to run the project.
- You can add breakpoints in the source code and step through the code.
- Logs are written to the debug console using the included logging library in
common/logging.
Note
If you haven't already, run the installer for the VSDebugger image in the VSCode terminal:
docker-compose up install.vsdbg.
RabbitMQ
- Open the RabbitMQ URL via:
http://localhost:15672
http://<ubuntu-eth0-ip>:15672 - Login using either the admin or broker account username and password.
Swagger
- Open the Swagger URL for the Producer via:
http://localhost:5000/swagger
http://<ubuntu-eth0-ip>:5000/swagger
Postman
- Example GET:
http://localhost:5000/api/Encryption/CheckEndpoint
http://<ubuntu-eth0-ip>:5000/api/Encryption/CheckEndpoint - Example POST:
http://localhost:5000/api/Encryption/EncryptString?encryptionMethod=1&value=test&key=abc123
http://<ubuntu-eth0-ip>:5000/api/Encryption/EncryptString?encryptionMethod=1&value=test&key=abc123
Unit Tests
- There are unit tests included in some areas (look for the Test projects in the folder tree), though you are welcome to expand on them.
- The Consumer project contains an integration test using the MassTransit Test Harness.
- DSL is a test pattern and stands for Domain Specific Language. There are builders to construct tests and they have been expanded to separate the SUTs (subject under test) into a separate class, as well as the assertions in some cases. Feel free to experiment with your own pattern(s).
Warning
The Moq nuget package has been used for the unit tests and uses a version prior to V4.20. It's recommend not to go beyond that version due to a decision by the author to include a closed source library which harvests email addresses. It's recommended to stick with older versions or to migrate to another mocking framework such as NSubstitute.
End-To-End Tests
- There is a webpage and WPF Desktop application in the accompanying repository.
The Producer API can be tested using a self-signed SSL certificate. An example of how the certificate is installed can be found in the SSL stage inside dockerfile.microservice-security-producer in the root of the repository.
- Edit the
.envfile in the root of the repository. - Set the ASPNETCORE_ENVIRONMENT value to either
DevelopmentorStaging. - Set the ASPNETCORE_URLS value to
https://+:5001orhttp://+:5000;https://+:5001(to enable both protocols). - Set the SSL_CERT_KEY value to a password of your choice.
- Open the Swagger URL for the Producer via:
https://localhost:5001/swagger
https://<ubuntu-eth0-ip>:5001/swagger - Use the https URL equivalents of those shown in the section above when using Postman (you may need to disbale SSL Certificate Validation in settings.)
Run in Powershell (Admin)
-
Install the VirtualMachinePlatform optional Windows feature.
i. Check Status:
Get-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatformii. Install:
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -NoRestart -
Install the WSL optional Windows feature.
i. Check Status:
Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linuxii. Install:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux -NoRestart -
Reboot.
-
Update the WSL Kernel.
i. Check the Kernel version pre-update:
wsl --statusii. Update WSL:
wsl --updateiii. Check the Kernel version post-update:
wsl --version -
Set the default version for new Linux installations to use WSL2.
wsl --set-default-version 2 -
Confirm the default version for new Linux installations.
wsl --status -
Show a list of any Linux distributions that are already installed.
wsl --list --verbose -
If you already have a distribution installed on WSL1 you can convert it to WSL2 e.g.
wsl --set-version Ubuntu-22.04 2 -
Show a list of the available distributions that can be installed.
wsl --list --online -
Install a distribution (recommended version Ubuntu-22.04).
wsl --install --distribution Ubuntu-22.04 -
During the installation:
- Enter a Unix username when prompted
- Enter a Unix password when prompted
-
Close PowerShell.
-
Login to the Ubuntu on Windows application from the start menu e.g.
Ubuntu 22.04.3 LTS. -
Install Docker by running each of the following commands in turn:
sudo apt-get updatesudo apt-get upgrade -ysudo apt install --no-install-recommends apt-transport-https ca-certificates curl gnupg2 -ycd ~curl -fsSL https://get.docker.com -o get-docker.shsudo sh get-docker.shsudo usermod -aG docker $USERecho "export DOCKER_HOST=tcp://localhost:2375" >> ~/.bash_profilesudo rm get-docker.sh -
Install Docker Compose.
i. Check to see if it is already installed:
docker compose versionii. Install using the package handler:
sudo apt-get install docker-compose-plugin -y -
Disable Docker from running on system startup.
i. Get the task names for the Docker service:
systemctl list-unit-files | grep -i dockerii. Disable the tasks found by the command above e.g:
sudo systemctl disable docker.servicesudo systemctl disable docker.socketiii. Confirm that the task STATE has been set to disabled:
systemctl list-unit-files | head -1; systemctl list-unit-files | grep -i dockeriv. Restart Docker:
sudo systemctl restart docker -
Close Ubuntu on Windows.
-
Download the latest
Dockerbinaries from https://download.docker.com/win/static/stable/x86_64/. -
Create the directory
C:\Dockerand extract the files from the archive above into this folder. -
Limit the memory usage for WSL Linux distributions.
i. Check the current memory/swap usage in Ubuntu:
free -mii. Create file
C:\Users\<UserName>\.wslconfigwith the following content:# Settings apply across all Linux distros running on WSL 2 [wsl2] memory=12GB processors=4 swap=4GB -
Disable Windows
PATHon WSL.i. Either, from the Ubuntu terminal:
echo -e "[interop]\nappendWindowsPath = false" | sudo tee -a /etc/wsl.confii. Or, by manually editing the wsl config file in Ubuntu:
sudo nano /etc/wsl.confInsert the following section:
[interop] enabled=false appendWindowsPath=false -
Download the
Docker Composebinary.i. Either, using PowerShell as Admin (update the source url below with the latest version number):
Start-BitsTransfer -Source "https://github.com/docker/compose/releases/download/v2.23.3/docker-compose-windows-x86_64.exe" -Destination C:\Docker\docker-compose.exeii. Or, by manually downloading:
- Find the latest version via https://github.com/docker/compose/releases.
- Click the download link for the
docker-compose-windows-x86_64.exebinary under theAssetsheading. - Move the downloaded file to folder
C:\Dockerand rename the file todocker-compose.exe.
-
Open the
System Environment Variablesdialog in Windows and add the following entries:Action System Variable Value Description Edit PATH C:\Docker Register location of Docker.exe for Windows. Add DOCKER_HOST tcp://localhost:2375 Exposes the url that Docker is listening to in Ubuntu. -
Verify that
Dockeris accessible through the terminal by running the following command in PowerShell:dockerd --version -
Verify that
Docker Composeis accessible through the terminal by running the following command in PowerShell:docker-compose --version
This process is the same every time you want to start docker on your environment:
- Login to the Ubuntu on Windows application from the start menu e.g.
Ubuntu 22.04.3 LTS. - Enter the following command in the Ubuntu terminal:
sudo dockerd -H localhost
The -H flag will start the Docker daemon and attach to the process to show it's output. If the daemon is already running you cannot attach to the ouput of the process directly. Either, stop and then start the daemon with the -H flag or inspect the log files to view the processes output.
-
Check if the Docker daemon is already running.
sudo systemctl status docker -
Stop the Docker service.
sudo systemctl stop docker -
Kill a hung Docker service.
i. Get the process ID (PID):
ps -ef | grep dockerii. Kill the process:
kill <process_id> -
Start Docker with the -H flag.
sudo dockerd -H localhost -
Inspect logs using any of these approaches.
i. Using Journalctl (systemd):
journalctl -u docker.serviceii. View the Docker daemon's logs in real-time:
docker logs <container_name_or_id>iii. Using Tail:
tail -f /var/log/docker.log