├── .dockerignore ├── .gitignore ├── Images ├── dashboard.png ├── features.png └── transaction.png ├── LICENSE ├── Northwind.Operations ├── App.config ├── Kubernetes │ ├── Istio │ │ ├── Canary │ │ │ ├── virtual-service-address-v1-v2-canary-0.yml │ │ │ ├── virtual-service-address-v1-v2-canary-10.yml │ │ │ ├── virtual-service-address-v1-v2-canary-100.yml │ │ │ ├── virtual-service-address-v1-v2-canary-20.yml │ │ │ ├── virtual-service-address-v1-v2-canary-30.yml │ │ │ ├── virtual-service-address-v1-v2-canary-40.yml │ │ │ ├── virtual-service-address-v1-v2-canary-50.yml │ │ │ ├── virtual-service-address-v1-v2-canary-60.yml │ │ │ ├── virtual-service-address-v1-v2-canary-70.yml │ │ │ ├── virtual-service-address-v1-v2-canary-80.yml │ │ │ ├── virtual-service-address-v1-v2-canary-90.yml │ │ │ ├── virtual-service-address-v1-v3-canary-0.yml │ │ │ ├── virtual-service-address-v1-v3-canary-10.yml │ │ │ ├── virtual-service-address-v1-v3-canary-100.yml │ │ │ ├── virtual-service-address-v1-v3-canary-20.yml │ │ │ ├── virtual-service-address-v1-v3-canary-30.yml │ │ │ ├── virtual-service-address-v1-v3-canary-40.yml │ │ │ ├── virtual-service-address-v1-v3-canary-50.yml │ │ │ ├── virtual-service-address-v1-v3-canary-60.yml │ │ │ ├── virtual-service-address-v1-v3-canary-70.yml │ │ │ ├── virtual-service-address-v1-v3-canary-80.yml │ │ │ ├── virtual-service-address-v1-v3-canary-90.yml │ │ │ ├── virtual-service-payment-canary-0.yml │ │ │ ├── virtual-service-payment-canary-10.yml │ │ │ ├── virtual-service-payment-canary-100.yml │ │ │ ├── virtual-service-payment-canary-20.yml │ │ │ ├── virtual-service-payment-canary-30.yml │ │ │ ├── virtual-service-payment-canary-40.yml │ │ │ ├── virtual-service-payment-canary-50.yml │ │ │ ├── virtual-service-payment-canary-60.yml │ │ │ ├── virtual-service-payment-canary-70.yml │ │ │ ├── virtual-service-payment-canary-80.yml │ │ │ └── virtual-service-payment-canary-90.yml │ │ ├── Fault │ │ │ ├── virtual-service-address-v3-fault-0.yml │ │ │ ├── virtual-service-address-v3-fault-10.yml │ │ │ ├── virtual-service-address-v3-fault-100.yml │ │ │ ├── virtual-service-address-v3-fault-20.yml │ │ │ ├── virtual-service-address-v3-fault-30.yml │ │ │ ├── virtual-service-address-v3-fault-40.yml │ │ │ ├── virtual-service-address-v3-fault-50.yml │ │ │ ├── virtual-service-address-v3-fault-60.yml │ │ │ ├── virtual-service-address-v3-fault-70.yml │ │ │ ├── virtual-service-address-v3-fault-80.yml │ │ │ └── virtual-service-address-v3-fault-90.yml │ │ ├── destination-rule-address.yml │ │ ├── destination-rule-order.yml │ │ ├── destination-rule-payment.yml │ │ ├── destination-rule-product.yml │ │ ├── virtual-service-address-v1.yml │ │ ├── virtual-service-address-v2.yml │ │ ├── virtual-service-address-v3.yml │ │ ├── virtual-service-order.yml │ │ ├── virtual-service-payment-v1.yml │ │ ├── virtual-service-payment-v2.yml │ │ └── virtual-service-product.yml │ ├── deployment-address-v1.yml │ ├── deployment-address-v2.yml │ ├── deployment-address-v3.yml │ ├── deployment-order-v1.yml │ ├── deployment-payment-v1.yml │ ├── deployment-payment-v2.yml │ ├── deployment-product-v1.yml │ ├── helm.yml │ ├── ingress-controller.yml │ ├── ingress.yml │ ├── service-address.yml │ ├── service-order.yml │ ├── service-payment.yml │ └── service-product.yml ├── MainWin.CLI.cs ├── MainWin.Designer.cs ├── MainWin.Events.cs ├── MainWin.cs ├── MainWin.resx ├── Model │ ├── OrderRequest.cs │ ├── OrderResponse.cs │ ├── ProductDetail.cs │ └── Response.cs ├── Northwind.Operations.csproj ├── Program.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── Services │ └── Transaction.cs ├── Swarm │ └── docker-stack.yml ├── Tester.cs ├── Users.Designer.cs ├── Users.cs ├── Users.resx └── packages.config ├── Northwind.Services.Address.v2 ├── Controllers │ ├── AddressController.cs │ └── HomeController.cs ├── Dockerfile ├── Model │ ├── ValidationRequest.cs │ └── ValidationResponse.cs ├── Northwind.Services.Address.v2.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── appsettings.Development.json └── appsettings.json ├── Northwind.Services.Address.v3 ├── Controllers │ ├── AddressController.cs │ └── HomeController.cs ├── Dockerfile ├── Model │ ├── ValidationRequest.cs │ └── ValidationResponse.cs ├── Northwind.Services.Address.v3.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── appsettings.Development.json └── appsettings.json ├── Northwind.Services.Address ├── Controllers │ ├── AddressController.cs │ └── HomeController.cs ├── Dockerfile ├── Model │ ├── ValidationRequest.cs │ └── ValidationResponse.cs ├── Northwind.Services.Address.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── appsettings.Development.json └── appsettings.json ├── Northwind.Services.Order ├── Controllers │ ├── HomeController.cs │ └── OrderController.cs ├── Dockerfile ├── Model │ ├── OrderRequest.cs │ ├── OrderResponse.cs │ ├── ProductDetail.cs │ └── ValidationResponse.cs ├── Northwind.Services.Order.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── appsettings.Development.json └── appsettings.json ├── Northwind.Services.Payment.v2 ├── Controllers │ ├── HomeController.cs │ └── PaymentController.cs ├── Dockerfile ├── Model │ ├── ValidationRequest.cs │ └── ValidationResponse.cs ├── Northwind.Services.Payment.v2.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── appsettings.Development.json └── appsettings.json ├── Northwind.Services.Payment ├── Controllers │ ├── HomeController.cs │ └── PaymentController.cs ├── Dockerfile ├── Model │ ├── ValidationRequest.cs │ └── ValidationResponse.cs ├── Northwind.Services.Payment.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── appsettings.Development.json └── appsettings.json ├── Northwind.Services.Product ├── Controllers │ ├── HomeController.cs │ └── ProductController.cs ├── Dockerfile ├── Model │ └── ProductDetail.cs ├── Northwind.Services.Product.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs ├── appsettings.Development.json └── appsettings.json ├── Northwind.Services.Shared ├── Northwind.Services.Shared.csproj └── Response.cs ├── Northwind.sln ├── README.md ├── docker-compose.dcproj ├── docker-compose.override.yml └── docker-compose.yml /.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .env 3 | .git 4 | .gitignore 5 | .vs 6 | .vscode 7 | docker-compose.yml 8 | docker-compose.*.yml 9 | */bin 10 | */obj 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | 332 | 333 | *.userosscache 334 | *.sln.docstates 335 | 336 | # User-specific files (MonoDevelop/Xamarin Studio) 337 | *.userprefs 338 | 339 | # Build results 340 | [Dd]ebug/ 341 | [Dd]ebugPublic/ 342 | [Rr]elease/ 343 | [Rr]eleases/ 344 | x64/ 345 | x86/ 346 | bld/ 347 | [Bb]in/ 348 | [Oo]bj/ 349 | [Ll]og/ 350 | 351 | # Visual Studio 2015/2017 cache/options directory 352 | .vs/ 353 | # Uncomment if you have tasks that create the project's static files in wwwroot 354 | #wwwroot/ 355 | 356 | # Visual Studio 2017 auto generated files 357 | Generated\ Files/ 358 | 359 | # MSTest test Results 360 | [Tt]est[Rr]esult*/ 361 | [Bb]uild[Ll]og.* 362 | 363 | # NUNIT 364 | *.VisualState.xml 365 | TestResult.xml 366 | 367 | # Build Results of an ATL Project 368 | [Dd]ebugPS/ 369 | [Rr]eleasePS/ 370 | dlldata.c 371 | 372 | # Benchmark Results 373 | BenchmarkDotNet.Artifacts/ 374 | 375 | # .NET Core 376 | project.lock.json 377 | project.fragment.lock.json 378 | artifacts/ 379 | **/Properties/launchSettings.json 380 | 381 | # StyleCop 382 | StyleCopReport.xml 383 | 384 | # Files built by Visual Studio 385 | *.ncb 386 | *.suo 387 | *.bak 388 | *.cache 389 | *.meta 390 | *.obj 391 | *.iobj 392 | *.pch 393 | *.pdb 394 | *.ipdb 395 | *.pgc 396 | *.pgd 397 | *.rsp 398 | *.sbr 399 | *.tlb 400 | *.tli 401 | *.tlh 402 | *.tmp 403 | *.tmp_proj 404 | *.vspscc 405 | *.vssscc 406 | .builds 407 | *.pidb 408 | *.svclog 409 | *.scc 410 | 411 | # Chutzpah Test files 412 | _Chutzpah* 413 | 414 | # Visual C++ cache files 415 | ipch/ 416 | *.aps 417 | *.ncb 418 | *.opendb 419 | *.opensdf 420 | *.sdf 421 | *.cachefile 422 | *.VC.db 423 | *.VC.VC.opendb 424 | 425 | # Visual Studio profiler 426 | *.psess 427 | *.vsp 428 | *.vspx 429 | *.sap 430 | 431 | # Visual Studio Trace Files 432 | *.e2e 433 | 434 | # TFS 2012 Local Workspace 435 | $tf/ 436 | 437 | # Guidance Automation Toolkit 438 | *.gpState 439 | 440 | # ReSharper is a .NET coding add-in 441 | *.[Rr]e[Ss]harper 442 | *.DotSettings.user 443 | 444 | # JustCode is a .NET coding add-in 445 | .JustCode 446 | 447 | # TeamCity is a build add-in 448 | _TeamCity* 449 | 450 | # DotCover is a Code Coverage Tool 451 | *.dotCover 452 | 453 | # AxoCover is a Code Coverage Tool 454 | .axoCover/* 455 | !.axoCover/settings.json 456 | 457 | # Visual Studio code coverage results 458 | *.coverage 459 | *.coveragexml 460 | 461 | # NCrunch 462 | _NCrunch_* 463 | .*crunch*.local.xml 464 | nCrunchTemp_* 465 | 466 | # MightyMoose 467 | *.mm.* 468 | AutoTest.Net/ 469 | 470 | # Web workbench (sass) 471 | .sass-cache/ 472 | 473 | # Installshield output folder 474 | [Ee]xpress/ 475 | 476 | # DocProject is a documentation generator add-in 477 | DocProject/buildhelp/ 478 | DocProject/Help/*.HxT 479 | DocProject/Help/*.HxC 480 | DocProject/Help/*.hhc 481 | DocProject/Help/*.hhk 482 | DocProject/Help/*.hhp 483 | DocProject/Help/Html2 484 | DocProject/Help/html 485 | 486 | # Click-Once directory 487 | publish/ 488 | 489 | # Publish Web Output 490 | *.[Pp]ublish.xml 491 | *.azurePubxml 492 | # Note: Comment the next line if you want to checkin your web deploy settings, 493 | # but database connection strings (with potential passwords) will be unencrypted 494 | *.pubxml 495 | *.publishproj 496 | 497 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 498 | # checkin your Azure Web App publish settings, but sensitive information contained 499 | # in these scripts will be unencrypted 500 | PublishScripts/ 501 | 502 | # NuGet Packages 503 | *.nupkg 504 | # The packages folder can be ignored because of Package Restore 505 | **/[Pp]ackages/* 506 | # except build/, which is used as an MSBuild target. 507 | !**/[Pp]ackages/build/ 508 | # Uncomment if necessary however generally it will be regenerated when needed 509 | #!**/[Pp]ackages/repositories.config 510 | # NuGet v3's project.json files produces more ignorable files 511 | *.nuget.props 512 | *.nuget.targets 513 | 514 | # Microsoft Azure Build Output 515 | csx/ 516 | *.build.csdef 517 | 518 | # Microsoft Azure Emulator 519 | ecf/ 520 | rcf/ 521 | 522 | # Windows Store app package directories and files 523 | AppPackages/ 524 | BundleArtifacts/ 525 | Package.StoreAssociation.xml 526 | _pkginfo.txt 527 | *.appx 528 | 529 | # Visual Studio cache files 530 | # files ending in .cache can be ignored 531 | *.[Cc]ache 532 | # but keep track of directories ending in .cache 533 | !*.[Cc]ache/ 534 | 535 | # Others 536 | ClientBin/ 537 | ~$* 538 | *~ 539 | *.dbmdl 540 | *.dbproj.schemaview 541 | *.jfm 542 | *.pfx 543 | *.publishsettings 544 | orleans.codegen.cs 545 | 546 | # Including strong name files can present a security risk 547 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 548 | #*.snk 549 | 550 | # Since there are multiple workflows, uncomment next line to ignore bower_components 551 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 552 | #bower_components/ 553 | 554 | # RIA/Silverlight projects 555 | Generated_Code/ 556 | 557 | # Backup & report files from converting an old project file 558 | # to a newer Visual Studio version. Backup files are not needed, 559 | # because we have git ;-) 560 | _UpgradeReport_Files/ 561 | Backup*/ 562 | UpgradeLog*.XML 563 | UpgradeLog*.htm 564 | ServiceFabricBackup/ 565 | *.rptproj.bak 566 | 567 | # SQL Server files 568 | *.mdf 569 | *.ldf 570 | *.ndf 571 | 572 | # Business Intelligence projects 573 | *.rdl.data 574 | *.bim.layout 575 | *.bim_*.settings 576 | *.rptproj.rsuser 577 | 578 | # Microsoft Fakes 579 | FakesAssemblies/ 580 | 581 | # GhostDoc plugin setting file 582 | *.GhostDoc.xml 583 | 584 | # Node.js Tools for Visual Studio 585 | .ntvs_analysis.dat 586 | node_modules/ 587 | 588 | # Visual Studio 6 build log 589 | *.plg 590 | 591 | # Visual Studio 6 workspace options file 592 | *.opt 593 | 594 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 595 | *.vbw 596 | 597 | # Visual Studio LightSwitch build output 598 | **/*.HTMLClient/GeneratedArtifacts 599 | **/*.DesktopClient/GeneratedArtifacts 600 | **/*.DesktopClient/ModelManifest.xml 601 | **/*.Server/GeneratedArtifacts 602 | **/*.Server/ModelManifest.xml 603 | _Pvt_Extensions 604 | 605 | # Paket dependency manager 606 | .paket/paket.exe 607 | paket-files/ 608 | 609 | # FAKE - F# Make 610 | .fake/ 611 | 612 | # JetBrains Rider 613 | .idea/ 614 | *.sln.iml 615 | 616 | # CodeRush 617 | .cr/ 618 | 619 | # Python Tools for Visual Studio (PTVS) 620 | __pycache__/ 621 | *.pyc 622 | 623 | # Cake - Uncomment if you are using it 624 | # tools/** 625 | # !tools/packages.config 626 | 627 | # Tabs Studio 628 | *.tss 629 | 630 | # Telerik's JustMock configuration file 631 | *.jmconfig 632 | 633 | # BizTalk build output 634 | *.btp.cs 635 | *.btm.cs 636 | *.odx.cs 637 | *.xsd.cs 638 | 639 | # OpenCover UI analysis results 640 | OpenCover/ 641 | 642 | # Azure Stream Analytics local run output 643 | ASALocalRun/ 644 | 645 | # MSBuild Binary and Structured Log 646 | *.binlog 647 | 648 | # NVidia Nsight GPU debugger configuration file 649 | *.nvuser 650 | 651 | # MFractors (Xamarin productivity tool) working folder 652 | .mfractor/ -------------------------------------------------------------------------------- /Images/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parameshg/istio-prototype/1296ed377ebe7eeed83dfa6fe180899e4b4405cc/Images/dashboard.png -------------------------------------------------------------------------------- /Images/features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parameshg/istio-prototype/1296ed377ebe7eeed83dfa6fe180899e4b4405cc/Images/features.png -------------------------------------------------------------------------------- /Images/transaction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parameshg/istio-prototype/1296ed377ebe7eeed83dfa6fe180899e4b4405cc/Images/transaction.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Paramesh Gunasekaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Northwind.Operations/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-0.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 100 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 0 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-10.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 90 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 10 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-100.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 0 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 100 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-20.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 80 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 20 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-30.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 70 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 30 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-40.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 60 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 40 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-50.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 50 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 50 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-60.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 40 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 60 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-70.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 30 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 70 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-80.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 20 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v2-canary-90.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 10 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 90 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-0.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 100 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 0 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-10.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 90 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 10 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-100.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 0 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 100 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-20.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 80 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 20 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-30.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 70 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 30 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-40.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 60 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 40 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-50.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 50 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 50 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-60.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 40 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 60 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-70.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 30 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 70 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-80.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 20 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-address-v1-v3-canary-90.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 13 | weight: 10 14 | - destination: 15 | host: address 16 | subset: v2 17 | weight: 90 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-0.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 100 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 0 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-10.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 90 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 10 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-100.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 0 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 100 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-20.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 80 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 20 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-30.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 70 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 30 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-40.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 60 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 40 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-50.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 50 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 50 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-60.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 40 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 60 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-70.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 30 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 70 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-80.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 20 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 80 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Canary/virtual-service-payment-canary-90.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 13 | weight: 10 14 | - destination: 15 | host: payment 16 | subset: v2 17 | weight: 90 18 | -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-0.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 0 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-10.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 10 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-100.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 100 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-20.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 20 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-30.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 30 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-40.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 40 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-50.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 50 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-60.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 60 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-70.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 70 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-80.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 80 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/Fault/virtual-service-address-v3-fault-90.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - fault: 10 | abort: 11 | percent: 90 12 | httpStatus: 400 13 | route: 14 | - destination: 15 | host: address 16 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/destination-rule-address.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: DestinationRule 3 | metadata: 4 | name: address 5 | spec: 6 | host: address 7 | subsets: 8 | - name: v1 9 | labels: 10 | version: "1" 11 | - name: v2 12 | labels: 13 | version: "2" 14 | - name: v3 15 | labels: 16 | version: "3" -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/destination-rule-order.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: DestinationRule 3 | metadata: 4 | name: order 5 | spec: 6 | host: order 7 | subsets: 8 | - name: v1 9 | labels: 10 | version: "1" -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/destination-rule-payment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: DestinationRule 3 | metadata: 4 | name: payment 5 | spec: 6 | host: payment 7 | subsets: 8 | - name: v1 9 | labels: 10 | version: "1" 11 | - name: v2 12 | labels: 13 | version: "2" -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/destination-rule-product.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: DestinationRule 3 | metadata: 4 | name: product 5 | spec: 6 | host: product 7 | subsets: 8 | - name: v1 9 | labels: 10 | version: "1" -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/virtual-service-address-v1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v1 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/virtual-service-address-v2.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v2 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/virtual-service-address-v3.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: address 5 | spec: 6 | hosts: 7 | - address 8 | http: 9 | - route: 10 | - destination: 11 | host: address 12 | subset: v3 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/virtual-service-order.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: order 5 | spec: 6 | hosts: 7 | - order 8 | http: 9 | - route: 10 | - destination: 11 | host: order 12 | subset: v1 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/virtual-service-payment-v1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v1 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/virtual-service-payment-v2.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: payment 5 | spec: 6 | hosts: 7 | - payment 8 | http: 9 | - route: 10 | - destination: 11 | host: payment 12 | subset: v2 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/Istio/virtual-service-product.yml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.istio.io/v1alpha3 2 | kind: VirtualService 3 | metadata: 4 | name: product 5 | spec: 6 | hosts: 7 | - product 8 | http: 9 | - route: 10 | - destination: 11 | host: product 12 | subset: v1 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/deployment-address-v1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: address-1 5 | labels: 6 | api: address 7 | version: "1" 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | api: address 13 | version: "1" 14 | template: 15 | metadata: 16 | name: address-1 17 | labels: 18 | api: address 19 | version: "1" 20 | spec: 21 | containers: 22 | - name: address 23 | image: parameshg/northwind.address:v1 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/deployment-address-v2.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: address-2 5 | labels: 6 | api: address 7 | version: "2" 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | api: address 13 | version: "2" 14 | template: 15 | metadata: 16 | name: address-2 17 | labels: 18 | api: address 19 | version: "2" 20 | spec: 21 | containers: 22 | - name: address 23 | image: parameshg/northwind.address:v2 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/deployment-address-v3.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: address-3 5 | labels: 6 | api: address 7 | version: "3" 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | api: address 13 | version: "3" 14 | template: 15 | metadata: 16 | name: address-3 17 | labels: 18 | api: address 19 | version: "3" 20 | spec: 21 | containers: 22 | - name: address 23 | image: parameshg/northwind.address:v3 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/deployment-order-v1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: order-1 5 | labels: 6 | api: order 7 | version: "1" 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | api: order 13 | version: "1" 14 | template: 15 | metadata: 16 | name: order-1 17 | labels: 18 | api: order 19 | version: "1" 20 | spec: 21 | containers: 22 | - name: order 23 | image: parameshg/northwind.order:v1 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/deployment-payment-v1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: payment-1 5 | labels: 6 | api: payment 7 | version: "1" 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | api: payment 13 | version: "1" 14 | template: 15 | metadata: 16 | name: payment-1 17 | labels: 18 | api: payment 19 | version: "1" 20 | spec: 21 | containers: 22 | - name: payment 23 | image: parameshg/northwind.payment:v1 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/deployment-payment-v2.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: payment-2 5 | labels: 6 | api: payment 7 | version: "2" 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | api: payment 13 | version: "2" 14 | template: 15 | metadata: 16 | name: payment-2 17 | labels: 18 | api: payment 19 | version: "2" 20 | spec: 21 | containers: 22 | - name: payment 23 | image: parameshg/northwind.payment:v2 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/deployment-product-v1.yml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: product-1 5 | labels: 6 | api: product 7 | version: "1" 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | api: product 13 | version: "1" 14 | template: 15 | metadata: 16 | name: product-1 17 | labels: 18 | api: product 19 | version: "1" 20 | spec: 21 | containers: 22 | - name: product 23 | image: "parameshg/northwind.product:v1" 24 | imagePullPolicy: Always 25 | ports: 26 | - containerPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/helm.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: tiller 5 | namespace: kube-system 6 | --- 7 | apiVersion: rbac.authorization.k8s.io/v1beta1 8 | kind: ClusterRoleBinding 9 | metadata: 10 | name: tiller 11 | roleRef: 12 | apiGroup: rbac.authorization.k8s.io 13 | kind: ClusterRole 14 | name: cluster-admin 15 | subjects: 16 | - kind: ServiceAccount 17 | name: tiller 18 | namespace: kube-system -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/ingress-controller.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # NAMEPSPACE #################################################################################################################### 3 | apiVersion: v1 4 | kind: Namespace 5 | metadata: 6 | name: ingress 7 | 8 | --- 9 | # DEFAULT BACKEND DEPLOYMENT #################################################################################################### 10 | apiVersion: extensions/v1beta1 11 | kind: Deployment 12 | metadata: 13 | namespace: ingress 14 | name: default-http-backend 15 | labels: 16 | app: default-http-backend 17 | spec: 18 | replicas: 1 19 | selector: 20 | matchLabels: 21 | app: default-http-backend 22 | template: 23 | metadata: 24 | namespace: ingress 25 | name: default-http-backend 26 | labels: 27 | app: default-http-backend 28 | spec: 29 | terminationGracePeriodSeconds: 60 30 | containers: 31 | - name: default-http-backend 32 | image: "gcr.io/google_containers/defaultbackend:1.4" 33 | ports: 34 | - containerPort: 8080 35 | livenessProbe: 36 | httpGet: 37 | path: /healthz 38 | port: 8080 39 | scheme: HTTP 40 | initialDelaySeconds: 30 41 | timeoutSeconds: 5 42 | 43 | --- 44 | # DEFAULT BACKEND SERVICE ####################################################################################################### 45 | apiVersion: v1 46 | kind: Service 47 | metadata: 48 | namespace: ingress 49 | name: default-http-backend 50 | labels: 51 | app: default-http-backend 52 | spec: 53 | selector: 54 | app: default-http-backend 55 | ports: 56 | - port: 80 57 | targetPort: 8080 58 | 59 | --- 60 | # CONFIG MAP #################################################################################################################### 61 | apiVersion: v1 62 | kind: ConfigMap 63 | metadata: 64 | namespace: ingress 65 | name: nginx-configuration 66 | labels: 67 | app: ingress 68 | 69 | --- 70 | # TCP SERVICE CONFIG MAP ######################################################################################################## 71 | apiVersion: v1 72 | kind: ConfigMap 73 | metadata: 74 | namespace: ingress 75 | name: tcp-services 76 | 77 | --- 78 | # UDP SERVICES CONFIG MAP ####################################################################################################### 79 | apiVersion: v1 80 | kind: ConfigMap 81 | metadata: 82 | namespace: ingress 83 | name: udp-services 84 | 85 | --- 86 | # SERVICE ACCOUNT ############################################################################################################### 87 | apiVersion: v1 88 | kind: ServiceAccount 89 | metadata: 90 | namespace: ingress 91 | name: ingress-service-account 92 | 93 | --- 94 | # CLUSTER ROLE ################################################################################################################## 95 | apiVersion: rbac.authorization.k8s.io/v1beta1 96 | kind: ClusterRole 97 | metadata: 98 | name: ingress-cluster-role 99 | rules: 100 | - apiGroups: 101 | - "" 102 | resources: 103 | - configmaps 104 | - endpoints 105 | - nodes 106 | - pods 107 | - secrets 108 | verbs: 109 | - list 110 | - watch 111 | - apiGroups: 112 | - "" 113 | resources: 114 | - nodes 115 | verbs: 116 | - get 117 | - apiGroups: 118 | - "" 119 | resources: 120 | - services 121 | verbs: 122 | - get 123 | - list 124 | - watch 125 | - apiGroups: 126 | - "extensions" 127 | resources: 128 | - ingresses 129 | verbs: 130 | - get 131 | - list 132 | - watch 133 | - apiGroups: 134 | - "" 135 | resources: 136 | - events 137 | verbs: 138 | - create 139 | - patch 140 | - apiGroups: 141 | - "extensions" 142 | resources: 143 | - ingresses/status 144 | verbs: 145 | - update 146 | 147 | --- 148 | # ROLE ########################################################################################################################## 149 | apiVersion: rbac.authorization.k8s.io/v1beta1 150 | kind: Role 151 | metadata: 152 | namespace: ingress 153 | name: ingress-role 154 | rules: 155 | - apiGroups: 156 | - "" 157 | resources: 158 | - configmaps 159 | - pods 160 | - secrets 161 | - namespaces 162 | verbs: 163 | - get 164 | - apiGroups: 165 | - "" 166 | resources: 167 | - configmaps 168 | resourceNames: 169 | - "ingress-controller-leader-nginx" 170 | verbs: 171 | - get 172 | - update 173 | - apiGroups: 174 | - "" 175 | resources: 176 | - configmaps 177 | verbs: 178 | - create 179 | - apiGroups: 180 | - "" 181 | resources: 182 | - endpoints 183 | verbs: 184 | - get 185 | 186 | --- 187 | # ROLE BINDING ################################################################################################################## 188 | apiVersion: rbac.authorization.k8s.io/v1beta1 189 | kind: RoleBinding 190 | metadata: 191 | namespace: ingress 192 | name: ingress-role-binding 193 | roleRef: 194 | apiGroup: rbac.authorization.k8s.io 195 | kind: Role 196 | name: ingress-role 197 | subjects: 198 | - kind: ServiceAccount 199 | namespace: ingress 200 | name: ingress-service-account 201 | 202 | --- 203 | # CLUSTER ROLE BINDING ########################################################################################################## 204 | apiVersion: rbac.authorization.k8s.io/v1beta1 205 | kind: ClusterRoleBinding 206 | metadata: 207 | name: ingress-cluster-role-binding 208 | roleRef: 209 | name: ingress-cluster-role 210 | apiGroup: rbac.authorization.k8s.io 211 | kind: ClusterRole 212 | 213 | subjects: 214 | - kind: ServiceAccount 215 | namespace: ingress 216 | name: ingress-service-account 217 | 218 | --- 219 | # DAEMON SET #################################################################################################################### 220 | apiVersion: extensions/v1beta1 221 | kind: DaemonSet 222 | metadata: 223 | namespace: ingress 224 | name: ingress-controller 225 | spec: 226 | selector: 227 | matchLabels: 228 | app: ingress-controller 229 | template: 230 | metadata: 231 | labels: 232 | app: ingress-controller 233 | annotations: 234 | prometheus.io/port: '10254' 235 | prometheus.io/scrape: 'true' 236 | spec: 237 | serviceAccountName: ingress-service-account 238 | hostNetwork: true 239 | containers: 240 | - name: ingress-controller 241 | image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.14.0 242 | args: 243 | - /ingress-controller 244 | - --default-backend-service=$(POD_NAMESPACE)/default-http-backend 245 | - --configmap=$(POD_NAMESPACE)/nginx-configuration 246 | - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services 247 | - --udp-services-configmap=$(POD_NAMESPACE)/udp-services 248 | - --annotations-prefix=nginx.ingress.kubernetes.io 249 | env: 250 | - name: POD_NAME 251 | valueFrom: 252 | fieldRef: 253 | fieldPath: metadata.name 254 | - name: POD_NAMESPACE 255 | valueFrom: 256 | fieldRef: 257 | fieldPath: metadata.namespace 258 | ports: 259 | - name: http 260 | containerPort: 80 261 | hostPort: 80 262 | livenessProbe: 263 | failureThreshold: 3 264 | httpGet: 265 | path: /healthz 266 | port: 10254 267 | scheme: HTTP 268 | initialDelaySeconds: 10 269 | periodSeconds: 10 270 | successThreshold: 1 271 | timeoutSeconds: 1 272 | readinessProbe: 273 | failureThreshold: 3 274 | httpGet: 275 | path: /healthz 276 | port: 10254 277 | scheme: HTTP 278 | periodSeconds: 10 279 | successThreshold: 1 280 | timeoutSeconds: 1 281 | securityContext: 282 | runAsNonRoot: false 283 | 284 | --- 285 | # INGRESS SERVICE ############################################################################################################### 286 | apiVersion: v1 287 | kind: Service 288 | metadata: 289 | namespace: ingress 290 | name: ingress-controller 291 | spec: 292 | selector: 293 | app: ingress-controller 294 | type: LoadBalancer 295 | ports: 296 | - name: http 297 | protocol: TCP 298 | port: 80 299 | targetPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/ingress.yml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | namespace: default 5 | name: northwind 6 | annotations: 7 | kubernetes.io/ingress.class: northwind 8 | nginx.ingress.kubernetes.io/ssl-redirect: "false" 9 | nginx.ingress.kubernetes.io/rewrite-target: / 10 | spec: 11 | rules: 12 | - host: matrix.7e32334e0e69428fba45.westus2.aksapp.io 13 | http: 14 | paths: 15 | - path: / 16 | backend: 17 | serviceName: product 18 | servicePort: 80 19 | - path: /products 20 | backend: 21 | serviceName: product 22 | servicePort: 80 23 | - path: /orders 24 | backend: 25 | serviceName: order 26 | servicePort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/service-address.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: address 5 | labels: 6 | api: address 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | api: address 11 | ports: 12 | - name: http 13 | protocol: TCP 14 | port: 80 15 | targetPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/service-order.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: order 5 | labels: 6 | api: order 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | api: order 11 | ports: 12 | - name: http 13 | protocol: TCP 14 | port: 80 15 | targetPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/service-payment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: payment 5 | labels: 6 | api: payment 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | api: payment 11 | ports: 12 | - name: http 13 | protocol: TCP 14 | port: 80 15 | targetPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/Kubernetes/service-product.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: product 5 | labels: 6 | api: product 7 | spec: 8 | type: ClusterIP 9 | selector: 10 | api: product 11 | ports: 12 | - name: http 13 | protocol: TCP 14 | port: 80 15 | targetPort: 80 -------------------------------------------------------------------------------- /Northwind.Operations/MainWin.CLI.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | using System.IO; 4 | using System.Windows.Forms; 5 | using Newtonsoft.Json; 6 | 7 | namespace Northwind.Operations 8 | { 9 | partial class MainWin 10 | { 11 | private dynamic kubectlj(string args) 12 | { 13 | dynamic result = null; 14 | 15 | using (var kubectl = new Process()) 16 | { 17 | kubectl.StartInfo.CreateNoWindow = true; 18 | kubectl.StartInfo.FileName = "kubectl.exe"; 19 | kubectl.StartInfo.Arguments = args + " -o json"; 20 | kubectl.StartInfo.UseShellExecute = false; 21 | kubectl.StartInfo.RedirectStandardOutput = true; 22 | kubectl.StartInfo.RedirectStandardError = true; 23 | kubectl.Start(); 24 | 25 | result = JsonConvert.DeserializeObject(kubectl.StandardOutput.ReadToEnd()); 26 | 27 | kubectl.WaitForExit(); 28 | } 29 | 30 | return result; 31 | } 32 | 33 | private dynamic kubectlx(string args) 34 | { 35 | dynamic result = null; 36 | 37 | using (var kubectl = new Process()) 38 | { 39 | kubectl.StartInfo.CreateNoWindow = true; 40 | kubectl.StartInfo.FileName = "kubectl.exe"; 41 | kubectl.StartInfo.Arguments = args + " --all-namespaces -o json"; 42 | kubectl.StartInfo.UseShellExecute = false; 43 | kubectl.StartInfo.RedirectStandardOutput = true; 44 | kubectl.StartInfo.RedirectStandardError = true; 45 | kubectl.Start(); 46 | 47 | result = JsonConvert.DeserializeObject(kubectl.StandardOutput.ReadToEnd()); 48 | 49 | kubectl.WaitForExit(); 50 | } 51 | 52 | return result; 53 | } 54 | 55 | private void kubectl(string args, bool validate = true) 56 | { 57 | if (!validate) 58 | args += " --validate=false"; 59 | 60 | if (InvokeRequired) 61 | { 62 | Invoke(new MethodInvoker(() => 63 | { 64 | txtTerminal.AppendText($"kubectl {args}"); 65 | txtTerminal.AppendText(Environment.NewLine); 66 | })); 67 | } 68 | else 69 | { 70 | txtTerminal.AppendText($"kubectl {args}"); 71 | txtTerminal.AppendText(Environment.NewLine); 72 | } 73 | 74 | using (var kubectl = new Process()) 75 | { 76 | kubectl.StartInfo.CreateNoWindow = true; 77 | kubectl.StartInfo.FileName = "kubectl.exe"; 78 | kubectl.StartInfo.Arguments = args; 79 | kubectl.StartInfo.UseShellExecute = false; 80 | kubectl.StartInfo.RedirectStandardOutput = true; 81 | kubectl.StartInfo.RedirectStandardError = true; 82 | kubectl.Start(); 83 | 84 | if (InvokeRequired) 85 | { 86 | Invoke(new MethodInvoker(() => 87 | { 88 | txtTerminal.AppendText(kubectl.StandardOutput.ReadToEnd()); 89 | txtTerminal.AppendText(kubectl.StandardError.ReadToEnd()); 90 | txtTerminal.AppendText(Environment.NewLine); 91 | })); 92 | } 93 | else 94 | { 95 | txtTerminal.AppendText(kubectl.StandardOutput.ReadToEnd()); 96 | txtTerminal.AppendText(kubectl.StandardError.ReadToEnd()); 97 | txtTerminal.AppendText(Environment.NewLine); 98 | } 99 | 100 | kubectl.WaitForExit(); 101 | } 102 | } 103 | 104 | private void kubectl(string args, string filename) 105 | { 106 | txtTerminal.AppendText($"kubectl {args} > {filename}"); 107 | txtTerminal.AppendText(Environment.NewLine); 108 | 109 | using (var kubectl = new Process()) 110 | { 111 | kubectl.StartInfo.CreateNoWindow = true; 112 | kubectl.StartInfo.FileName = "kubectl.exe"; 113 | kubectl.StartInfo.Arguments = args; 114 | kubectl.StartInfo.UseShellExecute = false; 115 | kubectl.StartInfo.RedirectStandardOutput = true; 116 | kubectl.StartInfo.RedirectStandardError = true; 117 | kubectl.Start(); 118 | 119 | using (var writer = new StreamWriter(filename)) 120 | { 121 | writer.Write(kubectl.StandardOutput.ReadToEnd().Replace("'", string.Empty)); 122 | writer.Write(kubectl.StandardError.ReadToEnd()); 123 | } 124 | 125 | kubectl.WaitForExit(); 126 | } 127 | } 128 | 129 | private void istioctl(string args) 130 | { 131 | txtTerminal.AppendText($"istioctl {args}"); 132 | txtTerminal.AppendText(Environment.NewLine); 133 | 134 | using (var istioctl = new Process()) 135 | { 136 | istioctl.StartInfo.CreateNoWindow = true; 137 | istioctl.StartInfo.FileName = Path.Combine(txtIstioPath.Text, @"bin\istioctl.exe"); 138 | istioctl.StartInfo.Arguments = args; 139 | istioctl.StartInfo.UseShellExecute = false; 140 | istioctl.StartInfo.RedirectStandardOutput = true; 141 | istioctl.StartInfo.RedirectStandardError = true; 142 | istioctl.Start(); 143 | 144 | txtTerminal.AppendText(istioctl.StandardOutput.ReadToEnd()); 145 | txtTerminal.AppendText(istioctl.StandardError.ReadToEnd()); 146 | txtTerminal.AppendText(Environment.NewLine); 147 | 148 | istioctl.WaitForExit(); 149 | } 150 | } 151 | 152 | private void helm(string args) 153 | { 154 | txtTerminal.AppendText($"helm {args}"); 155 | txtTerminal.AppendText(Environment.NewLine); 156 | 157 | using (var kubectl = new Process()) 158 | { 159 | kubectl.StartInfo.CreateNoWindow = true; 160 | kubectl.StartInfo.FileName = "helm.exe"; 161 | kubectl.StartInfo.Arguments = args; 162 | kubectl.StartInfo.UseShellExecute = false; 163 | kubectl.StartInfo.RedirectStandardOutput = true; 164 | kubectl.StartInfo.RedirectStandardError = true; 165 | kubectl.Start(); 166 | 167 | txtTerminal.AppendText(kubectl.StandardOutput.ReadToEnd()); 168 | txtTerminal.AppendText(kubectl.StandardError.ReadToEnd()); 169 | txtTerminal.AppendText(Environment.NewLine); 170 | 171 | kubectl.WaitForExit(); 172 | } 173 | } 174 | } 175 | } -------------------------------------------------------------------------------- /Northwind.Operations/MainWin.Events.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Net; 5 | using System.Windows.Forms; 6 | using Northwind.Operations.Model; 7 | using Northwind.Services.Shared; 8 | using RestSharp; 9 | 10 | namespace Northwind.Operations 11 | { 12 | partial class MainWin 13 | { 14 | private RestClient Api { get { return new RestClient(ConfigurationManager.AppSettings["api"]); } } 15 | 16 | private void OnLoad(object sender, EventArgs e) 17 | { 18 | dynamic config = kubectlj("config view"); 19 | 20 | txtEndpoint.Text = config.clusters[0].cluster.server; 21 | 22 | lstObjects.ShowGroups = true; 23 | lstObjects.Items.Clear(); 24 | 25 | dynamic pods = kubectlx("get pods"); 26 | 27 | foreach (dynamic i in pods.items) 28 | { 29 | string kind = i.kind; 30 | string name = i.metadata.name; 31 | string ns = i.metadata["namespace"]; 32 | string address = string.Empty; 33 | 34 | lstObjects.Items.Add(new ListViewItem(new string[] { ns, kind, name, address })); 35 | } 36 | 37 | dynamic deployments = kubectlx("get deployments"); 38 | 39 | foreach (dynamic i in deployments.items) 40 | { 41 | string kind = i.kind; 42 | string name = i.metadata.name; 43 | string ns = i.metadata["namespace"]; 44 | string address = string.Empty; 45 | 46 | lstObjects.Items.Add(new ListViewItem(new string[] { ns, kind, name, address })); 47 | } 48 | 49 | dynamic services = kubectlx("get services"); 50 | 51 | foreach (dynamic i in services.items) 52 | { 53 | string kind = i.kind; 54 | string name = i.metadata.name; 55 | string ns = i.metadata["namespace"]; 56 | string address = i.spec.clusterIP; 57 | string type = i.spec.type; 58 | 59 | if (type == "LoadBalancer") 60 | address = i?.status?.loadBalancer?.ingress?[0]?.ip; 61 | 62 | lstObjects.Items.Add(new ListViewItem(new string[] { ns, kind, name, address })); 63 | } 64 | 65 | dynamic ingress = kubectlx("get ingress"); 66 | 67 | foreach (dynamic i in ingress.items) 68 | { 69 | string kind = i.kind; 70 | string name = i.metadata.name; 71 | string ns = i.metadata["namespace"]; 72 | string address = string.Empty; 73 | 74 | lstObjects.Items.Add(new ListViewItem(new string[] { ns, kind, name, address })); 75 | } 76 | 77 | var response = Api.Execute>>(new RestRequest("/products/search?q=a", Method.GET)); 78 | 79 | if (response.StatusCode == HttpStatusCode.OK) 80 | { 81 | cbProducts.Items.Clear(); 82 | 83 | foreach (var i in response.Data.Data) 84 | { 85 | cbProducts.Items.Add(i); 86 | cbProducts.DisplayMember = "Name"; 87 | cbProducts.ValueMember = "Id"; 88 | } 89 | } 90 | } 91 | 92 | private void OnRefresh(object sender, EventArgs e) 93 | { 94 | OnLoad(sender, e); 95 | } 96 | 97 | private void OnObjectSelected(object sender, EventArgs e) 98 | { 99 | foreach (ListViewItem i in lstObjects.SelectedItems) 100 | Clipboard.SetText(i.SubItems[3].Text); 101 | } 102 | 103 | private void OnClearTerminal(object sender, EventArgs e) 104 | { 105 | txtTerminal.Clear(); 106 | } 107 | 108 | private void OnCanaryPercent(object sender, EventArgs e) 109 | { 110 | lblCanaryPercent.Text = $"{tbCanaryRelease.Value}%"; 111 | } 112 | 113 | private void OnFaultPercent(object sender, EventArgs e) 114 | { 115 | lblFaultPercent.Text = $"{tbFaultPercent.Value}%"; 116 | } 117 | } 118 | } -------------------------------------------------------------------------------- /Northwind.Operations/MainWin.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 213, 17 122 | 123 | 124 | 125 | 126 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 127 | YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG 128 | YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 129 | 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw 130 | bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc 131 | VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 132 | c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 133 | Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo 134 | mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ 135 | kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D 136 | TgDQASA1MVpwzwAAAABJRU5ErkJggg== 137 | 138 | 139 | 140 | 17, 17 141 | 142 | 143 | 144 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 145 | YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG 146 | YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9 147 | 0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw 148 | bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc 149 | VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9 150 | c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32 151 | Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo 152 | mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+ 153 | kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D 154 | TgDQASA1MVpwzwAAAABJRU5ErkJggg== 155 | 156 | 157 | 158 | 110, 17 159 | 160 | -------------------------------------------------------------------------------- /Northwind.Operations/Model/OrderRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Northwind.Operations.Model 4 | { 5 | public class OrderRequest 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public Guid Product { get; set; } 10 | 11 | public int Quantity { get; set; } 12 | 13 | public string Address { get; set; } 14 | 15 | public string Country { get; set; } 16 | 17 | public string Zip { get; set; } 18 | 19 | public string Payment { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /Northwind.Operations/Model/OrderResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Operations.Model 2 | { 3 | public class OrderResponse 4 | { 5 | public double Total { get; set; } 6 | 7 | public bool Status { get; set; } 8 | 9 | public string Message { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Northwind.Operations/Model/ProductDetail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Northwind.Operations.Model 4 | { 5 | public class ProductDetail 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public double Price { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Northwind.Operations/Model/Response.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Operations.Model 2 | { 3 | public class Response 4 | { 5 | public string Message { get; set; } 6 | 7 | public bool Error { get; set; } 8 | 9 | public Response() 10 | { 11 | Message = "OK"; 12 | } 13 | } 14 | 15 | public class Response : Response 16 | { 17 | public T Result { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /Northwind.Operations/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace Northwind.Operations 5 | { 6 | public static class Program 7 | { 8 | [STAThread] 9 | public static void Main() 10 | { 11 | Application.EnableVisualStyles(); 12 | Application.SetCompatibleTextRenderingDefault(false); 13 | Application.Run(new MainWin()); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /Northwind.Operations/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Northwind.Operations")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Northwind.Operations")] 13 | [assembly: AssemblyCopyright("Copyright © 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b1bd9fc1-c4b4-4fab-8ab7-c86b227ec990")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /Northwind.Operations/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Northwind.Operations.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Northwind.Operations.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Northwind.Operations/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /Northwind.Operations/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Northwind.Operations.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Northwind.Operations/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Northwind.Operations/Services/Transaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Northwind.Operations.Model; 4 | using RestSharp; 5 | 6 | namespace Northwind.Operations.Services 7 | { 8 | public class Transaction 9 | { 10 | private static Random rnd = new Random(); 11 | 12 | public string Search { get; private set; } 13 | 14 | private string ProductEndpoint { get; } 15 | 16 | private string OrderEndpoint { get; } 17 | 18 | private string Payment { get; } 19 | 20 | private string Zip { get; } 21 | 22 | private List Pattern { get; set; } 23 | 24 | public Transaction(string productEndpoint, string orderEndpoint, string payment, string zip) 25 | { 26 | ProductEndpoint = productEndpoint ?? throw new ArgumentNullException(nameof(productEndpoint)); 27 | OrderEndpoint = orderEndpoint ?? throw new ArgumentNullException(nameof(orderEndpoint)); 28 | Payment = payment ?? throw new ArgumentNullException(nameof(payment)); 29 | Zip = zip ?? throw new ArgumentNullException(nameof(zip)); 30 | 31 | Pattern = new List() { "chocolate", "laundry", "whiskey", "scotch", "champagne", "lacura", "degreaser", "SPF", "skin", "coffee" }; 32 | Search = Pattern[rnd.Next(0, 9)]; 33 | } 34 | 35 | public (bool status, string message, int products) Execute() 36 | { 37 | (bool status, string message, int products) result = (false, string.Empty, 0); 38 | 39 | try 40 | { 41 | var server = new RestClient(ProductEndpoint); 42 | var request = new RestRequest("/search", Method.GET); 43 | request.AddQueryParameter("q", Search); 44 | 45 | var response = server.Execute>(request); 46 | 47 | if (response.Data != null) 48 | { 49 | result.products = response.Data.Count; 50 | result.status = true; 51 | result.message = "OK"; 52 | 53 | foreach (var i in response.Data) 54 | { 55 | var order = Process(i.Id); 56 | 57 | result.status = order.status; 58 | result.message = order.message; 59 | 60 | if (!result.status) 61 | break; 62 | } 63 | } 64 | } 65 | catch (Exception e) 66 | { 67 | result.status = false; 68 | result.message = e.Message; 69 | } 70 | 71 | return result; 72 | } 73 | 74 | private (bool status, string message) Process(Guid productId) 75 | { 76 | (bool status, string message) result = (false, string.Empty); 77 | 78 | try 79 | { 80 | var server = new RestClient(OrderEndpoint); 81 | var request = new RestRequest("/order", Method.POST); 82 | 83 | request.RequestFormat = DataFormat.Json; 84 | request.AddBody(new OrderRequest() 85 | { 86 | Id = Guid.NewGuid(), 87 | Product = productId, 88 | Address = "Unit 1, 100 John Street, Sydney", 89 | Quantity = rnd.Next(1, 9), 90 | Payment = Payment, 91 | Zip = Zip, 92 | Country = "Australia" 93 | }); 94 | 95 | var response = server.Execute(request); 96 | 97 | if (response.IsSuccessful && response.Data != null) 98 | { 99 | result.status = response.Data.Status; 100 | result.message = response.Data.Message; 101 | } 102 | } 103 | catch (Exception e) 104 | { 105 | result.status = false; 106 | result.message = e.Message; 107 | } 108 | 109 | return result; 110 | } 111 | } 112 | } -------------------------------------------------------------------------------- /Northwind.Operations/Swarm/docker-stack.yml: -------------------------------------------------------------------------------- 1 | version: "3.6" 2 | services: 3 | product: 4 | image: parameshg/northwind.product:v1 5 | ports: 6 | - "8080:80" 7 | deploy: 8 | replicas: 1 9 | restart_policy: 10 | condition: any 11 | networks: 12 | - northwind 13 | 14 | order: 15 | image: parameshg/northwind.order:v1 16 | ports: 17 | - "8090:80" 18 | deploy: 19 | replicas: 1 20 | restart_policy: 21 | condition: any 22 | networks: 23 | - northwind 24 | 25 | address: 26 | image: parameshg/northwind.address:v1 27 | deploy: 28 | replicas: 1 29 | restart_policy: 30 | condition: any 31 | networks: 32 | - northwind 33 | 34 | payment: 35 | image: parameshg/northwind.payment:v1 36 | deploy: 37 | replicas: 1 38 | restart_policy: 39 | condition: any 40 | networks: 41 | - northwind 42 | 43 | networks: 44 | northwind: 45 | name: northwind 46 | driver: overlay 47 | 48 | # logging: 49 | # driver: syslog 50 | # options: 51 | # syslog-address: "udp://0.0.0.0:5000" 52 | -------------------------------------------------------------------------------- /Northwind.Operations/Tester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Net; 5 | using CreditCardValidator; 6 | using Northwind.Operations.Model; 7 | using Northwind.Services.Shared; 8 | using RestSharp; 9 | 10 | namespace Northwind.Operations 11 | { 12 | public class Tester 13 | { 14 | public event EventHandler RequestSent; 15 | public event EventHandler RequestPassed; 16 | public event EventHandler RequestFailed; 17 | 18 | public event EventHandler RequestProcessedByPaymentServer1; 19 | public event EventHandler RequestProcessedByPaymentServer2; 20 | 21 | public event EventHandler RequestProcessedByAddressServer1; 22 | public event EventHandler RequestProcessedByAddressServer2; 23 | public event EventHandler RequestProcessedByAddressServer3; 24 | 25 | private Random rnd = new Random(); 26 | 27 | private RestClient api { get { return new RestClient(ConfigurationManager.AppSettings["api"]); } } 28 | 29 | public void Execute(string card, string area, int count) 30 | { 31 | var products = SearchProducts("a"); 32 | 33 | for (var i = 0; i < count; i++) 34 | { 35 | var id = products[rnd.Next(0, products.Count - 1)].Id; 36 | 37 | var response = SubmitOrder(new OrderRequest() 38 | { 39 | Id = Guid.NewGuid(), 40 | Product = id, 41 | Address = "Unit 1, 100 John Street, Sydney", 42 | Quantity = rnd.Next(1, 9), 43 | Payment = GenerateCreditCardNumber(card), 44 | Zip = GenerateAreaCode(area), 45 | Country = "Australia" 46 | }); 47 | 48 | if (response.Data.Status) 49 | RequestPassed?.Invoke(this, new EventArgs()); 50 | else 51 | RequestFailed?.Invoke(this, new EventArgs()); 52 | 53 | foreach (var o in response.Downstream) 54 | { 55 | if (o.Endpoint.Contains("payment")) 56 | { 57 | if (o.Version.Equals(1)) 58 | RequestProcessedByPaymentServer1?.Invoke(this, new EventArgs()); 59 | 60 | if (o.Version.Equals(2)) 61 | RequestProcessedByPaymentServer2?.Invoke(this, new EventArgs()); 62 | } 63 | 64 | if (o.Endpoint.Contains("address")) 65 | { 66 | if (o.Version.Equals(1)) 67 | RequestProcessedByAddressServer1?.Invoke(this, new EventArgs()); 68 | 69 | if (o.Version.Equals(2)) 70 | RequestProcessedByAddressServer2?.Invoke(this, new EventArgs()); 71 | 72 | if (o.Version.Equals(3)) 73 | RequestProcessedByAddressServer3?.Invoke(this, new EventArgs()); 74 | } 75 | } 76 | 77 | RequestSent?.Invoke(this, new EventArgs()); 78 | } 79 | } 80 | 81 | private List SearchProducts(string pattern) 82 | { 83 | var result = new List(); 84 | 85 | var request = new RestRequest($"/products/search?q={pattern}", Method.GET); 86 | 87 | var response = api.Execute>>(request); 88 | 89 | if (response.StatusCode.Equals(HttpStatusCode.OK)) 90 | result.AddRange(response?.Data?.Data); 91 | 92 | return result; 93 | } 94 | 95 | private Response SubmitOrder(OrderRequest order) 96 | { 97 | Response result = null; 98 | 99 | var request = new RestRequest("/orders/order", Method.POST); 100 | request.RequestFormat = DataFormat.Json; 101 | request.AddBody(order); 102 | 103 | var response = api.Execute>(request); 104 | 105 | if (response.StatusCode == HttpStatusCode.OK) 106 | result = response.Data; 107 | 108 | return result; 109 | } 110 | 111 | private string GenerateAreaCode(string area) 112 | { 113 | var result = string.Empty; 114 | 115 | var region = new List<(int From, int To)>(); 116 | 117 | if (area.Equals("Central and Northern Sydney")) 118 | { 119 | region.Add((2000, 2019)); 120 | region.Add((2021, 2037)); 121 | region.Add((2042, 2044)); 122 | region.Add((2048, 2048)); 123 | region.Add((2050, 2050)); 124 | region.Add((2052, 2114)); 125 | region.Add((2119, 2122)); 126 | region.Add((2126, 2126)); 127 | region.Add((2159, 2159)); 128 | region.Add((2204, 2204)); 129 | } 130 | 131 | if (area.Equals("Western Sydney and Blue Mountains")) 132 | { 133 | region.Add((2038, 2041)); 134 | region.Add((2045, 2047)); 135 | region.Add((2115, 2118)); 136 | region.Add((2123, 2125)); 137 | region.Add((2127, 2128)); 138 | region.Add((2137, 2140)); 139 | region.Add((2142, 2142)); 140 | region.Add((2160, 2160)); 141 | region.Add((2745, 2751)); 142 | region.Add((2753, 2786)); 143 | } 144 | 145 | if (area.Equals("Greystanes - 2145 (Western Sydney)")) 146 | region.Add((2144, 2158)); 147 | 148 | if (region.Count > 0) 149 | { 150 | var code = region[rnd.Next(0, region.Count - 1)]; 151 | 152 | result = rnd.Next(code.From, code.To).ToString(); 153 | } 154 | 155 | return result; 156 | } 157 | 158 | private string GenerateCreditCardNumber(string issuer) 159 | { 160 | return CreditCardFactory.RandomCardNumber((CardIssuer)Enum.Parse(typeof(CardIssuer), issuer)); 161 | } 162 | } 163 | } -------------------------------------------------------------------------------- /Northwind.Operations/Users.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | using CreditCardValidator; 6 | using Northwind.Operations.Services; 7 | 8 | namespace Northwind.Operations 9 | { 10 | public partial class Users : Form 11 | { 12 | private Random rnd = new Random(); 13 | 14 | private int _TotalRequests; 15 | 16 | private int TotalRequests { get { return _TotalRequests; } set { _TotalRequests++; lblRequestSent.Text = $"Request Sent: {_TotalRequests}"; } } 17 | 18 | private int _PassedRequests; 19 | 20 | private int PassedRequests { get { return _PassedRequests; } set { _PassedRequests++; lblRequestPassed.Text = $"Request Passed: {_PassedRequests}"; } } 21 | 22 | private int _FailedRequests; 23 | 24 | private int FailedRequests { get { return _FailedRequests; } set { _FailedRequests++; lblRequestFailed.Text = $"Request Failed: {_FailedRequests}"; } } 25 | 26 | private List Timers { get; set; } 27 | 28 | private List CardIssuers { get; set; } 29 | 30 | private List<(int From, int To)> Areas { get; set; } 31 | 32 | public Users() 33 | { 34 | InitializeComponent(); 35 | CheckForIllegalCrossThreadCalls = false; 36 | 37 | Timers = new List(); 38 | CardIssuers = new List(); 39 | Areas = new List<(int From, int To)>(); 40 | } 41 | 42 | private void OnDelayChanged(object sender, EventArgs e) 43 | { 44 | foreach (var i in Timers) 45 | i.Interval = tbDelay.Value; 46 | 47 | lblDelay.Text = $"Delay: {tbDelay.Value} ms"; 48 | lblDelayInterval.Text = $"{tbDelay.Value} ms"; 49 | } 50 | 51 | private void OnUsersChanged(object sender, EventArgs e) 52 | { 53 | lblUsers.Text = $"Users: {tbUsers.Value}"; 54 | lblUsersCount.Text = tbUsers.Value.ToString(); 55 | 56 | if (!txtProductEndpoint.Enabled) 57 | { 58 | if (Timers.Count < tbUsers.Value) 59 | { 60 | while (Timers.Count < tbUsers.Value) 61 | { 62 | var timer = new Timer() 63 | { 64 | Interval = tbDelay.Value, 65 | Enabled = true, 66 | Tag = Timers.Count + 1 67 | }; 68 | timer.Tick += OnTimer; 69 | Timers.Add(timer); 70 | } 71 | } 72 | 73 | if (Timers.Count > tbUsers.Value) 74 | { 75 | while (Timers.Count > tbUsers.Value) 76 | { 77 | var timer = Timers.Last(); 78 | timer.Stop(); 79 | Timers.Remove(timer); 80 | } 81 | } 82 | } 83 | } 84 | 85 | private void OnStart(object sender, EventArgs e) 86 | { 87 | txtProductEndpoint.Enabled = false; 88 | txtOrderEndpoint.Enabled = false; 89 | btnStart.Enabled = false; 90 | btnStop.Enabled = true; 91 | 92 | var o = new Timer() 93 | { 94 | Interval = tbDelay.Value, 95 | Enabled = true, 96 | Tag = 1 97 | }; 98 | 99 | o.Tick += OnTimer; 100 | o.Start(); 101 | 102 | Timers.Add(o); 103 | } 104 | 105 | private void OnStop(object sender, EventArgs e) 106 | { 107 | foreach (var i in Timers) 108 | i.Enabled = false; 109 | 110 | Timers.Clear(); 111 | 112 | btnStart.Enabled = true; 113 | btnStop.Enabled = false; 114 | txtProductEndpoint.Enabled = true; 115 | txtOrderEndpoint.Enabled = true; 116 | } 117 | 118 | private void OnTimer(object sender, EventArgs e) 119 | { 120 | var transaction = new Transaction(txtProductEndpoint.Text, txtOrderEndpoint.Text, GenerateCreditCardNumber(), GeneratePostalCode()); 121 | 122 | txtLogs.AppendText($"User-{((Timer)sender).Tag.ToString()}: Searching for {transaction.Search}... "); 123 | 124 | var result = transaction.Execute(); 125 | 126 | if (result.status) 127 | { 128 | PassedRequests++; 129 | txtLogs.AppendText($"found {result.products} products!"); 130 | } 131 | else 132 | { 133 | FailedRequests++; 134 | txtLogs.AppendText($"failed! Error: {result.message}"); 135 | } 136 | 137 | txtLogs.AppendText(Environment.NewLine); 138 | TotalRequests++; 139 | } 140 | 141 | private void OnLoad(object sender, EventArgs e) 142 | { 143 | txtProductEndpoint.Enabled = true; 144 | txtOrderEndpoint.Enabled = true; 145 | btnStart.Enabled = true; 146 | btnStop.Enabled = false; 147 | } 148 | 149 | private void OnCardIssuersChecked(object sender, ItemCheckEventArgs e) 150 | { 151 | if (e.CurrentValue == CheckState.Unchecked && e.NewValue == CheckState.Checked) 152 | CardIssuers.Add((CardIssuer)Enum.Parse(typeof(CardIssuer), lstCardIssuers.Items[e.Index].ToString())); 153 | 154 | if (e.CurrentValue == CheckState.Checked && e.NewValue == CheckState.Unchecked) 155 | CardIssuers.Remove((CardIssuer)Enum.Parse(typeof(CardIssuer), lstCardIssuers.Items[e.Index].ToString())); 156 | } 157 | 158 | private void OnServiceAreadChecked(object sender, ItemCheckEventArgs e) 159 | { 160 | if (e.CurrentValue == CheckState.Unchecked && e.NewValue == CheckState.Checked) 161 | { 162 | if (lstServiceArea.Items[e.Index].ToString() == "Central and Northern Sydney") 163 | { 164 | Areas.Add((2000, 2019)); 165 | Areas.Add((2021, 2037)); 166 | Areas.Add((2042, 2044)); 167 | Areas.Add((2048, 2048)); 168 | Areas.Add((2050, 2050)); 169 | Areas.Add((2052, 2114)); 170 | Areas.Add((2119, 2122)); 171 | Areas.Add((2126, 2126)); 172 | Areas.Add((2159, 2159)); 173 | Areas.Add((2204, 2204)); 174 | } 175 | 176 | if (lstServiceArea.Items[e.Index].ToString() == "Western Sydney and Blue Mountains") 177 | { 178 | Areas.Add((2038, 2041)); 179 | Areas.Add((2045, 2047)); 180 | Areas.Add((2115, 2118)); 181 | Areas.Add((2123, 2125)); 182 | Areas.Add((2127, 2128)); 183 | Areas.Add((2137, 2140)); 184 | Areas.Add((2142, 2142)); 185 | Areas.Add((2160, 2160)); 186 | Areas.Add((2745, 2751)); 187 | Areas.Add((2753, 2786)); 188 | } 189 | 190 | if (lstServiceArea.Items[e.Index].ToString() == "Greystanes - 2145 (Western Sydney)") 191 | { 192 | Areas.Add((2144, 2158)); 193 | } 194 | } 195 | 196 | if (e.CurrentValue == CheckState.Checked && e.NewValue == CheckState.Unchecked) 197 | { 198 | if (lstServiceArea.Items[e.Index].ToString() == "Central and Northern Sydney") 199 | { 200 | Areas.Remove((2000, 2019)); 201 | Areas.Remove((2021, 2037)); 202 | Areas.Remove((2042, 2044)); 203 | Areas.Remove((2048, 2048)); 204 | Areas.Remove((2050, 2050)); 205 | Areas.Remove((2052, 2114)); 206 | Areas.Remove((2119, 2122)); 207 | Areas.Remove((2126, 2126)); 208 | Areas.Remove((2159, 2159)); 209 | Areas.Remove((2204, 2204)); 210 | } 211 | 212 | if (lstServiceArea.Items[e.Index].ToString() == "Western Sydney and Blue Mountains") 213 | { 214 | Areas.Remove((2038, 2041)); 215 | Areas.Remove((2045, 2047)); 216 | Areas.Remove((2115, 2118)); 217 | Areas.Remove((2123, 2125)); 218 | Areas.Remove((2127, 2128)); 219 | Areas.Remove((2137, 2140)); 220 | Areas.Remove((2142, 2142)); 221 | Areas.Remove((2160, 2160)); 222 | Areas.Remove((2745, 2751)); 223 | Areas.Remove((2753, 2786)); 224 | } 225 | 226 | if (lstServiceArea.Items[e.Index].ToString() == "Greystanes - 2145 (Western Sydney)") 227 | { 228 | Areas.Remove((2144, 2158)); 229 | } 230 | } 231 | } 232 | 233 | private string GenerateCreditCardNumber() 234 | { 235 | var result = string.Empty; 236 | 237 | if (CardIssuers.Count > 0) 238 | result = CreditCardFactory.RandomCardNumber(CardIssuers[rnd.Next(0, CardIssuers.Count - 1)]); 239 | 240 | return result; 241 | } 242 | 243 | private string GeneratePostalCode() 244 | { 245 | var result = string.Empty; 246 | 247 | if (Areas.Count > 0) 248 | { 249 | var area = Areas[rnd.Next(0, Areas.Count - 1)]; 250 | result = rnd.Next(area.From, area.To).ToString(); 251 | } 252 | 253 | return result; 254 | } 255 | } 256 | } -------------------------------------------------------------------------------- /Northwind.Operations/Users.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 17, 17 122 | 123 | -------------------------------------------------------------------------------- /Northwind.Operations/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Controllers/AddressController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.AspNetCore.Mvc; 5 | using Northwind.Services.Address.v2.Model; 6 | using Northwind.Services.Shared; 7 | 8 | namespace NorthWind.Services.Address.v2.Controllers 9 | { 10 | [Route("")] 11 | public class AddressController : Controller 12 | { 13 | private static List<(int From, int To)> Area { get; set; } 14 | 15 | static AddressController() 16 | { 17 | Area = new List<(int From, int To)>(); 18 | // Central & Northern Sydney 19 | Area.Add((2000, 2019)); 20 | Area.Add((2021, 2037)); 21 | Area.Add((2042, 2044)); 22 | Area.Add((2048, 2048)); 23 | Area.Add((2050, 2050)); 24 | Area.Add((2052, 2114)); 25 | Area.Add((2119, 2122)); 26 | Area.Add((2126, 2126)); 27 | Area.Add((2159, 2159)); 28 | Area.Add((2204, 2204)); 29 | // Western Sydney & Blue Mountains 30 | Area.Add((2038, 2041)); 31 | Area.Add((2045, 2047)); 32 | Area.Add((2115, 2118)); 33 | Area.Add((2123, 2125)); 34 | Area.Add((2127, 2128)); 35 | Area.Add((2137, 2140)); 36 | Area.Add((2142, 2142)); 37 | Area.Add((2160, 2160)); 38 | Area.Add((2745, 2751)); 39 | Area.Add((2753, 2786)); 40 | } 41 | 42 | [HttpGet("validate")] 43 | public Response Index() 44 | { 45 | return new Response("address/validate", 2); 46 | } 47 | 48 | [HttpPost("validate")] 49 | public Response Post([FromBody] ValidationRequest request) 50 | { 51 | var result = new Response("address/validate", 2); 52 | 53 | result.Data = new ValidationResponse(); 54 | 55 | try 56 | { 57 | result.Data.Status = !string.IsNullOrEmpty(request.Address) && request.Country.ToLower().Equals("australia"); 58 | 59 | if (result.Data.Status) 60 | result.Data.Status = Area.Where(i => request.Zip >= i.From && request.Zip <= i.To).Count() >= 1; 61 | 62 | if (!result.Data.Status) 63 | result.Data.Message = "address not valid or supported. currently supporting only australian areas of sydney (central, northern, western) and blue mountains"; 64 | } 65 | catch (Exception e) 66 | { 67 | result.Data.Status = false; 68 | result.Data.Message = e.Message; 69 | } 70 | 71 | return result; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Northwind.Services.Shared; 3 | 4 | namespace Northwind.Services.Address.v2.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | [HttpGet("")] 9 | public Response Index() 10 | { 11 | return new Response("address", 2); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/aspnetcore:2.0 AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/aspnetcore-build:2.0 AS build 6 | WORKDIR /src 7 | COPY Northwind.sln ./ 8 | COPY Northwind.Services.Address.v2/Northwind.Services.Address.v2.csproj Northwind.Services.Address.v2/ 9 | RUN dotnet restore -nowarn:msb3202,nu1503 10 | COPY . . 11 | WORKDIR /src/Northwind.Services.Address.v2 12 | RUN dotnet build -c Debug -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish -c Debug -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "Northwind.Services.Address.v2.dll"] 21 | -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Model/ValidationRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Address.v2.Model 2 | { 3 | public class ValidationRequest 4 | { 5 | public string Address { get; set; } 6 | 7 | public string Country { get; set; } 8 | 9 | public int Zip { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Model/ValidationResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Address.v2.Model 2 | { 3 | public class ValidationResponse 4 | { 5 | public bool Status { get; set; } 6 | 7 | public string Message { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Northwind.Services.Address.v2.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | ..\docker-compose.dcproj 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace NorthWind.Services.Address.v2 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup() 16 | .Build(); 17 | } 18 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:3101/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "NorthWind.Services.Address.v2": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:3102/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace NorthWind.Services.Address.v2 7 | { 8 | public class Startup 9 | { 10 | public Startup(IConfiguration configuration) 11 | { 12 | Configuration = configuration; 13 | } 14 | 15 | public IConfiguration Configuration { get; } 16 | 17 | // This method gets called by the runtime. Use this method to add services to the container. 18 | public void ConfigureServices(IServiceCollection services) 19 | { 20 | services.AddMvc(); 21 | } 22 | 23 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 24 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 25 | { 26 | if (env.IsDevelopment()) 27 | { 28 | app.UseDeveloperExceptionPage(); 29 | } 30 | 31 | app.UseMvc(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v2/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Trace" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Warning" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Controllers/AddressController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.AspNetCore.Mvc; 5 | using Northwind.Services.Address.v3.Model; 6 | using Northwind.Services.Shared; 7 | 8 | namespace NorthWind.Services.Address.v3.Controllers 9 | { 10 | [Route("")] 11 | public class AddressController : Controller 12 | { 13 | private static List<(int From, int To)> Area { get; set; } 14 | 15 | static AddressController() 16 | { 17 | Area = new List<(int From, int To)>(); 18 | // Central & Northern Sydney 19 | Area.Add((2000, 2019)); 20 | Area.Add((2021, 2037)); 21 | Area.Add((2042, 2044)); 22 | Area.Add((2048, 2048)); 23 | Area.Add((2050, 2050)); 24 | Area.Add((2052, 2114)); 25 | Area.Add((2119, 2122)); 26 | Area.Add((2126, 2126)); 27 | Area.Add((2159, 2159)); 28 | Area.Add((2204, 2204)); 29 | // Western Sydney & Blue Mountains 30 | Area.Add((2038, 2041)); 31 | Area.Add((2045, 2047)); 32 | Area.Add((2115, 2118)); 33 | Area.Add((2123, 2125)); 34 | Area.Add((2127, 2128)); 35 | Area.Add((2137, 2140)); 36 | Area.Add((2142, 2142)); 37 | Area.Add((2160, 2160)); 38 | Area.Add((2745, 2751)); 39 | Area.Add((2753, 2786)); 40 | // Bug Fix 41 | Area.Add((2144, 2158)); 42 | } 43 | 44 | [HttpGet("validate")] 45 | public Response Index() 46 | { 47 | return new Response("address/validate", 3); 48 | } 49 | 50 | [HttpPost("validate")] 51 | public Response Post([FromBody] ValidationRequest request) 52 | { 53 | var result = new Response("address/validate", 3); 54 | 55 | result.Data = new ValidationResponse(); 56 | 57 | try 58 | { 59 | result.Data.Status = !string.IsNullOrEmpty(request.Address) && request.Country.ToLower().Equals("australia"); 60 | 61 | if (result.Data.Status) 62 | result.Data.Status = Area.Where(i => request.Zip >= i.From && request.Zip <= i.To).Count() >= 1; 63 | 64 | if (!result.Data.Status) 65 | result.Data.Message = "address not valid or supported. currently supporting only australian areas of sydney (central, northern, western) and blue mountains"; 66 | } 67 | catch (Exception e) 68 | { 69 | result.Data.Status = false; 70 | result.Data.Message = e.Message; 71 | } 72 | 73 | return result; 74 | } 75 | } 76 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Northwind.Services.Shared; 3 | 4 | namespace Northwind.Services.Address.v3.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | [HttpGet("")] 9 | public Response Index() 10 | { 11 | return new Response("address", 3); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/aspnetcore:2.0 AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/aspnetcore-build:2.0 AS build 6 | WORKDIR /src 7 | COPY Northwind.sln ./ 8 | COPY Northwind.Services.Address.v3/Northwind.Services.Address.v3.csproj Northwind.Services.Address.v3/ 9 | RUN dotnet restore -nowarn:msb3202,nu1503 10 | COPY . . 11 | WORKDIR /src/Northwind.Services.Address.v3 12 | RUN dotnet build -c Debug -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish -c Debug -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "Northwind.Services.Address.v3.dll"] 21 | -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Model/ValidationRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Address.v3.Model 2 | { 3 | public class ValidationRequest 4 | { 5 | public string Address { get; set; } 6 | 7 | public string Country { get; set; } 8 | 9 | public int Zip { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Model/ValidationResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Address.v3.Model 2 | { 3 | public class ValidationResponse 4 | { 5 | public bool Status { get; set; } 6 | 7 | public string Message { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Northwind.Services.Address.v3.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | ..\docker-compose.dcproj 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace Northwind.Services.Payment.v3 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup() 16 | .Build(); 17 | } 18 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:3915/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "Northwind.Services.Payment.v3": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:3916/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace Northwind.Services.Payment.v3 7 | { 8 | public class Startup 9 | { 10 | public Startup(IConfiguration configuration) 11 | { 12 | Configuration = configuration; 13 | } 14 | 15 | public IConfiguration Configuration { get; } 16 | 17 | // This method gets called by the runtime. Use this method to add services to the container. 18 | public void ConfigureServices(IServiceCollection services) 19 | { 20 | services.AddMvc(); 21 | } 22 | 23 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 24 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 25 | { 26 | if (env.IsDevelopment()) 27 | { 28 | app.UseDeveloperExceptionPage(); 29 | } 30 | 31 | app.UseMvc(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Northwind.Services.Address.v3/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Trace" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Trace" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/Controllers/AddressController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.AspNetCore.Mvc; 5 | using Northwind.Services.Address.Model; 6 | using Northwind.Services.Shared; 7 | 8 | namespace NorthWind.Services.Address.Controllers 9 | { 10 | [Route("")] 11 | public class AddressController : Controller 12 | { 13 | private static List<(int From, int To)> Area { get; set; } 14 | 15 | static AddressController() 16 | { 17 | Area = new List<(int From, int To)>(); 18 | Area.Add((2000, 2019)); 19 | Area.Add((2021, 2037)); 20 | Area.Add((2042, 2044)); 21 | Area.Add((2048, 2048)); 22 | Area.Add((2050, 2050)); 23 | Area.Add((2052, 2114)); 24 | Area.Add((2119, 2122)); 25 | Area.Add((2126, 2126)); 26 | Area.Add((2159, 2159)); 27 | Area.Add((2204, 2204)); 28 | } 29 | 30 | [HttpGet("validate")] 31 | public Response Index() 32 | { 33 | return new Response("address/validate", 1); 34 | } 35 | 36 | [HttpPost("validate")] 37 | public Response Post([FromBody] ValidationRequest request) 38 | { 39 | var result = new Response("address/validate", 1); 40 | 41 | result.Data = new ValidationResponse(); 42 | 43 | try 44 | { 45 | result.Data.Status = !string.IsNullOrEmpty(request.Address) && request.Country.ToLower().Equals("australia"); 46 | 47 | if (result.Data.Status) 48 | result.Data.Status = Area.Where(i => request.Zip >= i.From && request.Zip <= i.To).Count() >= 1; 49 | 50 | if (!result.Data.Status) 51 | result.Data.Message = "address not valid or supported. currently supporting only australian areas of central and northen sydney"; 52 | } 53 | catch (Exception e) 54 | { 55 | result.Data.Status = false; 56 | result.Data.Message = e.Message; 57 | } 58 | 59 | return result; 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Northwind.Services.Shared; 3 | 4 | namespace Northwind.Services.Address.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | [HttpGet("")] 9 | public Response Index() 10 | { 11 | return new Response("address", 1); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/aspnetcore:2.0 AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/aspnetcore-build:2.0 AS build 6 | WORKDIR /src 7 | COPY Northwind.sln ./ 8 | COPY Northwind.Services.Address/Northwind.Services.Address.csproj Northwind.Services.Address/ 9 | RUN dotnet restore -nowarn:msb3202,nu1503 10 | COPY . . 11 | WORKDIR /src/Northwind.Services.Address 12 | RUN dotnet build -c Debug -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish -c Debug -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "Northwind.Services.Address.dll"] 21 | -------------------------------------------------------------------------------- /Northwind.Services.Address/Model/ValidationRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Address.Model 2 | { 3 | public class ValidationRequest 4 | { 5 | public string Address { get; set; } 6 | 7 | public string Country { get; set; } 8 | 9 | public int Zip { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/Model/ValidationResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Address.Model 2 | { 3 | public class ValidationResponse 4 | { 5 | public bool Status { get; set; } 6 | 7 | public string Message { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/Northwind.Services.Address.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | ..\docker-compose.dcproj 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Northwind.Services.Address/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace NorthWind.Services.Address 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup() 16 | .Build(); 17 | } 18 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:2988/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "NorthWind.Services.Address": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:2989/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace NorthWind.Services.Address 7 | { 8 | public class Startup 9 | { 10 | public Startup(IConfiguration configuration) 11 | { 12 | Configuration = configuration; 13 | } 14 | 15 | public IConfiguration Configuration { get; } 16 | 17 | // This method gets called by the runtime. Use this method to add services to the container. 18 | public void ConfigureServices(IServiceCollection services) 19 | { 20 | services.AddMvc(); 21 | } 22 | 23 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 24 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 25 | { 26 | if (env.IsDevelopment()) 27 | { 28 | app.UseDeveloperExceptionPage(); 29 | } 30 | 31 | app.UseMvc(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Northwind.Services.Address/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Trace" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Trace" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Northwind.Services.Shared; 3 | 4 | namespace Northwind.Services.Order.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | [HttpGet("")] 9 | public Response Index() 10 | { 11 | return new Response("order", 1); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Controllers/OrderController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | using Microsoft.AspNetCore.Mvc; 5 | using Microsoft.Extensions.Logging; 6 | using Northwind.Services.Order.Model; 7 | using Northwind.Services.Shared; 8 | using RestSharp; 9 | 10 | namespace NorthWind.Services.Order.Controllers 11 | { 12 | [Route("")] 13 | public class OrderController : Controller 14 | { 15 | public ILogger Logger { get; } 16 | 17 | public OrderController(ILogger logger) 18 | { 19 | Logger = logger ?? throw new ArgumentNullException(nameof(logger)); 20 | } 21 | 22 | [HttpGet("order")] 23 | public Response Index() 24 | { 25 | return new Response("order/submit", 1); 26 | } 27 | 28 | [HttpPost("order")] 29 | public Response Post([FromBody] OrderRequest order) 30 | { 31 | var result = new Response("order/submit", 1); 32 | 33 | result.Downstream = new List(); 34 | result.Data = new OrderResponse(); 35 | 36 | try 37 | { 38 | // Validate Payment 39 | { 40 | var payment = new RestClient("http://payment.default.svc.cluster.local"); 41 | 42 | var request = new RestRequest("/validate", Method.POST); 43 | Logger.LogDebug($"Executing {request.Method.ToString()} to {payment.BaseUrl.ToString()} on {request.Resource}"); 44 | 45 | request.RequestFormat = DataFormat.Json; 46 | request.AddBody(new { CreditCardNumber = order.Payment }); 47 | 48 | var response = payment.Execute>(request); 49 | 50 | if (response == null) 51 | throw new Exception("payment validation error [null]"); 52 | 53 | Logger.LogDebug(response.Content); 54 | 55 | if (response.StatusCode != HttpStatusCode.OK) 56 | throw new Exception($"payment validation error [{response.StatusCode}]"); 57 | 58 | if (response != null && response.Data != null && response.Data.Data != null) 59 | { 60 | result.Downstream.Add(response.Data); 61 | result.Data.Status = response.Data.Data.Status; 62 | result.Data.Message = response.Data.Data.Message; 63 | } 64 | } 65 | 66 | if (result.Data.Status) 67 | { 68 | // Validate Address 69 | { 70 | var address = new RestClient("http://address.default.svc.cluster.local"); 71 | 72 | var request = new RestRequest("/validate", Method.POST); 73 | Logger.LogDebug($"Executing {request.Method.ToString()} to {address.BaseUrl.ToString()} on {request.Resource}"); 74 | request.RequestFormat = DataFormat.Json; 75 | request.AddBody(new 76 | { 77 | Address = "Unit 1, 100 John Street, Sydney", 78 | Country = "Australia", 79 | Zip = order.Zip, 80 | }); 81 | 82 | var response = address.Execute>(request); 83 | 84 | if (response == null) 85 | throw new Exception("address validation error [null]"); 86 | 87 | Logger.LogDebug(response.Content); 88 | 89 | if (response.StatusCode != HttpStatusCode.OK) 90 | throw new Exception($"address validation error [{response.StatusCode}]"); 91 | 92 | if (response != null && response.Data != null && response.Data.Data != null) 93 | { 94 | result.Downstream.Add(response.Data); 95 | result.Data.Status = response.Data.Data.Status; 96 | result.Data.Message = response.Data.Data.Message; 97 | } 98 | } 99 | } 100 | 101 | if (result.Data.Status) 102 | { 103 | // Fetch Product 104 | { 105 | var product = new RestClient("http://product.default.svc.cluster.local"); 106 | var request = new RestRequest($"/products/{order.Product.ToString()}", Method.GET); 107 | Logger.LogDebug($"Executing {request.Method.ToString()} to {product.BaseUrl.ToString()} on {request.Resource}"); 108 | 109 | var response = product.Execute>(request); 110 | 111 | if (response == null) 112 | throw new Exception("product read error [null]"); 113 | 114 | Logger.LogDebug(response.Content); 115 | 116 | if (response.StatusCode != HttpStatusCode.OK) 117 | throw new Exception($"product read error [{response.StatusCode}]"); 118 | 119 | result.Data.Total = response.Data.Data.Price * order.Quantity; 120 | } 121 | } 122 | } 123 | catch (Exception e) 124 | { 125 | result.Data.Status = false; 126 | result.Data.Message = e.Message; 127 | result.Data.Total = -1; 128 | } 129 | 130 | return result; 131 | } 132 | } 133 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/aspnetcore:2.0 AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/aspnetcore-build:2.0 AS build 6 | WORKDIR /src 7 | COPY Northwind.sln ./ 8 | COPY Northwind.Services.Order/Northwind.Services.Order.csproj Northwind.Services.Order/ 9 | RUN dotnet restore -nowarn:msb3202,nu1503 10 | COPY . . 11 | WORKDIR /src/Northwind.Services.Order 12 | RUN dotnet build -c Debug -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish -c Debug -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "Northwind.Services.Order.dll"] 21 | -------------------------------------------------------------------------------- /Northwind.Services.Order/Model/OrderRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Northwind.Services.Order.Model 4 | { 5 | public class OrderRequest 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public Guid Product { get; set; } 10 | 11 | public int Quantity { get; set; } 12 | 13 | public string Address { get; set; } 14 | 15 | public string Country { get; set; } 16 | 17 | public string Zip { get; set; } 18 | 19 | public string Payment { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Model/OrderResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Order.Model 2 | { 3 | public class OrderResponse 4 | { 5 | public double Total { get; set; } 6 | 7 | public bool Status { get; set; } 8 | 9 | public string Message { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Model/ProductDetail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Northwind.Services.Order.Model 4 | { 5 | public class ProductDetail 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public double Price { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Model/ValidationResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Order.Model 2 | { 3 | public class ValidationResponse 4 | { 5 | public bool Status { get; set; } 6 | 7 | public string Message { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Northwind.Services.Order.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | ..\docker-compose.dcproj 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Northwind.Services.Order/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace NorthWind.Services.Order 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup() 16 | .Build(); 17 | } 18 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:2873/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "NorthWind.Services.Order": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:2874/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace NorthWind.Services.Order 7 | { 8 | public class Startup 9 | { 10 | public IConfiguration Configuration { get; } 11 | 12 | public Startup(IConfiguration configuration) 13 | { 14 | Configuration = configuration; 15 | } 16 | 17 | public void ConfigureServices(IServiceCollection services) 18 | { 19 | services.AddMvc(); 20 | } 21 | 22 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 23 | { 24 | if (env.IsDevelopment()) 25 | app.UseDeveloperExceptionPage(); 26 | 27 | app.UseMvc(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Northwind.Services.Order/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": true, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Trace" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Trace" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Northwind.Services.Shared; 3 | 4 | namespace Northwind.Services.Payment.v2.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | [HttpGet("")] 9 | public Response Index() 10 | { 11 | return new Response("payment", 2); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Controllers/PaymentController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CreditCardValidator; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Northwind.Services.Payment.v2.Model; 5 | using Northwind.Services.Shared; 6 | 7 | namespace NorthWind.Services.Payment.v2.Controllers 8 | { 9 | [Route("")] 10 | public class PaymentController : Controller 11 | { 12 | [HttpGet("validate")] 13 | public Response Index() 14 | { 15 | return new Response("payment/validate", 2); 16 | } 17 | 18 | [HttpPost("validate")] 19 | public Response Post([FromBody]ValidationRequest request) 20 | { 21 | var result = new Response("payment/validate", 2); 22 | 23 | result.Data = new ValidationResponse(); 24 | 25 | try 26 | { 27 | var detector = new CreditCardDetector(request.CreditCardNumber); 28 | 29 | result.Data.Status = detector.IsValid(CardIssuer.MasterCard, CardIssuer.Maestro, CardIssuer.Visa, CardIssuer.AmericanExpress, CardIssuer.DinersClub, CardIssuer.Discover, CardIssuer.RuPay); 30 | 31 | if (!result.Data.Status) 32 | result.Data.Message = "credit card is not valid. currently supporting only mastercard, maestro, visa, americanexpress, dinersclub, discover and rupay cards"; 33 | } 34 | catch (Exception e) 35 | { 36 | result.Data.Status = false; 37 | result.Data.Message = e.Message; 38 | } 39 | 40 | return result; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/aspnetcore:2.0 AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/aspnetcore-build:2.0 AS build 6 | WORKDIR /src 7 | COPY Northwind.sln ./ 8 | COPY Northwind.Services.Payment.v2/Northwind.Services.Payment.v2.csproj Northwind.Services.Payment.v2/ 9 | RUN dotnet restore -nowarn:msb3202,nu1503 10 | COPY . . 11 | WORKDIR /src/Northwind.Services.Payment.v2 12 | RUN dotnet build -c Debug -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish -c Debug -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "Northwind.Services.Payment.v2.dll"] 21 | -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Model/ValidationRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Payment.v2.Model 2 | { 3 | public class ValidationRequest 4 | { 5 | public string CreditCardNumber { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Model/ValidationResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Payment.v2.Model 2 | { 3 | public class ValidationResponse 4 | { 5 | public bool Status { get; set; } 6 | 7 | public string Message { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Northwind.Services.Payment.v2.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | ..\docker-compose.dcproj 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace Northwind.Services.CreditCard.v2 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup() 16 | .Build(); 17 | } 18 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:3612/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "Northwind.Services.CreditCard.v2": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:3613/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace Northwind.Services.CreditCard.v2 7 | { 8 | public class Startup 9 | { 10 | public Startup(IConfiguration configuration) 11 | { 12 | Configuration = configuration; 13 | } 14 | 15 | public IConfiguration Configuration { get; } 16 | 17 | // This method gets called by the runtime. Use this method to add services to the container. 18 | public void ConfigureServices(IServiceCollection services) 19 | { 20 | services.AddMvc(); 21 | } 22 | 23 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 24 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 25 | { 26 | if (env.IsDevelopment()) 27 | { 28 | app.UseDeveloperExceptionPage(); 29 | } 30 | 31 | app.UseMvc(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment.v2/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Trace" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Trace" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Northwind.Services.Shared; 3 | 4 | namespace Northwind.Services.Payment.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | [HttpGet("")] 9 | public Response Index() 10 | { 11 | return new Response("payment", 1); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/Controllers/PaymentController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using CreditCardValidator; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Northwind.Services.Payment.Model; 5 | using Northwind.Services.Shared; 6 | 7 | namespace NorthWind.Services.Payment.Controllers 8 | { 9 | [Route("")] 10 | public class PaymentController : Controller 11 | { 12 | [HttpGet("validate")] 13 | public Response Index() 14 | { 15 | return new Response("payment/validate", 1); 16 | } 17 | 18 | [HttpPost("validate")] 19 | public Response Post([FromBody] ValidationRequest request) 20 | { 21 | var result = new Response("payment/validate", 1); 22 | 23 | result.Data = new ValidationResponse(); 24 | 25 | try 26 | { 27 | var detector = new CreditCardDetector(request.CreditCardNumber); 28 | 29 | result.Data.Status = detector.IsValid(CardIssuer.MasterCard, CardIssuer.Visa); 30 | 31 | if (!result.Data.Status) 32 | result.Data.Message = "credit card is not valid. currently supporting only mastercard and visa cards"; 33 | } 34 | catch (Exception e) 35 | { 36 | result.Data.Status = false; 37 | result.Data.Message = e.Message; 38 | } 39 | 40 | return result; 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/aspnetcore:2.0 AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/aspnetcore-build:2.0 AS build 6 | WORKDIR /src 7 | COPY Northwind.sln ./ 8 | COPY Northwind.Services.Payment/Northwind.Services.Payment.csproj Northwind.Services.Payment/ 9 | RUN dotnet restore -nowarn:msb3202,nu1503 10 | COPY . . 11 | WORKDIR /src/Northwind.Services.Payment 12 | RUN dotnet build -c Debug -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish -c Debug -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "Northwind.Services.Payment.dll"] 21 | -------------------------------------------------------------------------------- /Northwind.Services.Payment/Model/ValidationRequest.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Payment.Model 2 | { 3 | public class ValidationRequest 4 | { 5 | public string CreditCardNumber { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/Model/ValidationResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Northwind.Services.Payment.Model 2 | { 3 | public class ValidationResponse 4 | { 5 | public bool Status { get; set; } 6 | 7 | public string Message { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/Northwind.Services.Payment.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | ..\docker-compose.dcproj 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Northwind.Services.Payment/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace NorthWind.Services.CreditCard 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup() 16 | .Build(); 17 | } 18 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:3228/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "NorthWind.Services.CreditCard": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:3229/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace NorthWind.Services.CreditCard 7 | { 8 | public class Startup 9 | { 10 | public Startup(IConfiguration configuration) 11 | { 12 | Configuration = configuration; 13 | } 14 | 15 | public IConfiguration Configuration { get; } 16 | 17 | // This method gets called by the runtime. Use this method to add services to the container. 18 | public void ConfigureServices(IServiceCollection services) 19 | { 20 | services.AddMvc(); 21 | } 22 | 23 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 24 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 25 | { 26 | if (env.IsDevelopment()) 27 | { 28 | app.UseDeveloperExceptionPage(); 29 | } 30 | 31 | app.UseMvc(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Northwind.Services.Payment/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Trace" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Trace" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Northwind.Services.Product/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Northwind.Services.Shared; 3 | 4 | namespace Northwind.Services.Product.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | [HttpGet("")] 9 | public Response Index() 10 | { 11 | return new Response("product", 1); 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Northwind.Services.Product/Controllers/ProductController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.AspNetCore.Mvc; 5 | using Northwind.Services.Product.Model; 6 | using Northwind.Services.Shared; 7 | 8 | namespace NorthWind.Services.Product.Controllers 9 | { 10 | [Route("")] 11 | public class ProductController : Controller 12 | { 13 | #region Seed Products 14 | 15 | private static List Products { get; } 16 | 17 | static ProductController() 18 | { 19 | Products = new List() 20 | { 21 | // Chocolate 22 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Choceur Coffee Cream Block Chocolate 200g", Price = 2.69 }, 23 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Choceur Milk Chocolate Sticks 200g", Price = 2.79 }, 24 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Choceur Mountain Bar Chocolate 100g", Price = 1.99 }, 25 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Dark Mini Chocolate Bars 5 x 40g", Price = 2.99 }, 26 | new ProductDetail() { Id = Guid.NewGuid(), Name = "White Mini Chocolate Bars 5 x 40g", Price = 2.39 }, 27 | 28 | // Cosmetics 29 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Lacura Essentials BB Cream SPF-15 50ml", Price = 6.69 }, 30 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Lacura Essentials Caring Cleansing Gel 150ml", Price = 3.69 }, 31 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Lacura Essentials Make-up Rounds 80pk", Price = 1.39 }, 32 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Lacura Skin Science Renew Day Cream SPF-15 50ml", Price = 6.99 }, 33 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Lacura Skin Science Revive Hyaluronic Gel 30ml", Price = 9.99 }, 34 | 35 | // Liquor 36 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Blackstone Paddock Margaret River Cabernet Sauvign", Price = 17.99 }, 37 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Veuve Monsigny Brut Champagne", Price = 24.99 }, 38 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Storm Brewing CO Premium Light Lager 6 x 330ml", Price = 7.99 }, 39 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Highland Earl Blended Scotch Whiskey 700ml", Price = 28.99 }, 40 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Darleys London Style Gin 700ml", Price = 26.99 }, 41 | 42 | // Laundry 43 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Trimat Advanced Laundry Liquid Regular 1L", Price = 3.99 }, 44 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Almat Laundry Powder Concentrate 2kg", Price = 4.99 }, 45 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Di San Pre-wash Stain Remover 500ml Degreaser", Price = 1.25 }, 46 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Anco Soft Fabric Softener 4x Concentrate 1L", Price = 3.49 }, 47 | new ProductDetail() { Id = Guid.NewGuid(), Name = "Laundrite Laundry Powder 4kg", Price = 3.69 }, 48 | }; 49 | } 50 | 51 | #endregion Seed Products 52 | 53 | [HttpGet("products")] 54 | public Response Index() 55 | { 56 | return new Response("product/get", 1); 57 | } 58 | 59 | [HttpGet("products/{id}")] 60 | public Response GetProductById(string id) 61 | { 62 | var result = new Response("product/detail", 1); 63 | 64 | try 65 | { 66 | result.Data = Products.SingleOrDefault(i => i.Id.Equals(Guid.Parse(id))); 67 | } 68 | catch 69 | { 70 | result = null; 71 | } 72 | 73 | return result; 74 | } 75 | 76 | [HttpGet("search")] 77 | public Response> SearchProducts(string q) 78 | { 79 | var result = new Response>("product/search", 1); 80 | 81 | result.Data = new List(); 82 | 83 | try 84 | { 85 | if (!string.IsNullOrEmpty(q)) 86 | result.Data.AddRange(Products.Where(i => i.Name.ToLower().Contains(q.ToLower())).ToList()); 87 | } 88 | catch 89 | { 90 | result = null; 91 | } 92 | 93 | return result; 94 | } 95 | } 96 | } -------------------------------------------------------------------------------- /Northwind.Services.Product/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/aspnetcore:2.0 AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/aspnetcore-build:2.0 AS build 6 | WORKDIR /src 7 | COPY Northwind.sln ./ 8 | COPY Northwind.Services.Product/Northwind.Services.Product.csproj Northwind.Services.Product/ 9 | RUN dotnet restore -nowarn:msb3202,nu1503 10 | COPY . . 11 | WORKDIR /src/Northwind.Services.Product 12 | RUN dotnet build -c Debug -o /app 13 | 14 | FROM build AS publish 15 | RUN dotnet publish -c Debug -o /app 16 | 17 | FROM base AS final 18 | WORKDIR /app 19 | COPY --from=publish /app . 20 | ENTRYPOINT ["dotnet", "Northwind.Services.Product.dll"] 21 | -------------------------------------------------------------------------------- /Northwind.Services.Product/Model/ProductDetail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Northwind.Services.Product.Model 4 | { 5 | public class ProductDetail 6 | { 7 | public Guid Id { get; set; } 8 | 9 | public string Name { get; set; } 10 | 11 | public double Price { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /Northwind.Services.Product/Northwind.Services.Product.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.0 5 | ..\docker-compose.dcproj 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Northwind.Services.Product/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | 4 | namespace NorthWind.Services.Product 5 | { 6 | public class Program 7 | { 8 | public static void Main(string[] args) 9 | { 10 | BuildWebHost(args).Run(); 11 | } 12 | 13 | public static IWebHost BuildWebHost(string[] args) => 14 | WebHost.CreateDefaultBuilder(args) 15 | .UseStartup() 16 | .Build(); 17 | } 18 | } -------------------------------------------------------------------------------- /Northwind.Services.Product/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:2626/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "search?q=chocolate", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "NorthWind.Services.Product": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:2627/" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /Northwind.Services.Product/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Builder; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace NorthWind.Services.Product 7 | { 8 | public class Startup 9 | { 10 | public Startup(IConfiguration configuration) 11 | { 12 | Configuration = configuration; 13 | } 14 | 15 | public IConfiguration Configuration { get; } 16 | 17 | // This method gets called by the runtime. Use this method to add services to the container. 18 | public void ConfigureServices(IServiceCollection services) 19 | { 20 | services.AddMvc(); 21 | } 22 | 23 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 24 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) 25 | { 26 | if (env.IsDevelopment()) 27 | { 28 | app.UseDeveloperExceptionPage(); 29 | } 30 | 31 | app.UseMvc(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /Northwind.Services.Product/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /Northwind.Services.Product/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "Debug": { 5 | "LogLevel": { 6 | "Default": "Trace" 7 | } 8 | }, 9 | "Console": { 10 | "LogLevel": { 11 | "Default": "Trace" 12 | } 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /Northwind.Services.Shared/Northwind.Services.Shared.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Northwind.Services.Shared/Response.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Northwind.Services.Shared 5 | { 6 | public class Response 7 | { 8 | public List Downstream { get; set; } 9 | 10 | public DateTime Timestamp { get; set; } 11 | 12 | public string Endpoint { get; set; } 13 | 14 | public int Version { get; set; } 15 | 16 | public Response() 17 | { 18 | Timestamp = DateTime.Now; 19 | } 20 | 21 | public Response(string endpoint, int version) 22 | { 23 | Timestamp = DateTime.Now; 24 | 25 | Endpoint = endpoint; 26 | 27 | Version = version; 28 | } 29 | } 30 | 31 | public class Response : Response 32 | { 33 | public T Data { get; set; } 34 | 35 | public Response() 36 | { 37 | } 38 | 39 | public Response(string endpoint, int version) 40 | : base(endpoint, version) 41 | { 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Northwind.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2015 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Northwind.Services.Product", "Northwind.Services.Product\Northwind.Services.Product.csproj", "{346806C8-39EF-4300-A8B7-EA0AA840F836}" 7 | EndProject 8 | Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{9D05B203-0BB9-48C3-BC65-45E9FAC206B2}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Northwind.Services.Order", "Northwind.Services.Order\Northwind.Services.Order.csproj", "{8433EFE2-E331-40EF-8245-CDC51201F517}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Northwind.Services.Address", "Northwind.Services.Address\Northwind.Services.Address.csproj", "{E4EC9301-B445-4E33-8A19-C33A2AE049EE}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Northwind.Services.Address.v2", "Northwind.Services.Address.v2\Northwind.Services.Address.v2.csproj", "{85F90023-6469-424A-BBD9-3F064686E67A}" 15 | EndProject 16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Northwind.Services.Payment", "Northwind.Services.Payment\Northwind.Services.Payment.csproj", "{4C8B3186-94C8-464E-AB25-15B1D53BEEC7}" 17 | EndProject 18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Northwind.Services.Payment.v2", "Northwind.Services.Payment.v2\Northwind.Services.Payment.v2.csproj", "{5DE489CA-A980-4E8C-9AC9-D2C5FBCFE449}" 19 | EndProject 20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Northwind.Services.Address.v3", "Northwind.Services.Address.v3\Northwind.Services.Address.v3.csproj", "{B285FEED-B604-4F81-AF0F-FBE21B1E7859}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Northwind.Operations", "Northwind.Operations\Northwind.Operations.csproj", "{B1BD9FC1-C4B4-4FAB-8AB7-C86B227EC990}" 23 | EndProject 24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Northwind.Services.Shared", "Northwind.Services.Shared\Northwind.Services.Shared.csproj", "{69779CF9-7B3D-4343-81C8-84B483AD3DD8}" 25 | EndProject 26 | Global 27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 28 | Debug|Any CPU = Debug|Any CPU 29 | Release|Any CPU = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {346806C8-39EF-4300-A8B7-EA0AA840F836}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {346806C8-39EF-4300-A8B7-EA0AA840F836}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {346806C8-39EF-4300-A8B7-EA0AA840F836}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {346806C8-39EF-4300-A8B7-EA0AA840F836}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {9D05B203-0BB9-48C3-BC65-45E9FAC206B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {9D05B203-0BB9-48C3-BC65-45E9FAC206B2}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {9D05B203-0BB9-48C3-BC65-45E9FAC206B2}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {9D05B203-0BB9-48C3-BC65-45E9FAC206B2}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {8433EFE2-E331-40EF-8245-CDC51201F517}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {8433EFE2-E331-40EF-8245-CDC51201F517}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {8433EFE2-E331-40EF-8245-CDC51201F517}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {8433EFE2-E331-40EF-8245-CDC51201F517}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {E4EC9301-B445-4E33-8A19-C33A2AE049EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {E4EC9301-B445-4E33-8A19-C33A2AE049EE}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {E4EC9301-B445-4E33-8A19-C33A2AE049EE}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {E4EC9301-B445-4E33-8A19-C33A2AE049EE}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {85F90023-6469-424A-BBD9-3F064686E67A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {85F90023-6469-424A-BBD9-3F064686E67A}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {85F90023-6469-424A-BBD9-3F064686E67A}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {85F90023-6469-424A-BBD9-3F064686E67A}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {4C8B3186-94C8-464E-AB25-15B1D53BEEC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {4C8B3186-94C8-464E-AB25-15B1D53BEEC7}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {4C8B3186-94C8-464E-AB25-15B1D53BEEC7}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {4C8B3186-94C8-464E-AB25-15B1D53BEEC7}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {5DE489CA-A980-4E8C-9AC9-D2C5FBCFE449}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {5DE489CA-A980-4E8C-9AC9-D2C5FBCFE449}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {5DE489CA-A980-4E8C-9AC9-D2C5FBCFE449}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {5DE489CA-A980-4E8C-9AC9-D2C5FBCFE449}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {B285FEED-B604-4F81-AF0F-FBE21B1E7859}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {B285FEED-B604-4F81-AF0F-FBE21B1E7859}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {B285FEED-B604-4F81-AF0F-FBE21B1E7859}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {B285FEED-B604-4F81-AF0F-FBE21B1E7859}.Release|Any CPU.Build.0 = Release|Any CPU 64 | {B1BD9FC1-C4B4-4FAB-8AB7-C86B227EC990}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {B1BD9FC1-C4B4-4FAB-8AB7-C86B227EC990}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {B1BD9FC1-C4B4-4FAB-8AB7-C86B227EC990}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {B1BD9FC1-C4B4-4FAB-8AB7-C86B227EC990}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {69779CF9-7B3D-4343-81C8-84B483AD3DD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {69779CF9-7B3D-4343-81C8-84B483AD3DD8}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {69779CF9-7B3D-4343-81C8-84B483AD3DD8}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {69779CF9-7B3D-4343-81C8-84B483AD3DD8}.Release|Any CPU.Build.0 = Release|Any CPU 72 | EndGlobalSection 73 | GlobalSection(SolutionProperties) = preSolution 74 | HideSolutionNode = FALSE 75 | EndGlobalSection 76 | GlobalSection(ExtensibilityGlobals) = postSolution 77 | SolutionGuid = {FB8FDAB0-C757-4547-B0AC-5D8A078F487D} 78 | EndGlobalSection 79 | EndGlobal 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Northwind Microservices and Service Mesh 2 | 3 | [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/parameshg/istio) 4 | 5 | ## Introduction 6 | This project is a prototype implementation of service mesh using istio on kubernetes cluster. 7 | 8 | ## Context 9 | This protoype allows customers to be able to browse products and submit orders from a location along with payment details. The system validates supported region and credit card issues. This prototype is structured in a way that features are progressively released in subsequent versions. The system contains the following services: 10 | * Product Service: Provides apis to search products 11 | * Order Service: Provides apis to submit orders 12 | * Payment Service: Facilitates validation of credit card details 13 | * Address Service: Facilitates address validation 14 | 15 | The storyline is as follows: On product launch, v1, the service is limited to central and northern Sydney area and accepts payment via Mastercard and Visa credit cards only. As the product gains traction, in v2, the service area is expaned to western Sydney accepting a wide range of credit cards. A bug has been found in address service where a few postal code has been missed (For example, 2145) during validation. Hence, a hotfix (v3) for address service has been released. 16 | 17 | ## Demo Features 18 | This prototype aims to demonstrate the following features of Istio Service Mesh. 19 | * Blue-Green Deployment 20 | * Canary Release 21 | * Fault Injection 22 | 23 | ## Demo User Interfaces 24 | 25 | ![Installation and Configuration](https://raw.githubusercontent.com/parameshg/northwind-mesh/master/Images/dashboard.png "Installation and Configuration") 26 | 27 | ![Features](https://raw.githubusercontent.com/parameshg/northwind-mesh/master/Images/features.png "Features") 28 | 29 | ![Transaction](https://raw.githubusercontent.com/parameshg/northwind-mesh/master/Images/transaction.png "Transaction") 30 | -------------------------------------------------------------------------------- /docker-compose.dcproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 2.1 5 | Linux 6 | 9d05b203-0bb9-48c3-bc65-45e9fac206b2 7 | LaunchBrowser 8 | http://localhost:{ServicePort}/api/values 9 | northwind.services.product 10 | 11 | 12 | 13 | docker-compose.yml 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | services: 4 | northwind.product.v1: 5 | environment: 6 | - ASPNETCORE_ENVIRONMENT=Development 7 | ports: 8 | - "80" 9 | 10 | northwind.order.v1: 11 | environment: 12 | - ASPNETCORE_ENVIRONMENT=Development 13 | ports: 14 | - "80" 15 | 16 | northwind.address.v1: 17 | environment: 18 | - ASPNETCORE_ENVIRONMENT=Development 19 | ports: 20 | - "80" 21 | 22 | northwind.address.v2: 23 | environment: 24 | - ASPNETCORE_ENVIRONMENT=Development 25 | ports: 26 | - "80" 27 | 28 | northwind.payment.v1: 29 | environment: 30 | - ASPNETCORE_ENVIRONMENT=Development 31 | ports: 32 | - "80" 33 | 34 | northwind.payment.v2: 35 | environment: 36 | - ASPNETCORE_ENVIRONMENT=Development 37 | ports: 38 | - "80" 39 | 40 | northwind.address.v3: 41 | environment: 42 | - ASPNETCORE_ENVIRONMENT=Development 43 | ports: 44 | - "80" -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.4' 2 | 3 | services: 4 | northwind.product.v1: 5 | image: parameshg/northwind.product:v1 6 | build: 7 | context: . 8 | dockerfile: Northwind.Services.Product/Dockerfile 9 | 10 | northwind.order.v1: 11 | image: parameshg/northwind.order:v1 12 | build: 13 | context: . 14 | dockerfile: Northwind.Services.Order/Dockerfile 15 | 16 | northwind.address.v1: 17 | image: parameshg/northwind.address:v1 18 | build: 19 | context: . 20 | dockerfile: Northwind.Services.Address/Dockerfile 21 | 22 | northwind.address.v2: 23 | image: parameshg/northwind.address:v2 24 | build: 25 | context: . 26 | dockerfile: Northwind.Services.Address.v2/Dockerfile 27 | 28 | northwind.payment.v1: 29 | image: parameshg/northwind.payment:v1 30 | build: 31 | context: . 32 | dockerfile: Northwind.Services.Payment/Dockerfile 33 | 34 | northwind.payment.v2: 35 | image: parameshg/northwind.payment:v2 36 | build: 37 | context: . 38 | dockerfile: Northwind.Services.Payment.v2/Dockerfile 39 | 40 | northwind.address.v3: 41 | image: parameshg/northwind.address:v3 42 | build: 43 | context: . 44 | dockerfile: Northwind.Services.Address.v3/Dockerfile --------------------------------------------------------------------------------