mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-13 04:06:07 +08:00
Compare commits
No commits in common. "main" and "v1.4.1" have entirely different histories.
@ -1,3 +0,0 @@
|
||||
{
|
||||
"appHostPath": "../src/Aspire/src/AppHost/AppHost.csproj"
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-outdated-tool": {
|
||||
"version": "4.6.9",
|
||||
"commands": [
|
||||
"dotnet-outdated"
|
||||
]
|
||||
},
|
||||
"dotnet-ef": {
|
||||
"version": "10.0.3",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
]
|
||||
},
|
||||
"aspire.cli": {
|
||||
"version": "13.1.1",
|
||||
"commands": [
|
||||
"aspire"
|
||||
]
|
||||
},
|
||||
"csharpier": {
|
||||
"version": "0.30.6",
|
||||
"commands": [
|
||||
"dotnet-csharpier"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,9 +22,6 @@
|
||||
**/.tye/
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
**/*.jwk
|
||||
**/keys
|
||||
LICENSE
|
||||
README.md
|
||||
CHANGELOG.md
|
||||
|
||||
|
||||
1390
.editorconfig
1390
.editorconfig
File diff suppressed because it is too large
Load Diff
64
.gitattributes
vendored
64
.gitattributes
vendored
@ -1,64 +0,0 @@
|
||||
###############################################################################
|
||||
# Set default behavior to automatically normalize line endings.
|
||||
###############################################################################
|
||||
* text=auto
|
||||
*.sh text eol=lf
|
||||
|
||||
###############################################################################
|
||||
# Set default behavior for command prompt diff.
|
||||
#
|
||||
# This is need for earlier builds of msysgit that does not have it on by
|
||||
# default for csharp files.
|
||||
# Note: This is only used by command line
|
||||
###############################################################################
|
||||
#*.cs diff=csharp
|
||||
|
||||
###############################################################################
|
||||
# Set the merge driver for project and solution files
|
||||
#
|
||||
# Merging from the command prompt will add diff markers to the files if there
|
||||
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||
# the diff markers are never inserted). Diff markers may cause the following
|
||||
# file extensions to fail to load in VS. An alternative would be to treat
|
||||
# these files as binary and thus will always conflict and require user
|
||||
# intervention with every merge. To do so, just uncomment the entries below
|
||||
###############################################################################
|
||||
#*.sln merge=binary
|
||||
#*.csproj merge=binary
|
||||
#*.vbproj merge=binary
|
||||
#*.vcxproj merge=binary
|
||||
#*.vcproj merge=binary
|
||||
#*.dbproj merge=binary
|
||||
#*.fsproj merge=binary
|
||||
#*.lsproj merge=binary
|
||||
#*.wixproj merge=binary
|
||||
#*.modelproj merge=binary
|
||||
#*.sqlproj merge=binary
|
||||
#*.wwaproj merge=binary
|
||||
|
||||
###############################################################################
|
||||
# behavior for image files
|
||||
#
|
||||
# image files are treated as binary by default.
|
||||
###############################################################################
|
||||
#*.jpg binary
|
||||
#*.png binary
|
||||
#*.gif binary
|
||||
|
||||
###############################################################################
|
||||
# diff behavior for common document formats
|
||||
#
|
||||
# Convert binary document formats to text before diffing them. This feature
|
||||
# is only available from the command line. Turn it on by uncommenting the
|
||||
# entries below.
|
||||
###############################################################################
|
||||
#*.doc diff=astextplain
|
||||
#*.DOC diff=astextplain
|
||||
#*.docx diff=astextplain
|
||||
#*.DOCX diff=astextplain
|
||||
#*.dot diff=astextplain
|
||||
#*.DOT diff=astextplain
|
||||
#*.pdf diff=astextplain
|
||||
#*.PDF diff=astextplain
|
||||
#*.rtf diff=astextplain
|
||||
#*.RTF diff=astextplain
|
||||
59
.github/actions/build-test/action.yml
vendored
59
.github/actions/build-test/action.yml
vendored
@ -1,59 +0,0 @@
|
||||
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions
|
||||
# https://doug.sh/posts/using-composite-actions-with-github-actions/
|
||||
# https://wallis.dev/blog/composite-github-actions
|
||||
|
||||
name: "Build-Test"
|
||||
description: "Build and test service"
|
||||
|
||||
# Input parameters allow you to specify data that the action expects to use during runtime. GitHub stores input parameters as environment variables.(so they are just string)
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs
|
||||
inputs:
|
||||
project-path:
|
||||
description: Project path
|
||||
required: true
|
||||
tests-path:
|
||||
description: Test path
|
||||
required: false
|
||||
default: ''
|
||||
reports-path:
|
||||
description: Test report path
|
||||
required: true
|
||||
reports-output-path:
|
||||
description: Test report output path
|
||||
required: true
|
||||
service-name:
|
||||
description: Service name
|
||||
required: true
|
||||
# https://stackoverflow.com/questions/70098241/using-secrets-in-composite-actions-github
|
||||
token:
|
||||
description: A Github PAT
|
||||
required: true
|
||||
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-composite-actions
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
|
||||
- name: Call Composite Action build
|
||||
uses: ./.github/actions/build
|
||||
if: success()
|
||||
id: build-step
|
||||
with:
|
||||
project-path: ${{ inputs.project-path }}
|
||||
service-name: ${{ inputs.service-name }}
|
||||
|
||||
- name: Call Composite Action test
|
||||
uses: ./.github/actions/test
|
||||
if: ${{ success() && inputs.tests-path != ''}}
|
||||
id: test-step
|
||||
with:
|
||||
tests-path: ${{ inputs.tests-path }}
|
||||
# wildcard search for files with the ".cobertura.xml" extension in all subdirectories of the current directory
|
||||
# https://www.jamescroft.co.uk/combining-multiple-code-coverage-results-in-azure-devops/
|
||||
# https://stackoverflow.com/questions/53255065/dotnet-unit-test-with-coverlet-how-to-get-coverage-for-entire-solution-and-not
|
||||
reports-path: ${{ github.workspace }}/**/*.cobertura.xml
|
||||
reports-output-path: ${{ github.workspace }}/output/test-results
|
||||
service-name: ${{ inputs.service-name }}
|
||||
token: ${{ inputs.token }}
|
||||
no-restore: true
|
||||
69
.github/actions/build/action.yml
vendored
69
.github/actions/build/action.yml
vendored
@ -1,69 +0,0 @@
|
||||
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions
|
||||
# https://doug.sh/posts/using-composite-actions-with-github-actions/
|
||||
# https://wallis.dev/blog/composite-github-actions
|
||||
|
||||
name: "Build"
|
||||
description: "Build service"
|
||||
|
||||
# Input parameters allow you to specify data that the action expects to use during runtime. GitHub stores input parameters as environment variables.(so they are just string)
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs
|
||||
inputs:
|
||||
project-path:
|
||||
description: Project path
|
||||
required: true
|
||||
service-name:
|
||||
description: Service name
|
||||
required: true
|
||||
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-composite-actions
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
|
||||
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows
|
||||
# https://devblogs.microsoft.com/dotnet/dotnet-loves-github-actions/
|
||||
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-net#caching-dependencies
|
||||
- name: Cache NuGet Packages
|
||||
uses: actions/cache@v4
|
||||
if: success()
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-dotnet-nuget
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '10.x.x'
|
||||
|
||||
# https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools
|
||||
- name: Restore .NET Tools
|
||||
shell: bash
|
||||
run: dotnet tool restore
|
||||
|
||||
# Note: `Ubuntu` file and folder names are case sensitive, be aware about naming them in solution references. because `Windows` file and folder names as case-insensitive.
|
||||
# prevent windows case-insensitive for our project with: git config core.ignorecase false; - https://stackoverflow.com/a/27139487/581476
|
||||
- name: Restore NuGet packages
|
||||
shell: bash
|
||||
if: success()
|
||||
# restore root solution
|
||||
run: dotnet restore
|
||||
|
||||
# npm install, runs `prepare` script automatically in the initialize step
|
||||
- name: Install NPM Dependencies
|
||||
shell: bash
|
||||
if: success()
|
||||
run: npm install
|
||||
|
||||
- name: Format Service
|
||||
shell: bash
|
||||
if: ${{ success()}}
|
||||
run: |
|
||||
npm run ci-format
|
||||
|
||||
- name: Build Service
|
||||
shell: bash
|
||||
if: ${{ success()}}
|
||||
working-directory: ${{ inputs.project-path }}
|
||||
run: |
|
||||
dotnet build -c Release --no-restore
|
||||
@ -34,11 +34,6 @@ runs:
|
||||
username: ${{ inputs.registry-username }}
|
||||
password: ${{ inputs.registry-password }}
|
||||
|
||||
- name: Docker Tag Info
|
||||
shell: bash
|
||||
run:
|
||||
echo "Docker tag version is:" ${{ inputs.tag-name }}
|
||||
|
||||
- name: Build Docker Image
|
||||
if: ${{ github.ref == 'refs/heads/main' && success() }}
|
||||
shell: bash
|
||||
|
||||
85
.github/actions/test/action.yml
vendored
85
.github/actions/test/action.yml
vendored
@ -1,85 +0,0 @@
|
||||
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions
|
||||
# https://doug.sh/posts/using-composite-actions-with-github-actions/
|
||||
# https://wallis.dev/blog/composite-github-actions
|
||||
|
||||
name: "Test"
|
||||
description: "Test service"
|
||||
|
||||
# Input parameters allow you to specify data that the action expects to use during runtime. GitHub stores input parameters as environment variables.(so they are just string)
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs
|
||||
inputs:
|
||||
tests-path:
|
||||
description: Test path
|
||||
required: true
|
||||
reports-path:
|
||||
description: Test report path
|
||||
required: true
|
||||
reports-output-path:
|
||||
description: Test report output path
|
||||
required: true
|
||||
service-name:
|
||||
description: Service name
|
||||
required: true
|
||||
# https://stackoverflow.com/questions/70098241/using-secrets-in-composite-actions-github
|
||||
token:
|
||||
description: A Github PAT
|
||||
required: true
|
||||
no-restore:
|
||||
description: No restore nuget packages, but building tests because they don't build in the build composition action
|
||||
default: 'true'
|
||||
|
||||
# https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-composite-actions
|
||||
runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
|
||||
# see here https://samlearnsazure.blog/2021/01/05/code-coverage-in-github-with-net-core/
|
||||
# https://www.jamescroft.co.uk/combining-multiple-code-coverage-results-in-azure-devops/
|
||||
# https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test#filter-option-details
|
||||
# https://josef.codes/dotnet-core-filter-out-specific-test-projects-when-running-dotnet-test/
|
||||
# https://learn.microsoft.com/en-us/dotnet/core/testing/selective-unit-tests?pivots=xunit
|
||||
# https://stackoverflow.com/questions/53255065/dotnet-unit-test-with-coverlet-how-to-get-coverage-for-entire-solution-and-not
|
||||
# https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/MSBuildIntegration.md
|
||||
# https://github.com/coverlet-coverage/coverlet/blob/master/Documentation/MSBuildIntegration.md#filters
|
||||
- name: Tests
|
||||
shell: bash
|
||||
id: tests-step
|
||||
working-directory: ${{ inputs.tests-path }}
|
||||
# https://stackoverflow.com/questions/3779701/msbuild-error-msb1008-only-one-project-can-be-specified
|
||||
# https://octopus.com/blog/githubactions-running-unit-tests
|
||||
# we should not do 'no-build' here, because our tests not build in build phase (build composite action) and should build here
|
||||
run: |
|
||||
for file in $(find . -name "*.csproj" -type f); do
|
||||
echo "Testing $file"
|
||||
if [ ${{ inputs.no-restore }} == 'true' ]; then
|
||||
echo "run tests in no-restore mode"
|
||||
dotnet test "$file" -c Release --no-restore --logger "trx;LogFileName=test-results.trx" || true
|
||||
else
|
||||
echo "run tests in restore nuget mode"
|
||||
dotnet test "$file" -c Release --logger "trx;LogFileName=test-results.trx" || true
|
||||
fi
|
||||
done
|
||||
|
||||
# GitHub Api call permissions problem here
|
||||
# https://github.com/dorny/test-reporter/issues/168
|
||||
# https://octopus.com/blog/githubactions-running-unit-tests
|
||||
# https://github.com/dorny/test-reporter/issues/67
|
||||
# https://github.com/phoenix-actions/test-reporting/pull/21
|
||||
- name: Test Results
|
||||
uses: phoenix-actions/test-reporting@v10
|
||||
id: test-report
|
||||
if: always()
|
||||
with:
|
||||
name: ${{ inputs.service-name }} Test Reports
|
||||
reporter: dotnet-trx
|
||||
token: ${{ inputs.token }}
|
||||
# only-summary: 'true'
|
||||
output-to: "step-summary"
|
||||
path: "**/test-results.trx"
|
||||
# Set action as failed if test report contains any failed test
|
||||
fail-on-error: true
|
||||
## https://github.com/dorny/test-reporter#recommended-setup-for-public-repositories
|
||||
## https://github.com/dorny/test-reporter/blob/0d9714ddc7ff86918ec725a527a3a069419d301a/src/utils/github-utils.ts#L44
|
||||
## artifact name to download trx test result if it is in seperated workflow with github rest call, if it is not in another workflow skip this
|
||||
# artifact: "'
|
||||
39
.github/pull_request_template.md
vendored
Normal file
39
.github/pull_request_template.md
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
<!-- Type of change
|
||||
Please label this PR with one of the existing labels, depending on the scope of your change.
|
||||
-->
|
||||
|
||||
## What does this PR do?
|
||||
|
||||
<!-- Mandatory
|
||||
Explain here the changes you made on the PR. Please explain the WHAT: patterns used, algorithms implemented, design architecture, etc.
|
||||
-->
|
||||
|
||||
## Why is it important?
|
||||
|
||||
<!-- Mandatory
|
||||
Explain here the WHY, or the rationale / motivation for the changes.
|
||||
-->
|
||||
|
||||
## Related issues
|
||||
|
||||
<!-- Recommended
|
||||
Link related issues below. Insert the issue link or reference after the word "Closes" if merging this should automatically close it.
|
||||
|
||||
- Closes #123
|
||||
- Relates #123
|
||||
- Requires #123
|
||||
- Supersedes #123
|
||||
-->
|
||||
-
|
||||
|
||||
<!-- Recommended
|
||||
## How to test this PR
|
||||
|
||||
Explain here how this PR will be tested by the reviewer: commands, dependencies, steps, etc.
|
||||
-->
|
||||
|
||||
<!-- Optional
|
||||
## Follow-ups
|
||||
|
||||
Add here any thought that you consider could be identified as an actionable step once this PR is merged.
|
||||
-->
|
||||
6
.github/release-drafter.yml
vendored
6
.github/release-drafter.yml
vendored
@ -28,7 +28,7 @@ categories:
|
||||
- title: 👷 CI
|
||||
labels:
|
||||
- ci
|
||||
- title: ♻️ Refactor
|
||||
- title: ♻️ Changes
|
||||
labels:
|
||||
- changed
|
||||
- enhancement
|
||||
@ -91,7 +91,9 @@ autolabeler:
|
||||
body:
|
||||
- '/JIRA-[0-9]{1,4}/'
|
||||
|
||||
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
|
||||
change-template: '- $TITLE (#$NUMBER)'
|
||||
exclude-contributors:
|
||||
- 'meysamhadeli'
|
||||
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
|
||||
version-resolver:
|
||||
major:
|
||||
|
||||
92
.github/workflows/ci.yml
vendored
92
.github/workflows/ci.yml
vendored
@ -2,83 +2,41 @@ name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main"]
|
||||
branches: [ "main" , "develop" ]
|
||||
paths-ignore:
|
||||
- "README.md"
|
||||
pull_request:
|
||||
branches: [ "main"]
|
||||
branches: [ "main" , "develop" ]
|
||||
paths-ignore:
|
||||
- "README.md"
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build and Test Flight Microservice
|
||||
uses: ./.github/actions/build-test
|
||||
if: success()
|
||||
id: build-test-flight-step
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v2
|
||||
with:
|
||||
project-path: 'src/Services/Flight/src/Flight.Api'
|
||||
tests-path: 'src/Services/Flight/tests/'
|
||||
# wildcard search for files with the ".cobertura.xml" extension in all subdirectories of the current directory
|
||||
# https://www.jamescroft.co.uk/combining-multiple-code-coverage-results-in-azure-devops/
|
||||
# https://stackoverflow.com/questions/53255065/dotnet-unit-test-with-coverlet-how-to-get-coverage-for-entire-solution-and-not
|
||||
reports-path: ${{ github.workspace }}/**/*.cobertura.xml
|
||||
reports-output-path: ${{ github.workspace }}/output/test-results
|
||||
service-name: 'Flight'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
dotnet-version: 7.0.x
|
||||
|
||||
- name: Build and Test Identity Microservice
|
||||
uses: ./.github/actions/build-test
|
||||
if: success()
|
||||
id: build-test-identity-step
|
||||
- name: Cache NuGet Packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
project-path: 'src/Services/Identity/src/Identity.Api'
|
||||
tests-path: 'src/Services/Identity/tests/'
|
||||
# wildcard search for files with the ".cobertura.xml" extension in all subdirectories of the current directory
|
||||
# https://www.jamescroft.co.uk/combining-multiple-code-coverage-results-in-azure-devops/
|
||||
# https://stackoverflow.com/questions/53255065/dotnet-unit-test-with-coverlet-how-to-get-coverage-for-entire-solution-and-not
|
||||
reports-path: ${{ github.workspace }}/**/*.cobertura.xml
|
||||
reports-output-path: ${{ github.workspace }}/output/test-results
|
||||
service-name: 'Identity'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
key: ${{ runner.os }}-dotnet-nuget
|
||||
path: ~/.nuget/packages
|
||||
|
||||
- name: Build and Test Passenger Microservice
|
||||
uses: ./.github/actions/build-test
|
||||
if: success()
|
||||
id: build-test-passenger-step
|
||||
with:
|
||||
project-path: 'src/Services/Passenger/src/Passenger.Api'
|
||||
tests-path: 'src/Services/Passenger/tests/'
|
||||
# wildcard search for files with the ".cobertura.xml" extension in all subdirectories of the current directory
|
||||
# https://www.jamescroft.co.uk/combining-multiple-code-coverage-results-in-azure-devops/
|
||||
# https://stackoverflow.com/questions/53255065/dotnet-unit-test-with-coverlet-how-to-get-coverage-for-entire-solution-and-not
|
||||
reports-path: ${{ github.workspace }}/**/*.cobertura.xml
|
||||
reports-output-path: ${{ github.workspace }}/output/test-results
|
||||
service-name: 'Passenger'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and Test Booking Microservice
|
||||
uses: ./.github/actions/build-test
|
||||
if: success()
|
||||
id: build-test-booking-step
|
||||
with:
|
||||
project-path: 'src/Services/Booking/src/Booking.Api'
|
||||
tests-path: 'src/Services/Booking/tests/'
|
||||
# wildcard search for files with the ".cobertura.xml" extension in all subdirectories of the current directory
|
||||
# https://www.jamescroft.co.uk/combining-multiple-code-coverage-results-in-azure-devops/
|
||||
# https://stackoverflow.com/questions/53255065/dotnet-unit-test-with-coverlet-how-to-get-coverage-for-entire-solution-and-not
|
||||
reports-path: ${{ github.workspace }}/**/*.cobertura.xml
|
||||
reports-output-path: ${{ github.workspace }}/output/test-results
|
||||
service-name: 'Booking'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build
|
||||
run: dotnet build -c Release --no-restore
|
||||
|
||||
- name: Test
|
||||
run: dotnet test -c Release --no-restore
|
||||
|
||||
- name: Update Release Drafter
|
||||
if: ${{ github.ref == 'refs/heads/main' && success() }}
|
||||
@ -87,11 +45,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Release Version Info
|
||||
run:
|
||||
echo "Release version is:" ${{ steps.last_release.outputs.tag_name }}
|
||||
|
||||
- name: Build and Publish Identity Microservice to Docker
|
||||
- name: Build and Publish Identity to Docker
|
||||
if: ${{ github.ref == 'refs/heads/main' && success() }}
|
||||
uses: ./.github/actions/docker-build-publish
|
||||
with:
|
||||
@ -101,7 +55,7 @@ jobs:
|
||||
dockerfile-path: 'src/Services/Identity/Dockerfile'
|
||||
image-name: 'booking-microservices-identity'
|
||||
|
||||
- name: Build and Publish Flight Microservice to Docker
|
||||
- name: Build and Publish Flight to Docker
|
||||
if: ${{ github.ref == 'refs/heads/main' && success() }}
|
||||
uses: ./.github/actions/docker-build-publish
|
||||
with:
|
||||
@ -111,7 +65,7 @@ jobs:
|
||||
dockerfile-path: 'src/Services/Flight/Dockerfile'
|
||||
image-name: 'booking-microservices-flight'
|
||||
|
||||
- name: Build and Publish Passenger Microservice to Docker
|
||||
- name: Build and Publish Passenger to Docker
|
||||
if: ${{ github.ref == 'refs/heads/main' && success() }}
|
||||
uses: ./.github/actions/docker-build-publish
|
||||
with:
|
||||
@ -121,7 +75,7 @@ jobs:
|
||||
dockerfile-path: 'src/Services/Passenger/Dockerfile'
|
||||
image-name: 'booking-microservices-passenger'
|
||||
|
||||
- name: Build and Publish Booking Microservice to Docker
|
||||
- name: Build and Publish Booking to Docker
|
||||
if: ${{ github.ref == 'refs/heads/main' && success() }}
|
||||
uses: ./.github/actions/docker-build-publish
|
||||
with:
|
||||
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
@ -226,6 +226,7 @@ ClientBin/
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
@ -431,12 +432,4 @@ fabric.properties
|
||||
*.sln.iml
|
||||
|
||||
# Tye
|
||||
.tye/
|
||||
|
||||
*.jwk
|
||||
|
||||
# Monitoring
|
||||
**/grafana-data
|
||||
|
||||
# EventStore
|
||||
**/eventstore
|
||||
.tye/
|
||||
1
.gitpod.Dockerfile
vendored
Normal file
1
.gitpod.Dockerfile
vendored
Normal file
@ -0,0 +1 @@
|
||||
FROM gitpod/workspace-dotnet:latest
|
||||
30
.gitpod.yml
Normal file
30
.gitpod.yml
Normal file
@ -0,0 +1,30 @@
|
||||
# https://github.com/gitpod-samples/template-dotnet-core-cli-csharp
|
||||
# https://www.gitpod.io/docs/introduction/languages/dotnet
|
||||
# https://github.com/gitpod-samples/template-docker-compose
|
||||
# https://www.gitpod.io/docs/references/gitpod-yml
|
||||
# https://www.gitpod.io/docs/configure
|
||||
# https://www.gitpod.io/docs/configure/workspaces/ports
|
||||
|
||||
image:
|
||||
file: .gitpod.Dockerfile
|
||||
|
||||
# https://www.gitpod.io/docs/configure/workspaces/tasks#execution-order
|
||||
# https://www.gitpod.io/docs/configure/projects/prebuilds
|
||||
tasks:
|
||||
- name: Init Docker-Compose
|
||||
# https://www.gitpod.io/docs/configure/projects/prebuilds
|
||||
# We load docker on pre-build for increasing speed
|
||||
init: |
|
||||
docker-compose pull
|
||||
docker-compose -f ./deployments/docker-compose/infrastracture.yaml up -d
|
||||
- name: Setup kubectl
|
||||
command: bash $GITPOD_REPO_ROOT/scripts/setup_kubectl_gitpod.sh
|
||||
- name: Restore & Build
|
||||
init: |
|
||||
dotnet dev-certs https
|
||||
dotnet restore
|
||||
dotnet build
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- muhammad-sammy.csharp
|
||||
@ -1 +0,0 @@
|
||||
npx --no -- commitlint --edit ${1}
|
||||
@ -1,2 +0,0 @@
|
||||
npm run format
|
||||
npm run ci-format
|
||||
@ -1,26 +0,0 @@
|
||||
## Contribution
|
||||
|
||||
This is great that you'd like to contribute to this project. All change requests should go through the steps described below.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
**Please, make sure you open an issue before starting with a Pull Request, unless it's a typo or a really obvious error.** Pull requests are the best way to propose changes.
|
||||
|
||||
## Conventional commits
|
||||
|
||||
Our repository follow [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) specification. Releasing to GitHub and NuGet is done with the support of [semantic-release](https://semantic-release.gitbook.io/semantic-release/).
|
||||
|
||||
Pull requests should have a title that follows the specification, otherwise, merging is blocked. If you are not familiar with the specification simply ask maintainers to modify. You can also use this cheatsheet if you want:
|
||||
|
||||
- `fix: ` prefix in the title indicates that PR is a bug fix and PATCH release must be triggered.
|
||||
- `feat: ` prefix in the title indicates that PR is a feature and MINOR release must be triggered.
|
||||
- `docs: ` prefix in the title indicates that PR is only related to the documentation and there is no need to trigger release.
|
||||
- `chore: ` prefix in the title indicates that PR is only related to cleanup in the project and there is no need to trigger release.
|
||||
- `test: ` prefix in the title indicates that PR is only related to tests and there is no need to trigger release.
|
||||
- `refactor: ` prefix in the title indicates that PR is only related to refactoring and there is no need to trigger release.
|
||||
|
||||
## Resources
|
||||
|
||||
- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
|
||||
- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
|
||||
- [GitHub Help](https://help.github.com)
|
||||
@ -1,48 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="all" Version="1.1.118">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Meziantou.Analyzer" PrivateAssets="all" Version="2.0.299">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.Analyzers" PrivateAssets="all" Version="4.15.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.CodeAnalysis.Analyzers" PrivateAssets="all" Version="4.15.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Roslynator.Formatting.Analyzers" PrivateAssets="all" Version="4.15.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" PrivateAssets="all" Version="17.14.15">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="AsyncAwaitBestPractices" PrivateAssets="all" Version="10.0.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="CSharpGuidelinesAnalyzer" PrivateAssets="all" Version="3.8.5">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<GlobalPackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="7.0.0" />
|
||||
<GlobalPackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" />
|
||||
<GlobalPackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.435" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
<CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
|
||||
<AnalysisLevel>latest-Recommended</AnalysisLevel>
|
||||
<AnalysisMode>Recommended</AnalysisMode>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
241
README.md
241
README.md
@ -2,128 +2,90 @@
|
||||
<img src="assets/logo.png" alt="booking-microservices" />
|
||||
<div align="center">
|
||||
<a href="https://github.com/meysamhadeli/booking-microservices/actions/workflows/ci.yml"><img alt="ci-status" src="https://github.com/meysamhadeli/booking-microservices/actions/workflows/ci.yml/badge.svg?branch=main&style=flat-square"/></a>
|
||||
<a href="https://gitpod.io/#https://github.com/meysamhadeli/booking-microservices"><img src="https://img.shields.io/badge/Gitpod-live--code-blue?logo=gitpod&style=flat-square&color=ff69b4"/></a>
|
||||
<a href="https://github.com/meysamhadeli/booking-microservices/blob/main/LICENSE"><img alt="build-status" src="https://img.shields.io/github/license/meysamhadeli/booking-microservices?color=%234275f5&style=flat-square"/></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
> 🚀 **A practical microservices with the latest technologies and architectures like Vertical Slice Architecture, Event Sourcing, CQRS, DDD, gRpc, MongoDB, RabbitMq, Masstransit, and Aspire in .Net 10.**
|
||||
|
||||
## You can find other version of this project here:
|
||||
- [Booking with Modular Monolith Architecture](https://github.com/meysamhadeli/booking-modular-monolith)
|
||||
- [Booking with Monolith Architecture](https://github.com/meysamhadeli/booking-monolith)
|
||||
|
||||
<div>
|
||||
<a href='https://codespaces.new/meysamhadeli/booking-microservices?quickstart=1'><img alt='Open in GitHub Codespaces' src='https://github.com/codespaces/badge.svg'></a>
|
||||
</div>
|
||||
> **The main idea of creating this project is implementing an infrastructure for up and running distributed system with the latest technology and architecture like Vertical Slice Architecture, Event Sourcing, CQRS, DDD, gRpc, MongoDB, RabbitMq, Masstransit in .Net, and we will not deal mainly with business.** 🚀
|
||||
|
||||
# Table of Contents
|
||||
|
||||
- [The Goals of This Project](#the-goals-of-this-project)
|
||||
- [Plan](#plan)
|
||||
- [Technologies - Libraries](#technologies---libraries)
|
||||
- [Key Features](#key-features)
|
||||
- [When to Use](#when-to-use)
|
||||
- [Challenges](#challenges)
|
||||
- [The Domain and Bounded Context - Service Boundary](#the-domain-and-bounded-context---service-boundary)
|
||||
- [Structure of Project](#structure-of-project)
|
||||
- [Development Setup](#development-setup)
|
||||
- [Dotnet Tools Packages](#dotnet-tools-packages)
|
||||
- [Husky](#husky)
|
||||
- [Upgrade Nuget Packages](#upgrade-nuget-packages)
|
||||
- [How to Run](#how-to-run)
|
||||
- [Config Certificate](#config-certificate)
|
||||
- [Aspire](#aspire)
|
||||
- [Docker Compose](#docker-compose)
|
||||
- [Kubernetes](#kubernetes)
|
||||
- [Build](#build)
|
||||
- [Run](#run)
|
||||
- [Test](#test)
|
||||
- [Documentation Apis](#documentation-apis)
|
||||
- [Support](#support)
|
||||
- [Contribution](#contribution)
|
||||
|
||||
|
||||
## The Goals of This Project
|
||||
|
||||
- :sparkle: Using `Vertical Slice Architecture` for `architecture` level.
|
||||
- :sparkle: Using `Domain Driven Design (DDD)` to implement all `business logic`.
|
||||
- :sparkle: Using `Rabbitmq` on top of `Masstransit` for `Event Driven Architecture`.
|
||||
- :sparkle: Using `gRPC` for `internal communication`.
|
||||
- :sparkle: Using `Vertical Slice Architecture` for architecture level.
|
||||
- :sparkle: Using `Domain Driven Design (DDD)` to implement all business processes in microservices.
|
||||
- :sparkle: Using `Rabbitmq` on top of `Masstransit` for `Event Driven Architecture` between our microservices.
|
||||
- :sparkle: Using `gRPC` for internal communication between our microservices.
|
||||
- :sparkle: Using `CQRS` implementation with `MediatR` library.
|
||||
- :sparkle: Using `Postgres` for `write side` database.
|
||||
- :sparkle: Using `MongoDB` for `read side` database.
|
||||
- :sparkle: Using `Event Store` for `write side` of Booking Microservice/Module to store all `historical change` of aggregate.
|
||||
- :sparkle: Using `Inbox Pattern` for ensuring message idempotency for receiver and `Exactly once Delivery`.
|
||||
- :sparkle: Using `Outbox Pattern` for ensuring no message is lost and there is at `At Least One Delivery`.
|
||||
- :sparkle: Using `Unit Testing` for testing small units and mocking our dependencies with `Nsubstitute`.
|
||||
- :sparkle: Using `End-To-End Testing` and `Integration Testing` for testing `features` with all dependencies using `testcontainers`.
|
||||
- :sparkle: Using `Postgres` for `write side` of some microservices.
|
||||
- :sparkle: Using `MongoDB` for `read side` of some microservices.
|
||||
- :sparkle: Using `Event Store` for `write side` of Booking-Microservice to store all `historical state` of aggregate.
|
||||
- :sparkle: Using `Inbox Pattern` for ensuring message idempotency for receiver and `Exactly once Delivery`.
|
||||
- :sparkle: Using `Outbox Pattern` for ensuring no message is lost and there is at `Least One Delivery`.
|
||||
- :sparkle: Using `Unit Testing`, `Integration Testing`, `End To End Testing` for testing level.
|
||||
- :sparkle: Using `Fluent Validation` and a `Validation Pipeline Behaviour` on top of `MediatR`.
|
||||
- :sparkle: Using `Minimal API` for all endpoints.
|
||||
- :sparkle: Using `AspNetCore OpenApi` for `generating` built-in support `OpenAPI documentation` in ASP.NET Core.
|
||||
- :sparkle: Using `Health Check` for `reporting` the `health` of app infrastructure components.
|
||||
- :sparkle: Using `Health Check` for reporting the health of app infrastructure components.
|
||||
- :sparkle: Using `Docker-Compose` and `Kubernetes` for our deployment mechanism.
|
||||
- :sparkle: Using `Kibana` on top of `Serilog` for `logging`.
|
||||
- :sparkle: Using `OpenTelemetry` for distributed tracing on top of `Jaeger`.
|
||||
- :sparkle: Using `OpenTelemetry` for monitoring on top of `Prometheus` and `Grafana`.
|
||||
- :sparkle: Using `OpenTelemetry` for distributed tracing.
|
||||
- :sparkle: Using `IdentityServer` for authentication and authorization base on `OpenID-Connect` and `OAuth2`.
|
||||
- :sparkle: Using `Yarp` as a microservices `gateway`.
|
||||
- :sparkle: Using `Kubernetes` to achieve efficient `scaling` and ensure `high availability` for each of our microservices.
|
||||
- :sparkle: Using `Nginx Ingress Controller` for `load balancing` between our microservices top of `Kubernetes`.
|
||||
- :sparkle: Using `cert-manager` to Configure `TLS` in `kubernetes cluster`.
|
||||
- :sparkle: Using `Aspire` for `service discovery`, `observability`, and `local orchestration` of microservices.
|
||||
- :sparkle: Using `Yarp` as a microservices gateway.
|
||||
|
||||
## Plan
|
||||
|
||||
## Technologies - Libraries
|
||||
> 🌀This project is a work in progress, new features will be added over time.🌀
|
||||
|
||||
- ✔️ **[`.NET 10`](https://github.com/dotnet/aspnetcore)** - .NET Framework and .NET Core, including ASP.NET and ASP.NET Core.
|
||||
- ✔️ **[`MVC Versioning API`](https://github.com/microsoft/aspnet-api-versioning)** - Set of libraries which add service API versioning to ASP.NET Web API, OData with ASP.NET Web API, and ASP.NET Core.
|
||||
- ✔️ **[`EF Core`](https://github.com/dotnet/efcore)** - Modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
|
||||
- ✔️ **[`AspNetCore OpenApi`](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/openapi/aspnetcore-openapi)** - Provides built-in support for OpenAPI document generation in ASP.NET Core.
|
||||
I will try to register future goals and additions in the [Issues](https://github.com/meysamhadeli/booking-microservices/issues) section of this repository.
|
||||
|
||||
High-level plan is represented in the table
|
||||
|
||||
| Feature | Status |
|
||||
| ----------------- | -------------- |
|
||||
| API Gateway | Completed ✔️ |
|
||||
| Identity Service | Completed ✔️ |
|
||||
| Flight Service | Completed ✔️ |
|
||||
| Passenger Service | Completed ✔️ |
|
||||
| Booking Service | Completed ✔️ |
|
||||
| Building Blocks | Completed ✔️ |
|
||||
|
||||
## :heart: Technologies - Libraries
|
||||
|
||||
- ✔️ **[`.NET 7`](https://dotnet.microsoft.com/download)** - .NET Framework and .NET Core, including ASP.NET and ASP.NET Core
|
||||
- ✔️ **[`MVC Versioning API`](https://github.com/microsoft/aspnet-api-versioning)** - Set of libraries which add service API versioning to ASP.NET Web API, OData with ASP.NET Web API, and ASP.NET Core
|
||||
- ✔️ **[`EF Core`](https://github.com/dotnet/efcore)** - Modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations
|
||||
- ✔️ **[`Masstransit`](https://github.com/MassTransit/MassTransit)** - Distributed Application Framework for .NET.
|
||||
- ✔️ **[`MediatR`](https://github.com/jbogard/MediatR)** - Simple, unambitious mediator implementation in .NET.
|
||||
- ✔️ **[`FluentValidation`](https://github.com/FluentValidation/FluentValidation)** - Popular .NET validation library for building strongly-typed validation rules.
|
||||
- ✔️ **[`Scalar`](https://github.com/scalar/scalar/tree/main/packages/scalar.aspnetcore)** - Scalar provides an easy way to render beautiful API references based on OpenAPI/Swagger documents.
|
||||
- ✔️ **[`Swagger UI`](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)** - Swagger tools for documenting API's built on ASP.NET Core.
|
||||
- ✔️ **[`FluentValidation`](https://github.com/FluentValidation/FluentValidation)** - Popular .NET validation library for building strongly-typed validation rules
|
||||
- ✔️ **[`Swagger & Swagger UI`](https://github.com/domaindrivendev/Swashbuckle.AspNetCore)** - Swagger tools for documenting API's built on ASP.NET Core
|
||||
- ✔️ **[`Serilog`](https://github.com/serilog/serilog)** - Simple .NET logging with fully-structured events
|
||||
- ✔️ **[`Polly`](https://github.com/App-vNext/Polly)** - Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner.
|
||||
- ✔️ **[`Polly`](https://github.com/App-vNext/Polly)** - Polly is a .NET resilience and transient-fault-handling library that allows developers to express policies such as Retry, Circuit Breaker, Timeout, Bulkhead Isolation, and Fallback in a fluent and thread-safe manner
|
||||
- ✔️ **[`Scrutor`](https://github.com/khellang/Scrutor)** - Assembly scanning and decoration extensions for Microsoft.Extensions.DependencyInjection
|
||||
- ✔️ **[`Opentelemetry-dotnet`](https://github.com/open-telemetry/opentelemetry-dotnet)** - The OpenTelemetry .NET Client
|
||||
- ✔️ **[`DuendeSoftware IdentityServer`](https://github.com/DuendeSoftware/IdentityServer)** - The most flexible and standards-compliant OpenID Connect and OAuth 2.x framework for ASP.NET Core.
|
||||
- ✔️ **[`DuendeSoftware IdentityServer`](https://github.com/DuendeSoftware/IdentityServer)** - The most flexible and standards-compliant OpenID Connect and OAuth 2.x framework for ASP.NET Core
|
||||
- ✔️ **[`EasyCaching`](https://github.com/dotnetcore/EasyCaching)** - Open source caching library that contains basic usages and some advanced usages of caching which can help us to handle caching more easier.
|
||||
- ✔️ **[`Mapster`](https://github.com/MapsterMapper/Mapster)** - Convention-based object-object mapper in .NET.
|
||||
- ✔️ **[`Hellang.Middleware.ProblemDetails`](https://github.com/khellang/Middleware/tree/master/src/ProblemDetails)** - A middleware for handling exception in .Net Core.
|
||||
- ✔️ **[`NewId`](https://github.com/phatboyg/NewId)** - NewId can be used as an embedded unique ID generator that produces 128 bit (16 bytes) sequential IDs.
|
||||
- ✔️ **[`Yarp`](https://github.com/microsoft/reverse-proxy)** - Reverse proxy toolkit for building fast proxy servers in .NET.
|
||||
- ✔️ **[`Tye`](https://github.com/dotnet/tye)** - Developer tool that makes developing, testing, and deploying microservices and distributed applications easier.
|
||||
- ✔️ **[`Hellang.Middleware.ProblemDetails`](https://github.com/khellang/Middleware/tree/master/src/ProblemDetails)** - A middleware for handling exception in .Net Core
|
||||
- ✔️ **[`IdGen`](https://github.com/RobThree/IdGen)** - Twitter Snowflake-alike ID generator for .Net
|
||||
- ✔️ **[`Yarp`](https://github.com/microsoft/reverse-proxy)** - Reverse proxy toolkit for building fast proxy servers in .NET
|
||||
- ✔️ **[`Tye`](https://github.com/dotnet/tye)** - Developer tool that makes developing, testing, and deploying microservices and distributed applications easier
|
||||
- ✔️ **[`gRPC-dotnet`](https://github.com/grpc/grpc-dotnet)** - gRPC functionality for .NET.
|
||||
- ✔️ **[`EventStore`](https://github.com/EventStore/EventStore)** - The open-source, functional database with Complex Event Processing.
|
||||
- ✔️ **[`MongoDB.Driver`](https://github.com/mongodb/mongo-csharp-driver)** - .NET Driver for MongoDB.
|
||||
- ✔️ **[`xUnit.net`](https://github.com/xunit/xunit)** - A free, open source, community-focused unit testing tool for the .NET Framework.
|
||||
- ✔️ **[`Respawn`](https://github.com/jbogard/Respawn)** - Respawn is a small utility to help in resetting test databases to a clean state.
|
||||
- ✔️ **[`Testcontainers`](https://github.com/testcontainers/testcontainers-dotnet)** - Testcontainers for .NET is a library to support tests with throwaway instances of Docker containers.
|
||||
- ✔️ **[`K6`](https://github.com/grafana/k6)** - Modern load testing for developers and testers in the DevOps era.
|
||||
- ✔️ **[`Aspire`](https://github.com/dotnet/aspire)** - .NET stack for building and orchestrating observable, distributed cloud-native applications.
|
||||
|
||||
|
||||
## Key Features
|
||||
1. **Independent Services**: Each service is a separate project with its own database and deployment pipeline, enabling independent development and deployment.
|
||||
2. **Decentralized Communication**: Services communicate via APIs (REST, gRPC) or message brokers (RabbitMQ, Kafka), ensuring loose coupling and resilience.
|
||||
3. **Scalability**: Services can be scaled independently based on demand, allowing efficient resource utilization.
|
||||
4. **Fault Tolerance**: Failures are isolated, preventing cascading failures and ensuring high availability.
|
||||
5. **Technology Agnostic**: Services can use different technologies, frameworks, or databases, providing flexibility.
|
||||
|
||||
|
||||
## When to Use
|
||||
1. **Large and Complex Projects**: Ideal for applications with complex business logic that can be broken into smaller, manageable services.
|
||||
2. **High Scalability Needs**: Suitable for applications requiring independent scaling of components.
|
||||
3. **Fault Tolerance and High Availability**: Perfect for systems where failure isolation and uptime are critical.
|
||||
4. **Distributed Teams**: Enables teams to work independently on different services.
|
||||
5. **Frequent Updates**: Supports continuous deployment and A/B testing for individual services.
|
||||
6. **Technology Diversity**: Allows the use of different technologies for different services.
|
||||
|
||||
|
||||
## Challenges
|
||||
- Increased complexity in management, DevOps overhead, data consistency, latency, and higher costs.
|
||||
|
||||
|
||||
## The Domain And Bounded Context - Service Boundary
|
||||
|
||||
@ -137,19 +99,26 @@
|
||||
|
||||

|
||||
|
||||
|
||||
## Structure of Project
|
||||
|
||||
In this project, I used [vertical slice architecture](https://jimmybogard.com/vertical-slice-architecture/) at the architectural level and [feature folder structure](http://www.kamilgrzybek.com/design/feature-folders/) to structure my files.
|
||||
In this project I used a mix of [clean architecture](https://jasontaylor.dev/clean-architecture-getting-started/), [vertical slice architecture](https://jimmybogard.com/vertical-slice-architecture/) and I used [feature folder structure](http://www.kamilgrzybek.com/design/feature-folders/) to structure my files.
|
||||
|
||||
I used [yarp reverse proxy](https://microsoft.github.io/reverse-proxy/articles/index.html) to route synchronous and asynchronous requests to the corresponding microservice. Each microservice has its dependencies such as databases, files etc. Each microservice is decoupled from other microservices and developed and deployed separately. Microservices talk to each other with Rest or gRPC for synchronous calls and use RabbitMq or Kafka for asynchronous calls.
|
||||
|
||||
We have a separate microservice ([IdentityServer](https://github.com/DuendeSoftware/IdentityServer)) for authentication and authorization of each request. Once signed-in users are issued a JWT token. This token is used by other microservices to validate the user, read claims and allow access to authorized/role specific endpoints.
|
||||
|
||||
I used [RabbitMQ](https://github.com/rabbitmq) as my MessageBroker for async communication between microservices using the eventual consistency mechanism. Each microservice uses [MassTransit](https://github.com/MassTransit/MassTransit) to interface with [RabbitMQ](https://github.com/rabbitmq) providing, messaging, availability, reliability, etc.
|
||||
|
||||
Microservices are `event based` which means they can publish and/or subscribe to any events occurring in the setup. By using this approach for communicating between services, each microservice does not need to know about the other services or handle errors occurred in other microservices.
|
||||
|
||||
After saving data in write side, I save a [Internal Command](https://github.com/kgrzybek/modular-monolith-with-ddd#38-internal-processing) record in my Persist Messages storage (like something we do in outbox pattern) and after committing transaction in write side, trigger our command handler in read side and this handler could save their read models in our MongoDB database.
|
||||
|
||||
I treat each request as a distinct use case or slice, encapsulating and grouping all concerns from front-end to back.
|
||||
When adding or changing a feature in an application in n-tire architecture, we are typically touching many "layers" in an application. We are changing the user interface, adding fields to models, modifying validation, and so on. Instead of coupling across a layer, we couple vertically along a slice. We `minimize coupling` `between slices`, and `maximize coupling` `in a slice`.
|
||||
|
||||
With this approach, each of our vertical slices can decide for itself how to best fulfill the request. New features only add code, we're not changing shared code and worrying about side effects.
|
||||
|
||||
<div align="center">
|
||||
<img src="./assets/vertical-slice-architecture.png" />
|
||||
</div>
|
||||

|
||||
|
||||
Instead of grouping related action methods in one controller, as found in traditional ASP.net controllers, I used the [REPR pattern](https://deviq.com/design-patterns/repr-design-pattern). Each action gets its own small endpoint, consisting of a route, the action, and an `IMediator` instance (see [MediatR](https://github.com/jbogard/MediatR)). The request is passed to the `IMediator` instance, routed through a [`Mediatr pipeline`](https://lostechies.com/jimmybogard/2014/09/09/tackling-cross-cutting-concerns-with-a-mediator-pipeline/) where custom [middleware](https://github.com/jbogard/MediatR/wiki/Behaviors) can log, validate and intercept requests. The request is then handled by a request specific `IRequestHandler` which performs business logic before returning the result.
|
||||
|
||||
@ -163,111 +132,43 @@ I used CQRS to decompose my features into small parts that makes our application
|
||||
|
||||
Using the CQRS pattern, we cut each business functionality into vertical slices, for each of these slices we group classes (see [technical folders structure](http://www.kamilgrzybek.com/design/feature-folders)) specific to that feature together (command, handlers, infrastructure, repository, controllers, etc). In our CQRS pattern each command/query handler is a separate slice. This is where you can reduce coupling between layers. Each handler can be a separated code unit, even copy/pasted. Thanks to that, we can tune down the specific method to not follow general conventions (e.g. use custom SQL query or even different storage). In a traditional layered architecture, when we change the core generic mechanism in one layer, it can impact all methods.
|
||||
|
||||
|
||||
## Development Setup
|
||||
|
||||
### Dotnet Tools Packages
|
||||
For installing our requirement packages with .NET cli tools, we need to install `dotnet tool manifest`.
|
||||
```bash
|
||||
dotnet new tool-manifest
|
||||
```
|
||||
And after that we can restore our dotnet tools packages with .NET cli tools from `.config` folder and `dotnet-tools.json` file.
|
||||
```
|
||||
dotnet tool restore
|
||||
```
|
||||
|
||||
### Husky
|
||||
Here we use `husky` to handel some pre commit rules and we used `conventional commits` rules and `formatting` as pre commit rules, here in [package.json](.././package.json). of course, we can add more rules for pre commit in future. (find more about husky in the [documentation](https://typicode.github.io/husky/get-started.html))
|
||||
We need to install `husky` package for `manage` `pre commits hooks` and also I add two packages `@commitlint/cli` and `@commitlint/config-conventional` for handling conventional commits rules in [package.json](.././package.json).
|
||||
Run the command bellow in the root of project to install all npm dependencies related to husky:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
> Note: In the root of project we have `.husky` folder and it has `commit-msg` file for handling conventional commits rules with provide user friendly message and `pre-commit` file that we can run our `scripts` as a `pre-commit` hooks. that here we call `format` script from [package.json](./package.json) for formatting purpose.
|
||||
|
||||
### Upgrade Nuget Packages
|
||||
For upgrading our nuget packages to last version, we use the great package [dotnet-outdated](https://github.com/dotnet-outdated/dotnet-outdated).
|
||||
Run the command below in the root of project to upgrade all of packages to last version:
|
||||
```bash
|
||||
dotnet outdated -u
|
||||
```
|
||||
|
||||
## How to Run
|
||||
|
||||
> ### Config Certificate
|
||||
Run the following commands to [Config SSL](https://docs.microsoft.com/en-us/aspnet/core/security/docker-compose-https?view=aspnetcore-6.0) in your system:
|
||||
### Config Certificate
|
||||
|
||||
Run the following commands for [Config SSL](https://docs.microsoft.com/en-us/aspnet/core/security/docker-compose-https?view=aspnetcore-6.0) in your system
|
||||
|
||||
#### Windows using Linux containers
|
||||
```bash
|
||||
dotnet dev-certs https -ep %USERPROFILE%\.aspnet\https\aspnetapp.pfx -p password
|
||||
dotnet dev-certs https --trust
|
||||
```
|
||||
> Note: for running this command in `powershell` use `$env:USERPROFILE` instead of `%USERPROFILE%`*
|
||||
> Note: for running this command in `powershell` use `$env:USERPROFILE` instead of `%USERPROFILE%`
|
||||
|
||||
#### macOS or Linux
|
||||
```bash
|
||||
dotnet dev-certs https -ep ${HOME}/.aspnet/https/aspnetapp.pfx -p $CREDENTIAL_PLACEHOLDER$
|
||||
dotnet dev-certs https --trust
|
||||
```
|
||||
### Docker Compose
|
||||
|
||||
### Aspire
|
||||
|
||||
To run the application using the `Aspire App Host`, execute the following command from the solution root:
|
||||
|
||||
```bash
|
||||
aspire run
|
||||
```
|
||||
|
||||
> Note:The `Aspire dashboard` will be available at `http://localhost:18888`
|
||||
|
||||
> ### Docker Compose
|
||||
|
||||
|
||||
To run this app in `Docker`, use the [docker-compose.yaml](./deployments/docker-compose/docker-compose.yaml) and execute the below command at the `root` of the application:
|
||||
Run this app in docker using the [docker-compose.yaml](./deployments/docker-compose/docker-compose.yaml) file with the below command at the root of the application:
|
||||
|
||||
```bash
|
||||
docker-compose -f ./deployments/docker-compose/docker-compose.yaml up -d
|
||||
```
|
||||
|
||||
> ### Kubernetes
|
||||
To `configure TLS` in the `Kubernetes cluster`, we need to install `cert-manager` based on the [docs](https://cert-manager.io/docs/installation) and run the following commands to apply TLS in our application. Here, we use [Let's Encrypt](https://letsencrypt.org/) to encrypt our certificate.
|
||||
Also we have a seprate docker file for up and running [infrastracture.yaml](./deployments/docker-compose/infrastracture.yaml) independently:
|
||||
|
||||
```bash
|
||||
kubectl apply -f ./deployments/kubernetes/booking-cert-manager.yml
|
||||
docker-compose -f ./deployments/docker-compose/infrastracture.yaml up -d
|
||||
```
|
||||
|
||||
To apply all necessary `deployments`, `pods`, `services`, `ingress`, and `config maps`, please run the following command:
|
||||
### Kubernetes - TODO
|
||||
|
||||
```bash
|
||||
kubectl apply -f ./deployments/kubernetes/booking-microservices.yml
|
||||
```
|
||||
### Documentation Apis
|
||||
|
||||
> ### Build
|
||||
To `build` all microservices, run this command in the `root` of the project:
|
||||
```bash
|
||||
dotnet build
|
||||
```
|
||||
|
||||
> ### Run
|
||||
To `run` each microservice, run this command in the root of the `Api` folder of each microservice where the `csproj` file is located:
|
||||
```bash
|
||||
dotnet run
|
||||
```
|
||||
|
||||
> ### Test
|
||||
|
||||
To `test` all microservices, run this command in the `root` of the project:
|
||||
```bash
|
||||
dotnet test
|
||||
```
|
||||
|
||||
> ### Documentation Apis
|
||||
|
||||
Each microservice provides `API documentation` and navigate to `/swagger` for `Swagger OpenAPI` or `/scalar/v1` for `Scalar OpenAPI` to visit list of endpoints.
|
||||
|
||||
As part of API testing, I created the [booking.rest](./booking.rest) file which can be run with the [REST Client](https://github.com/Huachao/vscode-restclient) `VSCode plugin`.
|
||||
Each microservice uses swagger open api, navigate to /swagger for a list of every endpoint.
|
||||
For testing apis I used the [REST Client](https://github.com/Huachao/vscode-restclient) plugin for VSCode running this file [booking.rest](./booking.rest).
|
||||
|
||||
# Support
|
||||
|
||||
@ -279,9 +180,7 @@ Thanks a bunch for supporting me!
|
||||
|
||||
## Contribution
|
||||
|
||||
Thanks to all [contributors](https://github.com/meysamhadeli/booking-microservices/graphs/contributors), you're awesome and this wouldn't be possible without you! The goal is to build a categorized, community-driven collection of very well-known resources.
|
||||
|
||||
Please follow this [contribution guideline](./CONTRIBUTION.md) to submit a pull request or create the issue.
|
||||
Thanks to all [contributors](https://github.com/meysamhadeli/booking-microservices/graphs/contributors), you're awesome and this wouldn't be possible without you! The goal is to build a categorized community-driven collection of very well-known resources.
|
||||
|
||||
## Project References & Credits
|
||||
|
||||
@ -289,7 +188,9 @@ Please follow this [contribution guideline](./CONTRIBUTION.md) to submit a pull
|
||||
- [https://github.com/kgrzybek/modular-monolith-with-ddd](https://github.com/kgrzybek/modular-monolith-with-ddd)
|
||||
- [https://github.com/oskardudycz/EventSourcing.NetCore](https://github.com/oskardudycz/EventSourcing.NetCore)
|
||||
- [https://github.com/thangchung/clean-architecture-dotnet](https://github.com/thangchung/clean-architecture-dotnet)
|
||||
- [https://github.com/jasontaylordev/CleanArchitecture](https://github.com/jasontaylordev/CleanArchitecture)
|
||||
- [https://github.com/pdevito3/MessageBusTestingInMemHarness](https://github.com/pdevito3/MessageBusTestingInMemHarness)
|
||||
- [https://github.com/devmentors/FeedR](https://github.com/devmentors/FeedR)
|
||||
|
||||
## License
|
||||
This project is made available under the MIT license. See [LICENSE](https://github.com/meysamhadeli/booking-microservices/blob/main/LICENSE) for details.
|
||||
|
||||
BIN
assets/Vertical-Slice-Architecture.jpg
Normal file
BIN
assets/Vertical-Slice-Architecture.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
File diff suppressed because one or more lines are too long
13426
assets/booking-microservices.excalidraw
Normal file
13426
assets/booking-microservices.excalidraw
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 643 KiB After Width: | Height: | Size: 1.4 MiB |
@ -1,431 +0,0 @@
|
||||
{
|
||||
"type": "excalidraw",
|
||||
"version": 2,
|
||||
"source": "https://excalidraw.com",
|
||||
"elements": [
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 242,
|
||||
"versionNonce": 1509780320,
|
||||
"isDeleted": false,
|
||||
"id": "80OGzNPG6Gk8NAvbV3XaF",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 648,
|
||||
"y": 187,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#a8bffe",
|
||||
"width": 538,
|
||||
"height": 62,
|
||||
"seed": 246982778,
|
||||
"groupIds": [],
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "46GLDhDwmnc8RGy3v8OK8"
|
||||
}
|
||||
],
|
||||
"updated": 1679316672934,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 137,
|
||||
"versionNonce": 703919968,
|
||||
"isDeleted": false,
|
||||
"id": "46GLDhDwmnc8RGy3v8OK8",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 897.848014831543,
|
||||
"y": 201.2,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 38.30397033691406,
|
||||
"height": 33.6,
|
||||
"seed": 2080176422,
|
||||
"groupIds": [],
|
||||
"roundness": null,
|
||||
"boundElements": [],
|
||||
"updated": 1679315949309,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Api",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "80OGzNPG6Gk8NAvbV3XaF",
|
||||
"originalText": "Api"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 358,
|
||||
"versionNonce": 356515488,
|
||||
"isDeleted": false,
|
||||
"id": "nZuYK7wbLObwRvpRRLHay",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 648,
|
||||
"y": 263,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fea8d5",
|
||||
"width": 538,
|
||||
"height": 62,
|
||||
"seed": 287502970,
|
||||
"groupIds": [],
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "OALII-DXtatRPgn_EkHfp"
|
||||
}
|
||||
],
|
||||
"updated": 1679316735759,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 246,
|
||||
"versionNonce": 1126108000,
|
||||
"isDeleted": false,
|
||||
"id": "OALII-DXtatRPgn_EkHfp",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 845.628044128418,
|
||||
"y": 277.2,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 142.74391174316406,
|
||||
"height": 33.6,
|
||||
"seed": 1016531494,
|
||||
"groupIds": [],
|
||||
"roundness": null,
|
||||
"boundElements": [],
|
||||
"updated": 1679315949309,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Application",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "nZuYK7wbLObwRvpRRLHay",
|
||||
"originalText": "Application"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 282,
|
||||
"versionNonce": 787808928,
|
||||
"isDeleted": false,
|
||||
"id": "za_4vz64MSfPF5TWmD7wj",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 650,
|
||||
"y": 338,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#f30358",
|
||||
"width": 538,
|
||||
"height": 62,
|
||||
"seed": 676018342,
|
||||
"groupIds": [],
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "6CqYCSOKHqhqJ8nf4b-Sv"
|
||||
}
|
||||
],
|
||||
"updated": 1679316783390,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 189,
|
||||
"versionNonce": 1441177440,
|
||||
"isDeleted": false,
|
||||
"id": "6CqYCSOKHqhqJ8nf4b-Sv",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 816.618049621582,
|
||||
"y": 352.2,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 204.76390075683594,
|
||||
"height": 33.6,
|
||||
"seed": 1067355322,
|
||||
"groupIds": [],
|
||||
"roundness": null,
|
||||
"boundElements": [],
|
||||
"updated": 1679315949309,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Infrastructure",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "za_4vz64MSfPF5TWmD7wj",
|
||||
"originalText": "Infrastructure"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 326,
|
||||
"versionNonce": 1669046112,
|
||||
"isDeleted": false,
|
||||
"id": "t2sZwLLvmq3y2ndIbEomB",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 70,
|
||||
"angle": 0,
|
||||
"x": 648,
|
||||
"y": 413,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#9d9ca2",
|
||||
"width": 538,
|
||||
"height": 62,
|
||||
"seed": 1173221990,
|
||||
"groupIds": [],
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"boundElements": [
|
||||
{
|
||||
"type": "text",
|
||||
"id": "b3wdaWjaVmgHpzMD26uKD"
|
||||
}
|
||||
],
|
||||
"updated": 1679316844215,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 224,
|
||||
"versionNonce": 1385935712,
|
||||
"isDeleted": false,
|
||||
"id": "b3wdaWjaVmgHpzMD26uKD",
|
||||
"fillStyle": "hachure",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 70,
|
||||
"angle": 0,
|
||||
"x": 886.5500106811523,
|
||||
"y": 427.2,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "transparent",
|
||||
"width": 60.89997863769531,
|
||||
"height": 33.6,
|
||||
"seed": 1307397882,
|
||||
"groupIds": [],
|
||||
"roundness": null,
|
||||
"boundElements": [],
|
||||
"updated": 1679315949310,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Core",
|
||||
"textAlign": "center",
|
||||
"verticalAlign": "middle",
|
||||
"containerId": "t2sZwLLvmq3y2ndIbEomB",
|
||||
"originalText": "Core"
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 202,
|
||||
"versionNonce": 1461187232,
|
||||
"isDeleted": false,
|
||||
"id": "FQZImjU2-VUOATU9Yeyly",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 678,
|
||||
"y": 154,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fefda8",
|
||||
"width": 48,
|
||||
"height": 361,
|
||||
"seed": 1254939642,
|
||||
"groupIds": [],
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"boundElements": [],
|
||||
"updated": 1679316609154,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "rectangle",
|
||||
"version": 249,
|
||||
"versionNonce": 1540775776,
|
||||
"isDeleted": false,
|
||||
"id": "_Vw9EnXAyzxRDEzXCTfeL",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 0,
|
||||
"x": 742,
|
||||
"y": 153.5,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#fefda8",
|
||||
"width": 48,
|
||||
"height": 361,
|
||||
"seed": 523058342,
|
||||
"groupIds": [],
|
||||
"roundness": {
|
||||
"type": 3
|
||||
},
|
||||
"boundElements": [],
|
||||
"updated": 1679316594766,
|
||||
"link": null,
|
||||
"locked": false
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 249,
|
||||
"versionNonce": 871687840,
|
||||
"isDeleted": false,
|
||||
"id": "hyJiOwPt7LFndn5R0xgfL",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 100,
|
||||
"angle": 4.707547804955119,
|
||||
"x": 637.1248451774691,
|
||||
"y": 317.9455509364301,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#f9e79f",
|
||||
"width": 130.73194885253906,
|
||||
"height": 33.6,
|
||||
"seed": 678740006,
|
||||
"groupIds": [],
|
||||
"roundness": null,
|
||||
"boundElements": [],
|
||||
"updated": 1679315961675,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Feature 1",
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Feature 1"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 182,
|
||||
"versionNonce": 1494113120,
|
||||
"isDeleted": false,
|
||||
"id": "7KOHd5JA_wVMmwXPVT1N3",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 80,
|
||||
"angle": 4.7123889803846915,
|
||||
"x": 695.6880416870117,
|
||||
"y": 313.20000000000005,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#f9e79f",
|
||||
"width": 143.07994079589844,
|
||||
"height": 33.6,
|
||||
"seed": 1387191482,
|
||||
"groupIds": [],
|
||||
"roundness": null,
|
||||
"boundElements": [],
|
||||
"updated": 1679315949310,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Feature 2",
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Feature 2"
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
"version": 163,
|
||||
"versionNonce": 1243581088,
|
||||
"isDeleted": false,
|
||||
"id": "SuFNrbzZGowiIybusnadN",
|
||||
"fillStyle": "solid",
|
||||
"strokeWidth": 1,
|
||||
"strokeStyle": "solid",
|
||||
"roughness": 1,
|
||||
"opacity": 70,
|
||||
"angle": 0,
|
||||
"x": 748,
|
||||
"y": 96,
|
||||
"strokeColor": "#000000",
|
||||
"backgroundColor": "#f9e79f",
|
||||
"width": 360.47186279296875,
|
||||
"height": 33.6,
|
||||
"seed": 2006173690,
|
||||
"groupIds": [],
|
||||
"roundness": null,
|
||||
"boundElements": [],
|
||||
"updated": 1679315949310,
|
||||
"link": null,
|
||||
"locked": false,
|
||||
"fontSize": 28,
|
||||
"fontFamily": 1,
|
||||
"text": "Vertical Slice Architecture",
|
||||
"textAlign": "left",
|
||||
"verticalAlign": "top",
|
||||
"containerId": null,
|
||||
"originalText": "Vertical Slice Architecture"
|
||||
}
|
||||
],
|
||||
"appState": {
|
||||
"gridSize": null,
|
||||
"viewBackgroundColor": "#ffffff"
|
||||
},
|
||||
"files": {}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB |
175
booking-microservices-sample.sln
Normal file
175
booking-microservices-sample.sln
Normal file
@ -0,0 +1,175 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30114.105
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{5B69EDFD-4B09-457A-AAAF-D816D402D595}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{9010E0B5-9C42-4256-ADE4-E290434F2CEF}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiGateway", "ApiGateway", "{3E38DD17-9EEE-4815-9D5B-BEB5549020A0}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{776BDF43-0DEA-44A3-AF72-99408CE544EE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiGateway", "src\ApiGateway\src\ApiGateway.csproj", "{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildingBlocks", "src\BuildingBlocks\BuildingBlocks.csproj", "{E42BB533-4144-4D78-BCCE-50BA00BCADBE}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Flight", "Flight", "{5F0996AB-F8DB-4240-BD4A-DFDD70638A73}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Passenger", "Passenger", "{1A2ABCD9-493B-4848-9C69-919CDBCA61F3}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Booking", "Booking", "{22447274-717D-4321-87F3-868BAF93CBEC}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{55BE6759-95AA-434D-925D-A8D32F274E66}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E2637D6D-04A5-4DE4-8AAF-E015C65DE8E1}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{5185D5C5-0EAD-49D5-B405-93B939F3639B}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{53D0AA09-F5FA-4721-8C1B-375CBD15B4E8}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{C6EE337B-91EA-472A-87C7-E9528408CE59}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F39D8F09-6233-4495-ACD0-F98904993B7E}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{295284BA-D4E4-40AA-A2C2-BE36343F7DE6}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{85DA00E5-CC11-463C-8577-C34967C328F7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{C1EBE17D-BFAD-47DA-88EB-BB073B84593E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Booking", "src\Services\Booking\src\Booking\Booking.csproj", "{B2BAA061-C005-409F-9D3E-BDCBE5B1B136}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Booking.Api", "src\Services\Booking\src\Booking.Api\Booking.Api.csproj", "{4E8FB852-4317-43D2-8EFC-14E3ECCFDA2C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flight", "src\Services\Flight\src\Flight\Flight.csproj", "{574222F8-9C26-4015-8F35-C1E5D41A505F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flight.Api", "src\Services\Flight\src\Flight.Api\Flight.Api.csproj", "{B8F734F5-873C-4367-9EBD-38EA420CD868}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity", "src\Services\Identity\src\Identity\Identity.csproj", "{65C1BB58-2A2E-44FF-B15D-2B023CF088D4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.Api", "src\Services\Identity\src\Identity.Api\Identity.Api.csproj", "{BEE7A9D7-1BFC-477E-B070-4BE63C0361AA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Passenger", "src\Services\Passenger\src\Passenger\Passenger.csproj", "{6D7BCECE-D77D-4C57-A296-CA6E728E94B7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Passenger.Api", "src\Services\Passenger\src\Passenger.Api\Passenger.Api.csproj", "{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Flight\tests\IntegrationTest\Integration.Test.csproj", "{6B6603C8-D8B6-4775-9C7A-FFE6058070C2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Identity\tests\IntegrationTest\Integration.Test.csproj", "{BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Passenger\tests\IntegrationTest\Integration.Test.csproj", "{539364C8-88B1-48A3-8406-D0B19FF30509}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Booking\tests\IntegrationTest\Integration.Test.csproj", "{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unit.Test", "src\Services\Flight\tests\UnitTest\Unit.Test.csproj", "{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EndToEnd.Test", "src\Services\Flight\tests\EndToEndTest\EndToEnd.Test.csproj", "{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{776BDF43-0DEA-44A3-AF72-99408CE544EE} = {3E38DD17-9EEE-4815-9D5B-BEB5549020A0}
|
||||
{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5} = {776BDF43-0DEA-44A3-AF72-99408CE544EE}
|
||||
{E42BB533-4144-4D78-BCCE-50BA00BCADBE} = {5B69EDFD-4B09-457A-AAAF-D816D402D595}
|
||||
{5F0996AB-F8DB-4240-BD4A-DFDD70638A73} = {9010E0B5-9C42-4256-ADE4-E290434F2CEF}
|
||||
{1A2ABCD9-493B-4848-9C69-919CDBCA61F3} = {9010E0B5-9C42-4256-ADE4-E290434F2CEF}
|
||||
{22447274-717D-4321-87F3-868BAF93CBEC} = {9010E0B5-9C42-4256-ADE4-E290434F2CEF}
|
||||
{55BE6759-95AA-434D-925D-A8D32F274E66} = {9010E0B5-9C42-4256-ADE4-E290434F2CEF}
|
||||
{E2637D6D-04A5-4DE4-8AAF-E015C65DE8E1} = {22447274-717D-4321-87F3-868BAF93CBEC}
|
||||
{5185D5C5-0EAD-49D5-B405-93B939F3639B} = {22447274-717D-4321-87F3-868BAF93CBEC}
|
||||
{53D0AA09-F5FA-4721-8C1B-375CBD15B4E8} = {5F0996AB-F8DB-4240-BD4A-DFDD70638A73}
|
||||
{C6EE337B-91EA-472A-87C7-E9528408CE59} = {5F0996AB-F8DB-4240-BD4A-DFDD70638A73}
|
||||
{F39D8F09-6233-4495-ACD0-F98904993B7E} = {55BE6759-95AA-434D-925D-A8D32F274E66}
|
||||
{295284BA-D4E4-40AA-A2C2-BE36343F7DE6} = {55BE6759-95AA-434D-925D-A8D32F274E66}
|
||||
{85DA00E5-CC11-463C-8577-C34967C328F7} = {1A2ABCD9-493B-4848-9C69-919CDBCA61F3}
|
||||
{C1EBE17D-BFAD-47DA-88EB-BB073B84593E} = {1A2ABCD9-493B-4848-9C69-919CDBCA61F3}
|
||||
{B2BAA061-C005-409F-9D3E-BDCBE5B1B136} = {E2637D6D-04A5-4DE4-8AAF-E015C65DE8E1}
|
||||
{4E8FB852-4317-43D2-8EFC-14E3ECCFDA2C} = {E2637D6D-04A5-4DE4-8AAF-E015C65DE8E1}
|
||||
{574222F8-9C26-4015-8F35-C1E5D41A505F} = {53D0AA09-F5FA-4721-8C1B-375CBD15B4E8}
|
||||
{B8F734F5-873C-4367-9EBD-38EA420CD868} = {53D0AA09-F5FA-4721-8C1B-375CBD15B4E8}
|
||||
{65C1BB58-2A2E-44FF-B15D-2B023CF088D4} = {F39D8F09-6233-4495-ACD0-F98904993B7E}
|
||||
{BEE7A9D7-1BFC-477E-B070-4BE63C0361AA} = {F39D8F09-6233-4495-ACD0-F98904993B7E}
|
||||
{6D7BCECE-D77D-4C57-A296-CA6E728E94B7} = {85DA00E5-CC11-463C-8577-C34967C328F7}
|
||||
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837} = {85DA00E5-CC11-463C-8577-C34967C328F7}
|
||||
{6B6603C8-D8B6-4775-9C7A-FFE6058070C2} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
|
||||
{BC7871B8-BB18-4BCC-96A8-7324C11BF4A2} = {295284BA-D4E4-40AA-A2C2-BE36343F7DE6}
|
||||
{539364C8-88B1-48A3-8406-D0B19FF30509} = {C1EBE17D-BFAD-47DA-88EB-BB073B84593E}
|
||||
{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC} = {5185D5C5-0EAD-49D5-B405-93B939F3639B}
|
||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
|
||||
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB} = {C6EE337B-91EA-472A-87C7-E9528408CE59}
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2D7C5C4-5148-4C3E-BB12-B7A197A290F5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E42BB533-4144-4D78-BCCE-50BA00BCADBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E42BB533-4144-4D78-BCCE-50BA00BCADBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E42BB533-4144-4D78-BCCE-50BA00BCADBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E42BB533-4144-4D78-BCCE-50BA00BCADBE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B2BAA061-C005-409F-9D3E-BDCBE5B1B136}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B2BAA061-C005-409F-9D3E-BDCBE5B1B136}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B2BAA061-C005-409F-9D3E-BDCBE5B1B136}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B2BAA061-C005-409F-9D3E-BDCBE5B1B136}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4E8FB852-4317-43D2-8EFC-14E3ECCFDA2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4E8FB852-4317-43D2-8EFC-14E3ECCFDA2C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4E8FB852-4317-43D2-8EFC-14E3ECCFDA2C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4E8FB852-4317-43D2-8EFC-14E3ECCFDA2C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{574222F8-9C26-4015-8F35-C1E5D41A505F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{574222F8-9C26-4015-8F35-C1E5D41A505F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{574222F8-9C26-4015-8F35-C1E5D41A505F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{574222F8-9C26-4015-8F35-C1E5D41A505F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B8F734F5-873C-4367-9EBD-38EA420CD868}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B8F734F5-873C-4367-9EBD-38EA420CD868}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B8F734F5-873C-4367-9EBD-38EA420CD868}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B8F734F5-873C-4367-9EBD-38EA420CD868}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{65C1BB58-2A2E-44FF-B15D-2B023CF088D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{65C1BB58-2A2E-44FF-B15D-2B023CF088D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{65C1BB58-2A2E-44FF-B15D-2B023CF088D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{65C1BB58-2A2E-44FF-B15D-2B023CF088D4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BEE7A9D7-1BFC-477E-B070-4BE63C0361AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BEE7A9D7-1BFC-477E-B070-4BE63C0361AA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BEE7A9D7-1BFC-477E-B070-4BE63C0361AA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BEE7A9D7-1BFC-477E-B070-4BE63C0361AA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6D7BCECE-D77D-4C57-A296-CA6E728E94B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6D7BCECE-D77D-4C57-A296-CA6E728E94B7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6D7BCECE-D77D-4C57-A296-CA6E728E94B7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6D7BCECE-D77D-4C57-A296-CA6E728E94B7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4F29C4B6-A7DA-4A92-9CDB-42FE98238837}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6B6603C8-D8B6-4775-9C7A-FFE6058070C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6B6603C8-D8B6-4775-9C7A-FFE6058070C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6B6603C8-D8B6-4775-9C7A-FFE6058070C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6B6603C8-D8B6-4775-9C7A-FFE6058070C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BC7871B8-BB18-4BCC-96A8-7324C11BF4A2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{539364C8-88B1-48A3-8406-D0B19FF30509}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{539364C8-88B1-48A3-8406-D0B19FF30509}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{539364C8-88B1-48A3-8406-D0B19FF30509}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{539364C8-88B1-48A3-8406-D0B19FF30509}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{50C66B53-ACA0-4AFF-8C5C-834D4EDA8FAC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8F78BCE2-C705-4357-A6B9-1B83B55ABBE8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8561089E-9FB9-4ACD-A1F5-EAAF213E1DDB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@ -1,348 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{CD4A4407-C3B0-422D-BB8C-2A810CED9938}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ApiGateway", "ApiGateway", "{CDFA86FA-BBBA-4A5B-A833-3BE219E373E5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{B19FD14B-4DFE-26B6-646B-3D5D94CC4D36}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BuildingBlocks", "BuildingBlocks", "{C734CEF7-A2AC-3076-84D8-694B7490AA9D}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Flight", "Flight", "{A3579DE0-F7C5-67E8-3CF8-3AC89B64E059}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Booking", "Booking", "{C6034A5C-F49A-5FA4-86A6-65B2CB19613F}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Passenger", "Passenger", "{9D4F3958-FE6E-C048-E6F9-6F53D8AF03CA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Identity", "Identity", "{B465D535-05D9-3A0A-08BF-35A1C18CEC46}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A2834164-BF04-BF13-ADC5-A97145852861}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{1B4FBE3A-43F5-1B1E-2877-3036AC5431EF}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DDEDC5E0-5D13-A45C-2393-A774DD4A1A07}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{51D8F471-B8EB-AD1C-0E89-AA84C5D0C759}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{773BFBD8-04CD-79F8-8301-C81308C3ED45}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{4B043475-1AFA-C467-FE09-A46D09CD6936}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5CED3889-AECF-A6CD-55DC-F680D3C18861}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{54BCCDE8-25E6-6FCB-4A9E-D5D2AF76D352}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Booking.Api", "src\Services\Booking\src\Booking.Api\Booking.Api.csproj", "{D3BF565A-C413-4185-9528-BE1B4F46993C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Booking", "src\Services\Booking\src\Booking\Booking.csproj", "{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flight", "src\Services\Flight\src\Flight\Flight.csproj", "{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Flight.Api", "src\Services\Flight\src\Flight.Api\Flight.Api.csproj", "{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity", "src\Services\Identity\src\Identity\Identity.csproj", "{BCDEAB10-6373-46E7-B408-846A3B0B508B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Identity.Api", "src\Services\Identity\src\Identity.Api\Identity.Api.csproj", "{B0EC74C5-9B2D-492C-ABAE-3E868397B122}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Passenger", "src\Services\Passenger\src\Passenger\Passenger.csproj", "{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Passenger.Api", "src\Services\Passenger\src\Passenger.Api\Passenger.Api.csproj", "{101FFD12-17A4-4615-9438-F347BBF4CC85}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuildingBlocks", "src\BuildingBlocks\BuildingBlocks.csproj", "{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{427BE8BE-DA7B-FC74-412B-547671E05463}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiGateway", "src\ApiGateway\src\ApiGateway.csproj", "{C015BF35-6977-407B-8948-636A9C81C5BE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Booking\tests\IntegrationTest\Integration.Test.csproj", "{19A89F36-FD3A-448D-90D1-04A1B67BB255}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EndToEnd.Test", "src\Services\Flight\tests\EndToEndTest\EndToEnd.Test.csproj", "{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Flight\tests\IntegrationTest\Integration.Test.csproj", "{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Unit.Test", "src\Services\Flight\tests\UnitTest\Unit.Test.csproj", "{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Identity\tests\IntegrationTest\Integration.Test.csproj", "{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Integration.Test", "src\Services\Passenger\tests\IntegrationTest\Integration.Test.csproj", "{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aspire", "Aspire", "{D1B6353A-63F5-4DD9-90E6-42B2CFDF1DEA}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C4287034-6833-4505-A6EB-704A86392ECB}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppHost", "src\Aspire\src\AppHost\AppHost.csproj", "{490BCB11-314C-473C-9B85-A32164783507}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceDefaults", "src\Aspire\src\ServiceDefaults\ServiceDefaults.csproj", "{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Release|x64.Build.0 = Release|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279}.Release|x86.Build.0 = Release|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122}.Release|x86.Build.0 = Release|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Release|x64.Build.0 = Release|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538}.Release|x86.Build.0 = Release|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Release|x64.Build.0 = Release|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Release|x64.Build.0 = Release|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4}.Release|x86.Build.0 = Release|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Release|x64.Build.0 = Release|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01}.Release|x86.Build.0 = Release|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Release|x64.Build.0 = Release|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5}.Release|x86.Build.0 = Release|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Release|x64.Build.0 = Release|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{490BCB11-314C-473C-9B85-A32164783507}.Release|x86.Build.0 = Release|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{CDFA86FA-BBBA-4A5B-A833-3BE219E373E5} = {CD4A4407-C3B0-422D-BB8C-2A810CED9938}
|
||||
{B19FD14B-4DFE-26B6-646B-3D5D94CC4D36} = {CD4A4407-C3B0-422D-BB8C-2A810CED9938}
|
||||
{C734CEF7-A2AC-3076-84D8-694B7490AA9D} = {CD4A4407-C3B0-422D-BB8C-2A810CED9938}
|
||||
{A3579DE0-F7C5-67E8-3CF8-3AC89B64E059} = {B19FD14B-4DFE-26B6-646B-3D5D94CC4D36}
|
||||
{C6034A5C-F49A-5FA4-86A6-65B2CB19613F} = {B19FD14B-4DFE-26B6-646B-3D5D94CC4D36}
|
||||
{9D4F3958-FE6E-C048-E6F9-6F53D8AF03CA} = {B19FD14B-4DFE-26B6-646B-3D5D94CC4D36}
|
||||
{B465D535-05D9-3A0A-08BF-35A1C18CEC46} = {B19FD14B-4DFE-26B6-646B-3D5D94CC4D36}
|
||||
{A2834164-BF04-BF13-ADC5-A97145852861} = {C6034A5C-F49A-5FA4-86A6-65B2CB19613F}
|
||||
{1B4FBE3A-43F5-1B1E-2877-3036AC5431EF} = {C6034A5C-F49A-5FA4-86A6-65B2CB19613F}
|
||||
{DDEDC5E0-5D13-A45C-2393-A774DD4A1A07} = {A3579DE0-F7C5-67E8-3CF8-3AC89B64E059}
|
||||
{51D8F471-B8EB-AD1C-0E89-AA84C5D0C759} = {A3579DE0-F7C5-67E8-3CF8-3AC89B64E059}
|
||||
{773BFBD8-04CD-79F8-8301-C81308C3ED45} = {B465D535-05D9-3A0A-08BF-35A1C18CEC46}
|
||||
{4B043475-1AFA-C467-FE09-A46D09CD6936} = {B465D535-05D9-3A0A-08BF-35A1C18CEC46}
|
||||
{5CED3889-AECF-A6CD-55DC-F680D3C18861} = {9D4F3958-FE6E-C048-E6F9-6F53D8AF03CA}
|
||||
{54BCCDE8-25E6-6FCB-4A9E-D5D2AF76D352} = {9D4F3958-FE6E-C048-E6F9-6F53D8AF03CA}
|
||||
{D3BF565A-C413-4185-9528-BE1B4F46993C} = {A2834164-BF04-BF13-ADC5-A97145852861}
|
||||
{3EA375C7-2900-4927-B1E5-C9D31E67F4A8} = {A2834164-BF04-BF13-ADC5-A97145852861}
|
||||
{BCC8A8A6-C2ED-42D2-86BB-A05C790D7279} = {DDEDC5E0-5D13-A45C-2393-A774DD4A1A07}
|
||||
{836D1466-3C20-4D74-B54A-FA09C0EE0FA2} = {DDEDC5E0-5D13-A45C-2393-A774DD4A1A07}
|
||||
{BCDEAB10-6373-46E7-B408-846A3B0B508B} = {773BFBD8-04CD-79F8-8301-C81308C3ED45}
|
||||
{B0EC74C5-9B2D-492C-ABAE-3E868397B122} = {773BFBD8-04CD-79F8-8301-C81308C3ED45}
|
||||
{9B4BDD42-56F3-4DB9-B3E5-74ABB7C19538} = {5CED3889-AECF-A6CD-55DC-F680D3C18861}
|
||||
{101FFD12-17A4-4615-9438-F347BBF4CC85} = {5CED3889-AECF-A6CD-55DC-F680D3C18861}
|
||||
{AEDB3219-5E1D-4716-8DE2-F5F9391913A2} = {C734CEF7-A2AC-3076-84D8-694B7490AA9D}
|
||||
{427BE8BE-DA7B-FC74-412B-547671E05463} = {CDFA86FA-BBBA-4A5B-A833-3BE219E373E5}
|
||||
{C015BF35-6977-407B-8948-636A9C81C5BE} = {427BE8BE-DA7B-FC74-412B-547671E05463}
|
||||
{19A89F36-FD3A-448D-90D1-04A1B67BB255} = {1B4FBE3A-43F5-1B1E-2877-3036AC5431EF}
|
||||
{B27759CD-5A7D-43A4-A55C-FE1154DC4CC4} = {51D8F471-B8EB-AD1C-0E89-AA84C5D0C759}
|
||||
{BD23EEF8-9196-4E0F-BF33-E14E99D34C1B} = {51D8F471-B8EB-AD1C-0E89-AA84C5D0C759}
|
||||
{B52D6341-AAD9-43CB-82AF-2DBE39CBF1DB} = {51D8F471-B8EB-AD1C-0E89-AA84C5D0C759}
|
||||
{0DAACE48-4EA6-4DB7-8A5C-99B86BCB1E01} = {4B043475-1AFA-C467-FE09-A46D09CD6936}
|
||||
{A85AE27D-81ED-485A-BA4B-161B25BEB8A5} = {54BCCDE8-25E6-6FCB-4A9E-D5D2AF76D352}
|
||||
{D1B6353A-63F5-4DD9-90E6-42B2CFDF1DEA} = {CD4A4407-C3B0-422D-BB8C-2A810CED9938}
|
||||
{C4287034-6833-4505-A6EB-704A86392ECB} = {D1B6353A-63F5-4DD9-90E6-42B2CFDF1DEA}
|
||||
{490BCB11-314C-473C-9B85-A32164783507} = {C4287034-6833-4505-A6EB-704A86392ECB}
|
||||
{5B7BF918-E47F-4932-B5C5-E8C2C35890E4} = {C4287034-6833-4505-A6EB-704A86392ECB}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
75
booking.rest
75
booking.rest
@ -1,15 +1,12 @@
|
||||
|
||||
## uncommnet this line for use kubernetes ingress controller instead of Yarp
|
||||
//@api-gateway=https://booking-microservices.com
|
||||
# https://github.com/Huachao/vscode-restclient
|
||||
@api-gateway=https://localhost:5000
|
||||
@identity-api=http://localhost:6005
|
||||
@flight-api=http://localhost:5004
|
||||
@passenger-api=http://localhost:6012
|
||||
@booking-api=http://localhost:6010
|
||||
|
||||
@identity-api=https://localhost:5005
|
||||
@flight-api=https://localhost:5003
|
||||
@passenger-api=https://localhost:5012
|
||||
@booking-api=https://localhost:5010
|
||||
@contentType = application/json
|
||||
@flightid = "3c5c0000-97c6-fc34-2eb9-08db322230c9"
|
||||
@passengerId = "8c9c0000-97c6-fc34-2eb9-66db322230c9"
|
||||
@flightid = 1
|
||||
@passengerId = 1
|
||||
|
||||
################################# Identity API #################################
|
||||
|
||||
@ -21,7 +18,7 @@ GET {{identity-api}}
|
||||
|
||||
###
|
||||
# @name Authenticate
|
||||
POST {{api-gateway}}/identity/connect/token
|
||||
POST {{api-gateway}}/connect/token
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
grant_type=password
|
||||
@ -29,16 +26,14 @@ grant_type=password
|
||||
&client_secret=secret
|
||||
&username=samh
|
||||
&password=Admin@123456
|
||||
&scope=flight-api role
|
||||
|
||||
### change scope base on microservices scope (eg. passenger-api, ...)
|
||||
&scope=flight-api
|
||||
###
|
||||
|
||||
|
||||
|
||||
###
|
||||
# @name Register_New_User
|
||||
POST {{api-gateway}}/identity/api/v1/identity/register-user
|
||||
POST {{api-gateway}}/api/v1/identity/register-user
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -47,7 +42,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
"firstName": "John",
|
||||
"lastName": "Do",
|
||||
"username": "admin",
|
||||
"passportNumber": "41290000",
|
||||
"passportNumber": "412900000000",
|
||||
"email": "admin@admin.com",
|
||||
"password": "Admin@12345",
|
||||
"confirmPassword": "Admin@12345"
|
||||
@ -63,7 +58,7 @@ GET {{flight-api}}
|
||||
|
||||
###
|
||||
# @name Create_Seat
|
||||
Post {{api-gateway}}/flight/api/v1/flight/seat
|
||||
Post {{api-gateway}}/api/v1/flight/seat
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -72,20 +67,20 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
"seatNumber": "1255",
|
||||
"type": 1,
|
||||
"class": 1,
|
||||
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9"
|
||||
"flightId": 1
|
||||
}
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# @name Reserve_Seat
|
||||
Post {{api-gateway}}/flight/api/v1/flight/reserve-seat
|
||||
Post {{api-gateway}}/api/v1/flight/reserve-seat
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9",
|
||||
"flightId": 1,
|
||||
"seatNumber": "1255"
|
||||
}
|
||||
###
|
||||
@ -93,7 +88,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Get_Available_Seats
|
||||
GET {{api-gateway}}/flight/api/v1/flight/get-available-seats/{{flightid}}
|
||||
GET {{api-gateway}}/api/v1/flight/get-available-seats/{{flightid}}
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -102,7 +97,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Get_Flight_By_Id
|
||||
GET {{api-gateway}}/flight/api/v1/flight/{{flightid}}
|
||||
GET {{api-gateway}}/api/v1/flight/{{flightid}}
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -111,7 +106,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Get_Available_Flights
|
||||
GET {{api-gateway}}/flight/api/v1/flight/get-available-flights
|
||||
GET {{api-gateway}}/api/v1/flight/get-available-flights
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -120,18 +115,18 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Create_Flights
|
||||
POST {{api-gateway}}/flight/api/v1/flight
|
||||
POST {{api-gateway}}/api/v1/flight
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"flightNumber": "12BB",
|
||||
"aircraftId": "3c5c0000-97c6-fc34-fcd3-08db322230c8",
|
||||
"departureAirportId": "3c5c0000-97c6-fc34-a0cb-08db322230c8",
|
||||
"aircraftId": 1,
|
||||
"departureAirportId": 1,
|
||||
"departureDate": "2022-03-01T14:55:41.255Z",
|
||||
"arriveDate": "2022-03-01T14:55:41.255Z",
|
||||
"arriveAirportId": "3c5c0000-97c6-fc34-fc3c-08db322230c8",
|
||||
"arriveAirportId": 2,
|
||||
"durationMinutes": 120,
|
||||
"flightDate": "2022-03-01T14:55:41.255Z",
|
||||
"status": 1,
|
||||
@ -142,7 +137,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Update_Flights
|
||||
PUT {{api-gateway}}/flight/api/v1/flight
|
||||
PUT {{api-gateway}}/api/v1/flight
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -150,11 +145,11 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
{
|
||||
"id": 1,
|
||||
"flightNumber": "BD467",
|
||||
"aircraftId": "3c5c0000-97c6-fc34-fcd3-08db322230c8",
|
||||
"departureAirportId": "3c5c0000-97c6-fc34-a0cb-08db322230c8",
|
||||
"aircraftId": 1,
|
||||
"departureAirportId": 1,
|
||||
"departureDate": "2022-04-23T12:17:45.140Z",
|
||||
"arriveDate": "2022-04-23T12:17:45.140Z",
|
||||
"arriveAirportId": "3c5c0000-97c6-fc34-fc3c-08db322230c8",
|
||||
"arriveAirportId": 2,
|
||||
"durationMinutes": 120,
|
||||
"flightDate": "2022-04-23T12:17:45.140Z",
|
||||
"status": 4,
|
||||
@ -166,7 +161,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Delete_Flights
|
||||
DELETE {{api-gateway}}/flight/api/v1/flight/{{flightid}}
|
||||
DELETE {{api-gateway}}/api/v1/flight/{{flightid}}
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -175,7 +170,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Create_Airport
|
||||
POST {{api-gateway}}/flight/api/v1/flight/airport
|
||||
POST {{api-gateway}}/api/v1/flight/airport
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -191,7 +186,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Create_Aircraft
|
||||
POST {{api-gateway}}/flight/api/v1/flight/aircraft
|
||||
POST {{api-gateway}}/api/v1/flight/aircraft
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -214,13 +209,13 @@ GET {{passenger-api}}
|
||||
|
||||
###
|
||||
# @name Complete_Registration_Passenger
|
||||
POST {{api-gateway}}/passenger/api/v1/passenger/complete-registration
|
||||
POST {{api-gateway}}/api/v1/passenger/complete-registration
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"passportNumber": "41290000",
|
||||
"passportNumber": "412900000000",
|
||||
"passengerType": 1,
|
||||
"age": 30
|
||||
}
|
||||
@ -229,7 +224,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
###
|
||||
# @name Get_Passenger_By_Id
|
||||
GET {{api-gateway}}/passenger/api/v1/passenger/{{passengerId}}
|
||||
GET {{api-gateway}}/api/v1/passenger/{{passengerId}}
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
@ -246,14 +241,14 @@ GET {{booking-api}}
|
||||
|
||||
###
|
||||
# @name Create_Booking
|
||||
POST {{api-gateway}}/booking/api/v1/booking
|
||||
POST {{api-gateway}}/api/v1/booking
|
||||
accept: application/json
|
||||
Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"passengerId": "8c9c0000-97c6-fc34-2eb9-66db322230c9",
|
||||
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9",
|
||||
"passengerId": 8765596234940416,
|
||||
"flightId": 1,
|
||||
"description": "I want to fly to iran"
|
||||
}
|
||||
###
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
extends: ["@commitlint/config-conventional"],
|
||||
}
|
||||
0
current-version.txt
Normal file
0
current-version.txt
Normal file
@ -1,8 +0,0 @@
|
||||
# Dashboards
|
||||
|
||||
- [Introducing ASP.NET Core metrics and Grafana dashboards in .NET 8](https://devblogs.microsoft.com/dotnet/introducing-aspnetcore-metrics-and-grafana-dashboards-in-dotnet-8/)
|
||||
- [ASP.NET Core](https://grafana.com/grafana/dashboards/19924-asp-net-core/)
|
||||
- [ASP.NET Core Endpoint](https://grafana.com/grafana/dashboards/19925-asp-net-core-endpoint/)
|
||||
- [Node Exporter Quickstart and Dashboard](https://grafana.com/grafana/dashboards/13978-node-exporter-quickstart-and-dashboard/)
|
||||
- [PostgreSQL Exporter Quickstart and Dashboard](https://grafana.com/grafana/dashboards/14114-postgres-overview/)
|
||||
- [RabbitMQ-Overview](https://grafana.com/grafana/dashboards/10991-rabbitmq-overview/)
|
||||
@ -1,908 +0,0 @@
|
||||
{
|
||||
"__inputs": [
|
||||
{
|
||||
"name": "DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY",
|
||||
"label": "Managed_Prometheus_jamesnk-telemetry",
|
||||
"description": "",
|
||||
"type": "datasource",
|
||||
"pluginId": "prometheus",
|
||||
"pluginName": "Prometheus"
|
||||
}
|
||||
],
|
||||
"__elements": {},
|
||||
"__requires": [
|
||||
{
|
||||
"type": "grafana",
|
||||
"id": "grafana",
|
||||
"name": "Grafana",
|
||||
"version": "9.4.8"
|
||||
},
|
||||
{
|
||||
"type": "datasource",
|
||||
"id": "prometheus",
|
||||
"name": "Prometheus",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "stat",
|
||||
"name": "Stat",
|
||||
"version": ""
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "table",
|
||||
"name": "Table",
|
||||
"version": ""
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "timeseries",
|
||||
"name": "Time series",
|
||||
"version": ""
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"list": [
|
||||
{
|
||||
"builtIn": 1,
|
||||
"datasource": {
|
||||
"type": "grafana",
|
||||
"uid": "-- Grafana --"
|
||||
},
|
||||
"enable": true,
|
||||
"hide": true,
|
||||
"iconColor": "rgba(0, 211, 255, 1)",
|
||||
"name": "Annotations & Alerts",
|
||||
"target": {
|
||||
"limit": 100,
|
||||
"matchAny": false,
|
||||
"tags": [],
|
||||
"type": "dashboard"
|
||||
},
|
||||
"type": "dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"editable": true,
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"id": null,
|
||||
"links": [
|
||||
{
|
||||
"asDropdown": false,
|
||||
"icon": "dashboard",
|
||||
"includeVars": false,
|
||||
"keepTime": true,
|
||||
"tags": [],
|
||||
"targetBlank": false,
|
||||
"title": " ASP.NET Core",
|
||||
"tooltip": "",
|
||||
"type": "link",
|
||||
"url": "/d/KdDACDp4z/asp-net-core-metrics"
|
||||
}
|
||||
],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"fixedColor": "dark-green",
|
||||
"mode": "continuous-GrYlRd",
|
||||
"seriesBy": "max"
|
||||
},
|
||||
"custom": {
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"axisSoftMin": 0,
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 50,
|
||||
"gradientMode": "opacity",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "smooth",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "never",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "s"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"__systemRef": "hideSeriesFrom",
|
||||
"matcher": {
|
||||
"id": "byNames",
|
||||
"options": {
|
||||
"mode": "exclude",
|
||||
"names": [
|
||||
"p50"
|
||||
],
|
||||
"prefix": "All except:",
|
||||
"readOnly": true
|
||||
}
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.hideFrom",
|
||||
"value": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 0
|
||||
},
|
||||
"id": 40,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [
|
||||
"lastNotNull",
|
||||
"min",
|
||||
"max"
|
||||
],
|
||||
"displayMode": "table",
|
||||
"placement": "right",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "multi",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "histogram_quantile(0.50, sum(rate(http_server_request_duration_s_bucket{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m])) by (le))",
|
||||
"legendFormat": "p50",
|
||||
"range": true,
|
||||
"refId": "p50"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "histogram_quantile(0.75, sum(rate(http_server_request_duration_s_bucket{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m])) by (le))",
|
||||
"hide": false,
|
||||
"legendFormat": "p75",
|
||||
"range": true,
|
||||
"refId": "p75"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "histogram_quantile(0.90, sum(rate(http_server_request_duration_s_bucket{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m])) by (le))",
|
||||
"hide": false,
|
||||
"legendFormat": "p90",
|
||||
"range": true,
|
||||
"refId": "p90"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "histogram_quantile(0.95, sum(rate(http_server_request_duration_s_bucket{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m])) by (le))",
|
||||
"hide": false,
|
||||
"legendFormat": "p95",
|
||||
"range": true,
|
||||
"refId": "p95"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "histogram_quantile(0.98, sum(rate(http_server_request_duration_s_bucket{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m])) by (le))",
|
||||
"hide": false,
|
||||
"legendFormat": "p98",
|
||||
"range": true,
|
||||
"refId": "p98"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "histogram_quantile(0.99, sum(rate(http_server_request_duration_s_bucket{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m])) by (le))",
|
||||
"hide": false,
|
||||
"legendFormat": "p99",
|
||||
"range": true,
|
||||
"refId": "p99"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "histogram_quantile(0.999, sum(rate(http_server_request_duration_s_bucket{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m])) by (le))",
|
||||
"hide": false,
|
||||
"legendFormat": "p99.9",
|
||||
"range": true,
|
||||
"refId": "p99.9"
|
||||
}
|
||||
],
|
||||
"title": "Requests Duration - $method $route",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "palette-classic",
|
||||
"seriesBy": "max"
|
||||
},
|
||||
"custom": {
|
||||
"axisCenteredZero": false,
|
||||
"axisColorMode": "text",
|
||||
"axisLabel": "",
|
||||
"axisPlacement": "auto",
|
||||
"barAlignment": 0,
|
||||
"drawStyle": "line",
|
||||
"fillOpacity": 50,
|
||||
"gradientMode": "opacity",
|
||||
"hideFrom": {
|
||||
"legend": false,
|
||||
"tooltip": false,
|
||||
"viz": false
|
||||
},
|
||||
"lineInterpolation": "smooth",
|
||||
"lineWidth": 1,
|
||||
"pointSize": 5,
|
||||
"scaleDistribution": {
|
||||
"type": "linear"
|
||||
},
|
||||
"showPoints": "never",
|
||||
"spanNulls": false,
|
||||
"stacking": {
|
||||
"group": "A",
|
||||
"mode": "none"
|
||||
},
|
||||
"thresholdsStyle": {
|
||||
"mode": "off"
|
||||
}
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"unit": "percentunit"
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "All"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "dark-orange",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "4XX"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "yellow",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "5XX"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"fixedColor": "dark-red",
|
||||
"mode": "fixed"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 9,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 0
|
||||
},
|
||||
"id": 46,
|
||||
"options": {
|
||||
"legend": {
|
||||
"calcs": [
|
||||
"lastNotNull",
|
||||
"min",
|
||||
"max"
|
||||
],
|
||||
"displayMode": "table",
|
||||
"placement": "right",
|
||||
"showLegend": true
|
||||
},
|
||||
"tooltip": {
|
||||
"mode": "multi",
|
||||
"sort": "none"
|
||||
}
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "sum(rate(http_server_request_duration_s_count{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\", status_code=~\"4..|5..\"}[5m]) or vector(0)) / sum(rate(http_server_request_duration_s_count{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m]))",
|
||||
"legendFormat": "All",
|
||||
"range": true,
|
||||
"refId": "All"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "sum(rate(http_server_request_duration_s_count{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\", status_code=~\"4..\"}[5m]) or vector(0)) / sum(rate(http_server_request_duration_s_count{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m]))",
|
||||
"hide": false,
|
||||
"legendFormat": "4XX",
|
||||
"range": true,
|
||||
"refId": "4XX"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "sum(rate(http_server_request_duration_s_count{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\", status_code=~\"5..\"}[5m]) or vector(0)) / sum(rate(http_server_request_duration_s_count{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[5m]))",
|
||||
"hide": false,
|
||||
"legendFormat": "5XX",
|
||||
"range": true,
|
||||
"refId": "5XX"
|
||||
}
|
||||
],
|
||||
"title": "Errors Rate - $method $route",
|
||||
"type": "timeseries"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"mode": "thresholds"
|
||||
},
|
||||
"custom": {
|
||||
"align": "auto",
|
||||
"cellOptions": {
|
||||
"type": "auto"
|
||||
},
|
||||
"inspect": false
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Requests"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "custom.width",
|
||||
"value": 300
|
||||
},
|
||||
{
|
||||
"id": "custom.cellOptions",
|
||||
"value": {
|
||||
"mode": "gradient",
|
||||
"type": "gauge"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "color",
|
||||
"value": {
|
||||
"mode": "continuous-YlRd"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"matcher": {
|
||||
"id": "byName",
|
||||
"options": "Route"
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"id": "links",
|
||||
"value": [
|
||||
{
|
||||
"title": "",
|
||||
"url": "/d/NagEsjE4z/asp-net-core-endpoint-details?var-route=${__data.fields.Route}&var-method=${__data.fields.Method}&${__url_time_range}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 8,
|
||||
"w": 12,
|
||||
"x": 0,
|
||||
"y": 9
|
||||
},
|
||||
"hideTimeOverride": false,
|
||||
"id": 44,
|
||||
"options": {
|
||||
"footer": {
|
||||
"countRows": false,
|
||||
"fields": "",
|
||||
"reducer": [
|
||||
"sum"
|
||||
],
|
||||
"show": false
|
||||
},
|
||||
"showHeader": true,
|
||||
"sortBy": [
|
||||
{
|
||||
"desc": true,
|
||||
"displayName": "Value"
|
||||
}
|
||||
]
|
||||
},
|
||||
"pluginVersion": "9.4.8",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"exemplar": false,
|
||||
"expr": "sum by (exception_name) (\r\n max_over_time(http_server_request_duration_s_count{route=\"$route\", method=\"$method\", exception_name!=\"\"}[$__rate_interval])\r\n)",
|
||||
"format": "table",
|
||||
"instant": true,
|
||||
"interval": "",
|
||||
"legendFormat": "{{route}}",
|
||||
"range": false,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Unhandled Exceptions",
|
||||
"transformations": [
|
||||
{
|
||||
"id": "organize",
|
||||
"options": {
|
||||
"excludeByName": {
|
||||
"Time": true,
|
||||
"method": false
|
||||
},
|
||||
"indexByName": {
|
||||
"Time": 0,
|
||||
"Value": 2,
|
||||
"exception_name": 1
|
||||
},
|
||||
"renameByName": {
|
||||
"Value": "Requests",
|
||||
"exception_name": "Exception",
|
||||
"method": "Method",
|
||||
"route": "Route"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"type": "table"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"fixedColor": "blue",
|
||||
"mode": "fixed"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 12,
|
||||
"x": 12,
|
||||
"y": 9
|
||||
},
|
||||
"id": 42,
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"max"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "value_and_name"
|
||||
},
|
||||
"pluginVersion": "9.4.8",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "sum by (status_code) (\r\n max_over_time(http_server_request_duration_s_count{route=\"$route\", method=\"$method\"}[$__rate_interval])\r\n )",
|
||||
"legendFormat": "Status {{status_code}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Requests HTTP Status Code",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"fixedColor": "green",
|
||||
"mode": "fixed"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 12,
|
||||
"y": 13
|
||||
},
|
||||
"id": 48,
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"max"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "value_and_name"
|
||||
},
|
||||
"pluginVersion": "9.4.8",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "sum by (scheme) (\r\n max_over_time(http_server_request_duration_s_count{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[$__rate_interval])\r\n )",
|
||||
"legendFormat": "{{scheme}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Requests Secured",
|
||||
"type": "stat"
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"description": "",
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"color": {
|
||||
"fixedColor": "purple",
|
||||
"mode": "fixed"
|
||||
},
|
||||
"mappings": [],
|
||||
"thresholds": {
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
"value": 80
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
"gridPos": {
|
||||
"h": 4,
|
||||
"w": 6,
|
||||
"x": 18,
|
||||
"y": 13
|
||||
},
|
||||
"id": 50,
|
||||
"options": {
|
||||
"colorMode": "background",
|
||||
"graphMode": "area",
|
||||
"justifyMode": "auto",
|
||||
"orientation": "auto",
|
||||
"reduceOptions": {
|
||||
"calcs": [
|
||||
"max"
|
||||
],
|
||||
"fields": "",
|
||||
"values": false
|
||||
},
|
||||
"textMode": "value_and_name"
|
||||
},
|
||||
"pluginVersion": "9.4.8",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"editorMode": "code",
|
||||
"expr": "sum by (protocol) (\r\n max_over_time(http_server_request_duration_s_count{job=\"$job\", instance=\"$instance\", route=\"$route\", method=\"$method\"}[$__rate_interval])\r\n )",
|
||||
"legendFormat": "{{protocol}}",
|
||||
"range": true,
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "Requests HTTP Protocol",
|
||||
"type": "stat"
|
||||
}
|
||||
],
|
||||
"refresh": "",
|
||||
"revision": 1,
|
||||
"schemaVersion": 38,
|
||||
"style": "dark",
|
||||
"tags": [
|
||||
"dotnet",
|
||||
"prometheus",
|
||||
"aspnetcore"
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"current": {},
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"definition": "label_values(http_server_current_requests, job)",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Job",
|
||||
"multi": false,
|
||||
"name": "job",
|
||||
"options": [],
|
||||
"query": {
|
||||
"query": "label_values(http_server_current_requests, job)",
|
||||
"refId": "StandardVariableQuery"
|
||||
},
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 1,
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"current": {},
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"definition": "label_values(http_server_current_requests{job=~\"$job\"}, instance)",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Instance",
|
||||
"multi": false,
|
||||
"name": "instance",
|
||||
"options": [],
|
||||
"query": {
|
||||
"query": "label_values(http_server_current_requests{job=~\"$job\"}, instance)",
|
||||
"refId": "StandardVariableQuery"
|
||||
},
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 1,
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"current": {},
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"definition": "label_values(http_server_request_duration_s_count, route)",
|
||||
"description": "Route",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Route",
|
||||
"multi": false,
|
||||
"name": "route",
|
||||
"options": [],
|
||||
"query": {
|
||||
"query": "label_values(http_server_request_duration_s_count, route)",
|
||||
"refId": "StandardVariableQuery"
|
||||
},
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 1,
|
||||
"type": "query"
|
||||
},
|
||||
{
|
||||
"current": {},
|
||||
"datasource": {
|
||||
"type": "prometheus",
|
||||
"uid": "${DS_MANAGED_PROMETHEUS_JAMESNK-TELEMETRY}"
|
||||
},
|
||||
"definition": "label_values(http_server_request_duration_s_count{route=~\"$route\"}, method)",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": "Method",
|
||||
"multi": false,
|
||||
"name": "method",
|
||||
"options": [],
|
||||
"query": {
|
||||
"query": "label_values(http_server_request_duration_s_count{route=~\"$route\"}, method)",
|
||||
"refId": "StandardVariableQuery"
|
||||
},
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"skipUrlSync": false,
|
||||
"sort": 1,
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-30m",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "ASP.NET Core Endpoint",
|
||||
"uid": "NagEsjE4z",
|
||||
"version": 10,
|
||||
"weekStart": ""
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,892 +0,0 @@
|
||||
{
|
||||
"__inputs": [],
|
||||
"__requires": [
|
||||
{
|
||||
"type": "grafana",
|
||||
"id": "grafana",
|
||||
"name": "Grafana",
|
||||
"version": "7.4.3"
|
||||
},
|
||||
{
|
||||
"type": "panel",
|
||||
"id": "graph",
|
||||
"name": "Graph",
|
||||
"version": ""
|
||||
},
|
||||
{
|
||||
"type": "datasource",
|
||||
"id": "prometheus",
|
||||
"name": "Prometheus",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
],
|
||||
"annotations": {
|
||||
"list": []
|
||||
},
|
||||
"editable": false,
|
||||
"gnetId": 13978,
|
||||
"graphTooltip": 0,
|
||||
"hideControls": false,
|
||||
"id": null,
|
||||
"links": [],
|
||||
"refresh": "",
|
||||
"rows": [
|
||||
{
|
||||
"collapse": false,
|
||||
"collapsed": false,
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {},
|
||||
"id": 2,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sideWidth": null,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": null,
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"span": 6,
|
||||
"stack": true,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "(\n (1 - rate(node_cpu_seconds_total{job=\"node\", mode=\"idle\", instance=\"$instance\"}[$__interval]))\n/ ignoring(cpu) group_left\n count without (cpu)( node_cpu_seconds_total{job=\"node\", mode=\"idle\", instance=\"$instance\"})\n)\n",
|
||||
"format": "time_series",
|
||||
"interval": "1m",
|
||||
"intervalFactor": 5,
|
||||
"legendFormat": "{{cpu}}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "CPU Usage",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "percentunit",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "percentunit",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": 1,
|
||||
"min": 0,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"fill": 0,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {},
|
||||
"id": 3,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sideWidth": null,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": null,
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"span": 6,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "node_load1{job=\"node\", instance=\"$instance\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "1m load average",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "node_load5{job=\"node\", instance=\"$instance\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "5m load average",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "node_load15{job=\"node\", instance=\"$instance\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "15m load average",
|
||||
"refId": "C"
|
||||
},
|
||||
{
|
||||
"expr": "count(node_cpu_seconds_total{job=\"node\", instance=\"$instance\", mode=\"idle\"})",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "logical cores",
|
||||
"refId": "D"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Load Average",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "short",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"repeat": null,
|
||||
"repeatIteration": null,
|
||||
"repeatRowId": null,
|
||||
"showTitle": false,
|
||||
"title": "Dashboard Row",
|
||||
"titleSize": "h6",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"collapse": false,
|
||||
"collapsed": false,
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {},
|
||||
"id": 4,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sideWidth": null,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": null,
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"span": 9,
|
||||
"stack": true,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "(\n node_memory_MemTotal_bytes{job=\"node\", instance=\"$instance\"}\n-\n node_memory_MemFree_bytes{job=\"node\", instance=\"$instance\"}\n-\n node_memory_Buffers_bytes{job=\"node\", instance=\"$instance\"}\n-\n node_memory_Cached_bytes{job=\"node\", instance=\"$instance\"}\n)\n",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "memory used",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "node_memory_Buffers_bytes{job=\"node\", instance=\"$instance\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "memory buffers",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "node_memory_Cached_bytes{job=\"node\", instance=\"$instance\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "memory cached",
|
||||
"refId": "C"
|
||||
},
|
||||
{
|
||||
"expr": "node_memory_MemFree_bytes{job=\"node\", instance=\"$instance\"}",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "memory free",
|
||||
"refId": "D"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Memory Usage",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cacheTimeout": null,
|
||||
"colorBackground": false,
|
||||
"colorValue": false,
|
||||
"colors": [
|
||||
"rgba(50, 172, 45, 0.97)",
|
||||
"rgba(237, 129, 40, 0.89)",
|
||||
"rgba(245, 54, 54, 0.9)"
|
||||
],
|
||||
"datasource": "$datasource",
|
||||
"format": "percent",
|
||||
"gauge": {
|
||||
"maxValue": 100,
|
||||
"minValue": 0,
|
||||
"show": true,
|
||||
"thresholdLabels": false,
|
||||
"thresholdMarkers": true
|
||||
},
|
||||
"gridPos": {},
|
||||
"id": 5,
|
||||
"interval": null,
|
||||
"links": [],
|
||||
"mappingType": 1,
|
||||
"mappingTypes": [
|
||||
{
|
||||
"name": "value to text",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"name": "range to text",
|
||||
"value": 2
|
||||
}
|
||||
],
|
||||
"maxDataPoints": 100,
|
||||
"nullPointMode": "connected",
|
||||
"nullText": null,
|
||||
"postfix": "",
|
||||
"postfixFontSize": "50%",
|
||||
"prefix": "",
|
||||
"prefixFontSize": "50%",
|
||||
"rangeMaps": [
|
||||
{
|
||||
"from": "null",
|
||||
"text": "N/A",
|
||||
"to": "null"
|
||||
}
|
||||
],
|
||||
"span": 3,
|
||||
"sparkline": {
|
||||
"fillColor": "rgba(31, 118, 189, 0.18)",
|
||||
"full": false,
|
||||
"lineColor": "rgb(31, 120, 193)",
|
||||
"show": false
|
||||
},
|
||||
"tableColumn": "",
|
||||
"targets": [
|
||||
{
|
||||
"expr": "100 -\n(\n avg(node_memory_MemAvailable_bytes{job=\"node\", instance=\"$instance\"})\n/\n avg(node_memory_MemTotal_bytes{job=\"node\", instance=\"$instance\"})\n* 100\n)\n",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": "80, 90",
|
||||
"title": "Memory Usage",
|
||||
"type": "singlestat",
|
||||
"valueFontSize": "80%",
|
||||
"valueMaps": [
|
||||
{
|
||||
"op": "=",
|
||||
"text": "N/A",
|
||||
"value": "null"
|
||||
}
|
||||
],
|
||||
"valueName": "current"
|
||||
}
|
||||
],
|
||||
"repeat": null,
|
||||
"repeatIteration": null,
|
||||
"repeatRowId": null,
|
||||
"showTitle": false,
|
||||
"title": "Dashboard Row",
|
||||
"titleSize": "h6",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"collapse": false,
|
||||
"collapsed": false,
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"fill": 0,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {},
|
||||
"id": 6,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sideWidth": null,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": null,
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "/ read| written/",
|
||||
"yaxis": 1
|
||||
},
|
||||
{
|
||||
"alias": "/ io time/",
|
||||
"yaxis": 2
|
||||
}
|
||||
],
|
||||
"spaceLength": 10,
|
||||
"span": 6,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "rate(node_disk_read_bytes_total{job=\"node\", instance=\"$instance\", device!=\"\"}[$__interval])",
|
||||
"format": "time_series",
|
||||
"interval": "1m",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{device}} read",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "rate(node_disk_written_bytes_total{job=\"node\", instance=\"$instance\", device!=\"\"}[$__interval])",
|
||||
"format": "time_series",
|
||||
"interval": "1m",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{device}} written",
|
||||
"refId": "B"
|
||||
},
|
||||
{
|
||||
"expr": "rate(node_disk_io_time_seconds_total{job=\"node\", instance=\"$instance\", device!=\"\"}[$__interval])",
|
||||
"format": "time_series",
|
||||
"interval": "1m",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{device}} io time",
|
||||
"refId": "C"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Disk I/O",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "s",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"fill": 1,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {},
|
||||
"id": 7,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sideWidth": null,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": null,
|
||||
"seriesOverrides": [
|
||||
{
|
||||
"alias": "used",
|
||||
"color": "#E0B400"
|
||||
},
|
||||
{
|
||||
"alias": "available",
|
||||
"color": "#73BF69"
|
||||
}
|
||||
],
|
||||
"spaceLength": 10,
|
||||
"span": 6,
|
||||
"stack": true,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sum(\n max by (device) (\n node_filesystem_size_bytes{job=\"node\", instance=\"$instance\", fstype!=\"\"}\n -\n node_filesystem_avail_bytes{job=\"node\", instance=\"$instance\", fstype!=\"\"}\n )\n)\n",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "used",
|
||||
"refId": "A"
|
||||
},
|
||||
{
|
||||
"expr": "sum(\n max by (device) (\n node_filesystem_avail_bytes{job=\"node\", instance=\"$instance\", fstype!=\"\"}\n )\n)\n",
|
||||
"format": "time_series",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "available",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Disk Space Usage",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"repeat": null,
|
||||
"repeatIteration": null,
|
||||
"repeatRowId": null,
|
||||
"showTitle": false,
|
||||
"title": "Dashboard Row",
|
||||
"titleSize": "h6",
|
||||
"type": "row"
|
||||
},
|
||||
{
|
||||
"collapse": false,
|
||||
"collapsed": false,
|
||||
"panels": [
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"fill": 0,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {},
|
||||
"id": 8,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sideWidth": null,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": null,
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"span": 6,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "rate(node_network_receive_bytes_total{job=\"node\", instance=\"$instance\", device!=\"lo\"}[$__interval])",
|
||||
"format": "time_series",
|
||||
"interval": "1m",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{device}}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Network Received",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"aliasColors": {},
|
||||
"bars": false,
|
||||
"dashLength": 10,
|
||||
"dashes": false,
|
||||
"datasource": "$datasource",
|
||||
"fill": 0,
|
||||
"fillGradient": 0,
|
||||
"gridPos": {},
|
||||
"id": 9,
|
||||
"legend": {
|
||||
"alignAsTable": false,
|
||||
"avg": false,
|
||||
"current": false,
|
||||
"max": false,
|
||||
"min": false,
|
||||
"rightSide": false,
|
||||
"show": true,
|
||||
"sideWidth": null,
|
||||
"total": false,
|
||||
"values": false
|
||||
},
|
||||
"lines": true,
|
||||
"linewidth": 1,
|
||||
"links": [],
|
||||
"nullPointMode": "null",
|
||||
"percentage": false,
|
||||
"pointradius": 5,
|
||||
"points": false,
|
||||
"renderer": "flot",
|
||||
"repeat": null,
|
||||
"seriesOverrides": [],
|
||||
"spaceLength": 10,
|
||||
"span": 6,
|
||||
"stack": false,
|
||||
"steppedLine": false,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "rate(node_network_transmit_bytes_total{job=\"node\", instance=\"$instance\", device!=\"lo\"}[$__interval])",
|
||||
"format": "time_series",
|
||||
"interval": "1m",
|
||||
"intervalFactor": 2,
|
||||
"legendFormat": "{{device}}",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"thresholds": [],
|
||||
"timeFrom": null,
|
||||
"timeShift": null,
|
||||
"title": "Network Transmitted",
|
||||
"tooltip": {
|
||||
"shared": true,
|
||||
"sort": 0,
|
||||
"value_type": "individual"
|
||||
},
|
||||
"type": "graph",
|
||||
"xaxis": {
|
||||
"buckets": null,
|
||||
"mode": "time",
|
||||
"name": null,
|
||||
"show": true,
|
||||
"values": []
|
||||
},
|
||||
"yaxes": [
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
},
|
||||
{
|
||||
"format": "bytes",
|
||||
"label": null,
|
||||
"logBase": 1,
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"repeat": null,
|
||||
"repeatIteration": null,
|
||||
"repeatRowId": null,
|
||||
"showTitle": false,
|
||||
"title": "Dashboard Row",
|
||||
"titleSize": "h6",
|
||||
"type": "row"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 14,
|
||||
"style": "dark",
|
||||
"tags": [],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"current": {
|
||||
"text": "Prometheus",
|
||||
"value": "Prometheus"
|
||||
},
|
||||
"hide": 0,
|
||||
"label": null,
|
||||
"name": "datasource",
|
||||
"options": [],
|
||||
"query": "prometheus",
|
||||
"refresh": 1,
|
||||
"regex": "",
|
||||
"type": "datasource"
|
||||
},
|
||||
{
|
||||
"allValue": null,
|
||||
"current": {},
|
||||
"datasource": "$datasource",
|
||||
"hide": 0,
|
||||
"includeAll": false,
|
||||
"label": null,
|
||||
"multi": false,
|
||||
"name": "instance",
|
||||
"options": [],
|
||||
"query": "label_values(node_exporter_build_info{job=\"node\"}, instance)",
|
||||
"refresh": 2,
|
||||
"regex": "",
|
||||
"sort": 0,
|
||||
"tagValuesQuery": "",
|
||||
"tags": [],
|
||||
"tagsQuery": "",
|
||||
"type": "query",
|
||||
"useTags": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": [
|
||||
"5s",
|
||||
"10s",
|
||||
"30s",
|
||||
"1m",
|
||||
"5m",
|
||||
"15m",
|
||||
"30m",
|
||||
"1h",
|
||||
"2h",
|
||||
"1d"
|
||||
],
|
||||
"time_options": [
|
||||
"5m",
|
||||
"15m",
|
||||
"1h",
|
||||
"6h",
|
||||
"12h",
|
||||
"24h",
|
||||
"2d",
|
||||
"7d",
|
||||
"30d"
|
||||
]
|
||||
},
|
||||
"timezone": "browser",
|
||||
"title": "Node Exporter Quickstart and Dashboard",
|
||||
"version": 0,
|
||||
"description": "A quickstart to setup Prometheus Node Exporter with preconfigured dashboards, alerting rules, and recording rules."
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,14 +0,0 @@
|
||||
# https://grafana.com/docs/grafana/latest/administration/provisioning/#dashboards
|
||||
apiVersion: 1
|
||||
|
||||
providers:
|
||||
- name: "default"
|
||||
orgId: 1
|
||||
folder: ""
|
||||
type: file
|
||||
disableDeletion: false
|
||||
editable: true
|
||||
allowUiUpdates: true
|
||||
updateIntervalSeconds: 5 # how often Grafana will scan for changed dashboards
|
||||
options:
|
||||
path: /var/lib/grafana/dashboards # path to dashboards on disk
|
||||
@ -1,88 +0,0 @@
|
||||
# https://grafana.com/docs/grafana/latest/administration/provisioning/
|
||||
# https://github.com/grafana/tempo/blob/main/example/docker-compose/shared/grafana-datasources.yaml
|
||||
# https://github.com/grafana/intro-to-mltp/blob/main/grafana/provisioning/datasources/datasources.yaml
|
||||
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
# https://github.com/grafana/tempo/blob/main/example/docker-compose/shared/grafana-datasources.yaml
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
typeName: Prometheus
|
||||
uid: prometheus-uid
|
||||
access: proxy
|
||||
orgId: 1
|
||||
url: http://prometheus:9090
|
||||
basicAuth: false
|
||||
isDefault: true
|
||||
readOnly: false
|
||||
user: ''
|
||||
database: ''
|
||||
version: 1
|
||||
editable: false
|
||||
jsonData:
|
||||
httpMethod: GET
|
||||
|
||||
- name: Jaeger
|
||||
type: jaeger
|
||||
access: proxy
|
||||
url: http://jaeger-all-in-one:16686
|
||||
editable: false
|
||||
uid: jaeger-uid
|
||||
|
||||
- name: Zipkin
|
||||
type: zipkin
|
||||
access: proxy
|
||||
url: http://zipkin-all-in-one:9411
|
||||
editable: false
|
||||
uid: zipkin-uid
|
||||
|
||||
# https://github.com/grafana/tempo/blob/main/example/docker-compose/shared/grafana-datasources.yaml
|
||||
- name: Tempo
|
||||
type: tempo
|
||||
access: proxy
|
||||
orgId: 1
|
||||
url: http://tempo:3200
|
||||
basicAuth: false
|
||||
isDefault: false
|
||||
version: 1
|
||||
editable: false
|
||||
apiVersion: 1
|
||||
uid: tempo-uid
|
||||
jsonData:
|
||||
httpMethod: GET
|
||||
serviceMap:
|
||||
datasourceUid: prometheus-uid
|
||||
streamingEnabled:
|
||||
search: true
|
||||
|
||||
#https://github.com/grafana/intro-to-mltp/blob/main/grafana/provisioning/datasources/datasources.yaml
|
||||
- name: Loki
|
||||
type: loki
|
||||
access: proxy
|
||||
uid: loki-uid
|
||||
url: http://loki:3100
|
||||
user: ''
|
||||
database: ''
|
||||
readOnly: false
|
||||
jsonData:
|
||||
derivedFields:
|
||||
- datasourceUid: tempo-uid
|
||||
matcherRegex: "^.*?traceI[d|D]=(\\w+).*$"
|
||||
name: traceId
|
||||
url: '$${__value.raw}'
|
||||
|
||||
- name: Kibana
|
||||
type: elasticsearch
|
||||
url: http://elasticsearch:9200
|
||||
access: proxy
|
||||
isDefault: false
|
||||
uid: kibana-uid
|
||||
jsonData:
|
||||
esVersion: 7
|
||||
timeField: "@timestamp"
|
||||
maxConcurrentShardRequests: 256
|
||||
interval: Daily
|
||||
logMessageField: "message" # Optional: Field for log messages
|
||||
logLevelField: "level" # Optional: Field for log levels
|
||||
editable: true
|
||||
@ -1,44 +0,0 @@
|
||||
# https://grafana.com/docs/loki/latest/configure/examples/configuration-examples/
|
||||
# https://github.com/grafana/loki/issues/2018#issuecomment-970789233
|
||||
# https://grafana.com/docs/opentelemetry/collector/send-logs-to-loki/
|
||||
# https://github.com/grafana/loki/blob/main/examples/getting-started/loki-config.yaml
|
||||
# https://github.com/grafana/loki/blob/main/cmd/loki/loki-local-config.yaml
|
||||
# https://grafana.com/docs/loki/latest/configure/examples/configuration-examples/#1-local-configuration-exampleyaml
|
||||
|
||||
---
|
||||
# https://grafana.com/docs/loki/latest/configure/examples/configuration-examples/#1-local-configuration-exampleyaml
|
||||
auth_enabled: false
|
||||
|
||||
# This is a complete configuration to deploy Loki backed by the filesystem.
|
||||
# The index will be shipped to the storage via tsdb-shipper.
|
||||
server:
|
||||
http_listen_port: 3100
|
||||
|
||||
common:
|
||||
ring:
|
||||
instance_addr: 127.0.0.1
|
||||
kvstore:
|
||||
store: inmemory
|
||||
replication_factor: 1
|
||||
path_prefix: /tmp/loki
|
||||
|
||||
schema_config:
|
||||
configs:
|
||||
- from: 2020-05-15
|
||||
store: tsdb
|
||||
object_store: filesystem
|
||||
schema: v13
|
||||
index:
|
||||
prefix: index_
|
||||
period: 24h
|
||||
|
||||
storage_config:
|
||||
filesystem:
|
||||
directory: /tmp/loki/chunks
|
||||
|
||||
# https://grafana.com/docs/loki/latest/send-data/otel/
|
||||
# https://grafana.com/docs/loki/latest/send-data/otel/#changing-the-default-mapping-of-otlp-to-loki-format
|
||||
limits_config:
|
||||
# this attribute should be `true` when we use `otlphttp/loki`, but if we want to use `loki component` from `opentelemetry-collector-contrib` it should be false.
|
||||
allow_structured_metadata: true
|
||||
|
||||
@ -1,131 +0,0 @@
|
||||
# ref: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/examples/demo/otel-collector-config.yaml
|
||||
# https://opentelemetry.io/docs/collector/configuration/
|
||||
# https://opentelemetry.io/docs/collector/architecture/
|
||||
# https://betterstack.com/community/guides/observability/opentelemetry-collector/
|
||||
# https://signoz.io/blog/opentelemetry-collector-complete-guide/
|
||||
|
||||
# This configuration sets up an OpenTelemetry Collector that receives trace data via the OTLP protocol over HTTP on port 4318, applies batch processing, and then exports the processed traces
|
||||
# to exporter components like `Jaeger` endpoint located at `jaeger-all-in-one:4317`. It also includes a health_check extension for monitoring the collector's status.
|
||||
|
||||
# Receivers in the OpenTelemetry Collector are components that collect telemetry data (traces, metrics, and logs) from various sources, such as instrumented applications or agents.
|
||||
# They act as entry points, converting incoming data into OpenTelemetry's internal format for processing and export.
|
||||
# https://betterstack.com/community/guides/observability/opentelemetry-collector/#exploring-the-opentelemetry-collector-components
|
||||
# https://opentelemetry.io/docs/collector/architecture/#receivers
|
||||
# https://github.com/open-telemetry/opentelemetry-collector/blob/main/receiver/README.md
|
||||
# https://opentelemetry.io/docs/collector/configuration/#receivers
|
||||
receivers:
|
||||
# supported receivers
|
||||
# https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/receiver
|
||||
# instead of specifying details explicitly we can just use `otlp` and it uses both grpc and http
|
||||
otlp:
|
||||
protocols:
|
||||
grpc:
|
||||
endpoint: 0.0.0.0:4317
|
||||
http:
|
||||
endpoint: 0.0.0.0:4318
|
||||
# prometheus:
|
||||
# config:
|
||||
# scrape_configs:
|
||||
# - job_name: 'node-exporter'
|
||||
# scrape_interval: 10s
|
||||
# static_configs:
|
||||
# - targets: [ 'node-exporter:9100' ]
|
||||
|
||||
|
||||
# Processors in the OpenTelemetry Collector modify and enhance telemetry data by filtering, transforming, enriching, or batching it to prepare it for export.
|
||||
# https://github.com/open-telemetry/opentelemetry-collector/tree/main/processor
|
||||
processors:
|
||||
batch: # Batches logs for better performance
|
||||
|
||||
# - Exporters in the OpenTelemetry Collector send processed telemetry data to backend systems like observability platforms, databases, or cloud services for storage, visualization, and analysis.
|
||||
# - The `key` follows the `type/name` format, where `type` specifies the exporter `type` (e.g., otlp, kafka, prometheus), and `name` (optional) can be appended to provide a unique name for multiple instance of the same type
|
||||
# https://betterstack.com/community/guides/observability/opentelemetry-collector/#exploring-the-opentelemetry-collector-components
|
||||
# https://opentelemetry.io/docs/collector/architecture/#exporters
|
||||
# https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter
|
||||
# https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter
|
||||
# https://opentelemetry.io/docs/collector/configuration/#exporters
|
||||
exporters:
|
||||
|
||||
# valid values: [prometheusremotewrite zipkin otlphttp file kafka prometheus debug nop otlp opencensus]
|
||||
|
||||
# Prometheus exporter metrics
|
||||
prometheus:
|
||||
endpoint: "0.0.0.0:8889"
|
||||
|
||||
prometheusremotewrite:
|
||||
endpoint: "http://prometheus:9090/api/v1/write"
|
||||
|
||||
# https://grafana.com/docs/loki/latest/send-data/otel/
|
||||
# https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/exporter/lokiexporter/README.md
|
||||
otlphttp/loki:
|
||||
endpoint: "http://loki:3100/otlp"
|
||||
tls:
|
||||
insecure: true
|
||||
|
||||
# # we can also use `loki component` from `opentelemetry-collector-contrib` if we don't want to use builtin `otlphttp` exporter type and `http://loki:3100/otlp` loki endpoint
|
||||
# loki:
|
||||
# endpoint: "http://loki:3100/loki/api/v1/push"
|
||||
# tls:
|
||||
# insecure: true
|
||||
|
||||
debug:
|
||||
|
||||
# https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/elasticsearchexporter
|
||||
# using `elasticsearch` from `opentelemetry-collector-contrib` components because it doesn't exist in `opentelemetry-collector`
|
||||
elasticsearch:
|
||||
endpoint: "http://elasticsearch:9200"
|
||||
|
||||
zipkin:
|
||||
endpoint: "http://zipkin-all-in-one:9411/api/v2/spans"
|
||||
format: proto
|
||||
|
||||
# export collected telemetry traces to jaeger OTLP grpc port, we can send data to other available endpoints and ports on jaeger as well
|
||||
otlp/jaeger:
|
||||
endpoint: "http://jaeger-all-in-one:4317"
|
||||
tls:
|
||||
insecure: true
|
||||
|
||||
otlp/tempo:
|
||||
endpoint: "http://tempo:4317"
|
||||
tls:
|
||||
insecure: true
|
||||
|
||||
# seq-otlp:
|
||||
# endpoint: "http://seq:5341/ingest/otlp"
|
||||
|
||||
# https://opentelemetry.io/docs/collector/configuration/#extensions
|
||||
# https://github.com/open-telemetry/opentelemetry-collector/blob/main/extension/README.md
|
||||
extensions:
|
||||
pprof:
|
||||
endpoint: 0.0.0.0:1888
|
||||
zpages:
|
||||
endpoint: 0.0.0.0:55679
|
||||
health_check:
|
||||
endpoint: 0.0.0.0:13133
|
||||
|
||||
# - The service section is used to configure what components are enabled in the Collector based on the configuration found in the receivers, processors, exporters, and extensions sections.
|
||||
# - If a component is configured, but not defined within the service section, then it’s not enabled.
|
||||
# https://betterstack.com/community/guides/observability/opentelemetry-collector/#exploring-the-opentelemetry-collector-components
|
||||
# https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/README.md
|
||||
# https://opentelemetry.io/docs/collector/architecture/
|
||||
# https://opentelemetry.io/docs/collector/configuration/#service
|
||||
service:
|
||||
# The `service.extensions` subsection determines which of the configured extensions will be enabled
|
||||
extensions: [pprof, zpages, health_check]
|
||||
# The `service.pipeline` Each pipeline starts with one or more receivers collecting data, which is then processed sequentially by processors (applying transformations, filtering, or sampling).
|
||||
# The processed data is finally sent to all configured exporters, ensuring each receives a copy. Components must be pre-configured in their respective sections before being used in a pipeline.
|
||||
# pipeline activate predefined components, defined components are disabled by default
|
||||
pipelines:
|
||||
traces:
|
||||
receivers: [otlp]
|
||||
processors: [batch]
|
||||
# https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#exporter-selection
|
||||
exporters: [debug, zipkin, otlp/jaeger, otlp/tempo]
|
||||
metrics:
|
||||
receivers: [otlp]
|
||||
processors: [batch]
|
||||
exporters: [debug, prometheusremotewrite, prometheus]
|
||||
logs:
|
||||
receivers: [otlp]
|
||||
processors: [batch]
|
||||
exporters: [otlphttp/loki, elasticsearch]
|
||||
@ -1,48 +0,0 @@
|
||||
# ref: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/examples/demo/prometheus.yaml
|
||||
# https://prometheus.io/docs/introduction/first_steps/
|
||||
# https://grafana.com/docs/grafana-cloud/send-data/metrics/metrics-prometheus/prometheus-config-examples/docker-compose-linux/
|
||||
|
||||
global:
|
||||
scrape_interval: 5s
|
||||
|
||||
scrape_configs:
|
||||
# when we use otel-collector we should comment other jobs in prometheus config, and we read configs from `otel-collector-config`
|
||||
- job_name: "otel-collector"
|
||||
scrape_interval: 10s
|
||||
static_configs:
|
||||
# otel-collector Prometheus exporter metrics
|
||||
- targets: [ 'otel-collector:8889' ]
|
||||
- targets: [ 'otel-collector:8888' ]
|
||||
|
||||
- job_name: "prometheus"
|
||||
static_configs:
|
||||
- targets: ["prometheus:9090"]
|
||||
|
||||
# # https://prometheus.io/docs/guides/node-exporter/
|
||||
# # https://grafana.com/docs/grafana-cloud/send-data/metrics/metrics-prometheus/prometheus-config-examples/docker-compose-linux/
|
||||
# - job_name: "node-exporter"
|
||||
# static_configs:
|
||||
# - targets: [ 'node-exporter:9100' ]
|
||||
|
||||
# # if we don't use otel collector we should uncomment this
|
||||
# # scrap application metrics
|
||||
# # http://localhost:4000/metrics by AddPrometheusExporter()
|
||||
# - job_name: vertical-slice-template-api
|
||||
# scrape_interval: 10s
|
||||
# metrics_path: /metrics
|
||||
# static_configs:
|
||||
# - targets: ['host.docker.internal:4000']
|
||||
#
|
||||
# # if we don't use otel collector we should uncomment this
|
||||
# # scrap application health metrics
|
||||
# # http://localhost:4000/health/metrics by AddPrometheusExporter()
|
||||
# - job_name: vertical-slice-template-api-healthchecks
|
||||
# scrape_interval: 10s
|
||||
# metrics_path: /health/metrics
|
||||
# static_configs:
|
||||
# - targets: ['host.docker.internal:4000']
|
||||
|
||||
## https://github.com/grafana/tempo/blob/main/example/docker-compose/shared/prometheus.yaml
|
||||
# - job_name: 'tempo'
|
||||
# static_configs:
|
||||
# - targets: [ 'tempo:3200' ]
|
||||
@ -1,49 +0,0 @@
|
||||
# https://grafana.com/docs/tempo/latest/configuration/
|
||||
# https://github.com/grafana/tempo/blob/main/example/docker-compose/local/tempo.yaml
|
||||
|
||||
# https://github.com/grafana/tempo/blob/main/example/docker-compose/shared/tempo.yaml
|
||||
stream_over_http_enabled: true
|
||||
server:
|
||||
http_listen_port: 3200
|
||||
log_level: info
|
||||
|
||||
distributor:
|
||||
receivers:
|
||||
otlp:
|
||||
protocols:
|
||||
grpc:
|
||||
endpoint: "tempo:4317"
|
||||
|
||||
ingester:
|
||||
max_block_duration: 5m # cut the headblock when this much time passes. this is being set for demo purposes and should probably be left alone normally
|
||||
|
||||
compactor:
|
||||
compaction:
|
||||
block_retention: 1h # overall Tempo trace retention. set for demo purposes
|
||||
|
||||
metrics_generator:
|
||||
registry:
|
||||
external_labels:
|
||||
source: tempo
|
||||
cluster: docker-compose
|
||||
storage:
|
||||
path: /var/tempo/generator/wal
|
||||
remote_write:
|
||||
- url: http://prometheus:9090/api/v1/write
|
||||
send_exemplars: true
|
||||
traces_storage:
|
||||
path: /var/tempo/generator/traces
|
||||
|
||||
storage:
|
||||
trace:
|
||||
backend: local # backend configuration to use
|
||||
wal:
|
||||
path: /var/tempo/wal # where to store the wal locally
|
||||
local:
|
||||
path: /var/tempo/blocks
|
||||
|
||||
overrides:
|
||||
defaults:
|
||||
metrics_generator:
|
||||
processors: [service-graphs, span-metrics, local-blocks] # enables metrics generator
|
||||
generate_native_histograms: both
|
||||
@ -1,362 +0,0 @@
|
||||
# ref: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/examples/demo/docker-compose.yaml
|
||||
# ref: https://github.com/joaofbantunes/DotNetMicroservicesObservabilitySample/blob/main/docker-compose.yml
|
||||
# ref: https://github.com/oskardudycz/EventSourcing.NetCore/blob/main/docker-compose.yml
|
||||
# https://github.com/grafana/intro-to-mltp
|
||||
# https://stackoverflow.com/questions/65272764/ports-are-not-available-listen-tcp-0-0-0-0-50070-bind-an-attempt-was-made-to
|
||||
|
||||
|
||||
name: booking-microservices-infrastructure
|
||||
|
||||
services:
|
||||
#######################################################
|
||||
# rabbitmq
|
||||
#######################################################
|
||||
rabbitmq:
|
||||
image: rabbitmq:management
|
||||
container_name: rabbitmq
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "5672:5672"
|
||||
- "15672:15672"
|
||||
# volumes:
|
||||
# - rabbitmq:/var/lib/rabbitmq
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
#######################################################
|
||||
# postgres
|
||||
#######################################################
|
||||
postgres:
|
||||
image: postgres:latest
|
||||
container_name: postgres
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- '5432:5432'
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
command:
|
||||
- "postgres"
|
||||
- "-c"
|
||||
- "wal_level=logical"
|
||||
- "-c"
|
||||
- "max_prepared_transactions=10"
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
#######################################################
|
||||
# EventStoreDB
|
||||
#######################################################
|
||||
eventstore:
|
||||
container_name: eventstore
|
||||
image: eventstore/eventstore:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- EVENTSTORE_CLUSTER_SIZE=1
|
||||
- EVENTSTORE_RUN_PROJECTIONS=All
|
||||
- EVENTSTORE_START_STANDARD_PROJECTIONS=True
|
||||
- EVENTSTORE_HTTP_PORT=2113
|
||||
- EVENTSTORE_INSECURE=True
|
||||
- EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP=True
|
||||
ports:
|
||||
- "2113:2113"
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # Mongo
|
||||
# #######################################################
|
||||
mongo:
|
||||
image: mongo:latest
|
||||
container_name: mongo
|
||||
restart: unless-stopped
|
||||
# environment:
|
||||
# - MONGO_INITDB_ROOT_USERNAME=root
|
||||
# - MONGO_INITDB_ROOT_PASSWORD=secret
|
||||
ports:
|
||||
- 27017:27017
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # Redis
|
||||
# #######################################################
|
||||
redis:
|
||||
image: redis
|
||||
container_name: redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 6379:6379
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # jaeger
|
||||
# # https://www.jaegertracing.io/docs/1.64/deployment/
|
||||
# # https://www.jaegertracing.io/docs/1.6/deployment/
|
||||
# #######################################################
|
||||
jaeger-all-in-one:
|
||||
image: jaegertracing/all-in-one:latest
|
||||
container_name: jaeger-all-in-one
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6831:6831/udp" # UDP port for Jaeger agent
|
||||
- "16686:16686" # endpoints and Jaeger UI
|
||||
- "14268:14268" # HTTP port for accept trace spans directly from clients
|
||||
- "14317:4317" # OTLP gRPC receiver for jaeger
|
||||
- "14318:4318" # OTLP http receiver for jaeger
|
||||
# - "9411" # Accepts Zipkin spans - /api/v2/spans
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # zipkin
|
||||
# # https://zipkin.io/pages/quickstart
|
||||
# #######################################################
|
||||
zipkin-all-in-one:
|
||||
image: openzipkin/zipkin:latest
|
||||
container_name: zipkin-all-in-one
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9411:9411"
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # otel-collector
|
||||
# # https://opentelemetry.io/docs/collector/installation/
|
||||
# # https://github.com/open-telemetry/opentelemetry-collector
|
||||
# # https://github.com/open-telemetry/opentelemetry-collector-contrib
|
||||
# # we can use none contrib docker `otel/opentelemetry-collector` version from `https://github.com/open-telemetry/opentelemetry-collector` repository but,
|
||||
# # if we need more components like `elasticsearch` we should use `otel/opentelemetry-collector-contrib` image of `https://github.com/open-telemetry/opentelemetry-collector-contrib` repository.
|
||||
# #######################################################
|
||||
otel-collector:
|
||||
image: otel/opentelemetry-collector-contrib:latest
|
||||
container_name: otel-collector
|
||||
restart: unless-stopped
|
||||
command: ["--config=/etc/otelcol-contrib/config.yaml"]
|
||||
volumes:
|
||||
- ./../configs/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
|
||||
ports:
|
||||
- "11888:1888" # pprof extension
|
||||
- "8888:8888" # Prometheus metrics exposed by the Collector
|
||||
- "8889:8889" # Prometheus exporter metrics
|
||||
- "13133:13133" # health_check extension
|
||||
- "4317:4317" # OTLP gRPC receiver
|
||||
- "4318:4318" # OTLP http receiver
|
||||
- "55679:55679" # zpages extension
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # prometheus
|
||||
# # https://prometheus.io/docs/introduction/first_steps/
|
||||
# # https://prometheus.io/docs/prometheus/3.1/installation/
|
||||
# # https://grafana.com/docs/grafana-cloud/send-data/metrics/metrics-prometheus/prometheus-config-examples/docker-compose-linux/
|
||||
# #######################################################
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9090:9090"
|
||||
volumes:
|
||||
- ./../configs/prometheus.yaml:/etc/prometheus/prometheus.yml
|
||||
# to passe one flag, such as "--log.level=debug" or "--web.enable-remote-write-receiver", we need to override the whole command, as we can't just pass one extra argument
|
||||
command:
|
||||
- "--config.file=/etc/prometheus/prometheus.yml"
|
||||
- "--storage.tsdb.path=/prometheus"
|
||||
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
|
||||
- "--web.console.templates=/usr/share/prometheus/consoles"
|
||||
# need this for the OpenTelemetry collector to be able to put metrics into Prometheus
|
||||
- "--web.enable-remote-write-receiver"
|
||||
# - "--log.level=debug"
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # node-exporter
|
||||
# # https://prometheus.io/docs/guides/node-exporter/
|
||||
# # https://grafana.com/docs/grafana-cloud/send-data/metrics/metrics-prometheus/prometheus-config-examples/docker-compose-linux/
|
||||
# #######################################################
|
||||
node-exporter:
|
||||
image: prom/node-exporter:latest
|
||||
container_name: node-exporter
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /proc:/host/proc:ro
|
||||
- /sys:/host/sys:ro
|
||||
- /:/rootfs:ro
|
||||
command:
|
||||
- '--path.procfs=/host/proc'
|
||||
- '--path.rootfs=/rootfs'
|
||||
- '--path.sysfs=/host/sys'
|
||||
ports:
|
||||
- "9101:9100"
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # grafana
|
||||
# # https://grafana.com/docs/grafana/latest/administration/provisioning/
|
||||
# # https://grafana.com/docs/grafana/latest/setup-grafana/installation/docker/
|
||||
# # https://grafana.com/docs/grafana/latest/setup-grafana/configure-docker/
|
||||
# # https://github.com/grafana/intro-to-mltp/blob/main/grafana/provisioning/datasources/datasources.yaml
|
||||
# #######################################################
|
||||
grafana:
|
||||
image: grafana/grafana:latest
|
||||
container_name: grafana
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
|
||||
- GF_SECURITY_ADMIN_USER=admin
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||
- GF_FEATURE_TOGGLES_ENABLE=traceqlEditor
|
||||
# - GF_AUTH_ANONYMOUS_ENABLED=true
|
||||
# - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
|
||||
# - GF_AUTH_DISABLE_LOGIN_FORM=true
|
||||
depends_on:
|
||||
- prometheus
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- ./../configs/grafana/provisioning:/etc/grafana/provisioning
|
||||
- ./../configs/grafana/dashboards:/var/lib/grafana/dashboards
|
||||
## https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/
|
||||
# - ./../configs/grafana/grafana.ini:/etc/grafana/grafana.ini
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # tempo
|
||||
# # https://github.com/grafana/tempo/blob/main/example/docker-compose/otel-collector/docker-compose.yaml
|
||||
# # https://github.com/grafana/tempo/blob/main/example/docker-compose/shared
|
||||
# # https://github.com/grafana/tempo/blob/main/example/docker-compose/local
|
||||
# # https://github.com/grafana/tempo/tree/main/example/docker-compose
|
||||
# #######################################################
|
||||
tempo:
|
||||
image: grafana/tempo:latest
|
||||
container_name: tempo
|
||||
restart: unless-stopped
|
||||
command: [ "-config.file=/etc/tempo.yaml" ]
|
||||
volumes:
|
||||
- ./../configs/tempo.yaml:/etc/tempo.yaml
|
||||
ports:
|
||||
- "3200" # tempo
|
||||
- "24317:4317" # otlp grpc
|
||||
- "24318:4318" # otlp http
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # loki
|
||||
# # https://grafana.com/docs/opentelemetry/collector/send-logs-to-loki/
|
||||
# # https://github.com/grafana/loki/blob/main/production/docker-compose.yaml
|
||||
# # https://github.com/grafana/loki/blob/main/examples/getting-started/docker-compose.yaml
|
||||
# #######################################################
|
||||
loki:
|
||||
image: grafana/loki:latest
|
||||
hostname: loki
|
||||
container_name: loki
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
volumes:
|
||||
- ./../configs/loki-config.yaml:/etc/loki/local-config.yaml
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # elasticsearch
|
||||
# # https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docker.html#docker-compose-file
|
||||
# #######################################################
|
||||
elasticsearch:
|
||||
container_name: elasticsearch
|
||||
restart: unless-stopped
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0
|
||||
environment:
|
||||
- discovery.type=single-node
|
||||
- cluster.name=docker-cluster
|
||||
- node.name=docker-node
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- xpack.security.enabled=false
|
||||
- xpack.security.http.ssl.enabled=false
|
||||
- xpack.security.transport.ssl.enabled=false
|
||||
- network.host=0.0.0.0
|
||||
- http.port=9200
|
||||
- transport.host=localhost
|
||||
- bootstrap.memory_lock=true
|
||||
- cluster.routing.allocation.disk.threshold_enabled=false
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- elastic-data:/usr/share/elasticsearch/data
|
||||
ports:
|
||||
- ${ELASTIC_HOST_PORT:-9200}:${ELASTIC_PORT:-9200}
|
||||
- 9300:9300
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # kibana
|
||||
# # https://www.elastic.co/guide/en/kibana/current/docker.html
|
||||
# #######################################################
|
||||
kibana:
|
||||
image: docker.elastic.co/kibana/kibana:8.17.0
|
||||
container_name: kibana
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
|
||||
ports:
|
||||
- ${KIBANA_HOST_PORT:-5601}:${KIBANA_PORT:-5601}
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
# #######################################################
|
||||
# # cadvisor
|
||||
# #######################################################
|
||||
cadvisor:
|
||||
image: gcr.io/cadvisor/cadvisor:latest
|
||||
container_name: cadvisor
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- /:/rootfs:ro
|
||||
- /var/run:/var/run:ro
|
||||
- /sys:/sys:ro
|
||||
- /var/lib/docker/:/var/lib/docker:ro
|
||||
- /dev/disk/:/dev/disk:ro
|
||||
devices:
|
||||
- /dev/kmsg
|
||||
networks:
|
||||
- infrastructure
|
||||
|
||||
|
||||
networks:
|
||||
infrastructure:
|
||||
name: infrastructure
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
elastic-data:
|
||||
postgres-data:
|
||||
@ -1,372 +1,31 @@
|
||||
name: booking-microservices
|
||||
|
||||
version: "3.3"
|
||||
services:
|
||||
|
||||
#######################################################
|
||||
# rabbitmq
|
||||
# Gateway
|
||||
#######################################################
|
||||
rabbitmq:
|
||||
image: rabbitmq:management
|
||||
container_name: rabbitmq
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "5672:5672"
|
||||
- "15672:15672"
|
||||
# volumes:
|
||||
# - rabbitmq:/var/lib/rabbitmq
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# postgres
|
||||
#######################################################
|
||||
postgres:
|
||||
image: postgres:latest
|
||||
container_name: postgres
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- '5432:5432'
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
command:
|
||||
- "postgres"
|
||||
- "-c"
|
||||
- "wal_level=logical"
|
||||
- "-c"
|
||||
- "max_prepared_transactions=10"
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# EventStoreDB
|
||||
#######################################################
|
||||
eventstore:
|
||||
container_name: eventstore
|
||||
image: eventstore/eventstore:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- EVENTSTORE_CLUSTER_SIZE=1
|
||||
- EVENTSTORE_RUN_PROJECTIONS=All
|
||||
- EVENTSTORE_START_STANDARD_PROJECTIONS=True
|
||||
- EVENTSTORE_HTTP_PORT=2113
|
||||
- EVENTSTORE_INSECURE=True
|
||||
- EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP=True
|
||||
ports:
|
||||
- "2113:2113"
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Mongo
|
||||
#######################################################
|
||||
mongo:
|
||||
image: mongo:latest
|
||||
container_name: mongo
|
||||
restart: unless-stopped
|
||||
# environment:
|
||||
# - MONGO_INITDB_ROOT_USERNAME=root
|
||||
# - MONGO_INITDB_ROOT_PASSWORD=secret
|
||||
ports:
|
||||
- 27017:27017
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Redis
|
||||
#######################################################
|
||||
redis:
|
||||
image: redis
|
||||
container_name: redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 6379:6379
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# jaeger
|
||||
# https://www.jaegertracing.io/docs/1.64/deployment/
|
||||
# https://www.jaegertracing.io/docs/1.6/deployment/
|
||||
#######################################################
|
||||
jaeger-all-in-one:
|
||||
image: jaegertracing/all-in-one:latest
|
||||
container_name: jaeger-all-in-one
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6831:6831/udp" # UDP port for Jaeger agent
|
||||
- "16686:16686" # endpoints and Jaeger UI
|
||||
- "14268:14268" # HTTP port for accept trace spans directly from clients
|
||||
- "14317:4317" # OTLP gRPC receiver for jaeger
|
||||
- "14318:4318" # OTLP http receiver for jaeger
|
||||
# - "9411" # Accepts Zipkin spans - /api/v2/spans
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# zipkin
|
||||
# https://zipkin.io/pages/quickstart
|
||||
#######################################################
|
||||
zipkin-all-in-one:
|
||||
image: openzipkin/zipkin:latest
|
||||
container_name: zipkin-all-in-one
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9411:9411"
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# otel-collector
|
||||
# https://opentelemetry.io/docs/collector/installation/
|
||||
# https://github.com/open-telemetry/opentelemetry-collector
|
||||
# https://github.com/open-telemetry/opentelemetry-collector-contrib
|
||||
# we can use none contrib docker `otel/opentelemetry-collector` version from `https://github.com/open-telemetry/opentelemetry-collector` repository but,
|
||||
# if we need more components like `elasticsearch` we should use `otel/opentelemetry-collector-contrib` image of `https://github.com/open-telemetry/opentelemetry-collector-contrib` repository.
|
||||
#######################################################
|
||||
otel-collector:
|
||||
image: otel/opentelemetry-collector-contrib:latest
|
||||
container_name: otel-collector
|
||||
restart: unless-stopped
|
||||
command: ["--config=/etc/otelcol-contrib/config.yaml"]
|
||||
volumes:
|
||||
- ./../configs/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
|
||||
ports:
|
||||
- "11888:1888" # pprof extension
|
||||
- "8888:8888" # Prometheus metrics exposed by the Collector
|
||||
- "8889:8889" # Prometheus exporter metrics
|
||||
- "13133:13133" # health_check extension
|
||||
- "4317:4317" # OTLP gRPC receiver
|
||||
- "4318:4318" # OTLP http receiver
|
||||
- "55679:55679" # zpages extension
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# prometheus
|
||||
# https://prometheus.io/docs/introduction/first_steps/
|
||||
# https://prometheus.io/docs/prometheus/3.1/installation/
|
||||
# https://grafana.com/docs/grafana-cloud/send-data/metrics/metrics-prometheus/prometheus-config-examples/docker-compose-linux/
|
||||
#######################################################
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9090:9090"
|
||||
volumes:
|
||||
- ./../configs/prometheus.yaml:/etc/prometheus/prometheus.yml
|
||||
# to passe one flag, such as "--log.level=debug" or "--web.enable-remote-write-receiver", we need to override the whole command, as we can't just pass one extra argument
|
||||
command:
|
||||
- "--config.file=/etc/prometheus/prometheus.yml"
|
||||
- "--storage.tsdb.path=/prometheus"
|
||||
- "--web.console.libraries=/usr/share/prometheus/console_libraries"
|
||||
- "--web.console.templates=/usr/share/prometheus/consoles"
|
||||
# need this for the OpenTelemetry collector to be able to put metrics into Prometheus
|
||||
- "--web.enable-remote-write-receiver"
|
||||
# - "--log.level=debug"
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# node-exporter
|
||||
# https://prometheus.io/docs/guides/node-exporter/
|
||||
# https://grafana.com/docs/grafana-cloud/send-data/metrics/metrics-prometheus/prometheus-config-examples/docker-compose-linux/
|
||||
#######################################################
|
||||
node-exporter:
|
||||
image: prom/node-exporter:latest
|
||||
container_name: node-exporter
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /proc:/host/proc:ro
|
||||
- /sys:/host/sys:ro
|
||||
- /:/rootfs:ro
|
||||
command:
|
||||
- '--path.procfs=/host/proc'
|
||||
- '--path.rootfs=/rootfs'
|
||||
- '--path.sysfs=/host/sys'
|
||||
ports:
|
||||
- "9101:9100"
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# grafana
|
||||
# https://grafana.com/docs/grafana/latest/administration/provisioning/
|
||||
# https://grafana.com/docs/grafana/latest/setup-grafana/installation/docker/
|
||||
# https://grafana.com/docs/grafana/latest/setup-grafana/configure-docker/
|
||||
# https://github.com/grafana/intro-to-mltp/blob/main/grafana/provisioning/datasources/datasources.yaml
|
||||
#######################################################
|
||||
grafana:
|
||||
image: grafana/grafana:latest
|
||||
container_name: grafana
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource
|
||||
- GF_SECURITY_ADMIN_USER=admin
|
||||
- GF_SECURITY_ADMIN_PASSWORD=admin
|
||||
- GF_FEATURE_TOGGLES_ENABLE=traceqlEditor
|
||||
# - GF_AUTH_ANONYMOUS_ENABLED=true
|
||||
# - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
|
||||
# - GF_AUTH_DISABLE_LOGIN_FORM=true
|
||||
depends_on:
|
||||
- prometheus
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- ./../configs/grafana/provisioning:/etc/grafana/provisioning
|
||||
- ./../configs/grafana/dashboards:/var/lib/grafana/dashboards
|
||||
## https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/
|
||||
# - ./../configs/grafana/grafana.ini:/etc/grafana/grafana.ini
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# tempo
|
||||
# https://github.com/grafana/tempo/blob/main/example/docker-compose/otel-collector/docker-compose.yaml
|
||||
# https://github.com/grafana/tempo/blob/main/example/docker-compose/shared
|
||||
# https://github.com/grafana/tempo/blob/main/example/docker-compose/local
|
||||
# https://github.com/grafana/tempo/tree/main/example/docker-compose
|
||||
#######################################################
|
||||
tempo:
|
||||
image: grafana/tempo:latest
|
||||
container_name: tempo
|
||||
restart: unless-stopped
|
||||
command: [ "-config.file=/etc/tempo.yaml" ]
|
||||
volumes:
|
||||
- ./../configs/tempo.yaml:/etc/tempo.yaml
|
||||
ports:
|
||||
- "3200" # tempo
|
||||
- "24317:4317" # otlp grpc
|
||||
- "24318:4318" # otlp http
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# loki
|
||||
# https://grafana.com/docs/opentelemetry/collector/send-logs-to-loki/
|
||||
# https://github.com/grafana/loki/blob/main/production/docker-compose.yaml
|
||||
# https://github.com/grafana/loki/blob/main/examples/getting-started/docker-compose.yaml
|
||||
#######################################################
|
||||
loki:
|
||||
image: grafana/loki:latest
|
||||
hostname: loki
|
||||
container_name: loki
|
||||
ports:
|
||||
- "3100:3100"
|
||||
command: -config.file=/etc/loki/local-config.yaml
|
||||
volumes:
|
||||
- ./../configs/loki-config.yaml:/etc/loki/local-config.yaml
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# elasticsearch
|
||||
# https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docker.html#docker-compose-file
|
||||
#######################################################
|
||||
elasticsearch:
|
||||
container_name: elasticsearch
|
||||
restart: unless-stopped
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:8.17.0
|
||||
environment:
|
||||
- discovery.type=single-node
|
||||
- cluster.name=docker-cluster
|
||||
- node.name=docker-node
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- xpack.security.enabled=false
|
||||
- xpack.security.http.ssl.enabled=false
|
||||
- xpack.security.transport.ssl.enabled=false
|
||||
- network.host=0.0.0.0
|
||||
- http.port=9200
|
||||
- transport.host=localhost
|
||||
- bootstrap.memory_lock=true
|
||||
- cluster.routing.allocation.disk.threshold_enabled=false
|
||||
ulimits:
|
||||
memlock:
|
||||
soft: -1
|
||||
hard: -1
|
||||
volumes:
|
||||
- elastic-data:/usr/share/elasticsearch/data
|
||||
ports:
|
||||
- ${ELASTIC_HOST_PORT:-9200}:${ELASTIC_PORT:-9200}
|
||||
- 9300:9300
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# kibana
|
||||
# https://www.elastic.co/guide/en/kibana/current/docker.html
|
||||
#######################################################
|
||||
kibana:
|
||||
image: docker.elastic.co/kibana/kibana:8.17.0
|
||||
container_name: kibana
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
|
||||
ports:
|
||||
- ${KIBANA_HOST_PORT:-5601}:${KIBANA_PORT:-5601}
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# cadvisor
|
||||
#######################################################
|
||||
cadvisor:
|
||||
image: gcr.io/cadvisor/cadvisor:latest
|
||||
container_name: cadvisor
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- /:/rootfs:ro
|
||||
- /var/run:/var/run:ro
|
||||
- /sys:/sys:ro
|
||||
- /var/lib/docker/:/var/lib/docker:ro
|
||||
- /dev/disk/:/dev/disk:ro
|
||||
devices:
|
||||
- /dev/kmsg
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
######################################################
|
||||
# Api-Gateway
|
||||
######################################################
|
||||
api-gateway:
|
||||
image: api-gateway
|
||||
gateway:
|
||||
image: gateway
|
||||
build:
|
||||
args:
|
||||
Version: "1"
|
||||
context: ../../
|
||||
dockerfile: src/ApiGateway/Dockerfile
|
||||
container_name: api-gateway
|
||||
container_name: booking-gateway
|
||||
ports:
|
||||
- "5001:80"
|
||||
- "5000:443"
|
||||
depends_on:
|
||||
- postgres
|
||||
- rabbitmq
|
||||
- jaeger
|
||||
- elasticsearch
|
||||
- kibana
|
||||
volumes:
|
||||
- ~/.aspnet/https:/https:ro
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=docker
|
||||
- ASPNETCORE_URLS=https://+;http://+
|
||||
- ASPNETCORE_HTTPS_PORT=5000
|
||||
- ASPNETCORE_HTTP_PORT=5001
|
||||
- 'ASPNETCORE_URLS=https://+;http://+'
|
||||
- ASPNETCORE_HTTPS_PORT=5001
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Password=password
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
|
||||
networks:
|
||||
@ -387,18 +46,24 @@ services:
|
||||
ports:
|
||||
- 5004:80
|
||||
- 5003:443
|
||||
depends_on:
|
||||
- postgres
|
||||
- rabbitmq
|
||||
- jaeger
|
||||
- elasticsearch
|
||||
- kibana
|
||||
- mongo
|
||||
volumes:
|
||||
- ~/.aspnet/https:/https:ro
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=docker
|
||||
- ASPNETCORE_URLS=https://+;http://+
|
||||
- 'ASPNETCORE_URLS=https://+;http://+'
|
||||
- ASPNETCORE_HTTPS_PORT=5003
|
||||
- ASPNETCORE_HTTP_PORT=5004
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Password=password
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Identity
|
||||
#######################################################
|
||||
@ -413,13 +78,17 @@ services:
|
||||
ports:
|
||||
- 6005:80
|
||||
- 5005:443
|
||||
depends_on:
|
||||
- postgres
|
||||
- rabbitmq
|
||||
- jaeger
|
||||
- elasticsearch
|
||||
- kibana
|
||||
volumes:
|
||||
- ~/.aspnet/https:/https:ro
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=docker
|
||||
- ASPNETCORE_URLS=https://+;http://+
|
||||
- 'ASPNETCORE_URLS=https://+;http://+'
|
||||
- ASPNETCORE_HTTPS_PORT=5005
|
||||
- ASPNETCORE_HTTP_PORT=6005
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Password=password
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
|
||||
networks:
|
||||
@ -440,13 +109,18 @@ services:
|
||||
ports:
|
||||
- 6012:80
|
||||
- 5012:443
|
||||
depends_on:
|
||||
- postgres
|
||||
- rabbitmq
|
||||
- jaeger
|
||||
- elasticsearch
|
||||
- kibana
|
||||
- mongo
|
||||
volumes:
|
||||
- ~/.aspnet/https:/https:ro
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=docker
|
||||
- ASPNETCORE_URLS=https://+;http://+
|
||||
- 'ASPNETCORE_URLS=https://+;http://+'
|
||||
- ASPNETCORE_HTTPS_PORT=5012
|
||||
- ASPNETCORE_HTTP_PORT=6012
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Password=password
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
|
||||
networks:
|
||||
@ -467,26 +141,154 @@ services:
|
||||
ports:
|
||||
- 6010:80
|
||||
- 5010:443
|
||||
depends_on:
|
||||
- postgres
|
||||
- rabbitmq
|
||||
- jaeger
|
||||
- eventstore
|
||||
- elasticsearch
|
||||
- kibana
|
||||
- mongo
|
||||
volumes:
|
||||
- ~/.aspnet/https:/https:ro
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=docker
|
||||
- ASPNETCORE_URLS=https://+;http://+
|
||||
- 'ASPNETCORE_URLS=https://+;http://+'
|
||||
- ASPNETCORE_HTTPS_PORT=5010
|
||||
- ASPNETCORE_HTTP_PORT=6010
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Password=password
|
||||
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
######################################################
|
||||
# Postgres
|
||||
######################################################
|
||||
postgres:
|
||||
image: postgres:latest
|
||||
container_name: postgres
|
||||
restart: on-failure
|
||||
ports:
|
||||
- '5432:5432'
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Rabbitmq
|
||||
#######################################################
|
||||
rabbitmq:
|
||||
container_name: rabbitmq
|
||||
image: rabbitmq:3-management
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5672:5672
|
||||
- 15672:15672
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Jaeger
|
||||
#######################################################
|
||||
jaeger:
|
||||
image: jaegertracing/all-in-one
|
||||
container_name: jaeger
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- booking
|
||||
ports:
|
||||
- 5775:5775/udp
|
||||
- 5778:5778
|
||||
- 6831:6831/udp
|
||||
- 6832:6832/udp
|
||||
- 9411:9411
|
||||
- 14268:14268
|
||||
- 16686:16686
|
||||
|
||||
|
||||
#######################################################
|
||||
# EventStoreDB
|
||||
#######################################################
|
||||
eventstore:
|
||||
container_name: eventstore
|
||||
image: eventstore/eventstore:21.2.0-buster-slim
|
||||
restart: on-failure
|
||||
environment:
|
||||
- EVENTSTORE_CLUSTER_SIZE=1
|
||||
- EVENTSTORE_RUN_PROJECTIONS=All
|
||||
- EVENTSTORE_START_STANDARD_PROJECTIONS=true
|
||||
- EVENTSTORE_EXT_TCP_PORT=1113
|
||||
- EVENTSTORE_EXT_HTTP_PORT=2113
|
||||
- EVENTSTORE_INSECURE=true
|
||||
- EVENTSTORE_ENABLE_EXTERNAL_TCP=true
|
||||
- EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP=true
|
||||
ports:
|
||||
- '1113:1113'
|
||||
- '2113:2113'
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Mongo
|
||||
#######################################################
|
||||
mongo:
|
||||
image: mongo:5
|
||||
container_name: mongo
|
||||
restart: unless-stopped
|
||||
# environment:
|
||||
# - MONGO_INITDB_ROOT_USERNAME=root
|
||||
# - MONGO_INITDB_ROOT_PASSWORD=secret
|
||||
networks:
|
||||
- booking
|
||||
ports:
|
||||
- 27017:27017
|
||||
|
||||
#######################################################
|
||||
# Elastic Search
|
||||
#######################################################
|
||||
elasticsearch:
|
||||
container_name: elasticsearch
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.9.2
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 9200:9200
|
||||
volumes:
|
||||
- elasticsearch-data:/usr/share/elasticsearch/data
|
||||
environment:
|
||||
- xpack.monitoring.enabled=true
|
||||
- xpack.watcher.enabled=false
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- discovery.type=single-node
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# Kibana
|
||||
#######################################################
|
||||
kibana:
|
||||
container_name: kibana
|
||||
image: docker.elastic.co/kibana/kibana:7.9.2
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5601:5601
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
environment:
|
||||
- ELASTICSEARCH_URL=http://localhost:9200
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
networks:
|
||||
booking:
|
||||
name: booking
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
elastic-data:
|
||||
postgres-data:
|
||||
elasticsearch-data:
|
||||
|
||||
|
||||
|
||||
|
||||
152
deployments/docker-compose/infrastracture.yaml
Normal file
152
deployments/docker-compose/infrastracture.yaml
Normal file
@ -0,0 +1,152 @@
|
||||
version: "3.3"
|
||||
services:
|
||||
|
||||
# #######################################################
|
||||
# # Rabbitmq
|
||||
# #######################################################
|
||||
rabbitmq:
|
||||
container_name: rabbitmq
|
||||
image: rabbitmq:3-management
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5672:5672
|
||||
- 15672:15672
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Postgres
|
||||
######################################################
|
||||
postgres:
|
||||
image: postgres:latest
|
||||
container_name: postgres
|
||||
restart: on-failure
|
||||
ports:
|
||||
- '5432:5432'
|
||||
environment:
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# Jaeger
|
||||
#######################################################
|
||||
jaeger:
|
||||
container_name: jaeger
|
||||
image: jaegertracing/all-in-one
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- booking
|
||||
ports:
|
||||
- 5775:5775/udp
|
||||
- 5778:5778
|
||||
- 6831:6831/udp
|
||||
- 6832:6832/udp
|
||||
- 9411:9411
|
||||
- 14268:14268
|
||||
- 16686:16686
|
||||
|
||||
|
||||
#######################################################
|
||||
# EventStoreDB
|
||||
#######################################################
|
||||
#https://stackoverflow.com/questions/65272764/ports-are-not-available-listen-tcp-0-0-0-0-50070-bind-an-attempt-was-made-to
|
||||
|
||||
eventstore:
|
||||
container_name: eventstore
|
||||
image: eventstore/eventstore:21.2.0-buster-slim
|
||||
restart: on-failure
|
||||
environment:
|
||||
- EVENTSTORE_CLUSTER_SIZE=1
|
||||
- EVENTSTORE_RUN_PROJECTIONS=All
|
||||
- EVENTSTORE_START_STANDARD_PROJECTIONS=true
|
||||
- EVENTSTORE_EXT_TCP_PORT=1113
|
||||
- EVENTSTORE_EXT_HTTP_PORT=2113
|
||||
- EVENTSTORE_INSECURE=true
|
||||
- EVENTSTORE_ENABLE_EXTERNAL_TCP=true
|
||||
- EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP=true
|
||||
ports:
|
||||
- '1113:1113'
|
||||
- '2113:2113'
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Mongo
|
||||
#######################################################
|
||||
mongo:
|
||||
image: mongo:5
|
||||
container_name: mongo
|
||||
restart: unless-stopped
|
||||
# environment:
|
||||
# - MONGO_INITDB_ROOT_USERNAME=root
|
||||
# - MONGO_INITDB_ROOT_PASSWORD=secret
|
||||
networks:
|
||||
- booking
|
||||
ports:
|
||||
- 27017:27017
|
||||
|
||||
|
||||
#######################################################
|
||||
# Elastic Search
|
||||
#######################################################
|
||||
elasticsearch:
|
||||
container_name: elasticsearch
|
||||
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.9
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 9200:9200
|
||||
volumes:
|
||||
- elasticsearch-data:/usr/share/elasticsearch/data
|
||||
environment:
|
||||
- xpack.monitoring.enabled=true
|
||||
- xpack.watcher.enabled=false
|
||||
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
|
||||
- discovery.type=single-node
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# Kibana
|
||||
#######################################################
|
||||
kibana:
|
||||
container_name: kibana
|
||||
image: docker.elastic.co/kibana/kibana:7.17.9
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5601:5601
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
environment:
|
||||
- ELASTICSEARCH_URL=http://localhost:9200
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# Redis
|
||||
#######################################################
|
||||
redis:
|
||||
image: redis
|
||||
container_name: redis
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- booking
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
|
||||
|
||||
networks:
|
||||
booking:
|
||||
name: booking
|
||||
|
||||
|
||||
volumes:
|
||||
elasticsearch-data:
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-staging
|
||||
spec:
|
||||
acme:
|
||||
# Staging API
|
||||
server: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
# server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: test@email.com
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-staging
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
File diff suppressed because it is too large
Load Diff
45
deployments/tye/tye.yml
Normal file
45
deployments/tye/tye.yml
Normal file
@ -0,0 +1,45 @@
|
||||
name: Booking
|
||||
services:
|
||||
- name: booking-gateway
|
||||
project: ./../../src/ApiGateway/src/ApiGateway.csproj
|
||||
bindings:
|
||||
- port: 5001
|
||||
env:
|
||||
- name: ASPNETCORE_ENVIRONMENT
|
||||
value: development
|
||||
|
||||
|
||||
- name: flight
|
||||
project: ./../../src/Services/Flight/src/Flight.Api/Flight.Api.csproj
|
||||
bindings:
|
||||
- port: 5003
|
||||
env:
|
||||
- name: ASPNETCORE_ENVIRONMENT
|
||||
value: development
|
||||
|
||||
|
||||
- name: identity
|
||||
project: ./../../src/Services/Identity/src/Identity.Api/Identity.Api.csproj
|
||||
bindings:
|
||||
- port: 5005
|
||||
env:
|
||||
- name: ASPNETCORE_ENVIRONMENT
|
||||
value: development
|
||||
|
||||
|
||||
- name: passenger
|
||||
project: ./../../src/Services/Passenger/src/Passenger.Api/Passenger.Api.csproj
|
||||
bindings:
|
||||
- port: 5012
|
||||
env:
|
||||
- name: ASPNETCORE_ENVIRONMENT
|
||||
value: development
|
||||
|
||||
|
||||
- name: booking
|
||||
project: ./../../src/Services/Booking/src/Booking.Api/Booking.Api.csproj
|
||||
bindings:
|
||||
- port: 5010
|
||||
env:
|
||||
- name: ASPNETCORE_ENVIRONMENT
|
||||
value: development
|
||||
@ -1,6 +0,0 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "10.0.103",
|
||||
"rollForward": "latestFeature"
|
||||
}
|
||||
}
|
||||
1346
package-lock.json
generated
1346
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@ -1,19 +1,3 @@
|
||||
{
|
||||
"name": "booking-microservices",
|
||||
"version": "1.0.0",
|
||||
"description": "booking-microservices",
|
||||
"author": "Meysam Hadeli",
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prepare": "husky && dotnet tool restore",
|
||||
"format": "dotnet tool run dotnet-csharpier booking-microservices.sln",
|
||||
"ci-format": "dotnet tool run dotnet-csharpier booking-microservices.sln --check",
|
||||
"upgrade-packages": "dotnet outdated --upgrade"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.5.0",
|
||||
"@commitlint/config-conventional": "^19.5.0",
|
||||
"husky": "^9.1.6"
|
||||
}
|
||||
{
|
||||
"version": "0.0.0"
|
||||
}
|
||||
|
||||
@ -1,38 +1,37 @@
|
||||
# ---------- Build Stage ----------
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS builder
|
||||
WORKDIR /src
|
||||
|
||||
# Copy solution-level files
|
||||
COPY .editorconfig .
|
||||
COPY global.json .
|
||||
COPY Directory.Build.props .
|
||||
# Setup working directory for the project
|
||||
WORKDIR /src
|
||||
COPY ./src/BuildingBlocks/BuildingBlocks.csproj ./BuildingBlocks/
|
||||
COPY ./src/ApiGateway/src/ApiGateway.csproj ./ApiGateway/src/
|
||||
|
||||
# Copy project files first (better Docker caching)
|
||||
COPY src/BuildingBlocks/BuildingBlocks.csproj src/BuildingBlocks/
|
||||
COPY src/ApiGateway/src/ApiGateway.csproj src/ApiGateway/src/
|
||||
COPY src/Aspire/src/ServiceDefaults/ServiceDefaults.csproj src/Aspire/src/ServiceDefaults/
|
||||
|
||||
# Restore dependencies
|
||||
RUN dotnet restore src/ApiGateway/src/ApiGateway.csproj
|
||||
# Restore nuget packages
|
||||
RUN dotnet restore ./ApiGateway/src/ApiGateway.csproj
|
||||
|
||||
# Copy the rest of the source code
|
||||
COPY src ./src
|
||||
# Copy project files
|
||||
COPY ./src/BuildingBlocks ./BuildingBlocks/
|
||||
COPY ./src/ApiGateway/src ./ApiGateway/src/
|
||||
|
||||
# Publish (build included)
|
||||
RUN dotnet publish src/ApiGateway/src/ApiGateway.csproj \
|
||||
-c Release \
|
||||
-o /app/publish \
|
||||
--no-restore
|
||||
# Build project with Release configuration
|
||||
# and no restore, as we did it already
|
||||
|
||||
# ---------- Runtime Stage ----------
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
|
||||
RUN ls
|
||||
RUN dotnet build -c Release --no-restore ./ApiGateway/src/ApiGateway.csproj
|
||||
|
||||
WORKDIR /src/ApiGateway/src
|
||||
|
||||
# Publish project to output folder
|
||||
# and no build, as we did it already
|
||||
RUN dotnet publish -c Release --no-build -o out
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:7.0
|
||||
|
||||
# Setup working directory for the project
|
||||
WORKDIR /app
|
||||
|
||||
COPY --from=build /app/publish .
|
||||
|
||||
ENV ASPNETCORE_URLS=http://+:80
|
||||
ENV ASPNETCORE_ENVIRONMENT=docker
|
||||
|
||||
COPY --from=builder /src/ApiGateway/src/out .
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
ENTRYPOINT ["dotnet", "ApiGateway.dll"]
|
||||
|
||||
ENTRYPOINT ["dotnet", "ApiGateway.dll"]
|
||||
@ -1,5 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\BuildingBlocks\BuildingBlocks.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Update="AsyncFixer" Version="1.6.0" />
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="1.0.747" />
|
||||
<PackageReference Update="Microsoft.VisualStudio.Threading.Analyzers" Version="17.4.27" />
|
||||
<PackageReference Update="Roslynator.Analyzers" Version="4.1.2" />
|
||||
<PackageReference Update="Roslynator.Formatting.Analyzers" Version="4.2.0" />
|
||||
<PackageReference Update="Roslynator.CodeAnalysis.Analyzers" Version="4.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
using BuildingBlocks.Jwt;
|
||||
using BuildingBlocks.Logging;
|
||||
using BuildingBlocks.Web;
|
||||
using Figgle;
|
||||
using Figgle.Fonts;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Serilog;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var env = builder.Environment;
|
||||
@ -8,6 +11,9 @@ var appOptions = builder.Services.GetOptions<AppOptions>("AppOptions");
|
||||
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
||||
|
||||
|
||||
|
||||
builder.AddCustomSerilog(env);
|
||||
builder.Services.AddJwt();
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
|
||||
@ -15,6 +21,7 @@ builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSecti
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.UseSerilogRequestLogging();
|
||||
app.UseCorrelationId();
|
||||
app.UseRouting();
|
||||
app.UseHttpsRedirection();
|
||||
@ -24,9 +31,18 @@ app.UseAuthorization();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapReverseProxy();
|
||||
endpoints.MapReverseProxy(proxyPipeline =>
|
||||
{
|
||||
proxyPipeline.Use(async (context, next) =>
|
||||
{
|
||||
var token = await context.GetTokenAsync("access_token");
|
||||
context.Request.Headers["Authorization"] = $"Bearer {token}";
|
||||
|
||||
await next().ConfigureAwait(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
app.MapGet("/", x => x.Response.WriteAsync(appOptions.Name));
|
||||
|
||||
app.Run();
|
||||
app.Run();
|
||||
|
||||
@ -1,5 +1,13 @@
|
||||
{
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:17191",
|
||||
"sslPort": 44352
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"ApiGateway": {
|
||||
"commandName": "Project",
|
||||
@ -9,6 +17,14 @@
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,36 +1,24 @@
|
||||
{
|
||||
"LogOptions": {
|
||||
"Level": "Information",
|
||||
"LogTemplate": "{Timestamp:HH:mm:ss} [{Level:u4}] {Message:lj}{NewLine}{Exception}",
|
||||
"ElasticUri": "elasticsearch:9200"
|
||||
},
|
||||
"Yarp": {
|
||||
"clusters": {
|
||||
"flight": {
|
||||
"destinations": {
|
||||
"destination1": {
|
||||
"address": "http://flight:80"
|
||||
}
|
||||
}
|
||||
},
|
||||
"identity": {
|
||||
"destinations": {
|
||||
"destination1": {
|
||||
"address": "http://identity:80"
|
||||
"address": "http://flight"
|
||||
}
|
||||
}
|
||||
},
|
||||
"passenger": {
|
||||
"destinations": {
|
||||
"destination1": {
|
||||
"address": "http://passenger:80"
|
||||
"address": "http://passenger"
|
||||
}
|
||||
}
|
||||
},
|
||||
"booking": {
|
||||
"destinations": {
|
||||
"destination1": {
|
||||
"address": "http://booking:80"
|
||||
"address": "http://booking"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,78 +15,61 @@
|
||||
"identity": {
|
||||
"clusterId": "identity",
|
||||
"match": {
|
||||
"path": "identity/{**catch-all}"
|
||||
},
|
||||
"Transforms": [
|
||||
{
|
||||
"PathRemovePrefix": "identity"
|
||||
"path": "/{**catch-all}"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flight": {
|
||||
"clusterId": "flight",
|
||||
"match": {
|
||||
"path": "flight/{**catch-all}"
|
||||
},
|
||||
"Transforms": [
|
||||
{
|
||||
"PathRemovePrefix": "flight"
|
||||
}
|
||||
]
|
||||
"path": "api/{version}/flight/{**catch-all}"
|
||||
}
|
||||
},
|
||||
"passenger": {
|
||||
"clusterId": "passenger",
|
||||
"match": {
|
||||
"path": "passenger/{**catch-all}"
|
||||
},
|
||||
"Transforms": [
|
||||
{
|
||||
"PathRemovePrefix": "passenger"
|
||||
}
|
||||
]
|
||||
"path": "api/{version}/passenger/{**catch-all}"
|
||||
}
|
||||
},
|
||||
"booking": {
|
||||
"clusterId": "booking",
|
||||
"match": {
|
||||
"path": "booking/{**catch-all}"
|
||||
},
|
||||
"Transforms": [
|
||||
{
|
||||
"PathRemovePrefix": "booking"
|
||||
}
|
||||
]
|
||||
"path": "api/{version}/booking/{**catch-all}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"clusters": {
|
||||
"flight": {
|
||||
"destinations": {
|
||||
"destination1": {
|
||||
"address": "http://localhost:5004"
|
||||
"address": "https://localhost:5003"
|
||||
}
|
||||
}
|
||||
},
|
||||
"identity": {
|
||||
"destinations": {
|
||||
"destination1": {
|
||||
"address": "http://localhost:6005"
|
||||
"address": "https://localhost:5005"
|
||||
}
|
||||
}
|
||||
},
|
||||
"passenger": {
|
||||
"destinations": {
|
||||
"destination1": {
|
||||
"address": "http://localhost:6012"
|
||||
"address": "https://localhost:5012"
|
||||
}
|
||||
}
|
||||
},
|
||||
"booking": {
|
||||
"destinations": {
|
||||
"destination1": {
|
||||
"address": "http://localhost:6010"
|
||||
"address": "https://localhost:5010"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"Jwt": {
|
||||
"Authority": "https://localhost:5005"
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Sdk Name="Aspire.AppHost.SDK" Version="13.1.1"/>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsAspireHost>true</IsAspireHost>
|
||||
<UserSecretsId>bde28db3-85ba-4201-b889-0f3faba24169</UserSecretsId>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Aspire.Hosting.AppHost" Version="13.1.1" />
|
||||
<PackageReference Include="Aspire.Hosting.Docker" Version="13.1.1-preview.1.26105.8" />
|
||||
<PackageReference Include="Aspire.Hosting.MongoDB" Version="13.1.1" />
|
||||
<PackageReference Include="Aspire.Hosting.PostgreSQL" Version="13.1.1" />
|
||||
<PackageReference Include="Aspire.Hosting.RabbitMQ" Version="13.1.1" />
|
||||
<PackageReference Include="Aspire.Hosting.Redis" Version="13.1.1" />
|
||||
<PackageReference Include="CommunityToolkit.Aspire.Hosting.EventStore" Version="9.9.0" />
|
||||
<PackageReference Include="Elastic.Aspire.Hosting.Elasticsearch" Version="9.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\ApiGateway\src\ApiGateway.csproj" />
|
||||
<ProjectReference Include="..\..\..\Services\Booking\src\Booking.Api\Booking.Api.csproj" />
|
||||
<ProjectReference Include="..\..\..\Services\Flight\src\Flight.Api\Flight.Api.csproj" />
|
||||
<ProjectReference Include="..\..\..\Services\Identity\src\Identity.Api\Identity.Api.csproj" />
|
||||
<ProjectReference Include="..\..\..\Services\Passenger\src\Passenger.Api\Passenger.Api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,366 +0,0 @@
|
||||
using System.Net.Sockets;
|
||||
|
||||
var builder = DistributedApplication.CreateBuilder(args);
|
||||
|
||||
builder.AddDockerComposeEnvironment("docker-compose");
|
||||
|
||||
// 1. Database Services
|
||||
var pgUsername = builder.AddParameter("pg-username", "postgres", secret: true);
|
||||
var pgPassword = builder.AddParameter("pg-password", "postgres", secret: true);
|
||||
|
||||
var postgres = builder.AddPostgres("postgres", pgUsername, pgPassword)
|
||||
.WithImage("postgres:latest")
|
||||
.WithEndpoint(
|
||||
"tcp",
|
||||
e =>
|
||||
{
|
||||
e.Port = 5432;
|
||||
e.TargetPort = 5432;
|
||||
e.IsProxied = true;
|
||||
e.IsExternal = false;
|
||||
})
|
||||
.WithArgs(
|
||||
"-c",
|
||||
"wal_level=logical",
|
||||
"-c",
|
||||
"max_prepared_transactions=10");
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
postgres.WithDataVolume("postgres-data")
|
||||
.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
|
||||
var flightDb = postgres.AddDatabase("flight");
|
||||
var passengerDb = postgres.AddDatabase("passenger");
|
||||
var identityDb = postgres.AddDatabase("identity");
|
||||
var persistMessageDb = postgres.AddDatabase("persist-message");
|
||||
|
||||
var mongoUsername = builder.AddParameter("mongo-username", "root", secret: true);
|
||||
var mongoPassword = builder.AddParameter("mongo-password", "secret", secret: true);
|
||||
|
||||
var mongo = builder.AddMongoDB("mongo", userName: mongoUsername, password: mongoPassword)
|
||||
.WithImage("mongo")
|
||||
.WithImageTag("latest")
|
||||
.WithEndpoint(
|
||||
"tcp",
|
||||
e =>
|
||||
{
|
||||
e.Port = 27017;
|
||||
e.TargetPort = 27017;
|
||||
e.IsProxied = true;
|
||||
e.IsExternal = false;
|
||||
});
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
mongo.WithDataVolume("mongo-data")
|
||||
.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
|
||||
var redis = builder.AddRedis("redis")
|
||||
.WithImage("redis:latest")
|
||||
.WithEndpoint(
|
||||
"tcp",
|
||||
e =>
|
||||
{
|
||||
e.Port = 6379;
|
||||
e.TargetPort = 6379;
|
||||
e.IsProxied = true;
|
||||
e.IsExternal = false;
|
||||
});
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
redis.WithDataVolume("redis-data")
|
||||
.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
|
||||
var eventstore = builder.AddEventStore("eventstore")
|
||||
.WithImage("eventstore/eventstore")
|
||||
.WithEnvironment("EVENTSTORE_CLUSTER_SIZE", "1")
|
||||
.WithEnvironment("EVENTSTORE_RUN_PROJECTIONS", "All")
|
||||
.WithEnvironment("EVENTSTORE_START_STANDARD_PROJECTIONS", "True")
|
||||
.WithEnvironment("EVENTSTORE_INSECURE", "True")
|
||||
.WithEnvironment("EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP", "True")
|
||||
.WithEndpoint(
|
||||
"http",
|
||||
e =>
|
||||
{
|
||||
e.TargetPort = 2113;
|
||||
e.Port = 2113;
|
||||
e.IsProxied = true;
|
||||
e.IsExternal = true;
|
||||
})
|
||||
.WithEndpoint(
|
||||
port: 1113,
|
||||
targetPort: 1113,
|
||||
name: "tcp",
|
||||
isProxied: true,
|
||||
isExternal: false);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
eventstore.WithDataVolume("eventstore-data")
|
||||
.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
// 2. Messaging Services
|
||||
var rabbitmqUsername = builder.AddParameter("rabbitmq-username", "guest", secret: true);
|
||||
var rabbitmqPassword = builder.AddParameter("rabbitmq-password", "guest", secret: true);
|
||||
|
||||
var rabbitmq = builder.AddRabbitMQ("rabbitmq", rabbitmqUsername, rabbitmqPassword)
|
||||
.WithManagementPlugin()
|
||||
.WithEndpoint(
|
||||
"tcp",
|
||||
e =>
|
||||
{
|
||||
e.TargetPort = 5672;
|
||||
e.Port = 5672;
|
||||
e.IsProxied = true;
|
||||
e.IsExternal = false;
|
||||
})
|
||||
.WithEndpoint(
|
||||
"management",
|
||||
e =>
|
||||
{
|
||||
e.TargetPort = 15672;
|
||||
e.Port = 15672;
|
||||
e.IsProxied = true;
|
||||
e.IsExternal = true;
|
||||
});
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
rabbitmq.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
// // 3. Observability Services
|
||||
var jaeger = builder.AddContainer("jaeger-all-in-one", "jaegertracing/all-in-one")
|
||||
.WithEndpoint(
|
||||
port: 6831,
|
||||
targetPort: 6831,
|
||||
name: "agent",
|
||||
protocol: ProtocolType.Udp,
|
||||
isProxied: true,
|
||||
isExternal: false)
|
||||
.WithEndpoint(port: 16686, targetPort: 16686, name: "http", isProxied: true, isExternal: true)
|
||||
.WithEndpoint(port: 14268, targetPort: 14268, name: "collector", isProxied: true, isExternal: false)
|
||||
.WithEndpoint(port: 14317, targetPort: 4317, name: "otlp-grpc", isProxied: true, isExternal: false)
|
||||
.WithEndpoint(port: 14318, targetPort: 4318, name: "otlp-http", isProxied: true, isExternal: false);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
jaeger.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var zipkin = builder.AddContainer("zipkin-all-in-one", "openzipkin/zipkin")
|
||||
.WithEndpoint(port: 9411, targetPort: 9411, name: "http", isProxied: true, isExternal: true);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
zipkin.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var otelCollector = builder.AddContainer("otel-collector", "otel/opentelemetry-collector-contrib")
|
||||
.WithBindMount(
|
||||
"../../../../deployments/configs/otel-collector-config.yaml",
|
||||
"/etc/otelcol-contrib/config.yaml",
|
||||
isReadOnly: true)
|
||||
.WithArgs("--config=/etc/otelcol-contrib/config.yaml")
|
||||
.WithEndpoint(port: 11888, targetPort: 1888, name: "otel-pprof", isProxied: true, isExternal: true)
|
||||
.WithEndpoint(port: 8888, targetPort: 8888, name: "otel-metrics", isProxied: true, isExternal: true)
|
||||
.WithEndpoint(port: 8889, targetPort: 8889, name: "otel-exporter-metrics", isProxied: true, isExternal: true)
|
||||
.WithEndpoint(port: 13133, targetPort: 13133, name: "otel-health", isProxied: true, isExternal: true)
|
||||
.WithEndpoint(port: 4317, targetPort: 4317, name: "otel-grpc", isProxied: true, isExternal: true)
|
||||
.WithEndpoint(port: 4318, targetPort: 4318, name: "otel-http", isProxied: true, isExternal: true)
|
||||
.WithEndpoint(port: 55679, targetPort: 55679, name: "otel-zpages", isProxied: true, isExternal: true);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
otelCollector.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var prometheus = builder.AddContainer("prometheus", "prom/prometheus")
|
||||
.WithBindMount("../../../../deployments/configs/prometheus.yaml", "/etc/prometheus/prometheus.yml")
|
||||
.WithArgs(
|
||||
"--config.file=/etc/prometheus/prometheus.yml",
|
||||
"--storage.tsdb.path=/prometheus",
|
||||
"--web.console.libraries=/usr/share/prometheus/console_libraries",
|
||||
"--web.console.templates=/usr/share/prometheus/consoles",
|
||||
"--web.enable-remote-write-receiver")
|
||||
.WithEndpoint(port: 9090, targetPort: 9090, name: "http", isProxied: true, isExternal: true);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
prometheus.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var grafana = builder.AddContainer("grafana", "grafana/grafana")
|
||||
.WithEnvironment("GF_INSTALL_PLUGINS", "grafana-clock-panel,grafana-simple-json-datasource")
|
||||
.WithEnvironment("GF_SECURITY_ADMIN_USER", "admin")
|
||||
.WithEnvironment("GF_SECURITY_ADMIN_PASSWORD", "admin")
|
||||
.WithEnvironment("GF_FEATURE_TOGGLES_ENABLE", "traceqlEditor")
|
||||
.WithBindMount("../../../../deployments/configs/grafana/provisioning", "/etc/grafana/provisioning")
|
||||
.WithBindMount("../../../../deployments/configs/grafana/dashboards", "/var/lib/grafana/dashboards")
|
||||
.WithEndpoint(port: 3000, targetPort: 3000, name: "http", isProxied: true, isExternal: true);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
grafana.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var nodeExporter = builder.AddContainer("node-exporter", "prom/node-exporter")
|
||||
.WithBindMount("/proc", "/host/proc", isReadOnly: true)
|
||||
.WithBindMount("/sys", "/host/sys", isReadOnly: true)
|
||||
.WithBindMount("/", "/rootfs", isReadOnly: true)
|
||||
.WithArgs(
|
||||
"--path.procfs=/host/proc",
|
||||
"--path.rootfs=/rootfs",
|
||||
"--path.sysfs=/host/sys")
|
||||
.WithEndpoint(port: 9101, targetPort: 9100, name: "http", isProxied: true, isExternal: true);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
nodeExporter.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var tempo = builder.AddContainer("tempo", "grafana/tempo")
|
||||
.WithBindMount("../../../../deployments/configs/tempo.yaml", "/etc/tempo.yaml", isReadOnly: true)
|
||||
.WithArgs("--config.file=/etc/tempo.yaml")
|
||||
.WithEndpoint(port: 3200, targetPort: 3200, name: "http", isProxied: true, isExternal: false)
|
||||
.WithEndpoint(port: 9095, targetPort: 9095, name: "grpc", isProxied: true, isExternal: false)
|
||||
.WithEndpoint(port: 4317, targetPort: 4317, name: "otlp-grpc", isProxied: true, isExternal: false)
|
||||
.WithEndpoint(port: 4318, targetPort: 4318, name: "otlp-http", isProxied: true, isExternal: false);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
tempo.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var loki = builder.AddContainer("loki", "grafana/loki")
|
||||
.WithBindMount("../../../../deployments/configs/loki-config.yaml", "/etc/loki/local-config.yaml", isReadOnly: true)
|
||||
.WithArgs("-config.file=/etc/loki/local-config.yaml")
|
||||
.WithEndpoint(port: 3100, targetPort: 3100, name: "http", isProxied: true, isExternal: false)
|
||||
.WithEndpoint(port: 9096, targetPort: 9096, name: "grpc", isProxied: true, isExternal: false);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
loki.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var elasticsearch = builder.AddElasticsearch("elasticsearch")
|
||||
.WithImage("docker.elastic.co/elasticsearch/elasticsearch:8.17.0")
|
||||
.WithEnvironment("discovery.type", "single-node")
|
||||
.WithEnvironment("cluster.name", "docker-cluster")
|
||||
.WithEnvironment("node.name", "docker-node")
|
||||
.WithEnvironment("ES_JAVA_OPTS", "-Xms512m -Xmx512m")
|
||||
.WithEnvironment("xpack.security.enabled", "false")
|
||||
.WithEnvironment("xpack.security.http.ssl.enabled", "false")
|
||||
.WithEnvironment("xpack.security.transport.ssl.enabled", "false")
|
||||
.WithEnvironment("network.host", "0.0.0.0")
|
||||
.WithEnvironment("http.port", "9200")
|
||||
.WithEnvironment("transport.host", "localhost")
|
||||
.WithEnvironment("bootstrap.memory_lock", "true")
|
||||
.WithEnvironment("cluster.routing.allocation.disk.threshold_enabled", "false")
|
||||
.WithEndpoint(
|
||||
"http",
|
||||
e =>
|
||||
{
|
||||
e.TargetPort = 9200;
|
||||
e.Port = 9200;
|
||||
e.IsProxied = true;
|
||||
e.IsExternal = false;
|
||||
})
|
||||
.WithEndpoint(
|
||||
"internal",
|
||||
e =>
|
||||
{
|
||||
e.TargetPort = 9300;
|
||||
e.Port = 9300;
|
||||
e.IsProxied = true;
|
||||
e.IsExternal = false;
|
||||
})
|
||||
.WithDataVolume("elastic-data");
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
elasticsearch.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
var kibana = builder.AddContainer("kibana", "docker.elastic.co/kibana/kibana:8.17.0")
|
||||
.WithEnvironment("ELASTICSEARCH_HOSTS", "http://elasticsearch:9200")
|
||||
.WithEndpoint(port: 5601, targetPort: 5601, name: "http", isProxied: true, isExternal: true)
|
||||
.WithReference(elasticsearch)
|
||||
.WaitFor(elasticsearch);
|
||||
|
||||
if (builder.ExecutionContext.IsPublishMode)
|
||||
{
|
||||
kibana.WithLifetime(ContainerLifetime.Persistent);
|
||||
}
|
||||
|
||||
// 5. Application Services
|
||||
var identity = builder.AddProject<Projects.Identity_Api>("identity-service")
|
||||
.WithReference(persistMessageDb)
|
||||
.WaitFor(persistMessageDb)
|
||||
.WithReference(identityDb)
|
||||
.WaitFor(identityDb)
|
||||
.WithReference(mongo)
|
||||
.WaitFor(mongo)
|
||||
.WithReference(rabbitmq)
|
||||
.WaitFor(rabbitmq)
|
||||
.WithHttpEndpoint(port: 6005, name: "identity-http")
|
||||
.WithHttpsEndpoint(port: 5005, name: "identity-https");
|
||||
|
||||
var passenger = builder.AddProject<Projects.Passenger_Api>("passenger-service")
|
||||
.WithReference(persistMessageDb)
|
||||
.WaitFor(persistMessageDb)
|
||||
.WithReference(passengerDb)
|
||||
.WaitFor(passengerDb)
|
||||
.WithReference(mongo)
|
||||
.WaitFor(mongo)
|
||||
.WithReference(rabbitmq)
|
||||
.WaitFor(rabbitmq)
|
||||
.WithHttpEndpoint(port: 6012, name: "passenger-http")
|
||||
.WithHttpsEndpoint(port: 5012, name: "passenger-https");
|
||||
|
||||
var flight = builder.AddProject<Projects.Flight_Api>("flight-service")
|
||||
.WithReference(persistMessageDb)
|
||||
.WaitFor(persistMessageDb)
|
||||
.WithReference(flightDb)
|
||||
.WaitFor(flightDb)
|
||||
.WithReference(mongo)
|
||||
.WaitFor(mongo)
|
||||
.WithReference(rabbitmq)
|
||||
.WaitFor(rabbitmq)
|
||||
.WithHttpEndpoint(port: 5004, name: "flight-http")
|
||||
.WithHttpsEndpoint(port: 5003, name: "flight-https");
|
||||
|
||||
var booking = builder.AddProject<Projects.Booking_Api>("booking-service")
|
||||
.WithReference(persistMessageDb)
|
||||
.WaitFor(persistMessageDb)
|
||||
.WithReference(eventstore)
|
||||
.WaitFor(eventstore)
|
||||
.WithReference(mongo)
|
||||
.WaitFor(mongo)
|
||||
.WithReference(rabbitmq)
|
||||
.WaitFor(rabbitmq)
|
||||
.WithHttpEndpoint(port: 6010, name: "booking-http")
|
||||
.WithHttpsEndpoint(port: 5010, name: "booking-https");
|
||||
|
||||
var gateway = builder.AddProject<Projects.ApiGateway>("api-gateway")
|
||||
.WithReference(flight)
|
||||
.WaitFor(flight)
|
||||
.WithReference(passenger)
|
||||
.WaitFor(passenger)
|
||||
.WithReference(identity)
|
||||
.WaitFor(identity)
|
||||
.WithReference(booking)
|
||||
.WaitFor(booking)
|
||||
.WithHttpEndpoint(port: 5001, name: "gateway-http")
|
||||
.WithHttpsEndpoint(port: 5000, name: "gateway-https");
|
||||
|
||||
builder.Build().Run();
|
||||
@ -1,18 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"profiles": {
|
||||
"AppHost": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:18888",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development",
|
||||
"DOTNET_ENVIRONMENT": "Development",
|
||||
"ASPIRE_ALLOW_UNSECURED_TRANSPORT": "true",
|
||||
"ASPIRE_DASHBOARD_OTLP_ENDPOINT_URL": "http://otel-collector:4317",
|
||||
"ASPIRE_DASHBOARD_OTLP_HTTP_ENDPOINT_URL": "http://otel-collector:4318"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,8 +0,0 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
@ -1,41 +0,0 @@
|
||||
using BuildingBlocks.HealthCheck;
|
||||
using BuildingBlocks.OpenTelemetryCollector;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace ServiceDefaults;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static IHostApplicationBuilder AddServiceDefaults(this WebApplicationBuilder builder)
|
||||
{
|
||||
builder.Services.AddCustomHealthCheck();
|
||||
builder.AddCustomObservability();
|
||||
builder.Services.AddServiceDiscovery();
|
||||
|
||||
builder.Services.ConfigureHttpClientDefaults(http =>
|
||||
{
|
||||
http.AddStandardResilienceHandler(options =>
|
||||
{
|
||||
var timeSpan = TimeSpan.FromMinutes(1);
|
||||
options.CircuitBreaker.SamplingDuration = timeSpan * 2;
|
||||
options.TotalRequestTimeout.Timeout = timeSpan * 3;
|
||||
options.Retry.MaxRetryAttempts = 3;
|
||||
});
|
||||
|
||||
// Turn on service discovery by default
|
||||
http.AddServiceDiscovery();
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static WebApplication UseServiceDefaults(this WebApplication app)
|
||||
{
|
||||
app.UseCustomHealthCheck();
|
||||
app.UseCustomObservability();
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\BuildingBlocks\BuildingBlocks.csproj" IsAspireProjectResource="false" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,110 +1,160 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.GuardClauses" Version="5.0.0" />
|
||||
<PackageReference Include="Asp.Versioning.Abstractions" Version="8.1.0" />
|
||||
<PackageReference Include="Asp.Versioning.Http" Version="8.1.1" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.1" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.1" />
|
||||
<PackageReference Include="Figgle.Fonts" Version="0.6.5" />
|
||||
<PackageReference Include="Ardalis.GuardClauses" Version="4.0.1" />
|
||||
<PackageReference Include="Asp.Versioning.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Asp.Versioning.Http" Version="7.0.0" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc" Version="7.0.0" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="7.0.0" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Elasticsearch" Version="6.0.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.EventStore" Version="6.0.3" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="6.0.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="6.0.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.SQLite.Storage" Version="6.0.5" />
|
||||
<PackageReference Include="Ben.BlockingDetector" Version="0.0.4" />
|
||||
<PackageReference Include="EasyCaching.Core" Version="1.8.0" />
|
||||
<PackageReference Include="EasyCaching.InMemory" Version="1.8.0" />
|
||||
<PackageReference Include="EasyNetQ.Management.Client" Version="1.4.2" />
|
||||
<PackageReference Include="EFCore.NamingConventions" Version="7.0.2" />
|
||||
<PackageReference Include="EntityFrameworkCore.Triggered" Version="3.2.2" />
|
||||
<PackageReference Include="Figgle" Version="0.5.1" />
|
||||
<PackageReference Include="FluentValidation" Version="11.4.0" />
|
||||
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
|
||||
<PackageReference Include="Grpc.Core.Testing" Version="2.46.6" />
|
||||
<PackageReference Include="EasyCaching.Core" Version="1.9.2" />
|
||||
<PackageReference Include="EasyCaching.InMemory" Version="1.9.2" />
|
||||
<PackageReference Include="EasyNetQ.Management.Client" Version="3.0.1" />
|
||||
<PackageReference Include="EFCore.NamingConventions" Version="10.0.1" />
|
||||
<PackageReference Include="Figgle" Version="0.6.5" />
|
||||
<PackageReference Include="FluentValidation" Version="12.1.1" />
|
||||
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Resilience" Version="10.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" Version="10.3.0" />
|
||||
<PackageReference Include="Npgsql" Version="10.0.1" />
|
||||
<PackageReference Include="NSubstitute" Version="5.3.0" />
|
||||
<PackageReference Include="Polly" Version="8.6.5" />
|
||||
<PackageReference Include="Humanizer.Core" Version="3.0.1" />
|
||||
<PackageReference Include="IdGen" Version="3.0.7" />
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
<PackageReference Include="Mapster.DependencyInjection" Version="1.0.1" />
|
||||
<PackageReference Include="MediatR" Version="14.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.3" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="3.6.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="Scalar.AspNetCore" Version="2.12.38" />
|
||||
<PackageReference Include="Scrutor" Version="7.0.0" />
|
||||
<PackageReference Include="Sieve" Version="2.5.5" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="10.1.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="10.1.2" />
|
||||
<PackageReference Include="MassTransit" Version="8.5.8" />
|
||||
<PackageReference Include="MassTransit.RabbitMQ" Version="8.5.8" />
|
||||
<PackageReference Include="Duende.IdentityServer" Version="7.4.5" />
|
||||
<PackageReference Include="Duende.IdentityServer.AspNetIdentity" Version="7.4.5" />
|
||||
<PackageReference Include="Duende.IdentityServer.EntityFramework" Version="7.4.5" />
|
||||
<PackageReference Include="Duende.IdentityServer.EntityFramework.Storage" Version="7.4.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="10.0.3" />
|
||||
<PackageReference Include="System.Linq.Async" Version="7.0.0" />
|
||||
<PackageReference Include="System.Linq.Async.Queryable" Version="7.0.0" />
|
||||
<PackageReference Include="Testcontainers" Version="4.9.0" />
|
||||
<PackageReference Include="Testcontainers.EventStoreDb" Version="4.9.0" />
|
||||
<PackageReference Include="Testcontainers.MongoDb" Version="4.9.0" />
|
||||
<PackageReference Include="Testcontainers.PostgreSql" Version="4.9.0" />
|
||||
<PackageReference Include="Testcontainers.RabbitMq" Version="4.9.0" />
|
||||
<PackageReference Include="xunit.abstractions" Version="2.0.3" />
|
||||
<PackageReference Include="xunit.extensibility.core" Version="2.9.3" />
|
||||
<PackageReference Include="Xunit.Extensions.Logging" Version="1.1.0" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" Version="2.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="10.0.3" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="9.0.0" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="9.0.0" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="9.0.0" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.EventStore" Version="9.0.0" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="9.0.0" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="9.0.0" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="9.0.0" />
|
||||
|
||||
<PackageReference Include="Npgsql.OpenTelemetry" Version="10.0.1" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.0" />
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.15.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.15.0-beta.1" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.15.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Process" Version="1.15.0-beta.1" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.15.0-beta.1" />
|
||||
<PackageReference Include="Grafana.OpenTelemetry" Version="1.5.2" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.15.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="1.15.0" />
|
||||
|
||||
<PackageReference Include="EventStore.Client.Grpc.Streams" Version="23.3.9" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
|
||||
|
||||
<PackageReference Include="AutoBogus" Version="2.13.1" />
|
||||
<PackageReference Include="Bogus" Version="35.6.5" />
|
||||
<PackageReference Include="FluentAssertions" Version="8.8.0" />
|
||||
<PackageReference Include="Respawn" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.3" />
|
||||
<PackageReference Include="WebMotions.Fake.Authentication.JwtBearer" Version="10.0.0" />
|
||||
|
||||
<PackageReference Include="Google.Protobuf" Version="3.33.5" />
|
||||
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.76.0" />
|
||||
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.3">
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
||||
<PackageReference Include="Mongo2Go" Version="3.1.3" />
|
||||
<PackageReference Include="Npgsql" Version="7.0.1" />
|
||||
<PackageReference Include="NSubstitute" Version="4.4.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.0.0-rc9.7" />
|
||||
<PackageReference Include="Polly" Version="7.2.3" />
|
||||
<PackageReference Include="protobuf-net.BuildTools" Version="3.1.25">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Hellang.Middleware.ProblemDetails" Version="6.5.1" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
|
||||
<PackageReference Include="IdGen" Version="3.0.3" />
|
||||
<PackageReference Include="Mapster" Version="7.3.0" />
|
||||
<PackageReference Include="Mapster.DependencyInjection" Version="1.0.0" />
|
||||
<PackageReference Include="MediatR" Version="11.1.0" />
|
||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.18.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
<PackageReference Include="OpenTelemetry.Contrib.Instrumentation.MassTransit" Version="1.0.0-beta2" />
|
||||
<PackageReference Include="Scrutor" Version="4.2.0" />
|
||||
<PackageReference Include="Scrutor.AspNetCore" Version="3.3.0" />
|
||||
<PackageReference Include="Sentry.Serilog" Version="3.25.0" />
|
||||
<PackageReference Include="Serilog" Version="2.12.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="6.1.0" />
|
||||
<PackageReference Include="Serilog.Enrichers.Span" Version="3.1.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||
<PackageReference Include="Serilog.Formatting.Elasticsearch" Version="8.4.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="8.4.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Seq" Version="5.2.2" />
|
||||
<PackageReference Include="Serilog.Sinks.SpectreConsole" Version="0.3.3" />
|
||||
<PackageReference Include="Serilog.Sinks.XUnit" Version="3.0.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="6.5.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.5.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.5.0" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="6.0.5" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="6.0.5" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="6.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="7.0.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" Version="6.0.2" />
|
||||
<PackageReference Include="System.Interactive.Async" Version="6.0.1" />
|
||||
<PackageReference Include="MassTransit" Version="8.0.12" />
|
||||
<PackageReference Include="MassTransit.RabbitMQ" Version="8.0.12" />
|
||||
<PackageReference Include="DotNetCore.CAP" Version="7.0.2" />
|
||||
<PackageReference Include="DotNetCore.CAP.Dashboard" Version="7.0.2" />
|
||||
<PackageReference Include="DotNetCore.CAP.MongoDB" Version="7.0.2" />
|
||||
<PackageReference Include="DotNetCore.CAP.OpenTelemetry" Version="7.0.2" />
|
||||
<PackageReference Include="DotNetCore.CAP.RabbitMQ" Version="7.0.2" />
|
||||
<PackageReference Include="DotNetCore.CAP.SqlServer" Version="7.0.2" />
|
||||
<PackageReference Include="Duende.IdentityServer" Version="6.2.2" />
|
||||
<PackageReference Include="Duende.IdentityServer.AspNetIdentity" Version="6.2.2" />
|
||||
<PackageReference Include="Duende.IdentityServer.EntityFramework" Version="6.2.2" />
|
||||
<PackageReference Include="Duende.IdentityServer.EntityFramework.Storage" Version="6.2.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.2" />
|
||||
<PackageReference Include="Testcontainers" Version="2.3.0" />
|
||||
<PackageReference Include="Unchase.Swashbuckle.AspNetCore.Extensions" Version="2.7.1" />
|
||||
<PackageReference Include="WebMotions.Fake.Authentication.JwtBearer" Version="7.0.0" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" Version="1.1.1" />
|
||||
<PackageReference Include="Microsoft.Identity.Web" Version="2.0.5-preview" />
|
||||
|
||||
<PackageReference Include="Jaeger" Version="1.0.3" />
|
||||
<PackageReference Include="OpenTracing" Version="0.12.1" />
|
||||
<PackageReference Include="prometheus-net" Version="7.0.0" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Version="7.0.0" />
|
||||
|
||||
<PackageReference Include="OpenTelemetry" Version="1.4.0-beta.1" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.4.0-beta.1" />
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.0.0-rc9.7" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.0.0-rc9.7" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.0.0-rc9.7" />
|
||||
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.0.64">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
<PackageReference Include="EventStore.Client.Grpc.Streams" Version="22.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.1" />
|
||||
|
||||
<PackageReference Include="Nito.AsyncEx" Version="5.1.2" />
|
||||
<PackageReference Include="AutoBogus" Version="2.13.1" />
|
||||
<PackageReference Include="Bogus" Version="34.0.2" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.9.0" />
|
||||
<PackageReference Include="Respawn" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="7.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.2" />
|
||||
<PackageReference Include="Moq" Version="4.18.4" />
|
||||
|
||||
<PackageReference Include="Google.Protobuf" Version="3.21.12" />
|
||||
<PackageReference Include="Grpc.Net.Client" Version="2.51.0" />
|
||||
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.51.0" />
|
||||
<PackageReference Update="AsyncFixer" Version="1.6.0" />
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="1.0.758" />
|
||||
<PackageReference Remove="Microsoft.VisualStudio.Threading.Analyzers" />
|
||||
<PackageReference Update="Microsoft.VisualStudio.Threading.Analyzers" Version="17.4.27" />
|
||||
<PackageReference Update="Roslynator.Analyzers" Version="4.2.0" />
|
||||
<PackageReference Update="Roslynator.CodeAnalysis.Analyzers" Version="4.2.0" />
|
||||
<PackageReference Update="Roslynator.Formatting.Analyzers" Version="4.2.0" />
|
||||
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Contracts" />
|
||||
<Folder Include="EventStoreDB\BackgroundWorkers" />
|
||||
<Folder Include="PersistMessageProcessor\Data\Configurations" />
|
||||
<Folder Include="PersistMessageProcessor\Data\Migrations" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
55
src/BuildingBlocks/CAP/Extensions.cs
Normal file
55
src/BuildingBlocks/CAP/Extensions.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Text.Unicode;
|
||||
using BuildingBlocks.Utils;
|
||||
using BuildingBlocks.Web;
|
||||
using DotNetCore.CAP;
|
||||
using DotNetCore.CAP.Messages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BuildingBlocks.CAP;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static IServiceCollection AddCustomCap<TDbContext>(this IServiceCollection services)
|
||||
where TDbContext : DbContext
|
||||
{
|
||||
var rabbitMqOptions = services.GetOptions<RabbitMQOptions>("RabbitMq");
|
||||
|
||||
services.AddCap(x =>
|
||||
{
|
||||
x.UseEntityFramework<TDbContext>();
|
||||
x.UseRabbitMQ(o =>
|
||||
{
|
||||
o.HostName = rabbitMqOptions.HostName;
|
||||
o.UserName = rabbitMqOptions.UserName;
|
||||
o.Password = rabbitMqOptions.Password;
|
||||
});
|
||||
x.UseDashboard();
|
||||
x.FailedRetryCount = 5;
|
||||
x.FailedThresholdCallback = failed =>
|
||||
{
|
||||
var logger = failed.ServiceProvider.GetService<ILogger>();
|
||||
logger?.LogError(
|
||||
$@"A message of type {failed.MessageType} failed after executing {x.FailedRetryCount} several times,
|
||||
requiring manual troubleshooting. Message name: {failed.Message.GetName()}");
|
||||
};
|
||||
x.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
|
||||
});
|
||||
|
||||
// services.AddOpenTelemetryTracing((builder) => builder
|
||||
// .AddAspNetCoreInstrumentation()
|
||||
// .AddCapInstrumentation()
|
||||
// .AddZipkinExporter()
|
||||
// );
|
||||
|
||||
services.Scan(s =>
|
||||
s.FromAssemblies(AppDomain.CurrentDomain.GetAssemblies())
|
||||
.AddClasses(c => c.AssignableTo(typeof(ICapSubscribe)))
|
||||
.AsImplementedInterfaces()
|
||||
.WithScopedLifetime());
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
using EasyCaching.Core;
|
||||
using EasyCaching.Core;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@ -47,4 +47,4 @@ public class CachingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest,
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,4 +4,4 @@ public interface ICacheRequest
|
||||
{
|
||||
string CacheKey { get; }
|
||||
DateTime? AbsoluteExpirationRelativeToNow { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,4 +4,4 @@ namespace BuildingBlocks.Caching
|
||||
{
|
||||
string CacheKey { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,4 +36,4 @@ namespace BuildingBlocks.Caching
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +0,0 @@
|
||||
namespace BuildingBlocks.Constants;
|
||||
|
||||
public static class IdentityConstant
|
||||
{
|
||||
public static class Role
|
||||
{
|
||||
public const string Admin = "admin";
|
||||
public const string User = "user";
|
||||
}
|
||||
}
|
||||
@ -2,10 +2,10 @@ using BuildingBlocks.Core.Event;
|
||||
|
||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||
|
||||
public record FlightCreated(Guid Id) : IIntegrationEvent;
|
||||
public record FlightUpdated(Guid Id) : IIntegrationEvent;
|
||||
public record FlightDeleted(Guid Id) : IIntegrationEvent;
|
||||
public record AircraftCreated(Guid Id) : IIntegrationEvent;
|
||||
public record AirportCreated(Guid Id) : IIntegrationEvent;
|
||||
public record SeatCreated(Guid Id) : IIntegrationEvent;
|
||||
public record SeatReserved(Guid Id) : IIntegrationEvent;
|
||||
public record FlightCreated(long Id) : IIntegrationEvent;
|
||||
public record FlightUpdated(long Id) : IIntegrationEvent;
|
||||
public record FlightDeleted(long Id) : IIntegrationEvent;
|
||||
public record AircraftCreated(long Id) : IIntegrationEvent;
|
||||
public record AirportCreated(long Id) : IIntegrationEvent;
|
||||
public record SeatCreated(long Id) : IIntegrationEvent;
|
||||
public record SeatReserved(long Id) : IIntegrationEvent;
|
||||
|
||||
@ -2,4 +2,4 @@ using BuildingBlocks.Core.Event;
|
||||
|
||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||
|
||||
public record UserCreated(Guid Id, string Name, string PassportNumber) : IIntegrationEvent;
|
||||
public record UserCreated(long Id, string Name, string PassportNumber) : IIntegrationEvent;
|
||||
|
||||
@ -2,5 +2,5 @@ using BuildingBlocks.Core.Event;
|
||||
|
||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||
|
||||
public record PassengerRegistrationCompleted(Guid Id) : IIntegrationEvent;
|
||||
public record PassengerCreated(Guid Id) : IIntegrationEvent;
|
||||
public record PassengerRegistrationCompleted(long Id) : IIntegrationEvent;
|
||||
public record PassengerCreated(long Id) : IIntegrationEvent;
|
||||
|
||||
@ -2,4 +2,4 @@ using BuildingBlocks.Core.Event;
|
||||
|
||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||
|
||||
public record BookingCreated(Guid Id) : IIntegrationEvent;
|
||||
public record BookingCreated(long Id) : IIntegrationEvent;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.CQRS;
|
||||
|
||||
@ -9,4 +9,4 @@ public interface ICommand : ICommand<Unit>
|
||||
public interface ICommand<out T> : IRequest<T>
|
||||
where T : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.CQRS;
|
||||
|
||||
@ -11,4 +11,4 @@ public interface ICommandHandler<in TCommand, TResponse> : IRequestHandler<TComm
|
||||
where TCommand : ICommand<TResponse>
|
||||
where TResponse : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.CQRS;
|
||||
|
||||
public interface IQuery<out T> : IRequest<T>
|
||||
where T : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.CQRS;
|
||||
|
||||
@ -6,4 +6,4 @@ public interface IQueryHandler<in TQuery, TResponse> : IRequestHandler<TQuery, T
|
||||
where TQuery : IQuery<TResponse>
|
||||
where TResponse : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
using BuildingBlocks.Core.Event;
|
||||
|
||||
namespace BuildingBlocks.Core;
|
||||
|
||||
public class CompositeEventMapper : IEventMapper
|
||||
{
|
||||
private readonly IEnumerable<IEventMapper> _mappers;
|
||||
|
||||
public CompositeEventMapper(IEnumerable<IEventMapper> mappers)
|
||||
{
|
||||
_mappers = mappers;
|
||||
}
|
||||
|
||||
public IIntegrationEvent? MapToIntegrationEvent(IDomainEvent @event)
|
||||
{
|
||||
foreach (var mapper in _mappers)
|
||||
{
|
||||
var integrationEvent = mapper.MapToIntegrationEvent(@event);
|
||||
if (integrationEvent is not null)
|
||||
return integrationEvent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IInternalCommand? MapToInternalCommand(IDomainEvent @event)
|
||||
{
|
||||
foreach (var mapper in _mappers)
|
||||
{
|
||||
var internalCommand = mapper.MapToInternalCommand(@event);
|
||||
if (internalCommand is not null)
|
||||
return internalCommand;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -6,4 +6,4 @@ public enum EventType
|
||||
DomainEvent = 1,
|
||||
IntegrationEvent = 2,
|
||||
InternalCommand = 4
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,4 +2,4 @@ namespace BuildingBlocks.Core.Event;
|
||||
|
||||
public interface IDomainEvent : IEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
using BuildingBlocks.IdsGenerator;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
|
||||
using global::MassTransit;
|
||||
|
||||
public interface IEvent : INotification
|
||||
{
|
||||
Guid EventId => NewId.NextGuid();
|
||||
long EventId => SnowFlakIdGenerator.NewId();
|
||||
public DateTime OccurredOn => DateTime.Now;
|
||||
public string EventType => GetType().AssemblyQualifiedName;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,4 +5,4 @@ namespace BuildingBlocks.Core.Event;
|
||||
[ExcludeFromTopology]
|
||||
public interface IIntegrationEvent : IEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
|
||||
public interface IInternalCommand : IEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using BuildingBlocks.Core.CQRS;
|
||||
using BuildingBlocks.Core.CQRS;
|
||||
using BuildingBlocks.IdsGenerator;
|
||||
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
|
||||
public record InternalCommand : IInternalCommand, ICommand;
|
||||
public record InternalCommand : IInternalCommand, ICommand;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf;
|
||||
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
|
||||
@ -23,4 +23,4 @@ public class MessageEnvelope<TMessage> : MessageEnvelope
|
||||
}
|
||||
|
||||
public new TMessage? Message { get; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,17 +9,30 @@ using MessageEnvelope = BuildingBlocks.Core.Event.MessageEnvelope;
|
||||
|
||||
namespace BuildingBlocks.Core;
|
||||
|
||||
public sealed class EventDispatcher(
|
||||
IServiceScopeFactory serviceScopeFactory,
|
||||
IEventMapper eventMapper,
|
||||
ILogger<EventDispatcher> logger,
|
||||
IPersistMessageProcessor persistMessageProcessor,
|
||||
IHttpContextAccessor httpContextAccessor
|
||||
)
|
||||
: IEventDispatcher
|
||||
public sealed class EventDispatcher : IEventDispatcher
|
||||
{
|
||||
private readonly IEventMapper _eventMapper;
|
||||
private readonly ILogger<EventDispatcher> _logger;
|
||||
private readonly IPersistMessageProcessor _persistMessageProcessor;
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
||||
|
||||
public EventDispatcher(IServiceScopeFactory serviceScopeFactory,
|
||||
IEventMapper eventMapper,
|
||||
ILogger<EventDispatcher> logger,
|
||||
IPersistMessageProcessor persistMessageProcessor,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_serviceScopeFactory = serviceScopeFactory;
|
||||
_eventMapper = eventMapper;
|
||||
_logger = logger;
|
||||
_persistMessageProcessor = persistMessageProcessor;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
|
||||
public async Task SendAsync<T>(IReadOnlyList<T> events, Type type = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
CancellationToken cancellationToken = default)
|
||||
where T : IEvent
|
||||
{
|
||||
if (events.Count > 0)
|
||||
@ -32,7 +45,7 @@ public sealed class EventDispatcher(
|
||||
{
|
||||
foreach (var integrationEvent in integrationEvents)
|
||||
{
|
||||
await persistMessageProcessor.PublishMessageAsync(
|
||||
await _persistMessageProcessor.PublishMessageAsync(
|
||||
new MessageEnvelope(integrationEvent, SetHeaders()),
|
||||
cancellationToken);
|
||||
}
|
||||
@ -41,13 +54,13 @@ public sealed class EventDispatcher(
|
||||
switch (events)
|
||||
{
|
||||
case IReadOnlyList<IDomainEvent> domainEvents:
|
||||
{
|
||||
var integrationEvents = await MapDomainEventToIntegrationEventAsync(domainEvents)
|
||||
{
|
||||
var integrationEvents = await MapDomainEventToIntegrationEventAsync(domainEvents)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
await PublishIntegrationEvent(integrationEvents);
|
||||
break;
|
||||
}
|
||||
await PublishIntegrationEvent(integrationEvents);
|
||||
break;
|
||||
}
|
||||
|
||||
case IReadOnlyList<IIntegrationEvent> integrationEvents:
|
||||
await PublishIntegrationEvent(integrationEvents);
|
||||
@ -61,7 +74,7 @@ public sealed class EventDispatcher(
|
||||
|
||||
foreach (var internalMessage in internalMessages)
|
||||
{
|
||||
await persistMessageProcessor.AddInternalMessageAsync(internalMessage, cancellationToken);
|
||||
await _persistMessageProcessor.AddInternalMessageAsync(internalMessage, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -70,34 +83,33 @@ public sealed class EventDispatcher(
|
||||
public async Task SendAsync<T>(T @event, Type type = null,
|
||||
CancellationToken cancellationToken = default)
|
||||
where T : IEvent =>
|
||||
await SendAsync(new[] { @event }, type, cancellationToken);
|
||||
await SendAsync(new[] {@event}, type, cancellationToken);
|
||||
|
||||
|
||||
private Task<IReadOnlyList<IIntegrationEvent>> MapDomainEventToIntegrationEventAsync(
|
||||
IReadOnlyList<IDomainEvent> events)
|
||||
{
|
||||
logger.LogTrace("Processing integration events start...");
|
||||
_logger.LogTrace("Processing integration events start...");
|
||||
|
||||
var wrappedIntegrationEvents = GetWrappedIntegrationEvents(events.ToList())?.ToList();
|
||||
if (wrappedIntegrationEvents?.Count > 0)
|
||||
return Task.FromResult<IReadOnlyList<IIntegrationEvent>>(wrappedIntegrationEvents);
|
||||
|
||||
var integrationEvents = new List<IIntegrationEvent>();
|
||||
using var scope = serviceScopeFactory.CreateScope();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
foreach (var @event in events)
|
||||
{
|
||||
var eventType = @event.GetType();
|
||||
logger.LogTrace($"Handling domain event: {eventType.Name}");
|
||||
_logger.LogTrace($"Handling domain event: {eventType.Name}");
|
||||
|
||||
var integrationEvent = eventMapper.MapToIntegrationEvent(@event);
|
||||
var integrationEvent = _eventMapper.MapToIntegrationEvent(@event);
|
||||
|
||||
if (integrationEvent is null)
|
||||
continue;
|
||||
if (integrationEvent is null) continue;
|
||||
|
||||
integrationEvents.Add(integrationEvent);
|
||||
}
|
||||
|
||||
logger.LogTrace("Processing integration events done...");
|
||||
_logger.LogTrace("Processing integration events done...");
|
||||
|
||||
return Task.FromResult<IReadOnlyList<IIntegrationEvent>>(integrationEvents);
|
||||
}
|
||||
@ -106,24 +118,23 @@ public sealed class EventDispatcher(
|
||||
private Task<IReadOnlyList<IInternalCommand>> MapDomainEventToInternalCommandAsync(
|
||||
IReadOnlyList<IDomainEvent> events)
|
||||
{
|
||||
logger.LogTrace("Processing internal message start...");
|
||||
_logger.LogTrace("Processing internal message start...");
|
||||
|
||||
var internalCommands = new List<IInternalCommand>();
|
||||
using var scope = serviceScopeFactory.CreateScope();
|
||||
using var scope = _serviceScopeFactory.CreateScope();
|
||||
foreach (var @event in events)
|
||||
{
|
||||
var eventType = @event.GetType();
|
||||
logger.LogTrace($"Handling domain event: {eventType.Name}");
|
||||
_logger.LogTrace($"Handling domain event: {eventType.Name}");
|
||||
|
||||
var integrationEvent = eventMapper.MapToInternalCommand(@event);
|
||||
var integrationEvent = _eventMapper.MapToInternalCommand(@event);
|
||||
|
||||
if (integrationEvent is null)
|
||||
continue;
|
||||
if (integrationEvent is null) continue;
|
||||
|
||||
internalCommands.Add(integrationEvent);
|
||||
}
|
||||
|
||||
logger.LogTrace("Processing internal message done...");
|
||||
_logger.LogTrace("Processing internal message done...");
|
||||
|
||||
return Task.FromResult<IReadOnlyList<IInternalCommand>>(internalCommands);
|
||||
}
|
||||
@ -146,10 +157,10 @@ public sealed class EventDispatcher(
|
||||
private IDictionary<string, object> SetHeaders()
|
||||
{
|
||||
var headers = new Dictionary<string, object>();
|
||||
headers.Add("CorrelationId", httpContextAccessor?.HttpContext?.GetCorrelationId());
|
||||
headers.Add("UserId", httpContextAccessor?.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier));
|
||||
headers.Add("UserName", httpContextAccessor?.HttpContext?.User?.FindFirstValue(ClaimTypes.Name));
|
||||
headers.Add("CorrelationId", _httpContextAccessor?.HttpContext?.GetCorrelationId());
|
||||
headers.Add("UserId", _httpContextAccessor?.HttpContext?.User?.FindFirstValue(ClaimTypes.NameIdentifier));
|
||||
headers.Add("UserName", _httpContextAccessor?.HttpContext?.User?.FindFirstValue(ClaimTypes.Name));
|
||||
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,4 +8,4 @@ public interface IEventDispatcher
|
||||
where T : IEvent;
|
||||
public Task SendAsync<T>(T @event, Type type = null, CancellationToken cancellationToken = default)
|
||||
where T : IEvent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,6 @@ namespace BuildingBlocks.Core;
|
||||
|
||||
public interface IEventMapper
|
||||
{
|
||||
IIntegrationEvent? MapToIntegrationEvent(IDomainEvent @event);
|
||||
IInternalCommand? MapToInternalCommand(IDomainEvent @event);
|
||||
}
|
||||
IIntegrationEvent MapToIntegrationEvent(IDomainEvent @event);
|
||||
IInternalCommand MapToInternalCommand(IDomainEvent @event);
|
||||
}
|
||||
|
||||
@ -3,4 +3,4 @@ using BuildingBlocks.Core.Event;
|
||||
namespace BuildingBlocks.Core;
|
||||
|
||||
public record IntegrationEventWrapper<TDomainEventType>(TDomainEventType DomainEvent) : IIntegrationEvent
|
||||
where TDomainEventType : IDomainEvent;
|
||||
where TDomainEventType : IDomainEvent;
|
||||
|
||||
@ -1,23 +1,32 @@
|
||||
using BuildingBlocks.Core.Event;
|
||||
using BuildingBlocks.Core.Event;
|
||||
|
||||
namespace BuildingBlocks.Core.Model;
|
||||
|
||||
public abstract record Aggregate<TId> : Entity<TId>, IAggregate<TId>
|
||||
namespace BuildingBlocks.Core.Model
|
||||
{
|
||||
private readonly List<IDomainEvent> _domainEvents = new();
|
||||
public IReadOnlyList<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
|
||||
|
||||
public void AddDomainEvent(IDomainEvent domainEvent)
|
||||
public abstract record Aggregate : Aggregate<long>
|
||||
{
|
||||
_domainEvents.Add(domainEvent);
|
||||
}
|
||||
|
||||
public IEvent[] ClearDomainEvents()
|
||||
public abstract record Aggregate<TId> : Audit, IAggregate<TId>
|
||||
{
|
||||
IEvent[] dequeuedEvents = _domainEvents.ToArray();
|
||||
private readonly List<IDomainEvent> _domainEvents = new();
|
||||
public IReadOnlyList<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
|
||||
|
||||
_domainEvents.Clear();
|
||||
public void AddDomainEvent(IDomainEvent domainEvent)
|
||||
{
|
||||
_domainEvents.Add(domainEvent);
|
||||
}
|
||||
|
||||
return dequeuedEvents;
|
||||
public IEvent[] ClearDomainEvents()
|
||||
{
|
||||
IEvent[] dequeuedEvents = _domainEvents.ToArray();
|
||||
|
||||
_domainEvents.Clear();
|
||||
|
||||
return dequeuedEvents;
|
||||
}
|
||||
|
||||
public long Version { get; set; }
|
||||
|
||||
public TId Id { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,10 @@
|
||||
namespace BuildingBlocks.Core.Model;
|
||||
|
||||
public interface IEntity<T> : IEntity
|
||||
{
|
||||
public T Id { get; set; }
|
||||
}
|
||||
|
||||
public interface IEntity : IVersion
|
||||
public abstract record Audit : IAudit
|
||||
{
|
||||
public DateTime? CreatedAt { get; set; }
|
||||
public long? CreatedBy { get; set; }
|
||||
public DateTime? LastModified { get; set; }
|
||||
public long? LastModifiedBy { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,13 +1,19 @@
|
||||
using BuildingBlocks.Core.Event;
|
||||
using BuildingBlocks.Core.Event;
|
||||
|
||||
namespace BuildingBlocks.Core.Model;
|
||||
|
||||
public interface IAggregate<T> : IAggregate, IEntity<T>
|
||||
{
|
||||
}
|
||||
|
||||
public interface IAggregate : IEntity
|
||||
public interface IAggregate : IAudit, IVersion
|
||||
{
|
||||
IReadOnlyList<IDomainEvent> DomainEvents { get; }
|
||||
IEvent[] ClearDomainEvents();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IAggregate<out T> : IAggregate
|
||||
{
|
||||
T Id { get; }
|
||||
}
|
||||
|
||||
public interface IVersion
|
||||
{
|
||||
long Version { get; set; }
|
||||
}
|
||||
|
||||
@ -1,12 +1,10 @@
|
||||
namespace BuildingBlocks.Core.Model;
|
||||
|
||||
public abstract record Entity<T> : IEntity<T>
|
||||
public interface IAudit
|
||||
{
|
||||
public T Id { get; set; }
|
||||
public DateTime? CreatedAt { get; set; }
|
||||
public long? CreatedBy { get; set; }
|
||||
public DateTime? LastModified { get; set; }
|
||||
public long? LastModifiedBy { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
public long Version { get; set; }
|
||||
}
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
namespace BuildingBlocks.Core.Model;
|
||||
|
||||
// For handling optimistic concurrency
|
||||
public interface IVersion
|
||||
{
|
||||
long Version { get; set; }
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
namespace BuildingBlocks.Core.Pagination;
|
||||
|
||||
using Sieve.Models;
|
||||
using Sieve.Services;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static async Task<IPageList<TEntity>> ApplyPagingAsync<TEntity>(
|
||||
this IQueryable<TEntity> queryable,
|
||||
IPageRequest pageRequest,
|
||||
ISieveProcessor sieveProcessor,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
where TEntity : class
|
||||
{
|
||||
var sieveModel = new SieveModel
|
||||
{
|
||||
PageSize = pageRequest.PageSize,
|
||||
Page = pageRequest.PageNumber,
|
||||
Sorts = pageRequest.SortOrder,
|
||||
Filters = pageRequest.Filters
|
||||
};
|
||||
|
||||
// https://github.com/Biarity/Sieve/issues/34#issuecomment-403817573
|
||||
var result = sieveProcessor.Apply(sieveModel, queryable, applyPagination: false);
|
||||
var total = result.Count();
|
||||
result = sieveProcessor.Apply(sieveModel, queryable, applyFiltering: false,
|
||||
applySorting: false); // Only applies pagination
|
||||
|
||||
var items = await result
|
||||
.ToAsyncEnumerable()
|
||||
.ToListAsync(cancellationToken: cancellationToken);
|
||||
|
||||
return PageList<TEntity>.Create(items.AsReadOnly(), pageRequest.PageNumber, pageRequest.PageSize, total);
|
||||
}
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
namespace BuildingBlocks.Core.Pagination;
|
||||
|
||||
public interface IPageList<T>
|
||||
where T : class
|
||||
{
|
||||
int CurrentPageSize { get; }
|
||||
int CurrentStartIndex { get; }
|
||||
int CurrentEndIndex { get; }
|
||||
int TotalPages { get; }
|
||||
bool HasPrevious { get; }
|
||||
bool HasNext { get; }
|
||||
IReadOnlyList<T> Items { get; init; }
|
||||
int TotalCount { get; init; }
|
||||
int PageNumber { get; init; }
|
||||
int PageSize { get; init; }
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
namespace BuildingBlocks.Core.Pagination;
|
||||
|
||||
using MediatR;
|
||||
|
||||
public interface IPageQuery<out TResponse> : IPageRequest, IRequest<TResponse>
|
||||
where TResponse : class
|
||||
{ }
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user