master 257a6ea78dbf cached
147 files
142.5 KB
38.6k tokens
275 symbols
1 requests
Download .txt
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
================================================
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <ProjectReference Include="..\..\..\DotnetIst.Shared\src\Shared\Shared.csproj" />
  </ItemGroup>

</Project>


================================================
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<IHttpContextAccessor, HttpContextAccessor>()
            .AddScoped<IAuthenticationService, AuthenticationService>()
            .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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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<Customer> 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<Customer>(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<Customer> 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<object> GetList();
    }
}

================================================
FILE: DotnetIst.Api/src/Api/HttpServices/ProductHttpService.cs
================================================
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Api.HttpServices
{
    public class ProductHttpService : IProductHttpService
    {
        private HttpClient _client { get; }

        public ProductHttpService(HttpClient client)
        {
            _client = client;
        }

        public async Task<object> GetList()
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"product");
            var response = await _client.SendAsync(request);

            var content = await response.Content.ReadAsStringAsync();
            if (response.IsSuccessStatusCode)
            {
                response.Content.Dispose();
                return JsonConvert.DeserializeObject<List<object>>(content);
            }
            throw new Exception("Product service connection error");
        }
    }
}

================================================
FILE: DotnetIst.Api/src/Api/Models/Customer.cs
================================================
using System;

namespace Api.Models
{
    public class Customer
    {
        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; }
    }
}

================================================
FILE: DotnetIst.Api/src/Api/Program.cs
================================================
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Shared.Logging;

namespace Api
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseLogging("Api");
    }
}


================================================
FILE: DotnetIst.Api/src/Api/Properties/launchSettings.json
================================================
{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:55301",
      "sslPort": 44356
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Api": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

================================================
FILE: DotnetIst.Api/src/Api/Startup.cs
================================================
using System;
using System.Net.Http.Headers;
using System.Reflection;
using Api.Authentication;
using Api.HttpServices;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Shared.Models;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Shared;

namespace Api
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddJwtAuthentication();

            var httpServices = Configuration.GetOptions<HttpServiceOptions>("HttpServices");
            services.AddHttpClient<ICustomerHttpService, CustomerHttpService>(client =>
            {
                client.BaseAddress = new Uri(httpServices.CustomerHttpServiceUrl);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            });
            services.AddHttpClient<IProductHttpService, ProductHttpService>(client =>
            {
                client.BaseAddress = new Uri(httpServices.ProductHttpServiceUrl);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            });

            return services.BuildContainer();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAuthentication();
            app.UseMvc();
        }
    }
}


================================================
FILE: DotnetIst.Api/src/Api/appsettings.Development.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}


================================================
FILE: DotnetIst.Api/src/Api/appsettings.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "HttpServices": {
    "CustomerHttpServiceUrl": "http://localhost:5005/api/",
    "ProductHttpServiceUrl": "http://localhost:5010/api/"
  },
  "rabbitMq": {
    "namespace": "api",
    "retries": 3,
    "retryInterval": 2,
    "username": "guest",
    "password": "guest",
    "virtualHost": "/",
    "port": 5672,
    "hostnames": [
      "localhost"
    ],
    "requestTimeout": "00:00:10",
    "publishConfirmTimeout": "00:00:01",
    "recoveryInterval": "00:00:10",
    "persistentDeliveryMode": true,
    "autoCloseConnection": true,
    "automaticRecovery": true,
    "topologyRecovery": true,
    "exchange": {
      "durable": true,
      "autoDelete": false,
      "type": "Topic"
    },
    "queue": {
      "autoDelete": false,
      "durable": true,
      "exclusive": false
    }
  }
}

================================================
FILE: DotnetIst.Services.Customers/README.MD
================================================
**Migration**

0- cd src/Services.Customers

1- *dotnet ef migrations add "migration_name" -o ./Data/Migrations*

2- *dotnet ef database update*

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Commands/AddProductToBasket.cs
================================================

