Web API Framework demonstrates scalable, multitenant, architecture and allows building its own solution in the minutes. Uses: Entity Framework, UnitOfWork, Repository patterns. Wrapped in Docker, Kubernetes
Web API Solution demonstrates mutliteantcy architecture, using Entity Framework, UnitOfWork,Repository patterns
Todo list, accomplished tasks, can be found Here.
Update-DataBase
.DefaultConnection
to ;Database=DeviceDb-ten2;
in appsettings.json
. Run EF migration Update-DataBase
. It will create another database.tenantConfigurationDictionary
).appsettings.json
.DatabaseType
field is used to specify the database type the application should connect.
Currently, the framework contains connection information for:
The value of DatabaseType
should come from DatabaseType
enum in Settings folder and should match the class name inside DatabaseTypes folder and implement IDatabaseType
interface.
To add a new database type, just add a class implementing IDatabaseType
and add the same name inside DatabaseType
and change connection string in the DefaultConnection
property and DatabaseType
to new database type.
Application supports localization support though resource files. Currently, shared resource file is used to support support for English
and German
languages.
According to (Microsoft docs), to use a UI culture pass it as a query parameter (ui-culture=de-DE
).
All the resource values for each UI culture should be added to a resource file under Resources folder. The file name should include culture code.
Text values from resource files based on the UI culture is obtained from using the instance of IStringLocalizer<SharedResource> sharedLocalizer
which is injected via constructor. Then use this object to get resource values using sharedLocalizer["ResourceKey"].Value
.
Check Ping
action in BaseController.
Note: If only one of culture
or ui-culture
is sent in the query parameter then dotnetcore
uses same value for the other one.
To seed database with initial data update SeedData
method in DataSeederclass.
There can be multiple data seeding classes. To create a new data seeding class:
DataSeeder
with new class name.Dapper is incorporated into the application. DapperUnitOfWork handles all the begin and commit transaction. The instance of Dapper Unit of work can be obtained by requesting instance of IDapperUnitOfWork.
DeviceService is using DapperUnitOfWork to fetch and create records in the database through DapperRepository. DapperRepository is a generic repository with built in methods for fetching and adding records into the database based on DapperInsert and DapperUpdate attributes defined on the Model. In the future update and delete will be implemented.
The DapperRepository builds generic insert
and fetch
using QueryBuilderHelper class based on the attributes defined on the model. For example Device model defines DapperInsert
on few properties. Only these property names will be considered while building insert query
.
The Dapper
region in the DeviceController uses Dapper to fetch and create records in the database.
App images available in Docker Hub Registry: https://hub.docker.com/r/boriszn/devicemanagerapi/ (LINUX and Windows images are available)
You can pull image:
docker pull boriszn/devicemanagerapi:1.0.4
docker pull boriszn/devicemanagerapi:latest
The solution was migrated to the docker container and support docker compose orchestration.
You can run docker using following options:
F5
) will run docker container.docker run -p 8080:80 --rm -d boriszn/devicemanagerapi:latest
will run docker container in background (or docker run -p 8080:80 boriszn/devicemanagerapi:latest
)You can access the the Web API locally via URL: http://localhost:8080
You can also Build container from solution. To do so run docker build -t boriszn/devicemanagerapi:1.0.4 .
or run it in VS.
IMPORTANT. To debug solution in Visual Studio replace file Dockerfile
with Dockerfile-VsDebug
file (or replace content of Dockerfile
from Dockerfile-VsDebug
) This is temporary work around to be able to run containers in command line and in Visual Studio. It will fixed (consolidated in one docker file) in upcoming PRs
To run/build project without docker, switch from Docker
to DeviceManagerApi
(specified in launchSettings.json
)
Bearer Authentication using IdentityServer4 is added to the application. The feature is enabled by default and can be turned off by removing the compiler switch UseAuthentication
under Build
tab in the project properties of bother DeviceManager.Api
and DeviceManager.Api.UnitTests
.
To use the authentication following two lines must be added to your hosts
file situated under c:\Windows\System32\Drivers\etc\
folder.
127.0.0.1 devicemanager.api
127.0.0.1 devicemanager.identityserver
IMPORTANT: Reason for adding the names to the hosts file is to use IdentityServer
authentication with or without docker-compose
Currently, a basic IdentityServer
with pre defined Clients, Users, ApiResourses
is added.
Config file defines two clients
Swagger Ui Client - Used to access the API resources using Swagger Ui
Test Client - Used to test the API end point by setting up Test Client.
TestUsers file contains two test users with predefined roles and tenants in claims.
The claims defined in the TestUsers file are used in the AuthenticationConfiguration file to grant access to the Api Resource.
services.AddAuthentication
handles the authentication and logic inside options.AddPolicy
handles the authorization part. There are 3 policies currently defined.
DefaultPolicy
This policy is executed when the controller
or action
contains [Authorize]
attribute like BaseController.
If the requesting user is having admin
role or the client is Test Client
from unit test then access to any resources beloging to any tenant is allowed.
But, if the user is neither of the above then access to only the Tenant
defined in the TenantClaim property is allowed.
Admin
This policy is executed when the controller
or action
is decorated with [Authorize(PolicyConstants.Admin)]
. So GetData
action in (AdminController)[src/DeviceManager.Api/Controllers/AdminController.cs] is accessed by users having admin
or manager
defined in their role
claims. In our predfined users only alice
can access the GetData
resource.
Manager
This policy is excuted when the controller
or action
is decorated with [Authorize(PolicyConstants.Manager)]
. Users with manager
in their role
claims.
v0.34.1
) (This article should help)minikube start --vm-driver=hyperv --hyperv-virtual-switch=testCluster
. My setup used Windows 10 Pro + Hyper-V Hypervisor)kubectl create -f ks-deployment.yaml
kubectl get deployments
kubectl expose deployment devicemanagerapi --type=NodePort
(as minikube doesn’t contain ingress/load balancer)minikube service devicemanagerapi --url
minikube dashboard
. Dashboard is displayed on image below.Or you can use This plugin for VS Code to manage/monitor minikube cluster
IMPORTANT: Ensure that you are switched to LINUX docker container. Because minikube support only LINUX based containers (at least v0.34.1
. In future it can be changed)
You can Setup Azure Container Registry or use docker hub.
devicemanagerreg
docker tag [image-id] devicemanagerreg.azurecr.io/boriszn/devicemanagerapi:1.0.4
docker push devicemanagerreg.azurecr.io/boriszn/devicemanagerapi:1.0.4
kubectl create secret docker-registry devicemanagerreg-connection --docker-server=devicemanagerreg.azurecr.io --docker-username=devicemanagerreg --docker-password=[ACR-Registry-Password] [email protected]
ServiceAccount.yaml
from Kubernetes.kubectl get serviceaccounts default -o yaml > ./serviceaccount.yaml
.imagePullSecrets
line to the end of service account file:....
imagePullSecrets:
- name: devicemanagerreg-connection
....
kubectl replace serviceaccount default -f ./serviceaccount.yaml
az aks get-credentials –resource-group [your-resource-group] –name [your-cluster-name]
).helm init
helm install stable/nginx-ingress –name devicemanagerreg-nginx –set rbac.create=false
kubectl get service -l app=nginx-ingress --namespace default
kubectl apply -f aks-deployment/ingress.yaml
.kubectl apply -f aks-deployment/ingress-service.yaml
kubectl apply -f aks-deployment/devicemanager-api-service.yaml
kubectl apply -f aks-deployment/aks-deployment.yaml
DeviceManager API should be accessible via public IP or with DNS name (FQDN).
Server
parameter. Also User Id
and Password
should be added.Server=192.168.1.36,1433;Database=DeviceDb;User Id=MyUser;Password=MySuperStringPassword;Trusted_Connection=True;MultipleActiveResultSets=true
Please be aware connection string like: Server=(localdb)\\mssqllocaldb;Database=DeviceDb;Trusted_Connection=True;MultipleActiveResultSets=true
will NOT work if app running from Docker container
git checkout -b my-new-feature
git commit -am 'Add some feature'
git push origin my-new-feature
All changes can be easily found in RELEASENOTES
This project is licensed under the MIT License