Repository: suadev/dotnet-istanbul-microservices-demo
Branch: master
Commit: 257a6ea78dbf
Files: 147
Total size: 142.5 KB
Directory structure:
gitextract_r_shzeh4/
├── .github/
│ └── workflows/
│ └── dotnet-core.yml
├── .gitignore
├── .postman_project/
│ └── Dotnet_Istanbul.postman_collection.json
├── .vscode/
│ ├── launch.json
│ └── tasks.json
├── DotnetIst.Api/
│ ├── README.MD
│ └── src/
│ └── Api/
│ ├── Api.csproj
│ ├── Authentication/
│ │ ├── AuthenticationExtensions.cs
│ │ ├── AuthenticationService.cs
│ │ ├── IAuthenticationService.cs
│ │ └── Model/
│ │ ├── LoginModel.cs
│ │ └── TokenModel.cs
│ ├── Commands/
│ │ ├── Baskets/
│ │ │ └── AddProductToBasket.cs
│ │ ├── Customers/
│ │ │ └── CreateCustomer.cs
│ │ └── Orders/
│ │ └── CreateOrder.cs
│ ├── Controllers/
│ │ ├── BaseController.cs
│ │ ├── BasketController.cs
│ │ ├── CustomerController.cs
│ │ ├── HomeController.cs
│ │ ├── OrderController.cs
│ │ ├── ProductController.cs
│ │ └── TokenController.cs
│ ├── HttpServices/
│ │ ├── CustomerHttpService.cs
│ │ ├── ICustomerHttpService.cs
│ │ ├── IProductHttpService.cs
│ │ └── ProductHttpService.cs
│ ├── Models/
│ │ └── Customer.cs
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
├── DotnetIst.Services.Customers/
│ ├── README.MD
│ └── src/
│ └── Services.Customers/
│ ├── Commands/
│ │ ├── AddProductToBasket.cs
│ │ └── CreateCustomer.cs
│ ├── Controllers/
│ │ ├── BasketController.cs
│ │ ├── CustomerController.cs
│ │ └── HomeController.cs
│ ├── Data/
│ │ ├── CustomerDBContext.cs
│ │ ├── Entity/
│ │ │ ├── Basket.cs
│ │ │ ├── BasketItem.cs
│ │ │ └── Customer.cs
│ │ ├── Migrations/
│ │ │ ├── 20190308211118_initial.Designer.cs
│ │ │ ├── 20190308211118_initial.cs
│ │ │ ├── 20190308222102_base_entity.Designer.cs
│ │ │ ├── 20190308222102_base_entity.cs
│ │ │ └── CustomerDBContextModelSnapshot.cs
│ │ └── SeedData.cs
│ ├── Events/
│ │ ├── OrderCompleted.cs
│ │ └── ProductAddedToBasket.cs
│ ├── Handlers/
│ │ ├── AddProductToBasketHandler.cs
│ │ ├── CreateCustomerdHandler.cs
│ │ └── OrderCompletedHandler.cs
│ ├── HttpServices/
│ │ ├── IProductHttpService.cs
│ │ └── ProductHttpService.cs
│ ├── Models/
│ │ └── Product.cs
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── Services.Customers.csproj
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
├── DotnetIst.Services.Notifications/
│ ├── README.MD
│ └── src/
│ └── Services.Notifications/
│ ├── Controllers/
│ │ └── HomeController.cs
│ ├── Events/
│ │ ├── OrderCompleted.cs
│ │ └── OrderFailed.cs
│ ├── Handlers/
│ │ ├── OrderCompletedHandler.cs
│ │ └── OrderFailedHandler.cs
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── Services.Notifications.csproj
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
├── DotnetIst.Services.Orders/
│ ├── README.md
│ └── src/
│ └── Services.Orders/
│ ├── Commands/
│ │ └── CreateOrder.cs
│ ├── Controllers/
│ │ └── HomeController.cs
│ ├── Data/
│ │ ├── Entity/
│ │ │ ├── Order.cs
│ │ │ ├── OrderItem.cs
│ │ │ └── OrderStatus.cs
│ │ ├── Migrations/
│ │ │ ├── 20190308211841_initial.Designer.cs
│ │ │ ├── 20190308211841_initial.cs
│ │ │ ├── 20190308222202_base_entity.Designer.cs
│ │ │ ├── 20190308222202_base_entity.cs
│ │ │ └── OrderDBContextModelSnapshot.cs
│ │ ├── OrderDBContext.cs
│ │ └── SeedData.cs
│ ├── Events/
│ │ ├── OrderCompleted.cs
│ │ ├── OrderCreated.cs
│ │ ├── OrderFailed.cs
│ │ ├── ProductsReserveFailed.cs
│ │ └── ProductsReserved.cs
│ ├── Handlers/
│ │ ├── CreateOrderHandler.cs
│ │ ├── ProductsReserveFailedHandler.cs
│ │ └── ProductsReservedHandler.cs
│ ├── HttpServices/
│ │ ├── CustomerHttpService.cs
│ │ └── ICustomerHttpService.cs
│ ├── Models/
│ │ ├── Basket.cs
│ │ └── BasketItem.cs
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── Services.Orders.csproj
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
├── DotnetIst.Services.Products/
│ ├── README.md
│ └── src/
│ └── Services.Products/
│ ├── Controllers/
│ │ ├── HomeController.cs
│ │ └── ProductController.cs
│ ├── Data/
│ │ ├── Entity/
│ │ │ └── Product.cs
│ │ ├── Migrations/
│ │ │ ├── 20190308212022_initial.Designer.cs
│ │ │ ├── 20190308212022_initial.cs
│ │ │ ├── 20190308222331_base_entity.Designer.cs
│ │ │ ├── 20190308222331_base_entity.cs
│ │ │ └── ProductDBContextModelSnapshot.cs
│ │ ├── ProductDBContext.cs
│ │ └── SeedData.cs
│ ├── Events/
│ │ ├── OrderCreated.cs
│ │ ├── ProductsReserveFailed.cs
│ │ └── ProductsReserved.cs
│ ├── Handlers/
│ │ └── OrderCreatedHandler.cs
│ ├── Program.cs
│ ├── Properties/
│ │ └── launchSettings.json
│ ├── Services.Products.csproj
│ ├── Startup.cs
│ ├── appsettings.Development.json
│ └── appsettings.json
├── DotnetIst.Shared/
│ └── src/
│ └── Shared/
│ ├── Extensions.cs
│ ├── Logging/
│ │ └── LoggingExtensions.cs
│ ├── MessageHandlers/
│ │ ├── ICommandHandler.cs
│ │ └── IEventHandler.cs
│ ├── Messages/
│ │ ├── ICommand.cs
│ │ ├── IEvent.cs
│ │ └── MessageNamespaceAttribute.cs
│ ├── Models/
│ │ ├── BaseEntity.cs
│ │ └── HttpServiceOptions.cs
│ ├── RabbitMq/
│ │ ├── BusPublisher.cs
│ │ ├── BusSubscriber.cs
│ │ ├── CorrelationContext.cs
│ │ ├── IBusPublisher.cs
│ │ ├── IBusSubscriber.cs
│ │ ├── ICorrelationContext.cs
│ │ ├── RabbitMqExtensions.cs
│ │ └── RabbitMqOptions.cs
│ └── Shared.csproj
├── README.md
├── docker-compose.yml
└── dotnet-istanbul-microservices-demo.sln
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/dotnet-core.yml
================================================
name: .NET Core
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.301
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --no-restore --verbosity normal
================================================
FILE: .gitignore
================================================
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
NuGet.config
appsettings.local.json
================================================
FILE: .postman_project/Dotnet_Istanbul.postman_collection.json
================================================
{
"info": {
"_postman_id": "1ce3bc02-2070-441c-9d1a-386db626d78b",
"name": "Dotnet_Istanbul",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"item": [
{
"name": "0-RegisterCustomer",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"FirstName\" :\"Suat\",\n\t\"LastName\" :\"Köse\",\n\t\"Address\" :\"Üsküdar\",\n\t\"Email\" :\"suadev@gmail.com\",\n\t\"Password\": \"12345\"\n}"
},
"url": {
"raw": "http://localhost:5000/api/customer",
"protocol": "http",
"host": [
"localhost"
],
"port": "5000",
"path": [
"api",
"customer"
]
}
},
"response": []
},
{
"name": "1-GetToken",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"type": "text",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"Email\" :\"suadev@gmail.com\",\n\t\"Password\" :\"12345\"\n}"
},
"url": {
"raw": "http://localhost:5000/api/token",
"protocol": "http",
"host": [
"localhost"
],
"port": "5000",
"path": [
"api",
"token"
]
}
},
"response": []
},
{
"name": "2-AddToBasket-Success",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
},
{
"key": "Authorization",
"value": "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6InN1YWRldkBnbWFpbC5jb20iLCJDdXN0b21lcklkIjoiMDQ1NzFlNDQtMDJjYi00Mzc1LWE0MTMtN2NiYTMxZDk2NGMyIiwibmJmIjoxNTUzNjMxNDk5LCJleHAiOjE1NTM3MTc4OTksImlhdCI6MTU1MzYzMTQ5OSwiaXNzIjoid2l6bG8uYXBpLmRlbW8iLCJhdWQiOiJTb21lQ3VzdG9tQXBwIn0.cQOe_IVK8oYzjiDdaNOMo5aviiDMt_gX-PYL-n_NPjc",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{\n\t\"ProductId\" :\"dc87e9ce-6d8d-4a01-a62d-2c2326472811\",\n\t\"Quantity\": 10\n}"
},
"url": {
"raw": "http://localhost:5000/api/basket",
"protocol": "http",
"host": [
"localhost"
],
"port": "5000",
"path": [
"api",
"basket"
]
}
},
"response": []
},
{
"name": "3-CreateOrder",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"name": "Content-Type",
"value": "application/json",
"type": "text"
},
{
"key": "Authorization",
"value": "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6InN1YWRldkBnbWFpbC5jb20iLCJDdXN0b21lcklkIjoiMDQ1NzFlNDQtMDJjYi00Mzc1LWE0MTMtN2NiYTMxZDk2NGMyIiwibmJmIjoxNTUzNjMxNDk5LCJleHAiOjE1NTM3MTc4OTksImlhdCI6MTU1MzYzMTQ5OSwiaXNzIjoid2l6bG8uYXBpLmRlbW8iLCJhdWQiOiJTb21lQ3VzdG9tQXBwIn0.cQOe_IVK8oYzjiDdaNOMo5aviiDMt_gX-PYL-n_NPjc",
"type": "text"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "http://localhost:5000/api/order",
"protocol": "http",
"host": [
"localhost"
],
"port": "5000",
"path": [
"api",
"order"
],
"query": [
{
"key": "",
"value": ""
}
]
}
},
"response": []
},
{
"name": "GetAllProducts",
"request": {
"method": "GET",
"header": [],
"body": {
"mode": "raw",
"raw": ""
},
"url": {
"raw": "http://localhost:5000/api/product",
"protocol": "http",
"host": [
"localhost"
],
"port": "5000",
"path": [
"api",
"product"
]
}
},
"response": []
}
]
}
================================================
FILE: .vscode/launch.json
================================================
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "api",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-api",
"program": "${workspaceFolder}/DotnetIst.Api/src/Api/bin/Debug/netcoreapp2.2/Api.dll",
"args": [],
"cwd": "${workspaceFolder}/DotnetIst.Api/src/Api",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://localhost:5000"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": "customer",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-customer",
"program": "${workspaceFolder}/DotnetIst.Services.Customers/src/Services.Customers/bin/Debug/netcoreapp2.2/Services.Customers.dll",
"args": [],
"cwd": "${workspaceFolder}/DotnetIst.Services.Customers/src/Services.Customers",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://localhost:5005"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": "products",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-product",
"program": "${workspaceFolder}/DotnetIst.Services.Products/src/Services.Products/bin/Debug/netcoreapp2.2/Services.Products.dll",
"args": [],
"cwd": "${workspaceFolder}/DotnetIst.Services.Products/src/Services.Products",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://localhost:5010"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": "orders",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-order",
"program": "${workspaceFolder}/DotnetIst.Services.Orders/src/Services.Orders/bin/Debug/netcoreapp2.2/Services.Orders.dll",
"args": [],
"cwd": "${workspaceFolder}/DotnetIst.Services.Orders/src/Services.Orders",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://localhost:5015"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": "notifications",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build-notification",
"program": "${workspaceFolder}/DotnetIst.Services.Notifications/src/Services.Notifications/bin/Debug/netcoreapp2.2/Services.Notifications.dll",
"args": [],
"cwd": "${workspaceFolder}/DotnetIst.Services.Notifications/src/Services.Notifications",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development",
"ASPNETCORE_URLS": "http://localhost:5020"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
],
"compounds": [
{
"name": "All",
"configurations": [
"api",
"customer",
"products",
"orders",
"notifications"
]
},
{
"name": "Api+Customer",
"configurations": [
"api",
"customer"
]
}
]
}
================================================
FILE: .vscode/tasks.json
================================================
{
"version": "2.0.0",
"tasks": [
{
"label": "build-api",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DotnetIst.Api/src/Api/Api.csproj"
],
"problemMatcher": "$msCompile"
},
{
"label": "build-customer",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DotnetIst.Services.Customers/src/Services.Customers/Services.Customers.csproj",
],
"problemMatcher": "$msCompile"
},
{
"label": "build-product",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DotnetIst.Services.Products/src/Services.Products/Services.Products.csproj",
],
"problemMatcher": "$msCompile"
},
{
"label": "build-order",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DotnetIst.Services.Orders/src/Services.Orders/Services.Orders.csproj",
],
"problemMatcher": "$msCompile"
},
{
"label": "build-notification",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/DotnetIst.Services.Notifications/src/Services.Notifications/Services.Notifications.csproj",
],
"problemMatcher": "$msCompile"
}
]
}
================================================
FILE: DotnetIst.Api/README.MD
================================================
## Api Gateway
todo: use ocelot
todo: create bffs for each channel type
================================================
FILE: DotnetIst.Api/src/Api/Api.csproj
================================================
netcoreapp2.2
InProcess
================================================
FILE: DotnetIst.Api/src/Api/Authentication/AuthenticationExtensions.cs
================================================
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
namespace Api.Authentication
{
public static class AuthenticationExtensions
{
private const string SecretKey = "SomeStaticAccessKey12345!";
public static void AddJwtAuthentication(this IServiceCollection services)
{
services
.AddScoped()
.AddScoped()
.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.Audience = "SomeCustomApp";
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.ClaimsIssuer = "dotnetist.api.demo";
x.TokenValidationParameters = new TokenValidationParameters
{
IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey)),
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidateIssuer = false,
ValidateAudience = true
};
x.Events = new JwtBearerEvents()
{
OnTokenValidated = (context) =>
{
var name = context.Principal.Identity.Name;
if (string.IsNullOrEmpty(name))
{
context.Fail("Unauthorized. Please re-login");
}
context.HttpContext.Items.Add("CurrentCustomer",
new TokenModel
{
Email = context.Principal.Identity.Name,
CustomerId = Guid.Parse(
context.Principal.Claims.First(s => s.Type == "CustomerId").Value),
});
return Task.CompletedTask;
}
};
});
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Authentication/AuthenticationService.cs
================================================
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Api.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
namespace Api.Authentication
{
public class AuthenticationService : IAuthenticationService
{
private IHttpContextAccessor _contextAccessor;
public AuthenticationService(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public TokenModel GetCurrentUser()
=> _contextAccessor.HttpContext?.Items?["CurrentCustomer"] != null ?
_contextAccessor.HttpContext.Items["CurrentCustomer"] as TokenModel : null;
public string GetToken(Customer customer)
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes("SomeStaticAccessKey12345!");
var tokenDescriptor = new SecurityTokenDescriptor
{
Audience = "SomeCustomApp",
Issuer = "wizlo.api.demo",
Subject = new ClaimsIdentity(new Claim[]
{
new Claim(ClaimTypes.Name, customer.Email),
new Claim("CustomerId", customer.Id.ToString())
}),
Expires = DateTime.UtcNow.AddDays(1),
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Authentication/IAuthenticationService.cs
================================================
using Api.Models;
namespace Api.Authentication
{
public interface IAuthenticationService
{
string GetToken(Customer customer);
}
}
================================================
FILE: DotnetIst.Api/src/Api/Authentication/Model/LoginModel.cs
================================================
namespace Api.Authentication
{
public class LoginModel
{
public string Email { get; set; }
public string Password { get; set; }
}
}
================================================
FILE: DotnetIst.Api/src/Api/Authentication/Model/TokenModel.cs
================================================
using System;
namespace Api.Authentication
{
public class TokenModel
{
public Guid CustomerId { get; set; }
public string Email { get; set; }
}
}
================================================
FILE: DotnetIst.Api/src/Api/Commands/Baskets/AddProductToBasket.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;
namespace Api.Commands.Baskets
{
[MessageNamespace("customers")]
public class AddProductToBasket : ICommand
{
public Guid ProductId { get; }
public int Quantity { get; }
public AddProductToBasket(Guid productId, int quantity)
{
ProductId = productId;
Quantity = quantity;
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Commands/Customers/CreateCustomer.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;
namespace Api.Commands.Customers
{
[MessageNamespace("customers")]
public class CreateCustomer : ICommand
{
public Guid Id { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public CreateCustomer(string email, string password, string firstName, string lastName, string address)
{
this.Id = Guid.NewGuid();
this.Email = email;
this.Password = password;
this.FirstName = firstName;
this.LastName = lastName;
this.Address = address;
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Commands/Orders/CreateOrder.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;
namespace Api.Commands.Orders
{
[MessageNamespace("orders")]
public class CreateOrder : ICommand
{
public Guid Id { get; private set; }
public CreateOrder()
{
Id = Guid.NewGuid();
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Controllers/BaseController.cs
================================================
using System;
using Api.Authentication;
using Shared.Messages;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Mvc;
namespace Api.Controllers
{
public class BaseController : ControllerBase
{
protected readonly IBusPublisher BusPublisher;
public BaseController(IBusPublisher busPublisher)
{
BusPublisher = busPublisher;
}
protected TokenModel CurrentUser
{
get
{
return HttpContext.Items["CurrentCustomer"] != null ?
HttpContext.Items["CurrentCustomer"] as TokenModel : null;
}
}
protected ICorrelationContext GetContext()
{
return GetContext(CurrentUser.CustomerId);
}
//This method is only for AllowAnonymus CustomerController
protected ICorrelationContext GetContext(Guid customerId)
{
return CorrelationContext.Create(Guid.NewGuid(), customerId);
}
// protected IActionResult Accepted(ICorrelationContext context)
// { //
// // Response.Headers.Add(OperationHeader, $"checktransactionstatus/{context.Id}");
// return base.Accepted();
// }
}
}
================================================
FILE: DotnetIst.Api/src/Api/Controllers/BasketController.cs
================================================
using System.Threading.Tasks;
using Api.Commands.Baskets;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class BasketController : BaseController
{
public BasketController(IBusPublisher busPublisher) : base(busPublisher)
{
}
[HttpPost]
public async Task Post(AddProductToBasket command)
{
var context = GetContext();
await BusPublisher.SendAsync(command, context);
return Accepted();
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Controllers/CustomerController.cs
================================================
using System.Threading.Tasks;
using Api.Commands.Customers;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class CustomerController : BaseController
{
public CustomerController(IBusPublisher busPublisher) : base(busPublisher)
{
}
[HttpPost]
public async Task Post(CreateCustomer command)
{
var context = GetContext(command.Id);
await BusPublisher.SendAsync(command, context);
return Accepted();
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Controllers/HomeController.cs
================================================
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Api.Controllers
{
[Route("")]
public class HomeController : ControllerBase
{
[HttpGet]
[AllowAnonymous]
public IActionResult Get()
{
return Ok("Api is up.");
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Controllers/OrderController.cs
================================================
using System.Threading.Tasks;
using Api.Commands.Orders;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class OrderController : BaseController
{
public OrderController(IBusPublisher busPublisher) : base(busPublisher)
{
}
[HttpPost]
public async Task Post(CreateOrder command)
{
var context = GetContext();
await BusPublisher.SendAsync(command, context);
return Accepted();
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Controllers/ProductController.cs
================================================
using System.Threading.Tasks;
using Api.Commands.Customers;
using Api.HttpServices;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ProductController : ControllerBase
{
private readonly IProductHttpService _productHttpService;
public ProductController(IProductHttpService productHttpService)
{
_productHttpService = productHttpService;
}
[HttpGet]
public async Task Get()
{
return Ok(await _productHttpService.GetList());
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/Controllers/TokenController.cs
================================================
using System.Threading.Tasks;
using Api.Authentication;
using Api.HttpServices;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Api.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TokenController : ControllerBase
{
private readonly IAuthenticationService _authService;
private readonly ICustomerHttpService _customerHttpService;
public TokenController(IAuthenticationService authService,
ICustomerHttpService customerHttpService)
{
_authService = authService;
_customerHttpService = customerHttpService;
}
[HttpPost]
[AllowAnonymous]
public async Task GenerateToken(LoginModel reqeust)
{
var customer = await _customerHttpService.GetCustomerByEmail(reqeust.Email);
if (customer == null)
{
return BadRequest("Customer not found.");
}
if (customer.Password != reqeust.Password)
{
return BadRequest("Wrong password.");
}
return Ok(_authService.GetToken(customer));
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/HttpServices/CustomerHttpService.cs
================================================
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Api.Models;
using Newtonsoft.Json;
namespace Api.HttpServices
{
public class CustomerHttpService : ICustomerHttpService
{
private HttpClient _client { get; }
public CustomerHttpService(HttpClient client)
{
_client = client;
}
public async Task GetCustomerByEmail(string email)
{
var request = new HttpRequestMessage(HttpMethod.Get, $"customer/customerbyemail/{email}");
var response = await _client.SendAsync(request);
var content = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
response.Content.Dispose();
return JsonConvert.DeserializeObject(content);
}
throw new Exception("Customer service connection error");
}
}
}
================================================
FILE: DotnetIst.Api/src/Api/HttpServices/ICustomerHttpService.cs
================================================
using System;
using System.Threading.Tasks;
using Api.Models;
namespace Api.HttpServices
{
public interface ICustomerHttpService
{
Task GetCustomerByEmail(string CustomerId);
}
}
================================================
FILE: DotnetIst.Api/src/Api/HttpServices/IProductHttpService.cs
================================================
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Api.HttpServices
{
public interface IProductHttpService
{
Task