using System;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Customers.Commands
{
    public class AddProductToBasket : ICommand
    {
        public Guid ProductId { get; }
        public int Quantity { get; }

        public AddProductToBasket(Guid productId,
            int quantity)
        {
            ProductId = productId;
            Quantity = quantity;
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Commands/CreateCustomer.cs
================================================

using System;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Customers.Commands
{
    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(Guid id, string email, string password, string firstName, string lastName, string address)
        {
            this.Id = id;
            this.Password = password;
            this.Email = email;
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Address = address;
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Controllers/BasketController.cs
================================================
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Services.Customers.Data;

namespace Services.Customers.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class BasketController : ControllerBase
    {
        private readonly CustomerDBContext _dbContext;

        public BasketController(CustomerDBContext dbContext)
        {
            _dbContext = dbContext;
        }
        [HttpGet("{customerId}")]
        public async Task<ActionResult> Get(Guid customerId)
        {
            return Ok(await _dbContext.Baskets.Include(i => i.Items)
                    .FirstOrDefaultAsync(s => s.CustomerId == customerId));
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Controllers/CustomerController.cs
================================================
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Services.Customers.Data;

namespace Services.Customers.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CustomerController : ControllerBase
    {
        private readonly CustomerDBContext _dbContext;

        public CustomerController(CustomerDBContext dbContext)
        {
            _dbContext = dbContext;
        }
        [HttpGet("customerbyemail/{email}")]
        public async Task<ActionResult> Get(string email)
        {
            return Ok(await _dbContext.Customers
                    .FirstOrDefaultAsync(s => s.Email == email));
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Controllers/HomeController.cs
================================================
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Services.Customers.Controllers
{
    [Route("")]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        [AllowAnonymous]
        public IActionResult Get()
        {
            return Ok("Customer service is up.");
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/CustomerDBContext.cs
================================================
using Microsoft.EntityFrameworkCore;

namespace Services.Customers.Data
{
    public class CustomerDBContext : DbContext
    {
        public CustomerDBContext(DbContextOptions<CustomerDBContext> options) : base(options)
        {
        }
        public DbSet<Basket> Baskets { get; set; }
        public DbSet<BasketItem> BasketItems { get; set; }
        public DbSet<Customer> Customers { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Basket>().ToTable("Basket");
            modelBuilder.Entity<Basket>().HasMany(x => x.Items);


            modelBuilder.Entity<BasketItem>().ToTable("BasketItem");

            modelBuilder.Entity<Customer>().ToTable("Customer");
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/Basket.cs
================================================
using System;
using System.Collections.Generic;
using Shared.Models;

namespace Services.Customers.Data
{
    public class Basket : BaseEntity
    {
        public Guid CustomerId { get; set; }
        public List<BasketItem> Items { get; set; }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/BasketItem.cs
================================================
using System;
using Shared.Models;

namespace Services.Customers.Data
{
    public class BasketItem : BaseEntity
    {
        public Guid BasketId { get; set; }
        public Guid ProductId { get; set; }
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public decimal UnitPrice { get; set; }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/Customer.cs
================================================
using System;
using Shared.Models;

namespace Services.Customers.Data
{
    public class Customer : BaseEntity
    {
        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; }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308211118_initial.Designer.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Customers.Data.Migrations
{
    [DbContext(typeof(CustomerDBContext))]
    [Migration("20190308211118_initial")]
    partial class initial
    {
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Customers.Data.Basket", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<DateTime>("CreatedAt");

                    b.Property<Guid>("CustomerId");



                    b.ToTable("Basket");
                });

            modelBuilder.Entity("Services.Customers.Data.BasketItem", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<Guid>("BasketId");

                    b.Property<long>("ProductId");

                    b.Property<string>("ProductName");

                    b.Property<int>("Quantity");

                    b.Property<decimal>("UnitPrice");



                    b.HasIndex("BasketId");

                    b.ToTable("BasketItem");
                });

            modelBuilder.Entity("Services.Customers.Data.Customer", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Address");

                    b.Property<string>("Email");

                    b.Property<string>("FirstName");

                    b.Property<string>("LastName");

                    b.Property<string>("Password");



                    b.ToTable("Customer");
                });

            modelBuilder.Entity("Services.Customers.Data.BasketItem", b =>
                {
                    b.HasOne("Services.Customers.Data.Basket")
                        .WithMany("Items")
                        .HasForeignKey("BasketId")
                        .OnDelete(DeleteBehavior.Cascade);
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308211118_initial.cs
================================================
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Services.Customers.Data.Migrations
{
    public partial class initial : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Basket",
                columns: table => new
                {
                    Id = table.Column<Guid>(nullable: false),
                    CustomerId = table.Column<Guid>(nullable: false),
                    CreatedAt = table.Column<DateTime>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Basket", x => x.Id);
                });

            migrationBuilder.CreateTable(
                name: "Customer",
                columns: table => new
                {
                    Id = table.Column<Guid>(nullable: false),
                    Email = table.Column<string>(nullable: true),
                    Password = table.Column<string>(nullable: true),
                    FirstName = table.Column<string>(nullable: true),
                    LastName = table.Column<string>(nullable: true),
                    Address = table.Column<string>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Customer", x => x.Id);
                });

            migrationBuilder.CreateTable(
                name: "BasketItem",
                columns: table => new
                {
                    Id = table.Column<Guid>(nullable: false),
                    BasketId = table.Column<Guid>(nullable: false),
                    ProductId = table.Column<long>(nullable: false),
                    ProductName = table.Column<string>(nullable: true),
                    Quantity = table.Column<int>(nullable: false),
                    UnitPrice = table.Column<decimal>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_BasketItem", x => x.Id);
                    table.ForeignKey(
                        name: "FK_BasketItem_Basket_BasketId",
                        column: x => x.BasketId,
                        principalTable: "Basket",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                });

            migrationBuilder.CreateIndex(
                name: "IX_BasketItem_BasketId",
                table: "BasketItem",
                column: "BasketId");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "BasketItem");

            migrationBuilder.DropTable(
                name: "Customer");

            migrationBuilder.DropTable(
                name: "Basket");
        }
    }
}


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308222102_base_entity.Designer.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Customers.Data.Migrations
{
    [DbContext(typeof(CustomerDBContext))]
    [Migration("20190308222102_base_entity")]
    partial class base_entity
    {
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Customers.Data.Basket", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<Guid>("CustomerId");

                    b.Property<DateTime?>("UpdateDate");



                    b.ToTable("Basket");
                });

            modelBuilder.Entity("Services.Customers.Data.BasketItem", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<Guid>("BasketId");

                    b.Property<long>("ProductId");

                    b.Property<string>("ProductName");

                    b.Property<int>("Quantity");

                    b.Property<decimal>("UnitPrice");

                    b.Property<DateTime?>("UpdateDate");



                    b.HasIndex("BasketId");

                    b.ToTable("BasketItem");
                });

            modelBuilder.Entity("Services.Customers.Data.Customer", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Address");

                    b.Property<string>("Email");

                    b.Property<string>("FirstName");

                    b.Property<string>("LastName");

                    b.Property<string>("Password");

                    b.Property<DateTime?>("UpdateDate");



                    b.ToTable("Customer");
                });

            modelBuilder.Entity("Services.Customers.Data.BasketItem", b =>
                {
                    b.HasOne("Services.Customers.Data.Basket")
                        .WithMany("Items")
                        .HasForeignKey("BasketId")
                        .OnDelete(DeleteBehavior.Cascade);
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308222102_base_entity.cs
================================================
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Services.Customers.Data.Migrations
{
    public partial class base_entity : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.RenameColumn(
                name: "CreatedAt",
                table: "Basket",
                newName: "UpdateDate");

            migrationBuilder.AddColumn<DateTime>(
                name: "UpdateDate",
                table: "Customer",
                nullable: false,
                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));

            migrationBuilder.AddColumn<DateTime>(
                name: "UpdateDate",
                table: "BasketItem",
                nullable: false,
                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "UpdateDate",
                table: "Customer");

            migrationBuilder.DropColumn(
                name: "UpdateDate",
                table: "BasketItem");

            migrationBuilder.RenameColumn(
                name: "UpdateDate",
                table: "Basket",
                newName: "CreatedAt");
        }
    }
}


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/CustomerDBContextModelSnapshot.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Customers.Data.Migrations
{
    [DbContext(typeof(CustomerDBContext))]
    partial class CustomerDBContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Customers.Data.Basket", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<Guid>("CustomerId");

                    b.Property<DateTime?>("UpdateDate");



                    b.ToTable("Basket");
                });

            modelBuilder.Entity("Services.Customers.Data.BasketItem", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<Guid>("BasketId");

                    b.Property<long>("ProductId");

                    b.Property<string>("ProductName");

                    b.Property<int>("Quantity");

                    b.Property<decimal>("UnitPrice");

                    b.Property<DateTime?>("UpdateDate");



                    b.HasIndex("BasketId");

                    b.ToTable("BasketItem");
                });

            modelBuilder.Entity("Services.Customers.Data.Customer", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Address");

                    b.Property<string>("Email");

                    b.Property<string>("FirstName");

                    b.Property<string>("LastName");

                    b.Property<string>("Password");

                    b.Property<DateTime?>("UpdateDate");



                    b.ToTable("Customer");
                });

            modelBuilder.Entity("Services.Customers.Data.BasketItem", b =>
                {
                    b.HasOne("Services.Customers.Data.Basket")
                        .WithMany("Items")
                        .HasForeignKey("BasketId")
                        .OnDelete(DeleteBehavior.Cascade);
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/SeedData.cs
================================================
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;

namespace Services.Customers.Data
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            var context = serviceProvider.GetRequiredService<CustomerDBContext>();
            context.Database.EnsureCreated();
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Events/OrderCompleted.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Customers.Events
{
    public class OrderCompleted : IEvent
    {
        public Guid Id { get; }

        public OrderCompleted(Guid id)
        {
            Id = id;
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Events/ProductAddedToBasket.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Customers.Events
{
    public class ProductAddedToBasket : IEvent
    {
        public Guid ProductId { get; }
        public int Quantity { get; }

        public ProductAddedToBasket(Guid productId, int quantity)
        {
            ProductId = productId;
            Quantity = quantity;
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Handlers/AddProductToBasketHandler.cs
================================================
using System;
using System.Linq;
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Services.Customers.Commands;
using Services.Customers.Data;
using Services.Customers.Events;
using Services.Customers.HttpServices;

namespace Services.Customers.Handlers
{
    public class AddProductToBasketHandler : ICommandHandler<AddProductToBasket>
    {
        private readonly IBusPublisher _busPublisher;
        private readonly CustomerDBContext _dbContext;
        private readonly IProductHttpService _productHttpService;
        private readonly ILogger<AddProductToBasketHandler> _logger;

        public AddProductToBasketHandler(IBusPublisher busPublisher,
            CustomerDBContext dbContext,
            IProductHttpService productHttpService,
            ILogger<AddProductToBasketHandler> logger
            )
        {
            _productHttpService = productHttpService;
            _logger = logger;
            _busPublisher = busPublisher;
            _dbContext = dbContext;
        }

        public async Task HandleAsync(AddProductToBasket command, ICorrelationContext context)
        {
            // Warning: Customer service needs Product service's data.
            // What if Product service can't response for a while? (assume no retry policy)
            // DDD - sharing data betwwen bounded cotext

            var product = await _productHttpService.GetAsync(command.ProductId);
            if (product == null)
                throw new Exception($"Product not found. Id: {command.ProductId}");

            var basket = await _dbContext.Baskets.FirstOrDefaultAsync(q => q.CustomerId == context.CustomerId);
            if (basket == null)
                throw new Exception($"Basket not found for customer: {context.CustomerId}");

            var basketItem = await _dbContext.BasketItems.FirstOrDefaultAsync(q => q.ProductId == command.ProductId);

            if (basketItem != null)
            {
                basketItem.Quantity += command.Quantity;
            }
            else
            {
                _dbContext.BasketItems.Add(
                    new BasketItem
                    {
                        BasketId = basket.Id,
                        ProductId = command.ProductId,
                        Quantity = command.Quantity,
                        ProductName = product.Name,
                        UnitPrice = product.Price
                    });
            }

            await _dbContext.SaveChangesAsync();

            // no event, just logging.
            _logger.LogInformation($"[Local Transaction] : {command.Quantity} {product.Name} added to basket. CorrelationId: {context.CorrelationId}");
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Handlers/CreateCustomerdHandler.cs
================================================
using System;
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.Extensions.Logging;
using Services.Customers.Commands;
using Services.Customers.Data;

namespace Services.Customers.Handlers
{
    public class CreateCustomerdHandler : ICommandHandler<CreateCustomer>
    {
        private readonly IBusPublisher _busPublisher;
        private readonly CustomerDBContext _dbContext;
        private readonly ILogger<CreateCustomerdHandler> _logger;

        public CreateCustomerdHandler(IBusPublisher busPublisher,
                                        CustomerDBContext dbContext,
                                        ILogger<CreateCustomerdHandler> logger)
        {
            _logger = logger;
            _busPublisher = busPublisher;
            _dbContext = dbContext;
        }
        public async Task HandleAsync(CreateCustomer _event, ICorrelationContext context)
        {
            _dbContext.Customers.Add(new Customer
            {
                Id = _event.Id,
                Password = _event.Password,
                Email = _event.Email,
                FirstName = _event.FirstName,
                LastName = _event.LastName,
                Address = _event.Address
            });

            _dbContext.Baskets.Add(new Basket
            {
                CustomerId = _event.Id
            });

            await _dbContext.SaveChangesAsync();
            _logger.LogInformation($"[Local Transaction] : Customer created. CorrelataionId: {context.CorrelationId}");
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Handlers/OrderCompletedHandler.cs
================================================
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Services.Customers.Data;
using Services.Customers.Events;

namespace Services.Customers.Handlers
{
    public class OrderCompletedHandler : IEventHandler<OrderCompleted>
    {
        private readonly IBusPublisher _busPublisher;
        private readonly CustomerDBContext _dbContext;
        private readonly ILogger<OrderCompletedHandler> _logger;

        public OrderCompletedHandler(IBusPublisher busPublisher,
                                    CustomerDBContext dbContext,
                                    ILogger<OrderCompletedHandler> logger)
        {
            _logger = logger;
            _busPublisher = busPublisher;
            _dbContext = dbContext;
        }
        public async Task HandleAsync(OrderCompleted _event, ICorrelationContext context)
        {
            var basket = await _dbContext.Baskets
                .Include(i => i.Items)
                .FirstOrDefaultAsync(q => q.CustomerId == context.CustomerId);

            _dbContext.BasketItems.RemoveRange(basket.Items);
            await _dbContext.SaveChangesAsync();
            //no event, just logging
            _logger.LogInformation($"[Local Transaction] : Basket items cleared. CorrelationId: {context.CorrelationId}");
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/HttpServices/IProductHttpService.cs
================================================
using System;
using System.Threading.Tasks;
using Services.Customers.Data;
using Services.Customers.Models;

namespace Services.Customers.HttpServices
{
    public interface IProductHttpService
    {
        Task<Product> GetAsync(Guid id);
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/HttpServices/ProductHttpService.cs
================================================
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Services.Customers.Data;
using Services.Customers.Models;

namespace Services.Customers.HttpServices
{
    public class ProductHttpService : IProductHttpService
    {
        private HttpClient _client { get; }

        public ProductHttpService(HttpClient client)
        {
            _client = client;
        }

        public async Task<Product> GetAsync(Guid id)
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"product/{id}");
            var response = await _client.SendAsync(request);

            var content = await response.Content.ReadAsStringAsync();
            if (response.IsSuccessStatusCode)
            {
                response.Content.Dispose();
                return JsonConvert.DeserializeObject<Product>(content);
            }
            throw new Exception("Product service connection error");
        }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Models/Product.cs
================================================
using System;

namespace Services.Customers.Models
{
    public class Product
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public int Quantity { get; set; }
    }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Program.cs
================================================
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Shared.Logging;

namespace Services.Customers
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }
        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseLogging("Customer.Service");
    }
}


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Properties/launchSettings.json
================================================
{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:5834",
      "sslPort": 44386
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "src": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5005",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Services.Customers.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <ProjectReference Include="..\..\..\DotnetIst.Shared\src\Shared\Shared.csproj" />
  </ItemGroup>

</Project>


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/Startup.cs
================================================
using System;
using System.Net.Http.Headers;
using Shared.Models;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Services.Customers.Commands;
using Services.Customers.Data;
using Shared;
using Services.Customers.HttpServices;
using Services.Customers.Events;

namespace Services.Customers
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<CustomerDBContext>(options =>
                options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"))
            );

            var httpServices = Configuration.GetOptions<HttpServiceOptions>("HttpServices");
            services.AddHttpClient<IProductHttpService, ProductHttpService>(client =>
            {
                client.BaseAddress = new Uri(httpServices.ProductHttpServiceUrl);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            return services.BuildContainer();
        }



        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            app.UseRabbitMq()
               .SubscribeCommand<CreateCustomer>()
               .SubscribeCommand<AddProductToBasket>()
               .SubscribeEvent<OrderCompleted>();

            SeedData.Initialize(app.ApplicationServices);
        }
    }
}


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/appsettings.Development.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}


================================================
FILE: DotnetIst.Services.Customers/src/Services.Customers/appsettings.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=Customers;"
  },
  "HttpServices": {
    "ProductHttpServiceUrl": "http://localhost:5010/api/"
  },
  "rabbitMq": {
    "namespace": "customers",
    "retries": 3,
    "retryInterval": 2,
    "username": "guest",
    "password": "guest",
    "virtualHost": "/",
    "port": 5672,
    "hostnames": [
      "localhost"
    ],
    "requestTimeout": "00:00:10",
    "publishConfirmTimeout": "00:00:01",
    "recoveryInterval": "00:00:10",
    "persistentDeliveryMode": true,
    "autoCloseConnection": true,
    "automaticRecovery": true,
    "topologyRecovery": true,
    "exchange": {
      "durable": true,
      "autoDelete": false,
      "type": "Topic"
    },
    "queue": {
      "autoDelete": false,
      "durable": true,
      "exclusive": false
    }
  }
}

================================================
FILE: DotnetIst.Services.Notifications/README.MD
================================================
**NotificationService**

================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Controllers/HomeController.cs
================================================
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Services.Notifications.Controllers
{
    [Route("")]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        [AllowAnonymous]
        public IActionResult Get()
        {
            return Ok("Notification service is up.");
        }
    }
}

================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Events/OrderCompleted.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Notifications.Events
{
    [MessageNamespace("customers")]
    public class OrderCompleted : IEvent
    {
        public Guid Id { get; }

        public OrderCompleted(Guid id)
        {
            Id = id;
        }
    }
}

================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Events/OrderFailed.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Notifications.Events
{
    public class OrderFailed : IEvent
    {
        public Guid Id { get; }

        public OrderFailed(Guid id)
        {
            Id = id;
        }
    }
}

================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Handlers/OrderCompletedHandler.cs
================================================
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.Extensions.Logging;
using Services.Notifications.Events;

namespace Services.Notifications.Handlers
{
    public class OrderCompletedHandler : IEventHandler<OrderCompleted>
    {
        private readonly ILogger<OrderCompletedHandler> _logger;
        public OrderCompletedHandler(ILogger<OrderCompletedHandler> logger)
        {
            _logger = logger;
        }
        public async Task HandleAsync(OrderCompleted _event, ICorrelationContext context)
        {
            // Order completed sms/mail/push...
            _logger.LogInformation($"[Local Transaction] : Notification sent for Created Order. CorrelationId: {context.CorrelationId}");
            await Task.CompletedTask;
        }
    }
}

================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Handlers/OrderFailedHandler.cs
================================================
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.Extensions.Logging;
using Services.Notifications.Events;

namespace Services.Notifications.Handlers
{
    public class OrderFailedHandler : IEventHandler<OrderFailed>
    {
        private readonly ILogger<OrderFailedHandler> _logger;
        public OrderFailedHandler(ILogger<OrderFailedHandler> logger)
        {
            _logger = logger;
        }
        public async Task HandleAsync(OrderFailed _event, ICorrelationContext context)
        {
            // Order failed sms/mail/push...
            _logger.LogInformation($"[Local Transaction] : Notification sent for Failed Order. CorrelationId: {context.CorrelationId}");
            await Task.CompletedTask;
        }
    }
}

================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Program.cs
================================================
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Shared.Logging;

namespace Services.Notifications
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseLogging("Notification.Service");
    }
}


================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Properties/launchSettings.json
================================================
{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:34801",
      "sslPort": 44346
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Services.Notifications": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5020",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Services.Notifications.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <ProjectReference Include="..\..\..\DotnetIst.Shared\src\Shared\Shared.csproj" />
  </ItemGroup>

</Project>


================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Startup.cs
================================================
using System;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Services.Notifications.Events;
using Shared;

namespace Services.Notifications
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            return services.BuildContainer();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            app.UseRabbitMq()
               .SubscribeEvent<OrderCompleted>(_namespace: "customers")
               .SubscribeEvent<OrderFailed>();
        }
    }
}


================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/appsettings.Development.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}


================================================
FILE: DotnetIst.Services.Notifications/src/Services.Notifications/appsettings.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "rabbitMq": {
    "namespace": "notifications",
    "retries": 3,
    "retryInterval": 2,
    "username": "guest",
    "password": "guest",
    "virtualHost": "/",
    "port": 5672,
    "hostnames": [
      "localhost"
    ],
    "requestTimeout": "00:00:10",
    "publishConfirmTimeout": "00:00:01",
    "recoveryInterval": "00:00:10",
    "persistentDeliveryMode": true,
    "autoCloseConnection": true,
    "automaticRecovery": true,
    "topologyRecovery": true,
    "exchange": {
      "durable": true,
      "autoDelete": false,
      "type": "Topic"
    },
    "queue": {
      "autoDelete": false,
      "durable": true,
      "exclusive": false
    }
  }
}

================================================
FILE: DotnetIst.Services.Orders/README.md
================================================
**Migration**

0- cd src/Services.Products

1- *dotnet ef migrations add "migration_name" -o ./Data/Migrations*

2- *dotnet ef database update*

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Commands/CreateOrder.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Orders.Commands
{
    public class CreateOrder : ICommand
    {
        public Guid Id { get; }

        public CreateOrder(Guid id)
        {
            this.Id = id;
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Controllers/HomeController.cs
================================================
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Services.Orders.Controllers
{
    [Route("")]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        [AllowAnonymous]
        public IActionResult Get()
        {
            return Ok("Order service is up.");
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/Order.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using Shared.Models;

namespace Services.Orders.Data
{
    public class Order : BaseEntity
    {
        public Guid CustomerId { get; set; }
        public List<OrderItem> Items { get; set; }
        public decimal TotalAmount { get; set; }
        public OrderStatus Status { get; set; }
    }
}



================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/OrderItem.cs
================================================
using System;
using Shared.Models;

namespace Services.Orders.Data
{
    public class OrderItem : BaseEntity
    {
        public Guid OrderId { get; set; }
        public Guid ProductId { get; set; }
        public string Name { get; set; }
        public int Quantity { get; set; }
        public decimal UnitPrice { get; set; }
        public decimal TotalPrice => Quantity * UnitPrice;
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/OrderStatus.cs
================================================
namespace Services.Orders.Data
{
    public enum OrderStatus
    {
        Created = 0,
        Completed = 1,
        Failed = 2
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308211841_initial.Designer.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Orders.Data.Migrations
{
    [DbContext(typeof(OrderDBContext))]
    [Migration("20190308211841_initial")]
    partial class initial
    {
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Orders.Data.Order", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<Guid>("CustomerId");

                    b.Property<int>("Status");

                    b.Property<decimal>("TotalAmount");



                    b.ToTable("Order");
                });

            modelBuilder.Entity("Services.Orders.Data.OrderItem", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Name");

                    b.Property<Guid>("OrderId");

                    b.Property<long>("ProductId");

                    b.Property<int>("Quantity");

                    b.Property<decimal>("UnitPrice");



                    b.HasIndex("OrderId");

                    b.ToTable("OrderItem");
                });

            modelBuilder.Entity("Services.Orders.Data.OrderItem", b =>
                {
                    b.HasOne("Services.Orders.Data.Order")
                        .WithMany("Items")
                        .HasForeignKey("OrderId")
                        .OnDelete(DeleteBehavior.Cascade);
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308211841_initial.cs
================================================
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Services.Orders.Data.Migrations
{
    public partial class initial : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Order",
                columns: table => new
                {
                    Id = table.Column<Guid>(nullable: false),
                    CustomerId = table.Column<Guid>(nullable: false),
                    TotalAmount = table.Column<decimal>(nullable: false),
                    Status = table.Column<int>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Order", x => x.Id);
                });

            migrationBuilder.CreateTable(
                name: "OrderItem",
                columns: table => new
                {
                    Id = table.Column<Guid>(nullable: false),
                    OrderId = table.Column<Guid>(nullable: false),
                    ProductId = table.Column<long>(nullable: false),
                    Name = table.Column<string>(nullable: true),
                    Quantity = table.Column<int>(nullable: false),
                    UnitPrice = table.Column<decimal>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_OrderItem", x => x.Id);
                    table.ForeignKey(
                        name: "FK_OrderItem_Order_OrderId",
                        column: x => x.OrderId,
                        principalTable: "Order",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                });

            migrationBuilder.CreateIndex(
                name: "IX_OrderItem_OrderId",
                table: "OrderItem",
                column: "OrderId");
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "OrderItem");

            migrationBuilder.DropTable(
                name: "Order");
        }
    }
}


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308222202_base_entity.Designer.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Orders.Data.Migrations
{
    [DbContext(typeof(OrderDBContext))]
    [Migration("20190308222202_base_entity")]
    partial class base_entity
    {
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Orders.Data.Order", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<Guid>("CustomerId");

                    b.Property<int>("Status");

                    b.Property<decimal>("TotalAmount");

                    b.Property<DateTime?>("UpdateDate");



                    b.ToTable("Order");
                });

            modelBuilder.Entity("Services.Orders.Data.OrderItem", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Name");

                    b.Property<Guid>("OrderId");

                    b.Property<long>("ProductId");

                    b.Property<int>("Quantity");

                    b.Property<decimal>("UnitPrice");

                    b.Property<DateTime?>("UpdateDate");



                    b.HasIndex("OrderId");

                    b.ToTable("OrderItem");
                });

            modelBuilder.Entity("Services.Orders.Data.OrderItem", b =>
                {
                    b.HasOne("Services.Orders.Data.Order")
                        .WithMany("Items")
                        .HasForeignKey("OrderId")
                        .OnDelete(DeleteBehavior.Cascade);
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308222202_base_entity.cs
================================================
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Services.Orders.Data.Migrations
{
    public partial class base_entity : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<DateTime>(
                name: "UpdateDate",
                table: "OrderItem",
                nullable: false,
                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));

            migrationBuilder.AddColumn<DateTime>(
                name: "UpdateDate",
                table: "Order",
                nullable: false,
                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "UpdateDate",
                table: "OrderItem");

            migrationBuilder.DropColumn(
                name: "UpdateDate",
                table: "Order");
        }
    }
}


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/OrderDBContextModelSnapshot.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Orders.Data.Migrations
{
    [DbContext(typeof(OrderDBContext))]
    partial class OrderDBContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Orders.Data.Order", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<Guid>("CustomerId");

                    b.Property<int>("Status");

                    b.Property<decimal>("TotalAmount");

                    b.Property<DateTime?>("UpdateDate");



                    b.ToTable("Order");
                });

            modelBuilder.Entity("Services.Orders.Data.OrderItem", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Name");

                    b.Property<Guid>("OrderId");

                    b.Property<long>("ProductId");

                    b.Property<int>("Quantity");

                    b.Property<decimal>("UnitPrice");

                    b.Property<DateTime?>("UpdateDate");



                    b.HasIndex("OrderId");

                    b.ToTable("OrderItem");
                });

            modelBuilder.Entity("Services.Orders.Data.OrderItem", b =>
                {
                    b.HasOne("Services.Orders.Data.Order")
                        .WithMany("Items")
                        .HasForeignKey("OrderId")
                        .OnDelete(DeleteBehavior.Cascade);
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/OrderDBContext.cs
================================================
using Microsoft.EntityFrameworkCore;
using Services.Orders.Data;

namespace Services.Customers.Data
{
    public class OrderDBContext : DbContext
    {
        public OrderDBContext(DbContextOptions<OrderDBContext> options) : base(options)
        {
        }
        public DbSet<Order> Orders { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Order>().ToTable("Order");
            modelBuilder.Entity<Order>().HasMany(x => x.Items);
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/SeedData.cs
================================================
using System;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Services.Customers.Data;

namespace Services.Orders.Data
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            var context = serviceProvider.GetRequiredService<OrderDBContext>();
            context.Database.EnsureCreated();
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/OrderCompleted.cs
================================================
using System;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Orders.Events
{
    [MessageNamespace("customers")]
    public class OrderCompleted : IEvent
    {
        public Guid Id { get; }

        public OrderCompleted(Guid id)
        {
            Id = id;
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/OrderCreated.cs
================================================
using System;
using System.Collections.Generic;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Orders.Events
{
    [MessageNamespace("products")]
    public class OrderCreated : IEvent
    {
        public Guid Id { get; }
        public IDictionary<Guid, int> Products { get; } // id, quantity

        public OrderCreated(Guid id, IDictionary<Guid, int> products)
        {
            Id = id;
            Products = products;
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/OrderFailed.cs
================================================
using System;
using Shared.Messages;

namespace Services.Orders.Events
{
    [MessageNamespace("notifications")]
    public class OrderFailed : IEvent
    {
        public Guid OrderId { get; set; }
        public OrderFailed(Guid orderId)
        {
            this.OrderId = orderId;
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/ProductsReserveFailed.cs
================================================
using System;
using Shared.Messages;

namespace Services.Orders.Events
{
    public class ProductsReserveFailed : IEvent
    {
        public Guid OrderId { get; set; }
        public ProductsReserveFailed(Guid orderId)
        {
            this.OrderId = orderId;
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/ProductsReserved.cs
================================================
using System;
using System.Collections.Generic;
using Shared.Messages;

namespace Services.Orders.Events
{
    public class ProductsReserved : IEvent
    {
        public Guid OrderId { get; set; }
        public IDictionary<Guid, int> Products { get; set; }

        public ProductsReserved(Guid orderId, IDictionary<Guid, int> products)
        {
            OrderId = orderId;
            Products = products;
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Handlers/CreateOrderHandler.cs
================================================
using System;
using System.Linq;
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.Extensions.Logging;
using Services.Customers.Data;
using Services.Orders.Commands;
using Services.Orders.Data;
using Services.Orders.Events;
using Services.Orders.HttpServices;

namespace Services.Orders.Handlers
{
    public class CreateOrderHandler : ICommandHandler<CreateOrder>
    {
        private readonly IBusPublisher _busPublisher;
        private readonly ICustomerHttpService _customerHttpService;
        private readonly OrderDBContext _dbContext;
        private readonly ILogger<CreateOrderHandler> _logger;

        public CreateOrderHandler(IBusPublisher busPublisher,
               ICustomerHttpService customerHttpService,
               OrderDBContext dbContext,
               ILogger<CreateOrderHandler> logger)
        {
            _busPublisher = busPublisher;
            _customerHttpService = customerHttpService;
            _dbContext = dbContext;
            _logger = logger;
        }

        public async Task HandleAsync(CreateOrder command, ICorrelationContext context)
        {
            // Warning: Order service needs Customer service's data.
            // What if Customer service can't response for a while? (assume no retry policy)   

            var basket = await _customerHttpService.GetBasket(context.CustomerId);

            var items = basket.Items.Select(i =>
                new OrderItem
                {
                    Id = Guid.NewGuid(),
                    OrderId = command.Id,
                    ProductId = i.ProductId,
                    Name = i.ProductName,
                    Quantity = i.Quantity,
                    UnitPrice = i.UnitPrice
                }).ToList();

            var order = new Order
            {
                Status = OrderStatus.Created,
                Id = command.Id,
                CustomerId = context.CustomerId,
                Items = items,
                TotalAmount = items.Sum(s => s.TotalPrice)
            };

            _dbContext.Orders.Add(order);
            await _dbContext.SaveChangesAsync();

            _logger.LogInformation($"[Local Transaction] : Order created. CorrelationId: {context.CorrelationId}");
            await _busPublisher.PublishAsync(new OrderCreated(
                command.Id, items.ToDictionary(i => i.ProductId, i => i.Quantity)), context);


        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Handlers/ProductsReserveFailedHandler.cs
================================================
using System;
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.Extensions.Logging;
using Services.Customers.Data;
using Services.Orders.Data;
using Services.Orders.Events;

namespace Services.Orders.Handlers
{
    public class ProductsReserveFailedHandler : IEventHandler<ProductsReserveFailed>
    {
        private readonly IBusPublisher _busPublisher;
        private readonly OrderDBContext _dbContext;
        private readonly ILogger<ProductsReserveFailedHandler> _logger;

        public ProductsReserveFailedHandler(IBusPublisher busPublisher,
                                         OrderDBContext dbContext,
                                         ILogger<ProductsReserveFailedHandler> logger)
        {
            _logger = logger;
            _busPublisher = busPublisher;
            _dbContext = dbContext;
        }
        public async Task HandleAsync(ProductsReserveFailed _event, ICorrelationContext context)
        {
            var order = await _dbContext.Orders.FindAsync(_event.OrderId);
            order.Status = OrderStatus.Failed;
            order.UpdateDate = DateTime.Now;

            await _dbContext.SaveChangesAsync();
            _logger.LogInformation($"[Local Transaction] : Order failed. CorrelationId: {context.CorrelationId}");
            await _busPublisher.PublishAsync(new OrderFailed(_event.OrderId), context);
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Handlers/ProductsReservedHandler.cs
================================================
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.Extensions.Logging;
using Services.Customers.Data;
using Services.Orders.Data;
using Services.Orders.Events;

namespace Services.Orders.Handlers
{
    public class ProductsReservedHandler : IEventHandler<ProductsReserved>
    {
        private readonly IBusPublisher _busPublisher;
        private readonly OrderDBContext _dbContext;
        private readonly ILogger<ProductsReservedHandler> _logger;

        public ProductsReservedHandler(IBusPublisher busPublisher,
                         OrderDBContext dbContext,
                         ILogger<ProductsReservedHandler> logger)
        {
            _logger = logger;
            _busPublisher = busPublisher;
            _dbContext = dbContext;
        }
        public async Task HandleAsync(ProductsReserved _event, ICorrelationContext context)
        {
            var order = await _dbContext.Orders.FindAsync(_event.OrderId);
            order.Status = OrderStatus.Completed;

            await _dbContext.SaveChangesAsync();
            _logger.LogInformation($"[Local Transaction] : Order completed. CorrelationId: {context.CorrelationId}");
            await _busPublisher.PublishAsync(new OrderCompleted(_event.OrderId), context);
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/HttpServices/CustomerHttpService.cs
================================================
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Services.Orders.Models;

namespace Services.Orders.HttpServices
{
    public class CustomerHttpService : ICustomerHttpService
    {
        private HttpClient _client { get; }

        public CustomerHttpService(HttpClient client)
        {
            _client = client;
        }

        public async Task<Basket> GetBasket(Guid customerId)
        {
            var request = new HttpRequestMessage(HttpMethod.Get, $"basket/{customerId}");
            var response = await _client.SendAsync(request);

            var content = await response.Content.ReadAsStringAsync();
            if (response.IsSuccessStatusCode)
            {
                response.Content.Dispose();
                return JsonConvert.DeserializeObject<Basket>(content);
            }
            throw new Exception("Customer service connection error");
        }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/HttpServices/ICustomerHttpService.cs
================================================
using System;
using System.Threading.Tasks;
using Services.Orders.Models;

namespace Services.Orders.HttpServices
{
    public interface ICustomerHttpService
    {
        Task<Basket> GetBasket(Guid CustomerId);
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Models/Basket.cs
================================================
using System;
using System.Collections.Generic;

namespace Services.Orders.Models
{
    public class Basket
    {
        public Guid Id { get; set; }
        public Guid CustomerId { get; set; }
        public DateTime CreatedAt { get; set; }
        public List<BasketItem> Items { get; set; }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Models/BasketItem.cs
================================================
using System;

namespace Services.Orders.Models
{
    public class BasketItem
    {
        public Guid Id { get; set; }
        public Guid BasketId { get; set; }
        public Guid ProductId { get; set; }
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public decimal UnitPrice { get; set; }
    }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Program.cs
================================================
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Shared.Logging;

namespace Services.Orders
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseLogging("Order.Service");
    }
}


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Properties/launchSettings.json
================================================
{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:35766",
      "sslPort": 44314
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Services.Orders": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5015",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Services.Orders.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <ProjectReference Include="..\..\..\DotnetIst.Shared\src\Shared\Shared.csproj" />
  </ItemGroup>

</Project>


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/Startup.cs
================================================
using System;
using System.Net.Http.Headers;
using Shared.Models;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Services.Orders.Commands;
using Services.Orders.Data;
using Shared;
using Services.Orders.HttpServices;
using Services.Customers.Data;
using Services.Orders.Events;

namespace Services.Orders
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<OrderDBContext>(options =>
                options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"))
            );

            var httpServices = Configuration.GetOptions<HttpServiceOptions>("HttpServices");
            services.AddHttpClient<ICustomerHttpService, CustomerHttpService>(client =>
            {
                client.BaseAddress = new Uri(httpServices.CustomerHttpServiceUrl);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            return services.BuildContainer();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            app.UseRabbitMq()
               .SubscribeCommand<CreateOrder>()
               .SubscribeEvent<ProductsReserved>()
               .SubscribeEvent<ProductsReserveFailed>();

            SeedData.Initialize(app.ApplicationServices);
        }
    }
}


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/appsettings.Development.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}


================================================
FILE: DotnetIst.Services.Orders/src/Services.Orders/appsettings.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=Orders;"
  },
  "HttpServices": {
    "CustomerHttpServiceUrl": "http://localhost:5005/api/"
  },
  "rabbitMq": {
    "namespace": "orders",
    "retries": 3,
    "retryInterval": 2,
    "username": "guest",
    "password": "guest",
    "virtualHost": "/",
    "port": 5672,
    "hostnames": [
      "localhost"
    ],
    "requestTimeout": "00:00:10",
    "publishConfirmTimeout": "00:00:01",
    "recoveryInterval": "00:00:10",
    "persistentDeliveryMode": true,
    "autoCloseConnection": true,
    "automaticRecovery": true,
    "topologyRecovery": true,
    "exchange": {
      "durable": true,
      "autoDelete": false,
      "type": "Topic"
    },
    "queue": {
      "autoDelete": false,
      "durable": true,
      "exclusive": false
    }
  }
}

================================================
FILE: DotnetIst.Services.Products/README.md
================================================
**Migration**

0- .csproj path

1- *dotnet ef migrations add "migration_name" -o ./Data/Migrations*

2- *dotnet ef database update*

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Controllers/HomeController.cs
================================================
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Services.Products.Controllers
{
    [Route("")]
    public class HomeController : ControllerBase
    {
        [HttpGet]
        [AllowAnonymous]
        public IActionResult Get()
        {
            return Ok("Product service is up.");
        }
    }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Controllers/ProductController.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Services.Customers.Data;
using Services.Products.Data;

namespace Services.Products.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ProductController : ControllerBase
    {
        private readonly ProductDBContext _dbContext;

        public ProductController(ProductDBContext dbContext)
        {
            _dbContext = dbContext;
        }
        [HttpGet("{id}")]
        public async Task<ActionResult> Get(Guid id)
        {
            return Ok(await _dbContext.Products.FindAsync(id));
        }

        [HttpGet]
        public async Task<ActionResult> Get()
        {
            return Ok(await _dbContext.Products.ToListAsync());
        }
    }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Data/Entity/Product.cs
================================================
using System;
using Shared.Models;

namespace Services.Products.Data
{
    public class Product : BaseEntity
    {
        public string Name { get; set; }
        public decimal Price { get; set; }
        public int Quantity { get; set; }
    }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308212022_initial.Designer.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Products.Data.Migrations
{
    [DbContext(typeof(ProductDBContext))]
    [Migration("20190308212022_initial")]
    partial class initial
    {
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Products.Data.Product", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Name");

                    b.Property<decimal>("Price");

                    b.Property<int>("Quantity");



                    b.ToTable("Product");
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308212022_initial.cs
================================================
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Services.Products.Data.Migrations
{
    public partial class initial : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.CreateTable(
                name: "Product",
                columns: table => new
                {
                    Id = table.Column<Guid>(nullable: false),
                    Name = table.Column<string>(nullable: true),
                    Price = table.Column<decimal>(nullable: false),
                    Quantity = table.Column<int>(nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Product", x => x.Id);
                });
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Product");
        }
    }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308222331_base_entity.Designer.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Products.Data.Migrations
{
    [DbContext(typeof(ProductDBContext))]
    [Migration("20190308222331_base_entity")]
    partial class base_entity
    {
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Products.Data.Product", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Name");

                    b.Property<decimal>("Price");

                    b.Property<int>("Quantity");

                    b.Property<DateTime?>("UpdateDate");



                    b.ToTable("Product");
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308222331_base_entity.cs
================================================
using System;
using Microsoft.EntityFrameworkCore.Migrations;

namespace Services.Products.Data.Migrations
{
    public partial class base_entity : Migration
    {
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AddColumn<DateTime>(
                name: "UpdateDate",
                table: "Product",
                nullable: false,
                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
        }

        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropColumn(
                name: "UpdateDate",
                table: "Product");
        }
    }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/ProductDBContextModelSnapshot.cs
================================================
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
using Services.Customers.Data;

namespace Services.Products.Data.Migrations
{
    [DbContext(typeof(ProductDBContext))]
    partial class ProductDBContextModelSnapshot : ModelSnapshot
    {
        protected override void BuildModel(ModelBuilder modelBuilder)
        {
#pragma warning disable 612, 618
            modelBuilder
                .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
                .HasAnnotation("ProductVersion", "2.2.1-servicing-10028")
                .HasAnnotation("Relational:MaxIdentifierLength", 63);

            modelBuilder.Entity("Services.Products.Data.Product", b =>
                {
                    b.Property<Guid>("Id")
                        .ValueGeneratedOnAdd();

                    b.Property<string>("Name");

                    b.Property<decimal>("Price");

                    b.Property<int>("Quantity");

                    b.Property<DateTime?>("UpdateDate");

                    b.ToTable("Product");
                });
#pragma warning restore 612, 618
        }
    }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Data/ProductDBContext.cs
================================================
using Microsoft.EntityFrameworkCore;
using Services.Products.Data;

namespace Services.Customers.Data
{
    public class ProductDBContext : DbContext
    {
        public ProductDBContext(DbContextOptions<ProductDBContext> options) : base(options)
        {
        }
        public DbSet<Product> Products { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Product>().ToTable("Product");
        }
    }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Data/SeedData.cs
================================================
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Extensions.DependencyInjection;
using Services.Customers.Data;
using Services.Products.Data;

namespace Services.Products.Data
{
    public static class SeedData
    {
        public static void Initialize(IServiceProvider serviceProvider)
        {
            var context = serviceProvider.GetRequiredService<ProductDBContext>();
            context.Database.EnsureCreated();
            if (!context.Products.Any())
            {
                var products = new List<Product>()
                {
                    new Product { Name = "Printer", Price = 200, Quantity = 500 },
                    new Product() { Name = "Mouse", Price = 20, Quantity = 500 },
                    new Product() { Name = "Keyboard", Price = 50, Quantity = 500 }
                };

                context.Products.AddRange(products);
                context.SaveChanges();
            }
        }
    }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Events/OrderCreated.cs
================================================
using System;
using System.Collections.Generic;
using Shared.Messages;
using Newtonsoft.Json;

namespace Services.Products.Events
{
    public class OrderCreated : IEvent
    {
        public Guid Id { get; }
        public IDictionary<Guid, int> Products { get; } // id, quantity

        public OrderCreated(Guid id, IDictionary<Guid, int> products)
        {
            Id = id;
            Products = products;
        }
    }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Events/ProductsReserveFailed.cs
================================================
using System;
using Shared.Messages;

namespace Services.Products.Events
{
    [MessageNamespace("orders")]
    public class ProductsReserveFailed : IEvent
    {
        public Guid OrderId { get; set; }
        public ProductsReserveFailed(Guid orderId)
        {
            this.OrderId = orderId;
        }
    }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Events/ProductsReserved.cs
================================================
using System;
using System.Collections.Generic;
using Shared.Messages;

namespace Services.Products.Events
{
    [MessageNamespace("orders")]
    public class ProductsReserved : IEvent
    {
        public Guid OrderId { get; set; }
        public IDictionary<Guid, int> Products { get; set; }
        public ProductsReserved(Guid orderId, IDictionary<Guid, int> products)
        {
            OrderId = orderId;
            Products = products;
        }
    }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Handlers/OrderCreatedHandler.cs
================================================
using System;
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.RabbitMq;
using Microsoft.Extensions.Logging;
using Services.Customers.Data;
using Services.Products.Events;

namespace Services.Products.Handlers
{
    public class OrderCreatedHandler : IEventHandler<OrderCreated>
    {
        private readonly ProductDBContext _dbContext;
        private readonly IBusPublisher _busPublisher;
        private readonly ILogger<OrderCreatedHandler> _logger;

        public OrderCreatedHandler(ProductDBContext dbContext,
                            IBusPublisher busPublisher,
                            ILogger<OrderCreatedHandler> logger)
        {
            _logger = logger;
            _dbContext = dbContext;
            _busPublisher = busPublisher;
        }
        public async Task HandleAsync(OrderCreated _event, ICorrelationContext context)
        {
            var isReserved = true;

            foreach ((Guid productId, int quantity) in _event.Products)
            {
                var product = await _dbContext.Products.FindAsync(productId);

                if (product == null)
                {
                    isReserved = false;
                    _logger.LogInformation($"[Local Transaction] : Product '{productId}' not found. CorrelationId: {context.CorrelationId}");
                    break;
                }

                if (quantity > product.Quantity)
                {
                    isReserved = false;
                    _logger.LogInformation($"[Local Transaction] : Not available {product.Quantity} {product.Name}. CorrelationId: {context.CorrelationId}");
                    break;
                }
                else
                {
                    product.Quantity -= quantity;
                    product.UpdateDate = DateTime.Now;
                }
            }

            if (isReserved)
            {
                await _dbContext.SaveChangesAsync();
                _logger.LogInformation($"[Local Transaction] : Products reserved. CorrelationId: {context.CorrelationId}");
                await _busPublisher.PublishAsync(new ProductsReserved(_event.Id, _event.Products), context);
            }
            else
            {
                _logger.LogInformation($"[Local Transaction] : Products could not be reserved. CorrelationId: {context.CorrelationId}");
                await _busPublisher.PublishAsync(new ProductsReserveFailed(_event.Id), context);
            }
        }
    }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Program.cs
================================================
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Shared.Logging;

namespace Services.Products
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
                .UseLogging("Product.Service");
    }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Properties/launchSettings.json
================================================
{
  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": {
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:29904",
      "sslPort": 44329
    }
  },
  "profiles": {
    "IIS Express": {
      "commandName": "IISExpress",
      "launchBrowser": true,
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    },
    "Services.Products": {
      "commandName": "Project",
      "launchBrowser": true,
      "applicationUrl": "http://localhost:5010",
      "environmentVariables": {
        "ASPNETCORE_ENVIRONMENT": "Development"
      }
    }
  }
}

================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Services.Products.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.2</TargetFramework>
    <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.App" />
    <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
    <ProjectReference Include="..\..\..\DotnetIst.Shared\src\Shared\Shared.csproj" />
  </ItemGroup>

</Project>


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/Startup.cs
================================================
using System;
using Shared;
using Shared.RabbitMq;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Services.Customers.Data;
using Services.Products.Data;
using Services.Products.Events;

namespace Services.Products
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<ProductDBContext>(options =>
                options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection"))
            );
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            return services.BuildContainer();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            app.UseRabbitMq()
               .SubscribeEvent<OrderCreated>();

            SeedData.Initialize(app.ApplicationServices);
        }
    }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/appsettings.Development.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}


================================================
FILE: DotnetIst.Services.Products/src/Services.Products/appsettings.json
================================================
{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Host=localhost;Port=5432;Username=postgres;Password=postgres;Database=Products;"
  },
  "rabbitMq": {
    "namespace": "products",
    "retries": 3,
    "retryInterval": 2,
    "username": "guest",
    "password": "guest",
    "virtualHost": "/",
    "port": 5672,
    "hostnames": [
      "localhost"
    ],
    "requestTimeout": "00:00:10",
    "publishConfirmTimeout": "00:00:01",
    "recoveryInterval": "00:00:10",
    "persistentDeliveryMode": true,
    "autoCloseConnection": true,
    "automaticRecovery": true,
    "topologyRecovery": true,
    "exchange": {
      "durable": true,
      "autoDelete": false,
      "type": "Topic"
    },
    "queue": {
      "autoDelete": false,
      "durable": true,
      "exclusive": false
    }
  }
}

================================================
FILE: DotnetIst.Shared/src/Shared/Extensions.cs
================================================
using System;
using System.Linq;
using System.Reflection;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Shared.RabbitMq;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace Shared
{
    public static class Extensions
    {
        public static string Underscore(this string value)
            => string.Concat(value.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString()));

        public static TModel GetOptions<TModel>(this IConfiguration configuration, string section) where TModel : new()
        {
            var model = new TModel();
            configuration.GetSection(section).Bind(model);
            return model;
        }

        public static IServiceProvider BuildContainer(this IServiceCollection services)
        {
            var builder = new ContainerBuilder();
            builder.RegisterAssemblyTypes(Assembly.GetCallingAssembly())
                .AsImplementedInterfaces();
            builder.Populate(services);
            builder.AddRabbitMq();
            return new AutofacServiceProvider(builder.Build());
        }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/Logging/LoggingExtensions.cs
================================================
using System;
using Microsoft.AspNetCore.Hosting;
using Serilog;
using Serilog.Sinks.Elasticsearch;

namespace Shared.Logging
{
    public static class Extensions
    {
        public static IWebHostBuilder UseLogging(this IWebHostBuilder webHostBuilder, string applicationName)
        {
            return webHostBuilder.UseSerilog((context, loggerConfiguration) =>
            {
                loggerConfiguration.Enrich.FromLogContext()
                    .Enrich.WithProperty("Environment", context.HostingEnvironment.EnvironmentName)
                    .Enrich.WithProperty("ApplicationName", applicationName);

                loggerConfiguration
                .WriteTo.Console()
                .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://localhost:9200/"))
                {
                    AutoRegisterTemplate = true,
                    IndexFormat = "logstash-{0:yyyy.MM.dd}"
                });
            });
        }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/MessageHandlers/ICommandHandler.cs
================================================
using System.Threading.Tasks;
using Shared.Messages;
using Shared.RabbitMq;

namespace Shared.MessageHandlers
{
    public interface ICommandHandler<in TCommand> where TCommand : ICommand
    {
        Task HandleAsync(TCommand command, ICorrelationContext context);
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/MessageHandlers/IEventHandler.cs
================================================
using System.Threading.Tasks;
using Shared.Messages;
using Shared.RabbitMq;

namespace Shared.MessageHandlers
{
    public interface IEventHandler<in TEvent> where TEvent : IEvent
    {
        Task HandleAsync(TEvent _event, ICorrelationContext context);
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/Messages/ICommand.cs
================================================
namespace Shared.Messages
{
    public interface ICommand
    {

    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/Messages/IEvent.cs
================================================
namespace Shared.Messages
{
    public interface IEvent
    {

    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/Messages/MessageNamespaceAttribute.cs
================================================
using System;

namespace Shared.Messages
{
    public class MessageNamespaceAttribute : Attribute
    {
        public string Namespace { get; }

        public MessageNamespaceAttribute(string _namespace)
        {
            Namespace = _namespace?.ToLowerInvariant();
        }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/Models/BaseEntity.cs
================================================
using System;

namespace Shared.Models
{
    public class BaseEntity
    {
        public Guid Id { get; set; }
        public DateTime CreateDate { get; set; }
        public DateTime? UpdateDate { get; set; }
        public BaseEntity()
        {
            this.CreateDate = DateTime.Now;
        }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/Models/HttpServiceOptions.cs
================================================
namespace Shared.Models
{
    public class HttpServiceOptions
    {
        public string ProductHttpServiceUrl { get; set; }
        public string CustomerHttpServiceUrl { get; set; }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/RabbitMq/BusPublisher.cs
================================================
using System.Reflection;
using System.Threading.Tasks;
using Shared.Messages;
using Microsoft.Extensions.Logging;
using RawRabbit;
using RawRabbit.Enrichers.MessageContext;

namespace Shared.RabbitMq
{
    public class BusPublisher : IBusPublisher
    {
        private readonly IBusClient _busClient;
        private readonly ILogger<IBusPublisher> _logger;
        private readonly string _defaultNamespace;

        public BusPublisher(IBusClient busClient, RabbitMqOptions options, ILogger<IBusPublisher> logger)
        {
            _busClient = busClient;
            _logger = logger;
            _defaultNamespace = options.Namespace;
        }

        public async Task SendAsync<TCommand>(TCommand command, ICorrelationContext context)
            where TCommand : ICommand
        {
            var commandName = command.GetType().Name;
            _logger.LogInformation($"[Sent a command] : '{commandName}' Correlation id: '{context.CorrelationId}'");

            await _busClient.PublishAsync(command, ctx => ctx.UseMessageContext(context)
                 .UsePublishConfiguration(p => p.WithRoutingKey(GetRoutingKey(command))));
        }

        public async Task PublishAsync<TEvent>(TEvent _event, ICorrelationContext context)
            where TEvent : IEvent
        {
            var eventName = _event.GetType().Name;
            _logger.LogInformation($"[Published an event] : '{eventName}' Correlation id: '{context.CorrelationId}'");

            await _busClient.PublishAsync(_event, ctx => ctx.UseMessageContext(context)
                 .UsePublishConfiguration(p => p.WithRoutingKey(GetRoutingKey(_event))));
        }

        private string GetRoutingKey<T>(T message)
        {
            var _namespace = message.GetType().GetCustomAttribute<MessageNamespaceAttribute>()?.Namespace ?? _defaultNamespace;
            _namespace = string.IsNullOrWhiteSpace(_namespace) ? string.Empty : $"{_namespace}.";

            return $"{_namespace}{typeof(T).Name.Underscore()}".ToLowerInvariant();
        }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/RabbitMq/BusSubscriber.cs
================================================
using System;
using System.Reflection;
using System.Threading.Tasks;
using Shared.MessageHandlers;
using Shared.Messages;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Polly;
using RawRabbit;
using RawRabbit.Common;

namespace Shared.RabbitMq
{
    public class BusSubscriber : IBusSubscriber
    {
        private readonly ILogger _logger;
        private readonly IBusClient _busClient;
        private readonly IServiceProvider _serviceProvider;
        private readonly string _defaultNamespace;
        private readonly int _retries;
        private readonly int _retryInterval;

        public BusSubscriber(IApplicationBuilder app)
        {
            _logger = app.ApplicationServices.GetService<ILogger<BusSubscriber>>();
            _serviceProvider = app.ApplicationServices.GetService<IServiceProvider>();
            _busClient = _serviceProvider.GetService<IBusClient>();

            var options = _serviceProvider.GetService<RabbitMqOptions>();
            _defaultNamespace = options.Namespace;
            _retries = options.Retries >= 0 ? options.Retries : 3;
            _retryInterval = options.RetryInterval > 0 ? options.RetryInterval : 2;
        }

        public IBusSubscriber SubscribeCommand<TCommand>(string _namespace = null)
            where TCommand : ICommand
        {
            _busClient.SubscribeAsync<TCommand, CorrelationContext>(async (command, correlationContext) =>
                {
                    var commandHandler = _serviceProvider.GetService<ICommandHandler<TCommand>>();

                    return await TryHandleAsync(command, correlationContext,
                        () => commandHandler.HandleAsync(command, correlationContext));
                },
                ctx => ctx.UseSubscribeConfiguration(cfg =>
                    cfg.FromDeclaredQueue(q => q.WithName(GetQueueName<TCommand>(_namespace)))));

            return this;
        }

        public IBusSubscriber SubscribeEvent<TEvent>(string _namespace = null)
            where TEvent : IEvent
        {
            _busClient.SubscribeAsync<TEvent, CorrelationContext>(async (_event, correlationContext) =>
                {
                    var eventHandler = _serviceProvider.GetService<IEventHandler<TEvent>>();

                    return await TryHandleAsync(_event, correlationContext,
                        () => eventHandler.HandleAsync(_event, correlationContext));
                },
                ctx => ctx.UseSubscribeConfiguration(cfg =>
                    cfg.FromDeclaredQueue(q => q.WithName(GetQueueName<TEvent>(_namespace)))));

            return this;
        }

        private async Task<Acknowledgement> TryHandleAsync<TMessage>(TMessage message,
            CorrelationContext correlationContext, Func<Task> handle)
        {
            var currentRetry = 0;
            var retryPolicy = Policy
                .Handle<Exception>()
                .WaitAndRetryAsync(_retries, i => TimeSpan.FromSeconds(_retryInterval));

            var messageName = message.GetType().Name;

            return await retryPolicy.ExecuteAsync<Acknowledgement>(async () =>
            {
                var retryMessage = currentRetry == 0 ? string.Empty : $"Retry: {currentRetry}'.";
                var messageType = message is IEvent ? "n event" : " command";

                _logger.LogInformation($"[Handled a{messageType}] : '{messageName}' " +
                                     $"Correlation id: '{correlationContext.CorrelationId}'. {retryMessage}");
                await handle();

                return new Ack();
            });
        }

        private string GetQueueName<T>(string _namespace = null)
        {
            _namespace = string.IsNullOrWhiteSpace(_namespace)
                ? (string.IsNullOrWhiteSpace(_defaultNamespace) ? string.Empty : _defaultNamespace)
                : _namespace;
            var separatedNamespace = string.IsNullOrWhiteSpace(_namespace) ? string.Empty : $"{_namespace}.";
            return $"{Assembly.GetEntryAssembly().GetName().Name}/{separatedNamespace}{typeof(T).Name.Underscore()}";
        }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/RabbitMq/CorrelationContext.cs
================================================
using System;
using Newtonsoft.Json;

namespace Shared.RabbitMq
{
    public class CorrelationContext : ICorrelationContext
    {
        public Guid CorrelationId { get; }
        public Guid CustomerId { get; }

        public CorrelationContext()
        {
        }

        [JsonConstructor]
        private CorrelationContext(Guid correlationId, Guid customerId)
        {
            CorrelationId = correlationId;
            CustomerId = customerId;
        }

        public static ICorrelationContext Create(Guid id, Guid customerId)
        {
            return new CorrelationContext(id, customerId);
        }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/RabbitMq/IBusPublisher.cs
================================================
using System.Threading.Tasks;
using Shared.Messages;

namespace Shared.RabbitMq
{
    public interface IBusPublisher
    {
        Task SendAsync<TCommand>(TCommand command, ICorrelationContext context)
            where TCommand : ICommand;

        Task PublishAsync<TEvent>(TEvent _event, ICorrelationContext context)
            where TEvent : IEvent;
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/RabbitMq/IBusSubscriber.cs
================================================
using System;
using Shared.Messages;

namespace Shared.RabbitMq
{
    public interface IBusSubscriber
    {
        IBusSubscriber SubscribeCommand<TCommand>(string _namespace = null)
            where TCommand : ICommand;

        IBusSubscriber SubscribeEvent<TEvent>(string _namespace = null)
            where TEvent : IEvent;
    }
}


================================================
FILE: DotnetIst.Shared/src/Shared/RabbitMq/ICorrelationContext.cs
================================================
using System;

namespace Shared.RabbitMq
{
    public interface ICorrelationContext
    {
        Guid CorrelationId { get; }
        Guid CustomerId { get; }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/RabbitMq/RabbitMqExtensions.cs
================================================
using System.Reflection;
using Autofac;
using Shared.MessageHandlers;
using Shared.Messages;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using RawRabbit;
using RawRabbit.Common;
using RawRabbit.Configuration;
using RawRabbit.Enrichers.MessageContext;
using RawRabbit.Instantiation;

namespace Shared.RabbitMq
{
    public static class RabbitMqExtensions
    {
        public static IBusSubscriber UseRabbitMq(this IApplicationBuilder app)
            => new BusSubscriber(app);

        public static void AddRabbitMq(this ContainerBuilder builder)
        {
            builder.Register(context =>
            {
                var configuration = context.Resolve<IConfiguration>();
                var options = configuration.GetOptions<RabbitMqOptions>("rabbitMq");
                return options;
            }).SingleInstance();

            builder.Register(context =>
            {
                var configuration = context.Resolve<IConfiguration>();
                var options = configuration.GetOptions<RawRabbitConfiguration>("rabbitMq");
                return options;
            }).SingleInstance();

            var assembly = Assembly.GetCallingAssembly();
            builder.RegisterAssemblyTypes(assembly)
                .AsClosedTypesOf(typeof(IEventHandler<>))
                .InstancePerDependency();
            builder.RegisterAssemblyTypes(assembly)
                .AsClosedTypesOf(typeof(ICommandHandler<>))
                .InstancePerDependency();
            builder.RegisterType<BusPublisher>().As<IBusPublisher>()
                .InstancePerDependency();
            ConfigureBus(builder);
        }

        private static void ConfigureBus(ContainerBuilder builder)
        {
            builder.Register<IInstanceFactory>(context =>
            {
                var options = context.Resolve<RabbitMqOptions>();
                var configuration = context.Resolve<RawRabbitConfiguration>();
                var namingConventions = new CustomNamingConventions(options.Namespace);

                return RawRabbitFactory.CreateInstanceFactory(new RawRabbitOptions
                {
                    DependencyInjection = ioc =>
                    {
                        ioc.AddSingleton(options);
                        ioc.AddSingleton(configuration);
                        ioc.AddSingleton<INamingConventions>(namingConventions);

                    },
                    Plugins = p => p
                        .UseAttributeRouting()
                        .UseRetryLater()
                        .UseMessageContext<CorrelationContext>()
                        .UseContextForwarding()
                });
            }).SingleInstance();
            builder.Register(context => context.Resolve<IInstanceFactory>().Create());
        }

        private class CustomNamingConventions : NamingConventions
        {
            public CustomNamingConventions(string defaultNamespace)
            {
                ExchangeNamingConvention = type => (type.GetCustomAttribute<MessageNamespaceAttribute>()?.Namespace ??
                     defaultNamespace).ToLowerInvariant();
                RoutingKeyConvention = type =>
                    $"#.{type.GetCustomAttribute<MessageNamespaceAttribute>()?.Namespace ?? defaultNamespace}.{type.Name.Underscore()}"
                    .ToLowerInvariant();
            }
        }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/RabbitMq/RabbitMqOptions.cs
================================================
using RawRabbit.Configuration;

namespace Shared.RabbitMq
{
    public class RabbitMqOptions : RawRabbitConfiguration
    {
        public string Namespace { get; set; }
        public int Retries { get; set; }
        public int RetryInterval { get; set; }
    }
}

================================================
FILE: DotnetIst.Shared/src/Shared/Shared.csproj
================================================
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
    <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />

    <PackageReference Include="RawRabbit" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.DependencyInjection.ServiceCollection" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.Enrichers.Attributes" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.Enrichers.Polly" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.Enrichers.MessageContext" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.Enrichers.MessageContext.Subscribe" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.DependencyInjection.Autofac" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.Enrichers.RetryLater" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.Operations.Publish" Version="2.0.0-rc5" />
    <PackageReference Include="RawRabbit.Operations.Subscribe" Version="2.0.0-rc5" />

    <PackageReference Include="Autofac" Version="4.8.1" />
    <PackageReference Include="Autofac.Extensions.DependencyInjection" Version="4.3.1" />

    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
    <PackageReference Include="NpgSql.EntityFrameworkCore.PostgreSQL.Design" Version="1.1.1" />

    <PackageReference Include="Serilog" Version="2.7.1" />
    <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" />
    <PackageReference Include="Serilog.Extensions.Logging" Version="2.0.2" />
    <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
    <PackageReference Include="Serilog.Sinks.Elasticsearch" Version="6.5.0" />
        
  </ItemGroup>

</Project>


================================================
FILE: README.md
================================================
Presentation : https://speakerdeck.com/suadev/microservice-architecture-and-implementation-with-asp-dot-net-core

The aim of the demo is showing ***event-driven and eventual consistent communication*** between the microservices. 

<img src="https://speakerd.s3.amazonaws.com/presentations/d74133b1f0d1409ab6093806e005f64e/preview_slide_17.jpg" />


## Prerequities

* DotNet Core SDK 2.2

* Docker

* pgAdmin or Azure Data Studio (Needs PostgreSQL extension - https://github.com/Microsoft/azuredatastudio-postgresql/ )


## Running in Debug Mode

* Run 'docker-compose up'

* Wait all services to up and running. ( rabbitmq, postgres, elasticsearch and kibana )

* Select 'All' debug option and start debuging.

* Wait until all microservices are up and running.

P.S. You can use ***.postman_project/Dotnet_Istanbul.postman_collection.json*** file for a quick test from Postman.


## Tool Set

* Asp.Net Core 2.2 
* Entity Framework Core 2.2
* PostgreSQL - Npgsql
* Serilog - Elasticsearch - Kibana
* RabbitMQ - RawRabbit
* Docker Containers ( PostgreSQL, RabbitMQ, Elasticsearch and Kibana )
* pgAdmin or Azure Data Studio
* VS Code


================================================
FILE: docker-compose.yml
================================================
version: '3.7'

services:

  rabbitmq:
    image: rabbitmq:3-management
    container_name: myrabbitmq
    ports:
      - "15672:15672"
      - "5672:5672"
    environment:
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest

  postgres:
    image: postgres
    container_name: mypostgres
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_PASSWORD=postgres

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.6.1
    container_name: myelastic
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    ports:
      - "9200:9200"
      - "9300:9300"

  kibana:
    image: docker.elastic.co/kibana/kibana:6.6.1
    container_name: mykibana
    ports:
      - "5601:5601"

================================================
FILE: dotnet-istanbul-microservices-demo.sln
================================================

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotnetIst.Api", "DotnetIst.Api", "{674A9DD4-F9DA-4F9F-81E3-AB6A24C5149D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CA1A4673-F703-4C40-B44E-AE28673B4A71}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Api", "DotnetIst.Api\src\Api\Api.csproj", "{2BCBD3FB-715D-45A5-96DB-346608043045}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotnetIst.Shared", "DotnetIst.Shared", "{A14724F1-AE75-45BE-AFF2-F46603C797DE}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{7FC87A4C-7F67-49D8-A702-9CC75F9910FB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shared", "DotnetIst.Shared\src\Shared\Shared.csproj", "{DCF6A908-B7C2-412C-924D-A598647F7540}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotnetIst.Services.Customers", "DotnetIst.Services.Customers", "{6806424F-4261-4347-8CDE-5F6399BBC6BF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EA331B36-EF9B-4C04-B52F-0192A629A229}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Customers", "DotnetIst.Services.Customers\src\Services.Customers\Services.Customers.csproj", "{FA617103-F493-4FDD-96FA-0E83B881E0B0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotnetIst.Services.Notifications", "DotnetIst.Services.Notifications", "{3B87C5C6-314D-4101-B233-A196403845AB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{84EC4F28-DC06-4F42-90B1-F7C8D57B6C1B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Notifications", "DotnetIst.Services.Notifications\src\Services.Notifications\Services.Notifications.csproj", "{577857E0-19A7-406C-8495-7BCF71886F71}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotnetIst.Services.Orders", "DotnetIst.Services.Orders", "{8E520BD8-B6D7-4205-93FC-7F9BFA99A4A7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{28BA3B30-1F93-4907-B6BB-32D09A038CC9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Orders", "DotnetIst.Services.Orders\src\Services.Orders\Services.Orders.csproj", "{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DotnetIst.Services.Products", "DotnetIst.Services.Products", "{020A54F8-7DC3-4148-8797-7534A89B32F7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B5E52D90-0C27-4D1C-9DCE-B614658969FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services.Products", "DotnetIst.Services.Products\src\Services.Products\Services.Products.csproj", "{83E22247-7E48-429B-83B7-979263473F36}"
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Debug|x64 = Debug|x64
		Debug|x86 = Debug|x86
		Release|Any CPU = Release|Any CPU
		Release|x64 = Release|x64
		Release|x86 = Release|x86
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = postSolution
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Debug|x64.ActiveCfg = Debug|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Debug|x64.Build.0 = Debug|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Debug|x86.ActiveCfg = Debug|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Debug|x86.Build.0 = Debug|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Release|Any CPU.Build.0 = Release|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Release|x64.ActiveCfg = Release|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Release|x64.Build.0 = Release|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Release|x86.ActiveCfg = Release|Any CPU
		{2BCBD3FB-715D-45A5-96DB-346608043045}.Release|x86.Build.0 = Release|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Debug|x64.ActiveCfg = Debug|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Debug|x64.Build.0 = Debug|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Debug|x86.ActiveCfg = Debug|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Debug|x86.Build.0 = Debug|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Release|Any CPU.Build.0 = Release|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Release|x64.ActiveCfg = Release|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Release|x64.Build.0 = Release|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Release|x86.ActiveCfg = Release|Any CPU
		{DCF6A908-B7C2-412C-924D-A598647F7540}.Release|x86.Build.0 = Release|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Debug|x64.ActiveCfg = Debug|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Debug|x64.Build.0 = Debug|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Debug|x86.ActiveCfg = Debug|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Debug|x86.Build.0 = Debug|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Release|Any CPU.Build.0 = Release|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Release|x64.ActiveCfg = Release|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Release|x64.Build.0 = Release|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Release|x86.ActiveCfg = Release|Any CPU
		{FA617103-F493-4FDD-96FA-0E83B881E0B0}.Release|x86.Build.0 = Release|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Debug|x64.ActiveCfg = Debug|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Debug|x64.Build.0 = Debug|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Debug|x86.ActiveCfg = Debug|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Debug|x86.Build.0 = Debug|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Release|Any CPU.Build.0 = Release|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Release|x64.ActiveCfg = Release|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Release|x64.Build.0 = Release|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Release|x86.ActiveCfg = Release|Any CPU
		{577857E0-19A7-406C-8495-7BCF71886F71}.Release|x86.Build.0 = Release|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Debug|x64.ActiveCfg = Debug|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Debug|x64.Build.0 = Debug|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Debug|x86.ActiveCfg = Debug|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Debug|x86.Build.0 = Debug|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Release|Any CPU.Build.0 = Release|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Release|x64.ActiveCfg = Release|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Release|x64.Build.0 = Release|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Release|x86.ActiveCfg = Release|Any CPU
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0}.Release|x86.Build.0 = Release|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Debug|x64.ActiveCfg = Debug|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Debug|x64.Build.0 = Debug|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Debug|x86.ActiveCfg = Debug|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Debug|x86.Build.0 = Debug|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Release|Any CPU.Build.0 = Release|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Release|x64.ActiveCfg = Release|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Release|x64.Build.0 = Release|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Release|x86.ActiveCfg = Release|Any CPU
		{83E22247-7E48-429B-83B7-979263473F36}.Release|x86.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(NestedProjects) = preSolution
		{CA1A4673-F703-4C40-B44E-AE28673B4A71} = {674A9DD4-F9DA-4F9F-81E3-AB6A24C5149D}
		{2BCBD3FB-715D-45A5-96DB-346608043045} = {CA1A4673-F703-4C40-B44E-AE28673B4A71}
		{7FC87A4C-7F67-49D8-A702-9CC75F9910FB} = {A14724F1-AE75-45BE-AFF2-F46603C797DE}
		{DCF6A908-B7C2-412C-924D-A598647F7540} = {7FC87A4C-7F67-49D8-A702-9CC75F9910FB}
		{EA331B36-EF9B-4C04-B52F-0192A629A229} = {6806424F-4261-4347-8CDE-5F6399BBC6BF}
		{FA617103-F493-4FDD-96FA-0E83B881E0B0} = {EA331B36-EF9B-4C04-B52F-0192A629A229}
		{84EC4F28-DC06-4F42-90B1-F7C8D57B6C1B} = {3B87C5C6-314D-4101-B233-A196403845AB}
		{577857E0-19A7-406C-8495-7BCF71886F71} = {84EC4F28-DC06-4F42-90B1-F7C8D57B6C1B}
		{28BA3B30-1F93-4907-B6BB-32D09A038CC9} = {8E520BD8-B6D7-4205-93FC-7F9BFA99A4A7}
		{3AF46C68-DA51-4CFE-B9D1-BA247AF2C9C0} = {28BA3B30-1F93-4907-B6BB-32D09A038CC9}
		{B5E52D90-0C27-4D1C-9DCE-B614658969FA} = {020A54F8-7DC3-4148-8797-7534A89B32F7}
		{83E22247-7E48-429B-83B7-979263473F36} = {B5E52D90-0C27-4D1C-9DCE-B614658969FA}
	EndGlobalSection
EndGlobal
Download .txt
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
Download .txt
SYMBOL INDEX (275 symbols across 113 files)

FILE: DotnetIst.Api/src/Api/Authentication/AuthenticationExtensions.cs
  class AuthenticationExtensions (line 12) | public static class AuthenticationExtensions
    method AddJwtAuthentication (line 15) | public static void AddJwtAuthentication(this IServiceCollection services)

FILE: DotnetIst.Api/src/Api/Authentication/AuthenticationService.cs
  class AuthenticationService (line 10) | public class AuthenticationService : IAuthenticationService
    method AuthenticationService (line 14) | public AuthenticationService(IHttpContextAccessor contextAccessor)
    method GetCurrentUser (line 19) | public TokenModel GetCurrentUser()
    method GetToken (line 23) | public string GetToken(Customer customer)

FILE: DotnetIst.Api/src/Api/Authentication/IAuthenticationService.cs
  type IAuthenticationService (line 5) | public interface IAuthenticationService
    method GetToken (line 7) | string GetToken(Customer customer);

FILE: DotnetIst.Api/src/Api/Authentication/Model/LoginModel.cs
  class LoginModel (line 3) | public class LoginModel

FILE: DotnetIst.Api/src/Api/Authentication/Model/TokenModel.cs
  class TokenModel (line 5) | public class TokenModel

FILE: DotnetIst.Api/src/Api/Commands/Baskets/AddProductToBasket.cs
  class AddProductToBasket (line 7) | [MessageNamespace("customers")]
    method AddProductToBasket (line 13) | public AddProductToBasket(Guid productId, int quantity)

FILE: DotnetIst.Api/src/Api/Commands/Customers/CreateCustomer.cs
  class CreateCustomer (line 7) | [MessageNamespace("customers")]
    method CreateCustomer (line 17) | public CreateCustomer(string email, string password, string firstName,...

FILE: DotnetIst.Api/src/Api/Commands/Orders/CreateOrder.cs
  class CreateOrder (line 7) | [MessageNamespace("orders")]
    method CreateOrder (line 12) | public CreateOrder()

FILE: DotnetIst.Api/src/Api/Controllers/BaseController.cs
  class BaseController (line 9) | public class BaseController : ControllerBase
    method BaseController (line 12) | public BaseController(IBusPublisher busPublisher)
    method GetContext (line 26) | protected ICorrelationContext GetContext()
    method GetContext (line 32) | protected ICorrelationContext GetContext(Guid customerId)

FILE: DotnetIst.Api/src/Api/Controllers/BasketController.cs
  class BasketController (line 9) | [Route("api/[controller]")]
    method BasketController (line 14) | public BasketController(IBusPublisher busPublisher) : base(busPublisher)
    method Post (line 19) | [HttpPost]

FILE: DotnetIst.Api/src/Api/Controllers/CustomerController.cs
  class CustomerController (line 9) | [Route("api/[controller]")]
    method CustomerController (line 13) | public CustomerController(IBusPublisher busPublisher) : base(busPublis...
    method Post (line 18) | [HttpPost]

FILE: DotnetIst.Api/src/Api/Controllers/HomeController.cs
  class HomeController (line 6) | [Route("")]
    method Get (line 9) | [HttpGet]

FILE: DotnetIst.Api/src/Api/Controllers/OrderController.cs
  class OrderController (line 9) | [Route("api/[controller]")]
    method OrderController (line 14) | public OrderController(IBusPublisher busPublisher) : base(busPublisher)
    method Post (line 19) | [HttpPost]

FILE: DotnetIst.Api/src/Api/Controllers/ProductController.cs
  class ProductController (line 10) | [Route("api/[controller]")]
    method ProductController (line 16) | public ProductController(IProductHttpService productHttpService)
    method Get (line 21) | [HttpGet]

FILE: DotnetIst.Api/src/Api/Controllers/TokenController.cs
  class TokenController (line 9) | [Route("api/[controller]")]
    method TokenController (line 16) | public TokenController(IAuthenticationService authService,
    method GenerateToken (line 23) | [HttpPost]

FILE: DotnetIst.Api/src/Api/HttpServices/CustomerHttpService.cs
  class CustomerHttpService (line 10) | public class CustomerHttpService : ICustomerHttpService
    method CustomerHttpService (line 14) | public CustomerHttpService(HttpClient client)
    method GetCustomerByEmail (line 19) | public async Task<Customer> GetCustomerByEmail(string email)

FILE: DotnetIst.Api/src/Api/HttpServices/ICustomerHttpService.cs
  type ICustomerHttpService (line 7) | public interface ICustomerHttpService
    method GetCustomerByEmail (line 9) | Task<Customer> GetCustomerByEmail(string CustomerId);

FILE: DotnetIst.Api/src/Api/HttpServices/IProductHttpService.cs
  type IProductHttpService (line 7) | public interface IProductHttpService
    method GetList (line 9) | Task<object> GetList();

FILE: DotnetIst.Api/src/Api/HttpServices/ProductHttpService.cs
  class ProductHttpService (line 9) | public class ProductHttpService : IProductHttpService
    method ProductHttpService (line 13) | public ProductHttpService(HttpClient client)
    method GetList (line 18) | public async Task<object> GetList()

FILE: DotnetIst.Api/src/Api/Models/Customer.cs
  class Customer (line 5) | public class Customer

FILE: DotnetIst.Api/src/Api/Program.cs
  class Program (line 7) | public class Program
    method Main (line 9) | public static void Main(string[] args)
    method CreateWebHostBuilder (line 14) | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

FILE: DotnetIst.Api/src/Api/Startup.cs
  class Startup (line 19) | public class Startup
    method Startup (line 21) | public Startup(IConfiguration configuration)
    method ConfigureServices (line 29) | public IServiceProvider ConfigureServices(IServiceCollection services)
    method Configure (line 50) | public void Configure(IApplicationBuilder app, IHostingEnvironment env)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Commands/AddProductToBasket.cs
  class AddProductToBasket (line 8) | public class AddProductToBasket : ICommand
    method AddProductToBasket (line 13) | public AddProductToBasket(Guid productId,

FILE: DotnetIst.Services.Customers/src/Services.Customers/Commands/CreateCustomer.cs
  class CreateCustomer (line 8) | public class CreateCustomer : ICommand
    method CreateCustomer (line 17) | public CreateCustomer(Guid id, string email, string password, string f...

FILE: DotnetIst.Services.Customers/src/Services.Customers/Controllers/BasketController.cs
  class BasketController (line 10) | [Route("api/[controller]")]
    method BasketController (line 16) | public BasketController(CustomerDBContext dbContext)
    method Get (line 20) | [HttpGet("{customerId}")]

FILE: DotnetIst.Services.Customers/src/Services.Customers/Controllers/CustomerController.cs
  class CustomerController (line 10) | [Route("api/[controller]")]
    method CustomerController (line 16) | public CustomerController(CustomerDBContext dbContext)
    method Get (line 20) | [HttpGet("customerbyemail/{email}")]

FILE: DotnetIst.Services.Customers/src/Services.Customers/Controllers/HomeController.cs
  class HomeController (line 6) | [Route("")]
    method Get (line 9) | [HttpGet]

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/CustomerDBContext.cs
  class CustomerDBContext (line 5) | public class CustomerDBContext : DbContext
    method CustomerDBContext (line 7) | public CustomerDBContext(DbContextOptions<CustomerDBContext> options) ...
    method OnModelCreating (line 14) | protected override void OnModelCreating(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/Basket.cs
  class Basket (line 7) | public class Basket : BaseEntity

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/BasketItem.cs
  class BasketItem (line 6) | public class BasketItem : BaseEntity

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/Customer.cs
  class Customer (line 6) | public class Customer : BaseEntity

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308211118_initial.Designer.cs
  class initial (line 12) | [DbContext(typeof(CustomerDBContext))]
    method BuildTargetModel (line 16) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308211118_initial.cs
  class initial (line 6) | public partial class initial : Migration
    method Up (line 8) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 67) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308222102_base_entity.Designer.cs
  class base_entity (line 12) | [DbContext(typeof(CustomerDBContext))]
    method BuildTargetModel (line 16) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308222102_base_entity.cs
  class base_entity (line 6) | public partial class base_entity : Migration
    method Up (line 8) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 28) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/CustomerDBContextModelSnapshot.cs
  class CustomerDBContextModelSnapshot (line 11) | [DbContext(typeof(CustomerDBContext))]
    method BuildModel (line 14) | protected override void BuildModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Data/SeedData.cs
  class SeedData (line 7) | public static class SeedData
    method Initialize (line 9) | public static void Initialize(IServiceProvider serviceProvider)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Events/OrderCompleted.cs
  class OrderCompleted (line 7) | public class OrderCompleted : IEvent
    method OrderCompleted (line 11) | public OrderCompleted(Guid id)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Events/ProductAddedToBasket.cs
  class ProductAddedToBasket (line 7) | public class ProductAddedToBasket : IEvent
    method ProductAddedToBasket (line 12) | public ProductAddedToBasket(Guid productId, int quantity)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Handlers/AddProductToBasketHandler.cs
  class AddProductToBasketHandler (line 15) | public class AddProductToBasketHandler : ICommandHandler<AddProductToBas...
    method AddProductToBasketHandler (line 22) | public AddProductToBasketHandler(IBusPublisher busPublisher,
    method HandleAsync (line 34) | public async Task HandleAsync(AddProductToBasket command, ICorrelation...

FILE: DotnetIst.Services.Customers/src/Services.Customers/Handlers/CreateCustomerdHandler.cs
  class CreateCustomerdHandler (line 11) | public class CreateCustomerdHandler : ICommandHandler<CreateCustomer>
    method CreateCustomerdHandler (line 17) | public CreateCustomerdHandler(IBusPublisher busPublisher,
    method HandleAsync (line 25) | public async Task HandleAsync(CreateCustomer _event, ICorrelationConte...

FILE: DotnetIst.Services.Customers/src/Services.Customers/Handlers/OrderCompletedHandler.cs
  class OrderCompletedHandler (line 11) | public class OrderCompletedHandler : IEventHandler<OrderCompleted>
    method OrderCompletedHandler (line 17) | public OrderCompletedHandler(IBusPublisher busPublisher,
    method HandleAsync (line 25) | public async Task HandleAsync(OrderCompleted _event, ICorrelationConte...

FILE: DotnetIst.Services.Customers/src/Services.Customers/HttpServices/IProductHttpService.cs
  type IProductHttpService (line 8) | public interface IProductHttpService
    method GetAsync (line 10) | Task<Product> GetAsync(Guid id);

FILE: DotnetIst.Services.Customers/src/Services.Customers/HttpServices/ProductHttpService.cs
  class ProductHttpService (line 10) | public class ProductHttpService : IProductHttpService
    method ProductHttpService (line 14) | public ProductHttpService(HttpClient client)
    method GetAsync (line 19) | public async Task<Product> GetAsync(Guid id)

FILE: DotnetIst.Services.Customers/src/Services.Customers/Models/Product.cs
  class Product (line 5) | public class Product

FILE: DotnetIst.Services.Customers/src/Services.Customers/Program.cs
  class Program (line 7) | public class Program
    method Main (line 9) | public static void Main(string[] args)
    method CreateWebHostBuilder (line 13) | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

FILE: DotnetIst.Services.Customers/src/Services.Customers/Startup.cs
  class Startup (line 19) | public class Startup
    method Startup (line 21) | public Startup(IConfiguration configuration)
    method ConfigureServices (line 29) | public IServiceProvider ConfigureServices(IServiceCollection services)
    method Configure (line 50) | public void Configure(IApplicationBuilder app, IHostingEnvironment env)

FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Controllers/HomeController.cs
  class HomeController (line 6) | [Route("")]
    method Get (line 9) | [HttpGet]

FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Events/OrderCompleted.cs
  class OrderCompleted (line 7) | [MessageNamespace("customers")]
    method OrderCompleted (line 12) | public OrderCompleted(Guid id)

FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Events/OrderFailed.cs
  class OrderFailed (line 7) | public class OrderFailed : IEvent
    method OrderFailed (line 11) | public OrderFailed(Guid id)

FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Handlers/OrderCompletedHandler.cs
  class OrderCompletedHandler (line 9) | public class OrderCompletedHandler : IEventHandler<OrderCompleted>
    method OrderCompletedHandler (line 12) | public OrderCompletedHandler(ILogger<OrderCompletedHandler> logger)
    method HandleAsync (line 16) | public async Task HandleAsync(OrderCompleted _event, ICorrelationConte...

FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Handlers/OrderFailedHandler.cs
  class OrderFailedHandler (line 9) | public class OrderFailedHandler : IEventHandler<OrderFailed>
    method OrderFailedHandler (line 12) | public OrderFailedHandler(ILogger<OrderFailedHandler> logger)
    method HandleAsync (line 16) | public async Task HandleAsync(OrderFailed _event, ICorrelationContext ...

FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Program.cs
  class Program (line 7) | public class Program
    method Main (line 9) | public static void Main(string[] args)
    method CreateWebHostBuilder (line 14) | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

FILE: DotnetIst.Services.Notifications/src/Services.Notifications/Startup.cs
  class Startup (line 13) | public class Startup
    method Startup (line 15) | public Startup(IConfiguration configuration)
    method ConfigureServices (line 23) | public IServiceProvider ConfigureServices(IServiceCollection services)
    method Configure (line 31) | public void Configure(IApplicationBuilder app, IHostingEnvironment env)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Commands/CreateOrder.cs
  class CreateOrder (line 7) | public class CreateOrder : ICommand
    method CreateOrder (line 11) | public CreateOrder(Guid id)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Controllers/HomeController.cs
  class HomeController (line 6) | [Route("")]
    method Get (line 9) | [HttpGet]

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/Order.cs
  class Order (line 8) | public class Order : BaseEntity

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/OrderItem.cs
  class OrderItem (line 6) | public class OrderItem : BaseEntity

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/OrderStatus.cs
  type OrderStatus (line 3) | public enum OrderStatus

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308211841_initial.Designer.cs
  class initial (line 12) | [DbContext(typeof(OrderDBContext))]
    method BuildTargetModel (line 16) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308211841_initial.cs
  class initial (line 6) | public partial class initial : Migration
    method Up (line 8) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 52) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308222202_base_entity.Designer.cs
  class base_entity (line 12) | [DbContext(typeof(OrderDBContext))]
    method BuildTargetModel (line 16) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308222202_base_entity.cs
  class base_entity (line 6) | public partial class base_entity : Migration
    method Up (line 8) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 23) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/OrderDBContextModelSnapshot.cs
  class OrderDBContextModelSnapshot (line 11) | [DbContext(typeof(OrderDBContext))]
    method BuildModel (line 14) | protected override void BuildModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/OrderDBContext.cs
  class OrderDBContext (line 6) | public class OrderDBContext : DbContext
    method OrderDBContext (line 8) | public OrderDBContext(DbContextOptions<OrderDBContext> options) : base...
    method OnModelCreating (line 13) | protected override void OnModelCreating(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Data/SeedData.cs
  class SeedData (line 8) | public static class SeedData
    method Initialize (line 10) | public static void Initialize(IServiceProvider serviceProvider)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/OrderCompleted.cs
  class OrderCompleted (line 7) | [MessageNamespace("customers")]
    method OrderCompleted (line 12) | public OrderCompleted(Guid id)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/OrderCreated.cs
  class OrderCreated (line 8) | [MessageNamespace("products")]
    method OrderCreated (line 14) | public OrderCreated(Guid id, IDictionary<Guid, int> products)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/OrderFailed.cs
  class OrderFailed (line 6) | [MessageNamespace("notifications")]
    method OrderFailed (line 10) | public OrderFailed(Guid orderId)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/ProductsReserveFailed.cs
  class ProductsReserveFailed (line 6) | public class ProductsReserveFailed : IEvent
    method ProductsReserveFailed (line 9) | public ProductsReserveFailed(Guid orderId)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Events/ProductsReserved.cs
  class ProductsReserved (line 7) | public class ProductsReserved : IEvent
    method ProductsReserved (line 12) | public ProductsReserved(Guid orderId, IDictionary<Guid, int> products)

FILE: DotnetIst.Services.Orders/src/Services.Orders/Handlers/CreateOrderHandler.cs
  class CreateOrderHandler (line 15) | public class CreateOrderHandler : ICommandHandler<CreateOrder>
    method CreateOrderHandler (line 22) | public CreateOrderHandler(IBusPublisher busPublisher,
    method HandleAsync (line 33) | public async Task HandleAsync(CreateOrder command, ICorrelationContext...

FILE: DotnetIst.Services.Orders/src/Services.Orders/Handlers/ProductsReserveFailedHandler.cs
  class ProductsReserveFailedHandler (line 12) | public class ProductsReserveFailedHandler : IEventHandler<ProductsReserv...
    method ProductsReserveFailedHandler (line 18) | public ProductsReserveFailedHandler(IBusPublisher busPublisher,
    method HandleAsync (line 26) | public async Task HandleAsync(ProductsReserveFailed _event, ICorrelati...

FILE: DotnetIst.Services.Orders/src/Services.Orders/Handlers/ProductsReservedHandler.cs
  class ProductsReservedHandler (line 11) | public class ProductsReservedHandler : IEventHandler<ProductsReserved>
    method ProductsReservedHandler (line 17) | public ProductsReservedHandler(IBusPublisher busPublisher,
    method HandleAsync (line 25) | public async Task HandleAsync(ProductsReserved _event, ICorrelationCon...

FILE: DotnetIst.Services.Orders/src/Services.Orders/HttpServices/CustomerHttpService.cs
  class CustomerHttpService (line 9) | public class CustomerHttpService : ICustomerHttpService
    method CustomerHttpService (line 13) | public CustomerHttpService(HttpClient client)
    method GetBasket (line 18) | public async Task<Basket> GetBasket(Guid customerId)

FILE: DotnetIst.Services.Orders/src/Services.Orders/HttpServices/ICustomerHttpService.cs
  type ICustomerHttpService (line 7) | public interface ICustomerHttpService
    method GetBasket (line 9) | Task<Basket> GetBasket(Guid CustomerId);

FILE: DotnetIst.Services.Orders/src/Services.Orders/Models/Basket.cs
  class Basket (line 6) | public class Basket

FILE: DotnetIst.Services.Orders/src/Services.Orders/Models/BasketItem.cs
  class BasketItem (line 5) | public class BasketItem

FILE: DotnetIst.Services.Orders/src/Services.Orders/Program.cs
  class Program (line 7) | public class Program
    method Main (line 9) | public static void Main(string[] args)
    method CreateWebHostBuilder (line 14) | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

FILE: DotnetIst.Services.Orders/src/Services.Orders/Startup.cs
  class Startup (line 20) | public class Startup
    method Startup (line 22) | public Startup(IConfiguration configuration)
    method ConfigureServices (line 30) | public IServiceProvider ConfigureServices(IServiceCollection services)
    method Configure (line 49) | public void Configure(IApplicationBuilder app, IHostingEnvironment env)

FILE: DotnetIst.Services.Products/src/Services.Products/Controllers/HomeController.cs
  class HomeController (line 6) | [Route("")]
    method Get (line 9) | [HttpGet]

FILE: DotnetIst.Services.Products/src/Services.Products/Controllers/ProductController.cs
  class ProductController (line 12) | [Route("api/[controller]")]
    method ProductController (line 18) | public ProductController(ProductDBContext dbContext)
    method Get (line 22) | [HttpGet("{id}")]
    method Get (line 28) | [HttpGet]

FILE: DotnetIst.Services.Products/src/Services.Products/Data/Entity/Product.cs
  class Product (line 6) | public class Product : BaseEntity

FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308212022_initial.Designer.cs
  class initial (line 12) | [DbContext(typeof(ProductDBContext))]
    method BuildTargetModel (line 16) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308212022_initial.cs
  class initial (line 6) | public partial class initial : Migration
    method Up (line 8) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 25) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308222331_base_entity.Designer.cs
  class base_entity (line 12) | [DbContext(typeof(ProductDBContext))]
    method BuildTargetModel (line 16) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308222331_base_entity.cs
  class base_entity (line 6) | public partial class base_entity : Migration
    method Up (line 8) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 17) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: DotnetIst.Services.Products/src/Services.Products/Data/Migrations/ProductDBContextModelSnapshot.cs
  class ProductDBContextModelSnapshot (line 11) | [DbContext(typeof(ProductDBContext))]
    method BuildModel (line 14) | protected override void BuildModel(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Products/src/Services.Products/Data/ProductDBContext.cs
  class ProductDBContext (line 6) | public class ProductDBContext : DbContext
    method ProductDBContext (line 8) | public ProductDBContext(DbContextOptions<ProductDBContext> options) : ...
    method OnModelCreating (line 13) | protected override void OnModelCreating(ModelBuilder modelBuilder)

FILE: DotnetIst.Services.Products/src/Services.Products/Data/SeedData.cs
  class SeedData (line 10) | public static class SeedData
    method Initialize (line 12) | public static void Initialize(IServiceProvider serviceProvider)

FILE: DotnetIst.Services.Products/src/Services.Products/Events/OrderCreated.cs
  class OrderCreated (line 8) | public class OrderCreated : IEvent
    method OrderCreated (line 13) | public OrderCreated(Guid id, IDictionary<Guid, int> products)

FILE: DotnetIst.Services.Products/src/Services.Products/Events/ProductsReserveFailed.cs
  class ProductsReserveFailed (line 6) | [MessageNamespace("orders")]
    method ProductsReserveFailed (line 10) | public ProductsReserveFailed(Guid orderId)

FILE: DotnetIst.Services.Products/src/Services.Products/Events/ProductsReserved.cs
  class ProductsReserved (line 7) | [MessageNamespace("orders")]
    method ProductsReserved (line 12) | public ProductsReserved(Guid orderId, IDictionary<Guid, int> products)

FILE: DotnetIst.Services.Products/src/Services.Products/Handlers/OrderCreatedHandler.cs
  class OrderCreatedHandler (line 11) | public class OrderCreatedHandler : IEventHandler<OrderCreated>
    method OrderCreatedHandler (line 17) | public OrderCreatedHandler(ProductDBContext dbContext,
    method HandleAsync (line 25) | public async Task HandleAsync(OrderCreated _event, ICorrelationContext...

FILE: DotnetIst.Services.Products/src/Services.Products/Program.cs
  class Program (line 7) | public class Program
    method Main (line 9) | public static void Main(string[] args)
    method CreateWebHostBuilder (line 14) | public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>

FILE: DotnetIst.Services.Products/src/Services.Products/Startup.cs
  class Startup (line 16) | public class Startup
    method Startup (line 18) | public Startup(IConfiguration configuration)
    method ConfigureServices (line 26) | public IServiceProvider ConfigureServices(IServiceCollection services)
    method Configure (line 37) | public void Configure(IApplicationBuilder app, IHostingEnvironment env)

FILE: DotnetIst.Shared/src/Shared/Extensions.cs
  class Extensions (line 12) | public static class Extensions
    method Underscore (line 14) | public static string Underscore(this string value)
    method GetOptions (line 17) | public static TModel GetOptions<TModel>(this IConfiguration configurat...
    method BuildContainer (line 24) | public static IServiceProvider BuildContainer(this IServiceCollection ...

FILE: DotnetIst.Shared/src/Shared/Logging/LoggingExtensions.cs
  class Extensions (line 8) | public static class Extensions
    method UseLogging (line 10) | public static IWebHostBuilder UseLogging(this IWebHostBuilder webHostB...

FILE: DotnetIst.Shared/src/Shared/MessageHandlers/ICommandHandler.cs
  type ICommandHandler (line 7) | public interface ICommandHandler<in TCommand> where TCommand : ICommand
    method HandleAsync (line 9) | Task HandleAsync(TCommand command, ICorrelationContext context);

FILE: DotnetIst.Shared/src/Shared/MessageHandlers/IEventHandler.cs
  type IEventHandler (line 7) | public interface IEventHandler<in TEvent> where TEvent : IEvent
    method HandleAsync (line 9) | Task HandleAsync(TEvent _event, ICorrelationContext context);

FILE: DotnetIst.Shared/src/Shared/Messages/ICommand.cs
  type ICommand (line 3) | public interface ICommand

FILE: DotnetIst.Shared/src/Shared/Messages/IEvent.cs
  type IEvent (line 3) | public interface IEvent

FILE: DotnetIst.Shared/src/Shared/Messages/MessageNamespaceAttribute.cs
  class MessageNamespaceAttribute (line 5) | public class MessageNamespaceAttribute : Attribute
    method MessageNamespaceAttribute (line 9) | public MessageNamespaceAttribute(string _namespace)

FILE: DotnetIst.Shared/src/Shared/Models/BaseEntity.cs
  class BaseEntity (line 5) | public class BaseEntity
    method BaseEntity (line 10) | public BaseEntity()

FILE: DotnetIst.Shared/src/Shared/Models/HttpServiceOptions.cs
  class HttpServiceOptions (line 3) | public class HttpServiceOptions

FILE: DotnetIst.Shared/src/Shared/RabbitMq/BusPublisher.cs
  class BusPublisher (line 10) | public class BusPublisher : IBusPublisher
    method BusPublisher (line 16) | public BusPublisher(IBusClient busClient, RabbitMqOptions options, ILo...
    method SendAsync (line 23) | public async Task SendAsync<TCommand>(TCommand command, ICorrelationCo...
    method PublishAsync (line 33) | public async Task PublishAsync<TEvent>(TEvent _event, ICorrelationCont...
    method GetRoutingKey (line 43) | private string GetRoutingKey<T>(T message)

FILE: DotnetIst.Shared/src/Shared/RabbitMq/BusSubscriber.cs
  class BusSubscriber (line 15) | public class BusSubscriber : IBusSubscriber
    method BusSubscriber (line 24) | public BusSubscriber(IApplicationBuilder app)
    method SubscribeCommand (line 36) | public IBusSubscriber SubscribeCommand<TCommand>(string _namespace = n...
    method SubscribeEvent (line 52) | public IBusSubscriber SubscribeEvent<TEvent>(string _namespace = null)
    method TryHandleAsync (line 68) | private async Task<Acknowledgement> TryHandleAsync<TMessage>(TMessage ...
    method GetQueueName (line 91) | private string GetQueueName<T>(string _namespace = null)

FILE: DotnetIst.Shared/src/Shared/RabbitMq/CorrelationContext.cs
  class CorrelationContext (line 6) | public class CorrelationContext : ICorrelationContext
    method CorrelationContext (line 11) | public CorrelationContext()
    method CorrelationContext (line 15) | [JsonConstructor]
    method Create (line 22) | public static ICorrelationContext Create(Guid id, Guid customerId)

FILE: DotnetIst.Shared/src/Shared/RabbitMq/IBusPublisher.cs
  type IBusPublisher (line 6) | public interface IBusPublisher
    method SendAsync (line 8) | Task SendAsync<TCommand>(TCommand command, ICorrelationContext context)
    method PublishAsync (line 11) | Task PublishAsync<TEvent>(TEvent _event, ICorrelationContext context)

FILE: DotnetIst.Shared/src/Shared/RabbitMq/IBusSubscriber.cs
  type IBusSubscriber (line 6) | public interface IBusSubscriber
    method SubscribeCommand (line 8) | IBusSubscriber SubscribeCommand<TCommand>(string _namespace = null)
    method SubscribeEvent (line 11) | IBusSubscriber SubscribeEvent<TEvent>(string _namespace = null)

FILE: DotnetIst.Shared/src/Shared/RabbitMq/ICorrelationContext.cs
  type ICorrelationContext (line 5) | public interface ICorrelationContext

FILE: DotnetIst.Shared/src/Shared/RabbitMq/RabbitMqExtensions.cs
  class RabbitMqExtensions (line 15) | public static class RabbitMqExtensions
    method UseRabbitMq (line 17) | public static IBusSubscriber UseRabbitMq(this IApplicationBuilder app)
    method AddRabbitMq (line 20) | public static void AddRabbitMq(this ContainerBuilder builder)
    method ConfigureBus (line 48) | private static void ConfigureBus(ContainerBuilder builder)
    class CustomNamingConventions (line 75) | private class CustomNamingConventions : NamingConventions
      method CustomNamingConventions (line 77) | public CustomNamingConventions(string defaultNamespace)

FILE: DotnetIst.Shared/src/Shared/RabbitMq/RabbitMqOptions.cs
  class RabbitMqOptions (line 5) | public class RabbitMqOptions : RawRabbitConfiguration
Condensed preview — 147 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (169K chars).
[
  {
    "path": ".github/workflows/dotnet-core.yml",
    "chars": 501,
    "preview": "name: .NET Core\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n\n    runs"
  },
  {
    "path": ".gitignore",
    "chars": 4480,
    "preview": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User"
  },
  {
    "path": ".postman_project/Dotnet_Istanbul.postman_collection.json",
    "chars": 3846,
    "preview": "{\n\t\"info\": {\n\t\t\"_postman_id\": \"1ce3bc02-2070-441c-9d1a-386db626d78b\",\n\t\t\"name\": \"Dotnet_Istanbul\",\n\t\t\"schema\": \"https://"
  },
  {
    "path": ".vscode/launch.json",
    "chars": 6814,
    "preview": "{\n    // Use IntelliSense to learn about possible attributes.\n    // Hover to view descriptions of existing attributes.\n"
  },
  {
    "path": ".vscode/tasks.json",
    "chars": 1721,
    "preview": "{\n    \"version\": \"2.0.0\",\n    \"tasks\": [\n        {\n            \"label\": \"build-api\",\n            \"command\": \"dotnet\",\n  "
  },
  {
    "path": "DotnetIst.Api/README.MD",
    "chars": 73,
    "preview": "## Api Gateway\n\ntodo: use ocelot\n\ntodo: create bffs for each channel type"
  },
  {
    "path": "DotnetIst.Api/src/Api/Api.csproj",
    "chars": 485,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.2</TargetFramework>\n    <AspNe"
  },
  {
    "path": "DotnetIst.Api/src/Api/Authentication/AuthenticationExtensions.cs",
    "chars": 2458,
    "preview": "using System;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authenticat"
  },
  {
    "path": "DotnetIst.Api/src/Api/Authentication/AuthenticationService.cs",
    "chars": 1661,
    "preview": "using System;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Security.Claims;\nusing System.Text;\nusing Api.Models;\n"
  },
  {
    "path": "DotnetIst.Api/src/Api/Authentication/IAuthenticationService.cs",
    "chars": 151,
    "preview": "using Api.Models;\n\nnamespace Api.Authentication\n{\n    public interface IAuthenticationService\n    {\n        string GetTo"
  },
  {
    "path": "DotnetIst.Api/src/Api/Authentication/Model/LoginModel.cs",
    "chars": 159,
    "preview": "namespace Api.Authentication\n{\n    public class LoginModel\n    {\n        public string Email { get; set; }\n        publi"
  },
  {
    "path": "DotnetIst.Api/src/Api/Authentication/Model/TokenModel.cs",
    "chars": 174,
    "preview": "using System;\n\nnamespace Api.Authentication\n{\n    public class TokenModel\n    {\n        public Guid CustomerId { get; se"
  },
  {
    "path": "DotnetIst.Api/src/Api/Commands/Baskets/AddProductToBasket.cs",
    "chars": 419,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Api.Commands.Baskets\n{\n    [MessageNamespace(\"cus"
  },
  {
    "path": "DotnetIst.Api/src/Api/Commands/Customers/CreateCustomer.cs",
    "chars": 802,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Api.Commands.Customers\n{\n    [MessageNamespace(\"c"
  },
  {
    "path": "DotnetIst.Api/src/Api/Commands/Orders/CreateOrder.cs",
    "chars": 307,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Api.Commands.Orders\n{\n    [MessageNamespace(\"orde"
  },
  {
    "path": "DotnetIst.Api/src/Api/Controllers/BaseController.cs",
    "chars": 1244,
    "preview": "using System;\nusing Api.Authentication;\nusing Shared.Messages;\nusing Shared.RabbitMq;\nusing Microsoft.AspNetCore.Mvc;\n\nn"
  },
  {
    "path": "DotnetIst.Api/src/Api/Controllers/BasketController.cs",
    "chars": 665,
    "preview": "using System.Threading.Tasks;\nusing Api.Commands.Baskets;\nusing Shared.RabbitMq;\nusing Microsoft.AspNetCore.Authorizati"
  },
  {
    "path": "DotnetIst.Api/src/Api/Controllers/CustomerController.cs",
    "chars": 661,
    "preview": "using System.Threading.Tasks;\nusing Api.Commands.Customers;\nusing Shared.RabbitMq;\nusing Microsoft.AspNetCore.Authoriza"
  },
  {
    "path": "DotnetIst.Api/src/Api/Controllers/HomeController.cs",
    "chars": 316,
    "preview": "using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Api.Controllers\n{\n    [Route(\"\")]\n "
  },
  {
    "path": "DotnetIst.Api/src/Api/Controllers/OrderController.cs",
    "chars": 655,
    "preview": "using System.Threading.Tasks;\nusing Api.Commands.Orders;\nusing Shared.RabbitMq;\nusing Microsoft.AspNetCore.Authorizatio"
  },
  {
    "path": "DotnetIst.Api/src/Api/Controllers/ProductController.cs",
    "chars": 689,
    "preview": "using System.Threading.Tasks;\nusing Api.Commands.Customers;\nusing Api.HttpServices;\nusing Shared.RabbitMq;\nusing Micros"
  },
  {
    "path": "DotnetIst.Api/src/Api/Controllers/TokenController.cs",
    "chars": 1214,
    "preview": "using System.Threading.Tasks;\nusing Api.Authentication;\nusing Api.HttpServices;\nusing Microsoft.AspNetCore.Authorization"
  },
  {
    "path": "DotnetIst.Api/src/Api/HttpServices/CustomerHttpService.cs",
    "chars": 947,
    "preview": "using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Api.Models;\nusing Newtonsoft.Json;\n\n\nnamespace "
  },
  {
    "path": "DotnetIst.Api/src/Api/HttpServices/ICustomerHttpService.cs",
    "chars": 209,
    "preview": "using System;\nusing System.Threading.Tasks;\nusing Api.Models;\n\nnamespace Api.HttpServices\n{\n    public interface ICustom"
  },
  {
    "path": "DotnetIst.Api/src/Api/HttpServices/IProductHttpService.cs",
    "chars": 181,
    "preview": "using System.Collections.Generic;\nusing System.Threading.Tasks;\n\n\nnamespace Api.HttpServices\n{\n    public interface IPro"
  },
  {
    "path": "DotnetIst.Api/src/Api/HttpServices/ProductHttpService.cs",
    "chars": 912,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Newtonsoft.Js"
  },
  {
    "path": "DotnetIst.Api/src/Api/Models/Customer.cs",
    "chars": 336,
    "preview": "using System;\n\nnamespace Api.Models\n{\n    public class Customer\n    {\n        public Guid Id { get; set; }\n        publi"
  },
  {
    "path": "DotnetIst.Api/src/Api/Program.cs",
    "chars": 464,
    "preview": "using Microsoft.AspNetCore;\nusing Microsoft.AspNetCore.Hosting;\nusing Shared.Logging;\n\nnamespace Api\n{\n    public class"
  },
  {
    "path": "DotnetIst.Api/src/Api/Properties/launchSettings.json",
    "chars": 681,
    "preview": "{\n  \"$schema\": \"http://json.schemastore.org/launchsettings.json\",\n  \"iisSettings\": {\n    \"windowsAuthentication\": false"
  },
  {
    "path": "DotnetIst.Api/src/Api/Startup.cs",
    "chars": 2149,
    "preview": "using System;\nusing System.Net.Http.Headers;\nusing System.Reflection;\nusing Api.Authentication;\nusing Api.HttpServices;"
  },
  {
    "path": "DotnetIst.Api/src/Api/appsettings.Development.json",
    "chars": 137,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Informat"
  },
  {
    "path": "DotnetIst.Api/src/Api/appsettings.json",
    "chars": 896,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\",\n  \"HttpServices\": {\n    "
  },
  {
    "path": "DotnetIst.Services.Customers/README.MD",
    "chars": 144,
    "preview": "**Migration**\n\n0- cd src/Services.Customers\n\n1- *dotnet ef migrations add \"migration_name\" -o ./Data/Migrations*\n\n2- *do"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Commands/AddProductToBasket.cs",
    "chars": 403,
    "preview": "\nusing System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Customers.Commands\n{\n    public class A"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Commands/CreateCustomer.cs",
    "chars": 769,
    "preview": "\nusing System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Customers.Commands\n{\n    public class C"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Controllers/BasketController.cs",
    "chars": 756,
    "preview": "using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.EntityFra"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Controllers/CustomerController.cs",
    "chars": 738,
    "preview": "using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.EntityFra"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Controllers/HomeController.cs",
    "chars": 344,
    "preview": "using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Services.Customers.Controllers\n{\n  "
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/CustomerDBContext.cs",
    "chars": 772,
    "preview": "using Microsoft.EntityFrameworkCore;\n\nnamespace Services.Customers.Data\n{\n    public class CustomerDBContext : DbContext"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/Basket.cs",
    "chars": 253,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Shared.Models;\n\nnamespace Services.Customers.Data\n{\n    public cla"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/BasketItem.cs",
    "chars": 350,
    "preview": "using System;\nusing Shared.Models;\n\nnamespace Services.Customers.Data\n{\n    public class BasketItem : BaseEntity\n    {\n "
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/Entity/Customer.cs",
    "chars": 346,
    "preview": "using System;\nusing Shared.Models;\n\nnamespace Services.Customers.Data\n{\n    public class Customer : BaseEntity\n    {\n   "
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308211118_initial.Designer.cs",
    "chars": 2690,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308211118_initial.cs",
    "chars": 2945,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Services.Customers.Data.Migrations\n{\n    publi"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308222102_base_entity.Designer.cs",
    "chars": 2816,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/20190308222102_base_entity.cs",
    "chars": 1385,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Services.Customers.Data.Migrations\n{\n    publi"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/Migrations/CustomerDBContextModelSnapshot.cs",
    "chars": 2751,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Data/SeedData.cs",
    "chars": 385,
    "preview": "using System;\nusing System.Linq;\nusing Microsoft.Extensions.DependencyInjection;\n\nnamespace Services.Customers.Data\n{\n  "
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Events/OrderCompleted.cs",
    "chars": 266,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Customers.Events\n{\n    public class Orde"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Events/ProductAddedToBasket.cs",
    "chars": 390,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Customers.Events\n{\n    public class Prod"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Handlers/AddProductToBasketHandler.cs",
    "chars": 2801,
    "preview": "using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusin"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Handlers/CreateCustomerdHandler.cs",
    "chars": 1567,
    "preview": "using System;\nusing System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusing Microsoft.Extensi"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Handlers/OrderCompletedHandler.cs",
    "chars": 1403,
    "preview": "using System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusing Microsoft.EntityFrameworkCore;\n"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/HttpServices/IProductHttpService.cs",
    "chars": 248,
    "preview": "using System;\nusing System.Threading.Tasks;\nusing Services.Customers.Data;\nusing Services.Customers.Models;\n\nnamespace S"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/HttpServices/ProductHttpService.cs",
    "chars": 966,
    "preview": "using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\nusing Services.Customers.Data;"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Models/Product.cs",
    "chars": 254,
    "preview": "using System;\n\nnamespace Services.Customers.Models\n{\n    public class Product\n    {\n        public Guid Id { get; set; }"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Program.cs",
    "chars": 491,
    "preview": "using Microsoft.AspNetCore;\nusing Microsoft.AspNetCore.Hosting;\nusing Shared.Logging;\n\nnamespace Services.Customers\n{\n "
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Properties/launchSettings.json",
    "chars": 680,
    "preview": "{\n  \"$schema\": \"http://json.schemastore.org/launchsettings.json\",\n  \"iisSettings\": {\n    \"windowsAuthentication\": false"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Services.Customers.csproj",
    "chars": 485,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.2</TargetFramework>\n    <AspNe"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/Startup.cs",
    "chars": 2223,
    "preview": "using System;\nusing System.Net.Http.Headers;\nusing Shared.Models;\nusing Shared.RabbitMq;\nusing Microsoft.AspNetCore.Bui"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/appsettings.Development.json",
    "chars": 137,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Informat"
  },
  {
    "path": "DotnetIst.Services.Customers/src/Services.Customers/appsettings.json",
    "chars": 980,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\",\n  \"ConnectionStrings\": {"
  },
  {
    "path": "DotnetIst.Services.Notifications/README.MD",
    "chars": 23,
    "preview": "**NotificationService**"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Controllers/HomeController.cs",
    "chars": 352,
    "preview": "using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Services.Notifications.Controllers\n"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Events/OrderCompleted.cs",
    "chars": 306,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Notifications.Events\n{\n    [MessageNames"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Events/OrderFailed.cs",
    "chars": 264,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Notifications.Events\n{\n    public class "
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Handlers/OrderCompletedHandler.cs",
    "chars": 810,
    "preview": "using System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusing Microsoft.Extensions.Logging;\nu"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Handlers/OrderFailedHandler.cs",
    "chars": 788,
    "preview": "using System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusing Microsoft.Extensions.Logging;\nu"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Program.cs",
    "chars": 500,
    "preview": "using Microsoft.AspNetCore;\nusing Microsoft.AspNetCore.Hosting;\nusing Shared.Logging;\n\nnamespace Services.Notifications"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Properties/launchSettings.json",
    "chars": 700,
    "preview": "{\n  \"$schema\": \"http://json.schemastore.org/launchsettings.json\",\n  \"iisSettings\": {\n    \"windowsAuthentication\": false"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Services.Notifications.csproj",
    "chars": 485,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.2</TargetFramework>\n    <AspNe"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/Startup.cs",
    "chars": 1363,
    "preview": "using System;\nusing Shared.RabbitMq;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosting;\nusing Micr"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/appsettings.Development.json",
    "chars": 137,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Informat"
  },
  {
    "path": "DotnetIst.Services.Notifications/src/Services.Notifications/appsettings.json",
    "chars": 763,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\",\n  \"rabbitMq\": {\n    \"nam"
  },
  {
    "path": "DotnetIst.Services.Orders/README.md",
    "chars": 143,
    "preview": "**Migration**\n\n0- cd src/Services.Products\n\n1- *dotnet ef migrations add \"migration_name\" -o ./Data/Migrations*\n\n2- *dot"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Commands/CreateOrder.cs",
    "chars": 266,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Orders.Commands\n{\n    public class Creat"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Controllers/HomeController.cs",
    "chars": 338,
    "preview": "using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Services.Orders.Controllers\n{\n    ["
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/Order.cs",
    "chars": 366,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Shared.Models;\n\nnamespace Services.Orders.Data\n"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/OrderItem.cs",
    "chars": 397,
    "preview": "using System;\nusing Shared.Models;\n\nnamespace Services.Orders.Data\n{\n    public class OrderItem : BaseEntity\n    {\n     "
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/Entity/OrderStatus.cs",
    "chars": 137,
    "preview": "namespace Services.Orders.Data\n{\n    public enum OrderStatus\n    {\n        Created = 0,\n        Completed = 1,\n        F"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308211841_initial.Designer.cs",
    "chars": 2194,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308211841_initial.cs",
    "chars": 2214,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Services.Orders.Data.Migrations\n{\n    public p"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308222202_base_entity.Designer.cs",
    "chars": 2318,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/20190308222202_base_entity.cs",
    "chars": 1070,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Services.Orders.Data.Migrations\n{\n    public p"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/Migrations/OrderDBContextModelSnapshot.cs",
    "chars": 2250,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/OrderDBContext.cs",
    "chars": 535,
    "preview": "using Microsoft.EntityFrameworkCore;\nusing Services.Orders.Data;\n\nnamespace Services.Customers.Data\n{\n    public class O"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Data/SeedData.cs",
    "chars": 410,
    "preview": "using System;\nusing System.Linq;\nusing Microsoft.Extensions.DependencyInjection;\nusing Services.Customers.Data;\n\nnamespa"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Events/OrderCompleted.cs",
    "chars": 299,
    "preview": "using System;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Orders.Events\n{\n    [MessageNamespace(\"c"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Events/OrderCreated.cs",
    "chars": 466,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Orders"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Events/OrderFailed.cs",
    "chars": 303,
    "preview": "using System;\nusing Shared.Messages;\n\nnamespace Services.Orders.Events\n{\n    [MessageNamespace(\"notifications\")]\n    pub"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Events/ProductsReserveFailed.cs",
    "chars": 283,
    "preview": "using System;\nusing Shared.Messages;\n\nnamespace Services.Orders.Events\n{\n    public class ProductsReserveFailed : IEvent"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Events/ProductsReserved.cs",
    "chars": 430,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Shared.Messages;\n\nnamespace Services.Orders.Events\n{\n    public cl"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Handlers/CreateOrderHandler.cs",
    "chars": 2451,
    "preview": "using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusin"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Handlers/ProductsReserveFailedHandler.cs",
    "chars": 1428,
    "preview": "using System;\nusing System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusing Microsoft.Extensi"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Handlers/ProductsReservedHandler.cs",
    "chars": 1316,
    "preview": "using System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusing Microsoft.Extensions.Logging;\nu"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/HttpServices/CustomerHttpService.cs",
    "chars": 947,
    "preview": "using System;\nusing System.Net.Http;\nusing System.Threading.Tasks;\nusing Newtonsoft.Json;\nusing Services.Orders.Models;\n"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/HttpServices/ICustomerHttpService.cs",
    "chars": 220,
    "preview": "using System;\nusing System.Threading.Tasks;\nusing Services.Orders.Models;\n\nnamespace Services.Orders.HttpServices\n{\n    "
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Models/Basket.cs",
    "chars": 303,
    "preview": "using System;\nusing System.Collections.Generic;\n\nnamespace Services.Orders.Models\n{\n    public class Basket\n    {\n      "
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Models/BasketItem.cs",
    "chars": 352,
    "preview": "using System;\n\nnamespace Services.Orders.Models\n{\n    public class BasketItem\n    {\n        public Guid Id { get; set; }"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Program.cs",
    "chars": 486,
    "preview": "using Microsoft.AspNetCore;\nusing Microsoft.AspNetCore.Hosting;\nusing Shared.Logging;\n\nnamespace Services.Orders\n{\n    "
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Properties/launchSettings.json",
    "chars": 693,
    "preview": "{\n  \"$schema\": \"http://json.schemastore.org/launchsettings.json\",\n  \"iisSettings\": {\n    \"windowsAuthentication\": false"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Services.Orders.csproj",
    "chars": 485,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.2</TargetFramework>\n    <AspNe"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/Startup.cs",
    "chars": 2237,
    "preview": "using System;\nusing System.Net.Http.Headers;\nusing Shared.Models;\nusing Shared.RabbitMq;\nusing Microsoft.AspNetCore.Bui"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/appsettings.Development.json",
    "chars": 137,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Informat"
  },
  {
    "path": "DotnetIst.Services.Orders/src/Services.Orders/appsettings.json",
    "chars": 975,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\",\n  \"ConnectionStrings\": {"
  },
  {
    "path": "DotnetIst.Services.Products/README.md",
    "chars": 131,
    "preview": "**Migration**\n\n0- .csproj path\n\n1- *dotnet ef migrations add \"migration_name\" -o ./Data/Migrations*\n\n2- *dotnet ef datab"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Controllers/HomeController.cs",
    "chars": 342,
    "preview": "using Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Services.Products.Controllers\n{\n   "
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Controllers/ProductController.cs",
    "chars": 873,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.AspNet"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Data/Entity/Product.cs",
    "chars": 248,
    "preview": "using System;\nusing Shared.Models;\n\nnamespace Services.Products.Data\n{\n    public class Product : BaseEntity\n    {\n     "
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308212022_initial.Designer.cs",
    "chars": 1327,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308212022_initial.cs",
    "chars": 976,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Services.Products.Data.Migrations\n{\n    public"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308222331_base_entity.Designer.cs",
    "chars": 1393,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Data/Migrations/20190308222331_base_entity.cs",
    "chars": 713,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace Services.Products.Data.Migrations\n{\n    public"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Data/Migrations/ProductDBContextModelSnapshot.cs",
    "chars": 1325,
    "preview": "// <auto-generated />\nusing System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastruc"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Data/ProductDBContext.cs",
    "chars": 487,
    "preview": "using Microsoft.EntityFrameworkCore;\nusing Services.Products.Data;\n\nnamespace Services.Customers.Data\n{\n    public class"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Data/SeedData.cs",
    "chars": 977,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing Microsoft.Extensions.DependencyInjection;\nusing"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Events/OrderCreated.cs",
    "chars": 433,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Shared.Messages;\nusing Newtonsoft.Json;\n\nnamespace Services.Produc"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Events/ProductsReserveFailed.cs",
    "chars": 318,
    "preview": "using System;\nusing Shared.Messages;\n\nnamespace Services.Products.Events\n{\n    [MessageNamespace(\"orders\")]\n    public c"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Events/ProductsReserved.cs",
    "chars": 464,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Shared.Messages;\n\nnamespace Services.Products.Events\n{\n    [Messag"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Handlers/OrderCreatedHandler.cs",
    "chars": 2500,
    "preview": "using System;\nusing System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.RabbitMq;\nusing Microsoft.Extensi"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Program.cs",
    "chars": 490,
    "preview": "using Microsoft.AspNetCore;\nusing Microsoft.AspNetCore.Hosting;\nusing Shared.Logging;\n\nnamespace Services.Products\n{\n  "
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Properties/launchSettings.json",
    "chars": 695,
    "preview": "{\n  \"$schema\": \"http://json.schemastore.org/launchsettings.json\",\n  \"iisSettings\": {\n    \"windowsAuthentication\": false"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Services.Products.csproj",
    "chars": 485,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.2</TargetFramework>\n    <AspNe"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/Startup.cs",
    "chars": 1607,
    "preview": "using System;\nusing Shared;\nusing Shared.RabbitMq;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Hosti"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/appsettings.Development.json",
    "chars": 137,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Informat"
  },
  {
    "path": "DotnetIst.Services.Products/src/Services.Products/appsettings.json",
    "chars": 895,
    "preview": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\",\n  \"ConnectionStrings\": {"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/Extensions.cs",
    "chars": 1154,
    "preview": "using System;\nusing System.Linq;\nusing System.Reflection;\nusing Autofac;\nusing Autofac.Extensions.DependencyInjection;\nu"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/Logging/LoggingExtensions.cs",
    "chars": 975,
    "preview": "using System;\nusing Microsoft.AspNetCore.Hosting;\nusing Serilog;\nusing Serilog.Sinks.Elasticsearch;\n\nnamespace Shared.Lo"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/MessageHandlers/ICommandHandler.cs",
    "chars": 274,
    "preview": "using System.Threading.Tasks;\nusing Shared.Messages;\nusing Shared.RabbitMq;\n\nnamespace Shared.MessageHandlers\n{\n    publ"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/MessageHandlers/IEventHandler.cs",
    "chars": 263,
    "preview": "using System.Threading.Tasks;\nusing Shared.Messages;\nusing Shared.RabbitMq;\n\nnamespace Shared.MessageHandlers\n{\n    publ"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/Messages/ICommand.cs",
    "chars": 72,
    "preview": "namespace Shared.Messages\n{\n    public interface ICommand\n    {\n\n    }\n}"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/Messages/IEvent.cs",
    "chars": 70,
    "preview": "namespace Shared.Messages\n{\n    public interface IEvent\n    {\n\n    }\n}"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/Messages/MessageNamespaceAttribute.cs",
    "chars": 289,
    "preview": "using System;\n\nnamespace Shared.Messages\n{\n    public class MessageNamespaceAttribute : Attribute\n    {\n        public s"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/Models/BaseEntity.cs",
    "chars": 310,
    "preview": "using System;\n\nnamespace Shared.Models\n{\n    public class BaseEntity\n    {\n        public Guid Id { get; set; }\n        "
  },
  {
    "path": "DotnetIst.Shared/src/Shared/Models/HttpServiceOptions.cs",
    "chars": 192,
    "preview": "namespace Shared.Models\n{\n    public class HttpServiceOptions\n    {\n        public string ProductHttpServiceUrl { get; s"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/RabbitMq/BusPublisher.cs",
    "chars": 2043,
    "preview": "using System.Reflection;\nusing System.Threading.Tasks;\nusing Shared.Messages;\nusing Microsoft.Extensions.Logging;\nusing "
  },
  {
    "path": "DotnetIst.Shared/src/Shared/RabbitMq/BusSubscriber.cs",
    "chars": 4200,
    "preview": "using System;\nusing System.Reflection;\nusing System.Threading.Tasks;\nusing Shared.MessageHandlers;\nusing Shared.Message"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/RabbitMq/CorrelationContext.cs",
    "chars": 631,
    "preview": "using System;\nusing Newtonsoft.Json;\n\nnamespace Shared.RabbitMq\n{\n    public class CorrelationContext : ICorrelationCont"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/RabbitMq/IBusPublisher.cs",
    "chars": 363,
    "preview": "using System.Threading.Tasks;\nusing Shared.Messages;\n\nnamespace Shared.RabbitMq\n{\n    public interface IBusPublisher\n   "
  },
  {
    "path": "DotnetIst.Shared/src/Shared/RabbitMq/IBusSubscriber.cs",
    "chars": 340,
    "preview": "using System;\nusing Shared.Messages;\n\nnamespace Shared.RabbitMq\n{\n    public interface IBusSubscriber\n    {\n        IBu"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/RabbitMq/ICorrelationContext.cs",
    "chars": 166,
    "preview": "using System;\n\nnamespace Shared.RabbitMq\n{\n    public interface ICorrelationContext\n    {\n        Guid CorrelationId { g"
  },
  {
    "path": "DotnetIst.Shared/src/Shared/RabbitMq/RabbitMqExtensions.cs",
    "chars": 3421,
    "preview": "using System.Reflection;\nusing Autofac;\nusing Shared.MessageHandlers;\nusing Shared.Messages;\nusing Microsoft.AspNetCore."
  },
  {
    "path": "DotnetIst.Shared/src/Shared/RabbitMq/RabbitMqOptions.cs",
    "chars": 265,
    "preview": "using RawRabbit.Configuration;\n\nnamespace Shared.RabbitMq\n{\n    public class RabbitMqOptions : RawRabbitConfiguration\n  "
  },
  {
    "path": "DotnetIst.Shared/src/Shared/Shared.csproj",
    "chars": 1888,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>netstandard2.0</TargetFramework>\n  </PropertyG"
  },
  {
    "path": "README.md",
    "chars": 1135,
    "preview": "Presentation : https://speakerdeck.com/suadev/microservice-architecture-and-implementation-with-asp-dot-net-core\n\nThe ai"
  },
  {
    "path": "docker-compose.yml",
    "chars": 864,
    "preview": "version: '3.7'\n\nservices:\n\n  rabbitmq:\n    image: rabbitmq:3-management\n    container_name: myrabbitmq\n    ports:\n      "
  },
  {
    "path": "dotnet-istanbul-microservices-demo.sln",
    "chars": 10154,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.26124.0\nMini"
  }
]

About this extraction

This page contains the full source code of the suadev/dotnet-istanbul-microservices-demo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 147 files (142.5 KB), approximately 38.6k tokens, and a symbol index with 275 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!