Compare commits

...

481 Commits
v1.4.1 ... main

Author SHA1 Message Date
Meysam Hadeli
d99d1a9a9a
Merge pull request #374 from meysamhadeli/refactor/refactor-docker-files
refactor: refactor dockerfiles
2026-02-26 23:50:46 +03:30
Meysam Hadeli
6e1fe61a65 refactor: refactor dockerfiles 2026-02-26 23:49:12 +03:30
Meysam Hadeli
a882b3cfe2
Merge pull request #373 from meysamhadeli/fix/fix-ci
fix: fix ci failed
2026-02-24 22:56:10 +03:30
Meysam Hadeli
14cc9e7c96 fix: fix ci failed 2026-02-24 22:54:44 +03:30
Meysam Hadeli
0f66c14299 fix: fix ci failed for tests 2026-02-21 22:00:57 +03:30
Meysam Hadeli
7f9cf8b922 fix: fix ci failed for tests 2026-02-20 23:18:29 +03:30
Meysam Hadeli
23d4babd52 fix: fix ci failed for tests 2026-02-20 20:57:26 +03:30
Meysam Hadeli
8d4819624e fix: fix ci failed for tests 2026-02-20 02:47:07 +03:30
Meysam Hadeli
043c20002c
Merge pull request #372 from meysamhadeli/fix/fix-ci-field-for-tests
fix: fix ci failed for tests
2026-02-20 02:11:41 +03:30
Meysam Hadeli
94a22dfc23 fix: fix ci failed for tests 2026-02-20 02:10:54 +03:30
Meysam Hadeli
3ce312891a Merge branch 'fix/fix-ci-failed' 2026-02-20 00:27:53 +03:30
Meysam Hadeli
a62177a6c4 fix: fix ci failed 2026-02-20 00:25:48 +03:30
Meysam Hadeli
b67d000580
Merge pull request #371 from meysamhadeli/fix/fix-ci-failed
fix: fix ci failed
2026-02-19 23:32:27 +03:30
Meysam Hadeli
2a5909bdbd fix: fix ci failed 2026-02-19 23:30:10 +03:30
Meysam Hadeli
786fbb121f
Merge pull request #370 from meysamhadeli/fix/fix-ci-failed
fix: fix ci failed
2026-02-19 23:19:09 +03:30
Meysam Hadeli
b9b3c26edc fix: fix ci failed 2026-02-19 23:17:14 +03:30
Meysam Hadeli
9dcd6625b2
Merge pull request #369 from meysamhadeli/fix/fix-ci-failed
Fix/fix ci failed
2026-02-19 22:03:04 +03:30
Meysam Hadeli
43666a7dd3 fix: fix ci failed 2026-02-19 22:01:04 +03:30
Meysam Hadeli
23b14eabe7 fix: fix ci failed 2026-02-19 21:59:25 +03:30
Meysam Hadeli
9164c770b5
Merge pull request #368 from meysamhadeli/fix/fix-ci-failed
Fix/fix ci failed
2026-02-19 21:08:53 +03:30
Meysam Hadeli
3bdcc6341f fix: fix ci failed 2026-02-19 21:06:59 +03:30
Meysam Hadeli
20e49770b2 fix: fix ci failed 2026-02-19 21:05:18 +03:30
Meysam Hadeli
e259b64476
Merge pull request #367 from meysamhadeli/chore-update-dockerfiles-to-dotnet-10
Chore update dockerfiles to dotnet 10
2026-02-16 21:13:10 +03:30
Meysam Hadeli
7476502e50 fix: fix formatting 2026-02-16 21:09:00 +03:30
Meysam Hadeli
64dfee4224 chore: update Dockerfiles to .net 10 2026-02-16 21:06:37 +03:30
Meysam Hadeli
bd94742d18
Merge pull request #366 from meysamhadeli/chore/update-config-file
chore: update .config file
2026-02-13 17:49:13 +03:30
Meysam Hadeli
d5e9f75dfc chore: update .config file 2026-02-13 17:29:58 +03:30
Meysam Hadeli
eef8aead7e
Merge pull request #365 from meysamhadeli/feat/update-packages-to-dotnet-10
Feat/update packages to dotnet 10
2026-02-13 14:52:12 +03:30
Meysam Hadeli
38c339c1aa chore: update ci build version 2026-02-13 00:49:49 +03:30
Meysam Hadeli
20bd2ac0bc docs: update documentation 2026-02-13 00:47:15 +03:30
Meysam Hadeli
3b86cf7917 feat: update packages to .net 10 2026-02-13 00:39:59 +03:30
Meysam Hadeli
d1dbe6209c feat: update packages to .net 10 2026-02-13 00:38:09 +03:30
Meysam Hadeli
475fa90e1c
Merge pull request #364 from meysamhadeli/chore/update-aspire-namespaces
chore: update aspire namespaces
2025-10-10 14:19:28 +03:30
Meysam Hadeli
0dd7941136 chore: update aspire namespaces 2025-10-10 14:07:55 +03:30
Meysam Hadeli
29a1e47a2d
Merge pull request #363 from meysamhadeli/chore/remove-additional-files
chore: remove additional files
2025-10-09 17:20:48 +03:30
Meysam Hadeli
68f768d687 chore: remove additional files 2025-10-09 17:18:05 +03:30
Meysam Hadeli
e2fbd27222
docs: update documentation 2025-10-09 16:15:00 +03:30
Meysam Hadeli
d6e313a560
Merge pull request #360 from meysamhadeli/chore/update-aspire-structure
chore/update aspire structure
2025-07-30 20:14:38 +03:30
Meysam Hadeli
57000c5802 chore: update aspire structure 2025-07-30 19:38:31 +03:30
Meysam Hadeli
b3ce2889b2 chore: update aspire structure 2025-07-30 19:37:07 +03:30
Meysam Hadeli
a3c6f670e1
Merge pull request #359 from meysamhadeli/feat/add-docker-compose-deployment-to-aspire-host
feat: add docker compose deployment to aspire host
2025-07-29 23:58:52 +03:30
Meysam Hadeli
3bd8cb1db3 feat: add docker compose deployment to aspire host 2025-07-29 23:13:26 +03:30
Meysam Hadeli
b9e1a1b949
Merge pull request #358 from meysamhadeli/docs/update-documentation
docs: update aspire documentation
2025-07-23 16:40:39 +03:30
Meysam Hadeli
e76353c2df docs: update aspire documentation 2025-07-23 16:37:40 +03:30
Meysam Hadeli
44e408258f
Merge pull request #357 from meysamhadeli/docs/update-aspir-docs
docs/update aspir docs
2025-07-23 16:28:40 +03:30
Meysam Hadeli
10627f8de6 fix: fix formatting 2025-07-23 16:18:05 +03:30
Meysam Hadeli
61d90da20e docs: update aspire documentation 2025-07-23 16:11:20 +03:30
Meysam Hadeli
be13a0ac27
Merge pull request #356 from meysamhadeli/docs/add-aspire-documentation
docs/add aspire documentation
2025-07-23 15:50:16 +03:30
Meysam Hadeli
aba06b9675 chore: update .editorconfig 2025-07-23 15:39:50 +03:30
Meysam Hadeli
a887b0406e chore: update .gitattributes 2025-07-23 15:37:24 +03:30
Meysam Hadeli
da1a3df324 docs: add aspire documentation 2025-07-23 15:28:05 +03:30
Meysam Hadeli
756f166711
Merge pull request #355 from meysamhadeli/feat/add-aspire-integrations
feat: add .net aspire integrations
2025-07-22 02:03:09 +03:30
Meysam Hadeli
0809701fe7 Merge branch 'main' into feat/add-aspire-integrations 2025-07-22 01:36:07 +03:30
Meysam Hadeli
ab512476d0 feat: add .net aspire integrations 2025-07-22 01:32:05 +03:30
Meysam Hadeli
b2e6d4c834
Update README.md 2025-07-14 20:27:44 +03:30
Meysam Hadeli
a67909d109
Update README.md 2025-07-14 20:26:56 +03:30
Meysam Hadeli
11e3bb3904
Merge pull request #354 from meysamhadeli/fix/fix-building-blocks-path-in-dockerfile
fix: fix building-blocks path in dockerfiles
2025-07-04 00:10:20 +03:30
Meysam Hadeli
e3154c23bc fix: fix building-blocks path in dockerfiles 2025-07-03 23:59:11 +03:30
Meysam Hadeli
89589c2c72
Merge pull request #353 from meysamhadeli/chore/cleanup-unused-files
chore: cleanup unused files
2025-07-03 23:43:47 +03:30
Meysam Hadeli
406d3e16e7 chore: cleanup unused files 2025-07-03 23:39:55 +03:30
Meysam Hadeli
aeb19e2f4b
Merge pull request #352 from meysamhadeli/refactor/refactor-structure
refactor: refactor structure of project
2025-07-03 23:36:49 +03:30
Meysam Hadeli
2e02f1b3bf refactor: refactor structure of project 2025-07-03 23:22:26 +03:30
Meysam Hadeli
c33eaf4d07
Merge pull request #351 from meysamhadeli/refactro/refactor-app-and-domain-exceptions
refactor: refactor app and domain exceptions
2025-06-12 21:22:39 +03:30
Meysam Hadeli
afbe8ffeff refactor: refactor app and domain exceptions 2025-06-12 20:37:29 +03:30
Meysam Hadeli
05fcc24bc8
Merge pull request #350 from meysamhadeli/fix/dotnet-format-issue
Fix/dotnet format issue
2025-05-17 20:13:05 +03:30
Meysam Hadeli
768178b153 fix: fix dotnet format issue 2025-05-17 19:57:23 +03:30
Meysam Hadeli
ca7ee3833b fix: fix dotnet format issue 2025-05-17 19:54:14 +03:30
Meysam Hadeli
b0da80bfff
Merge pull request #349 from AyobKafrashian/Complete-modular-monolith-tests
feat: compleate modular monolith tests
2025-05-16 22:30:44 +03:30
AyobKafrashian
93850aaf2f Merge remote-tracking branch 'origin/main' into Complete-modular-monolith-tests 2025-05-16 21:58:30 +03:30
Meysam Hadeli
d26115ccc5
chore: bypass dotnet format 2025-05-16 21:31:42 +03:30
unknown
1bf20a8334 feat:compleate modular monolith tests 2025-05-16 17:59:41 +03:30
Meysam Hadeli
157d9e24d0
Merge pull request #347 from meysamhadeli/chore/update-rest-client-in-monolith
chore: update rest client in monolith
2025-05-13 01:20:55 +03:30
Meysam Hadeli
a6b9d1c948 chore: update rest client in monolith 2025-05-13 01:20:13 +03:30
Meysam Hadeli
dedf6086fc
Merge pull request #346 from meysamhadeli/feat/add-support-role-base-policy
feat: add support role base authorization policy
2025-05-12 00:47:16 +03:30
Meysam Hadeli
eb5bf1da61 feat: add support role base authorization policy 2025-05-12 00:46:19 +03:30
Meysam Hadeli
879fde8d80
Merge pull request #345 from meysamhadeli/refactor/refactor-loading-invisible-asseblies
refactor: refactor loading invisible assemblies
2025-05-11 18:20:20 +03:30
Meysam Hadeli
5115e0daec refactor: refactor loading invisible assemblies 2025-05-11 18:19:22 +03:30
Meysam Hadeli
774866e9ad
Merge pull request #343 from AyobKafrashian/Add-tests-modular-monolith
Add tests modular monolith(flight module)
2025-05-11 13:42:22 +03:30
a.kafrashian
444b96bc73 fix(package-lock): update integrity hashes 2025-05-11 12:51:20 +03:30
unknown
ba0bcc120e refactor:add end to end testing to flight csproj 2025-05-11 01:08:50 +03:30
Meysam Hadeli
fadd128d1f
Update TestBase.cs 2025-05-10 20:43:42 +03:30
a.kafrashian
f3b96dab73 refactor:import end to end test to flight csproj 2025-05-05 15:52:51 +03:30
a.kafrashian
68d9db7849 feat:add end to end test for flight 2025-05-05 15:48:54 +03:30
unknown
1fb9558227 fix(TestBase):add postgres connection settings for Flight, Identity and Passenger 2025-05-05 00:39:27 +03:30
a.kafrashian
c91538493b fix:unify 'flight' namespace in Booking and Flight modules 2025-05-04 12:51:44 +03:30
unknown
660cac9ee5 feat(flight):add initial Unit.Test project 2025-05-04 07:12:26 +03:30
Meysam Hadeli
628257ba6c
docs: update documentation 2025-05-01 00:45:31 +03:30
Meysam Hadeli
a1f12f7129
Merge pull request #338 from meysamhadeli/docs/update-documentation
docs: update documentation
2025-04-30 17:00:25 +03:30
Meysam Hadeli
c7a92d7391 docs: update documentation 2025-04-30 16:59:26 +03:30
Meysam Hadeli
4b4eca5a8f
Merge pull request #337 from AyobKafrashian/Ad-docker-compose-deployment-for-modular-monolith
feat: add docker compose and docker compose infrastructure to modular…
2025-04-29 00:54:28 +03:30
unknown
d04169e6c2 feat: add docker compose and docker compose infrastructure to modular monolith deployment 2025-04-27 22:58:27 +03:30
Meysam Hadeli
92fac775ba
Merge pull request #336 from meysamhadeli/refactor/refactor-deployments
refactor: refactor deployments
2025-04-24 23:27:58 +03:30
Meysam Hadeli
5dde8aab42 refactor: refactor deployments 2025-04-24 23:26:57 +03:30
Meysam Hadeli
c9c2478bbf
Merge pull request #335 from AyobKafrashian/Complete-docker-compose-services-for-monolith
feat: complete docker compose services for monolith
2025-04-24 21:47:40 +03:30
unknown
566f9bd8b7 feat: complete docker compose services for monolith 2025-04-24 21:27:04 +03:30
Meysam Hadeli
56f3a1cc94
Merge pull request #334 from AyobKafrashian/Add-docker-compose-deployment-for-monolith
feat: Add docker compose configuration to Monolith deployment
2025-04-24 17:50:30 +03:30
unknown
24b1f08901 feat: Add docker compose configuration to Monolith deployment 2025-04-22 15:35:50 +03:30
Meysam Hadeli
c8faa3097f
Merge pull request #331 from meysamhadeli/fix/fix-jwt-config
fix/fix jwt config
2025-04-11 23:15:01 +03:30
Meysam Hadeli
33c2f9cf81 fix: fix jwt config in test base 2025-04-11 23:00:24 +03:30
Meysam Hadeli
ab579347c6 fix: fix bug in jwt config 2025-04-11 21:52:22 +03:30
Meysam Hadeli
c9b1767b41
Merge pull request #330 from meysamhadeli/fix/fix-bug-404-in-jwt-config
fix: fix bug 404 in jwt config
2025-04-11 18:26:40 +03:30
Meysam Hadeli
5e2c92fda6 fix: fix bug 404 in jwt config 2025-04-11 18:21:23 +03:30
Meysam Hadeli
d705ff12f2
Merge pull request #329 from meysamhadeli/refactor/refactor-launch-settings
refactor: refactor launch settings
2025-04-09 02:28:09 +03:30
Meysam Hadeli
d469663559 refactor: refactor launch settings 2025-04-09 02:24:24 +03:30
Meysam Hadeli
4417096bae
Merge pull request #328 from meysamhadeli/docs/update-documentation
feat: update documentation
2025-04-08 16:54:50 +03:30
Meysam Hadeli
e2ae2c237b feat: update documentation 2025-04-08 16:43:45 +03:30
Meysam Hadeli
8ad716f850
Merge pull request #327 from meysamhadeli/feat/add-monolith-source
feat/add monolith source
2025-04-08 02:04:21 +03:30
Meysam Hadeli
16109bf052 feat: add monolith source 2025-04-08 01:42:21 +03:30
Meysam Hadeli
20a8363103 feat: add monolith source 2025-04-08 01:41:18 +03:30
Meysam Hadeli
d5fa86cdaf
Merge pull request #326 from meysamhadeli/feat/add-rest-client-for-modular-monolith
feat: add rest client for modular monolith
2025-04-07 02:54:06 +03:30
Meysam Hadeli
d5312430ac feat: add rest client for modular monolith 2025-04-07 02:41:14 +03:30
Meysam Hadeli
ff8badcd4a
Merge pull request #325 from meysamhadeli/feat/add-modular-monolith-source
Feat/add modular monolith source
2025-04-06 19:33:45 +03:30
Meysam Hadeli
95123ee6b2 feat: add modular monolith source 2025-04-06 19:23:23 +03:30
Meysam Hadeli
d278e36fd2 feat: add modular monolith source 2025-04-06 17:56:12 +03:30
Meysam Hadeli
27d25aa47d feat: add modular monolith source 2025-04-06 17:55:28 +03:30
Meysam Hadeli
0d4dfb3459
Merge pull request #324 from meysamhadeli/chore/update-sln-name
chore: update sln name
2025-03-29 15:52:39 +03:30
Meysam Hadeli
871620d18c chore: update sln name 2025-03-29 15:51:14 +03:30
Meysam Hadeli
f8041f4d12
docs: update documentation 2025-03-29 15:06:19 +03:30
Meysam Hadeli
ecfcccf36e docs: update documentation 2025-03-25 23:42:20 +03:30
Meysam Hadeli
e783f726e5 Merge remote-tracking branch 'origin/main' 2025-03-25 21:39:24 +03:30
Meysam Hadeli
c3c20710a2 docs: update documentation 2025-03-25 21:38:37 +03:30
Meysam Hadeli
c503186b69 docs: update documentation 2025-03-25 21:36:56 +03:30
Meysam Hadeli
105826202e
Merge pull request #323 from meysamhadeli/docs/update-documentation
docs: update documentation
2025-03-15 22:56:26 +03:30
Meysam Hadeli
97c121a51e docs: update documentation 2025-03-15 22:55:10 +03:30
Meysam Hadeli
da39702e33
Merge pull request #322 from meysamhadeli/fix/fix-load-docker-files-in-ci
fix: fix load docker files in ci
2025-03-15 22:30:30 +03:30
Meysam Hadeli
33553ad15b fix: fix load docker files in ci 2025-03-15 22:29:20 +03:30
Meysam Hadeli
1d7eb5057e
Merge pull request #321 from meysamhadeli/chore/update-folder-structure-in-microservices
chore: clean up folder structure in microservices architecture
2025-03-15 22:08:57 +03:30
Meysam Hadeli
b9e76e7183 chore: clean up folder structure in microservices architecture 2025-03-15 22:07:20 +03:30
Meysam Hadeli
28651fe9b1
Merge pull request #320 from meysamhadeli/chore/update-architecture-root-names
chore/update architecture root names
2025-03-15 21:02:52 +03:30
Meysam Hadeli
8abd53e02f chore: update architecture root names 2025-03-15 21:01:06 +03:30
Meysam Hadeli
19ed23482e chore: clean up folder names 2025-03-15 19:27:27 +03:30
Meysam Hadeli
adb47d25a9
Merge pull request #319 from meysamhadeli/docs/update-documentation
docs: update documentation
2025-03-15 17:05:20 +03:30
Meysam Hadeli
5841d8c331
Merge branch 'main' into docs/update-documentation 2025-03-15 16:55:45 +03:30
Meysam Hadeli
12658f6b0c docs: update documentation 2025-03-15 16:54:20 +03:30
Meysam Hadeli
97637ac9dd
Merge pull request #318 from meysamhadeli/fix/fix-build-and-publish-flight-in-cd
fix: fix build and publish flight in cd
2025-03-15 03:02:02 +03:30
Meysam Hadeli
e8b1c2783e fix: fix build and publish flight in cd 2025-03-15 03:00:33 +03:30
Meysam Hadeli
3d5326a22f
Merge pull request #317 from meysamhadeli/feat/add-architecture-style-to-project
feat: add architecture style to project
2025-03-15 01:53:05 +03:30
Meysam Hadeli
ccce0faef1 feat: add architecture style to project 2025-03-15 01:39:43 +03:30
Meysam Hadeli
76551a21f2
Update README.md 2025-03-14 18:42:47 +03:30
Meysam Hadeli
7eb8c73002
Update README.md 2025-03-14 18:40:08 +03:30
Meysam Hadeli
28ff69a8e2
Update README.md 2025-03-14 18:36:54 +03:30
Meysam Hadeli
abe4860a1c
Merge pull request #315 from meysamhadeli/feat/add-full-observibility-with-otel-collector
feat/add full observibility with otel collector
2025-02-14 02:09:53 +03:30
Meysam Hadeli
3bf8733f5e fix: fix failed unit tests in flight 2025-02-14 01:59:57 +03:30
Meysam Hadeli
9f284b3604 feat: add full observability top of open telemetry collector 2025-02-14 01:23:38 +03:30
Meysam Hadeli
6ed7ee7409 feat: add full observability top of open telemetry collector 2025-02-14 01:13:01 +03:30
Meysam Hadeli
c3471f8229 docs: update diagram 2025-02-10 02:11:58 +03:30
Meysam Hadeli
3844e42cc8 docs: update diagram 2025-02-10 02:11:09 +03:30
Meysam Hadeli
3efe4c0261 docs: update diagram 2025-02-09 20:58:49 +03:30
Meysam Hadeli
1cfb9fb8cc docs: update diagram 2025-02-09 19:06:25 +03:30
Meysam Hadeli
05a4416da1
Merge pull request #314 from meysamhadeli/docs/update-diagram
docs: update diagram
2025-02-09 18:09:21 +03:30
Meysam Hadeli
8ac5a0a536 docs: update diagram 2025-02-09 18:07:55 +03:30
Meysam Hadeli
668869dbef
Merge pull request #312 from meysamhadeli/docs/update-docs
docs: update documentation
2024-12-22 00:50:57 +03:30
Meysam Hadeli
2e050fb328 docs: update documentation 2024-12-22 00:49:19 +03:30
Meysam Hadeli
1e9391ad1f
Merge pull request #311 from meysamhadeli/chore/update-dockerfiles-versions-to-9
chore: update dockerfiles .net versions to 9
2024-12-19 23:30:23 +03:30
Meysam Hadeli
29d734427f chore: update dockerfiles .net versions to 9 2024-12-19 22:45:23 +03:30
Meysam Hadeli
b7fdbc22fa
Merge pull request #310 from meysamhadeli/feat/update-dotnet-to-version-9
feat: update dotnet to version 9
2024-12-19 21:05:29 +03:30
Meysam Hadeli
6c9d183970 fix: fix test issues 2024-12-19 20:53:08 +03:30
Meysam Hadeli
68a9185070 docs: update documentation 2024-12-19 19:27:40 +03:30
Meysam Hadeli
321b7ce901 fix: fix issue in registration persist message background service in test base 2024-12-19 19:20:58 +03:30
Meysam Hadeli
b9aa18a043 fix: fix issue in seed-manager 2024-12-19 03:59:40 +03:30
Meysam Hadeli
cc8989a6b3 fix: fix db-update exception in tests 2024-12-19 03:09:50 +03:30
Meysam Hadeli
bd345ae949 fix: try to fix failed tests in ci 2024-12-19 01:33:06 +03:30
Meysam Hadeli
e871a37217 fix: fix .net format issue 2024-12-19 01:14:25 +03:30
Meysam Hadeli
671816cd63 chore: update .net version in deployments 2024-12-19 01:05:16 +03:30
Meysam Hadeli
4785a680da feat: update dotnet to version 9 2024-12-18 23:28:18 +03:30
Meysam Hadeli
42c300fd96
Merge pull request #307 from meysamhadeli/chore/update-ci-pipeline
chore: update ci pipeline
2024-09-17 20:15:32 +03:30
Meysam Hadeli
69751df021 chore: update ci pipeline 2024-09-17 20:13:03 +03:30
Meysam Hadeli
0bb7462d66
chore: update release drafter template 2024-09-17 20:04:26 +03:30
Meysam Hadeli
092ecdef72
Merge pull request #306 from meysamhadeli/chore/update-dockerfiles-for-copy-dependencies-in-root
chore: update dockerfiles for copy dependencies in root
2024-09-16 22:35:09 +03:30
Meysam Hadeli
cd802762b9 chore: update dockerfiles for copy dependencies in root 2024-09-16 22:20:27 +03:30
Meysam Hadeli
b6dc2c5449
Merge pull request #305 from meysamhadeli/chore/update-dockerfiles-for-root-directory-files
chore: update docker files for root directory files
2024-09-16 21:46:40 +03:30
Meysam Hadeli
93428042d2 chore: update docker files for root directory files 2024-09-16 21:28:58 +03:30
Meysam Hadeli
15af03ddb4
chore: update build ci pipeline 2024-09-16 20:27:19 +03:30
Meysam Hadeli
8568a89432 Merge branch 'refs/heads/develop' 2024-09-16 18:12:53 +03:30
Meysam Hadeli
b349d5e585
Merge pull request #304 from meysamhadeli/refactor/refactor-analyzer-configs
refactor/refactor analyzer configs
2024-09-16 18:10:20 +03:30
Meysam Hadeli
fa3b1842a8 refactor: refactor analyzer configs and add formating to cli 2024-09-16 17:59:45 +03:30
Meysam Hadeli
dda4a3f92b refactor: refactor analyzer configs and add formating to cli 2024-09-16 17:57:37 +03:30
Meysam Hadeli
352982be9e
Merge pull request #303 from meysamhadeli/develop
Develop
2024-09-16 02:38:31 +03:30
Meysam Hadeli
f9eb00c880
Merge pull request #302 from meysamhadeli/feat/Add-husky-for-pre-commit-rules
feat/add husky for pre commit rules
2024-09-16 02:37:42 +03:30
Meysam Hadeli
89657e832b feat: add husky for handling pre commit rules 2024-09-16 02:17:30 +03:30
Meysam Hadeli
6da82e39ce . 2024-09-16 01:58:31 +03:30
Meysam Hadeli
f28e809033 Merge branch 'refs/heads/develop' 2024-08-22 18:10:58 +03:30
Meysam Hadeli
31db8aa1ba docs: Update README.md. 2024-08-22 18:10:35 +03:30
Meysam Hadeli
21c99e0a9f Merge branch 'refs/heads/develop' 2024-08-22 18:00:17 +03:30
Meysam Hadeli
aa112bceb9
Merge pull request #301 from meysamhadeli/fix/fix-event-store-restore-policy-in-docker-compose
fix: Fix event store restart policy in docker compose.
2024-08-22 17:59:16 +03:30
Meysam Hadeli
9544b95ce3 fix: Fix event store restart policy in docker compose. 2024-08-22 17:58:22 +03:30
Meysam Hadeli
bb86232fef Merge branch 'refs/heads/develop' 2024-08-22 17:55:53 +03:30
Meysam Hadeli
05683c70c4
Merge pull request #300 from meysamhadeli/feature/add-dotnet-tool-configurations
feat: Add dotnet tools configurations.
2024-08-22 17:54:26 +03:30
Meysam Hadeli
1ce4da33fa feat: Add dotnet tools configurations. 2024-08-22 17:53:04 +03:30
Meysam Hadeli
68b3c2ed43
Merge pull request #299 from meysamhadeli/develop
Develop
2024-08-07 00:12:40 +03:30
Meysam Hadeli
17fbcde9c6
Merge pull request #298 from meysamhadeli/ci/update-deployments-configurations
Ci/update deployments configurations
2024-08-07 00:12:17 +03:30
Meysam Hadeli
8f7492915b ci: Update deployments configurations. 2024-08-07 00:01:15 +03:30
Meysam Hadeli
d2f3b022b3
Merge pull request #297 from meysamhadeli/develop
Merge Develop to Main
2024-07-23 23:52:52 +02:00
Meysam Hadeli
d565de403e
Merge pull request #296 from meysamhadeli/chore/update-nuget-packages
Chore/update nuget packages
2024-07-23 23:24:19 +02:00
meysamhadeli
9465c4d2d4 chore: Update nuget packages. 2024-07-23 23:09:57 +02:00
Meysam Hadeli
d256b8ed21
Merge pull request #293 from meysamhadeli/develop
Update README.md
2024-05-13 21:02:00 +02:00
Meysam Hadeli
9c5ac6fdb9
Update README.md 2024-05-13 21:01:08 +02:00
Meysam Hadeli
6685cc0882
Merge pull request #292 from meysamhadeli/develop
Develop
2024-05-13 20:53:24 +02:00
Meysam Hadeli
2c3438f2f8
Update README.md 2024-05-13 20:52:59 +02:00
Meysam Hadeli
3466de4231
Update README.md 2024-05-13 20:51:57 +02:00
Meysam Hadeli
a718a47de7
Merge pull request #291 from meysamhadeli/develop
chore: Improve registeration services injection in test base.
2024-05-12 19:57:35 +02:00
Meysam Hadeli
590b2e78d5 chore: Improve registeration services injection in test base. 2024-05-12 17:55:04 +00:00
Meysam Hadeli
00f036873a
Merge pull request #290 from meysamhadeli/feature/update-kubernetes-image-versions
feat: Update kubernetes image versions.
2024-04-04 17:59:30 +03:30
Meysam Hadeli
32702e505e feat: Update kubernetes image versions. 2024-04-04 14:19:46 +00:00
Meysam Hadeli
006ad9f508
Merge pull request #289 from meysamhadeli/develop
Develop
2024-04-04 17:18:23 +03:30
Meysam Hadeli
965eb55f96
Merge pull request #288 from meysamhadeli/feature/Update-docker-image-versions
Feature/update docker image versions
2024-04-04 17:15:06 +03:30
Pc
5d88cfccdd feat: Update docker image versions 2024-04-04 17:04:41 +03:30
Meysam Hadeli
ccd6fccc7f
Merge pull request #287 from meysamhadeli/develop
Update README.md
2024-04-03 02:38:44 +03:30
Meysam Hadeli
75414c7a92
Update README.md 2024-04-03 02:38:20 +03:30
Meysam Hadeli
9cc8259db2
Merge pull request #286 from meysamhadeli/develop
Develop
2024-04-03 01:27:17 +03:30
Meysam Hadeli
b56f2526b8
Merge pull request #285 from meysamhadeli/feature/update-all-nuget-packages-to-last-versions
Feature/update all nuget packages to last versions
2024-04-03 01:14:48 +03:30
Pc
c49bdfa898 feat: Update all nuget packages to last version. 2024-04-03 00:55:50 +03:30
Meysam Hadeli
6bcf68a06f
Merge pull request #283 from meysamhadeli/develop
chore: Delete pull_request_template.md
2024-02-23 23:49:55 +01:00
Meysam Hadeli
43b6653e3a
chore: Delete pull_request_template.md 2024-02-23 23:40:08 +01:00
Meysam Hadeli
04f7f13e54
chore: Delete pull_request_template.md 2024-02-23 23:38:06 +01:00
Meysam Hadeli
d6698275af
Merge pull request #282 from bunkrur/main
Update README.md spelling and grammar
2024-02-23 23:32:54 +01:00
bunkrur
5aab7b28cd
Update README.md
Fix spelling and grammer
2024-02-23 01:46:30 -08:00
Pc
53077d1965 Merge branch 'develop' 2023-12-19 16:55:40 +03:30
Pc
b014ee333d docs: Update documentation 2023-12-19 16:55:18 +03:30
Pc
0812aa8f27 Merge branch 'develop' 2023-12-19 00:51:20 +03:30
Pc
28be8c52c1 docs: Update documentation 2023-12-19 00:50:46 +03:30
Pc
39626a29c0 Merge branch 'develop' 2023-12-09 02:58:39 +03:30
Pc
8c50440839 fix: fix root .gitignore 2023-12-09 02:58:07 +03:30
Meysam Hadeli
2f604ae333
Merge pull request #281 from meysamhadeli/develop
Update README.md
2023-10-26 23:35:05 +03:30
Meysam Hadeli
41387cf653
Update README.md 2023-10-26 23:34:46 +03:30
Meysam Hadeli
00e400cfd1
Merge pull request #280 from meysamhadeli/develop
Update README.md
2023-10-06 16:51:30 +03:30
Meysam Hadeli
525830c5c9
Update README.md 2023-10-06 16:51:10 +03:30
Pc
cc16caaa0c Merge branch 'develop' 2023-10-05 22:53:01 +03:30
Meysam Hadeli
15f10c06ec
Merge pull request #279 from meysamhadeli/meysamhadeli-patch-1
Update README.md
2023-10-05 22:51:49 +03:30
Meysam Hadeli
692d3d1d1b
Update README.md 2023-10-05 22:51:23 +03:30
Pc
e06c40116f Merge branch 'develop' 2023-10-05 01:52:18 +03:30
Pc
9570a9bac7 chore: Update diagram 2023-10-05 01:51:44 +03:30
Pc
69eccbebc1 Merge branch 'develop' 2023-09-17 11:44:49 +03:30
Pc
08eba2850c chore: move problem-details to building-blocks 2023-09-17 11:28:04 +03:30
Pc
638de4478e Merge branch 'develop' 2023-09-04 01:07:32 +03:30
Meysam Hadeli
98ef515d08
Update README.md 2023-09-04 01:06:02 +03:30
Meysam Hadeli
9dc09c1a2f
Merge pull request #276 from meysamhadeli/develop
chore: Remove moq library
2023-08-11 13:07:55 +03:30
Pc
9d63043257 chore: Remove moq library 2023-08-11 12:58:49 +03:30
Meysam Hadeli
1274853016
Merge pull request #275 from meysamhadeli/ci/add-grafana-dotnet-core-dashboards
ci: Add grafana dashboards for dotnet core
2023-08-07 22:32:09 +03:30
Pc
5123934ccc ci: Add grafana dashboards for dotnet core 2023-08-07 22:20:41 +03:30
Meysam Hadeli
7234ef169a
Merge pull request #274 from meysamhadeli/feat/add-prometheus-grafana-to-kubernetes
feat: Add prometheus and grafana to kubernetes deployment
2023-08-01 22:50:27 +03:30
Pc
3698ab517c feat: Add prometheus and grafana to kubernetes deployment 2023-08-01 22:08:46 +03:30
Pc
c10fc5db98 chore: Remove additional files form building blocks 2023-08-01 02:26:38 +03:30
Meysam Hadeli
4d505554a0
Update README.md 2023-08-01 01:13:59 +03:30
Meysam Hadeli
e2bf3f0203
Merge pull request #273 from meysamhadeli/feat/add-node-exporter-and-cadvisor
feat: Add node exporter and cadvisor to prometheus exporters
2023-07-31 20:51:23 +03:30
Pc
818d9e2e8e feat: Add node exporter and cadvisor to prometheus exporters 2023-07-31 16:52:32 +03:30
Meysam Hadeli
5b30430ed1
Merge pull request #272 from meysamhadeli/feat/add-monitoring
feat: Add monitoring with prometheus and grafana
2023-07-30 01:31:04 +03:30
Pc
a75ac09648 fix: Fix build ci pipeline with .net 8 2023-07-30 01:06:07 +03:30
Pc
ef72d64700 feat: Add monitoring with prometheus and grafana 2023-07-30 00:58:05 +03:30
Pc
668991d006 docs: Update documentation 2023-07-26 20:26:00 +03:30
Pc
93bce8c359 docs: Update documentation 2023-07-26 20:23:17 +03:30
Meysam Hadeli
b4fd4d512b
Merge pull request #270 from meysamhadeli/refactor/refactor-access-modifieres-in-feature-slices
refactor: Refactor access modifiers in feature slices
2023-07-16 16:59:13 +03:30
Pc
25230eed1c refactor: Refactor access modifiers in feature slices 2023-07-16 16:49:00 +03:30
Pc
12625661e6 refactor: Refactor mappings 2023-07-05 23:54:10 +03:30
Pc
bb7aaa2edb refactor: Use ClockSkew options For prevent add default value (5min) to life time token 2023-06-25 13:41:22 +03:30
Meysam Hadeli
0b47559441
Merge pull request #269 from meysamhadeli/refactor/refactor-booking-value-objects-validation
refactor: Refactor booking value objects validation
2023-06-19 19:34:06 +03:30
Pc
05025591c5 refactor: Refactor booking value objects validation 2023-06-19 19:08:26 +03:30
Pc
af4d03441d refactor: Refactor domain models 2023-06-15 21:39:19 +03:30
Pc
c3697e4d04 fix: Fix bug multiple instance tracking in CompleteRegisterPassengerCommandHandler in update operation 2023-06-15 21:16:54 +03:30
Pc
17269df649 chore: Update diagram 2023-06-15 02:27:19 +03:30
Pc
161f1fed09 refactor: Refactor validation of value object from constructor to Of method 2023-06-15 01:56:27 +03:30
Pc
ef53893263 refactor: Refactor value objects 2023-06-12 19:13:50 +03:30
Pc
728b8a7a57 refactor: Refactor database migrations models 2023-06-12 01:03:15 +03:30
Pc
11fc165a80 refactor: Set default value for aggregates 2023-06-12 00:44:48 +03:30
Meysam Hadeli
7348c2c6ac
Merge pull request #266 from amirhossein18121380/AddValueObject(Seats/Flights/Airports)
AddValueObjects(Seats/Flights/Airports)
2023-06-11 19:04:28 +03:30
amir.gholami
188a121ad5 Resolve issues 2023-06-11 18:24:55 +03:30
Meysam Hadeli
d324e87301
Merge pull request #267 from meysamhadeli/meysamhadeli-patch-1
Update README.md
2023-06-11 13:16:59 +03:30
Meysam Hadeli
5e715b2983
Update README.md 2023-06-11 13:15:02 +03:30
amir.gholami
343d0d63c6 AddValueObjects(Seats/Flights/Airports) 2023-06-09 21:37:03 +03:30
Pc
cc710292a3 fix: Fix EfTxBehavior for save persist-message 2023-06-04 13:55:04 +03:30
Meysam Hadeli
7e9cea74f6
Merge pull request #265 from meysamhadeli/feat/add_retry_for_distributed_transaction_in_postgres
feat: Add retry for distributed transaction in postgres
2023-06-04 03:58:47 +03:30
Pc
9e27099ef2 fix: Fix unit tests error 2023-06-04 03:58:05 +03:30
Pc
66cd7c54be feat: Add retry for distributed transaction in postgres 2023-06-04 03:17:45 +03:30
Pc
39bee67fa1 chore: change directory value objects 2023-06-02 18:01:12 +03:30
Pc
aefb114e50 fix: Fix using in DbContextFactory flight service 2023-06-02 17:49:58 +03:30
Meysam Hadeli
f928dc2506
Merge pull request #262 from amirhossein18121380/RefactorModel
Add Value Objects to Aircraft and Passenger
2023-06-02 17:44:47 +03:30
Meysam Hadeli
d71bf7200c
Update CompleteRegisterPassenger.cs 2023-06-02 17:35:44 +03:30
Meysam Hadeli
827089858e
Update Passenger.cs 2023-06-02 17:35:21 +03:30
Meysam Hadeli
70d009e323
Update CreateAircraft.cs 2023-06-02 17:34:42 +03:30
Meysam Hadeli
04a71dd1f4
Update InitialData.cs 2023-06-02 17:34:03 +03:30
Meysam Hadeli
5e70400563
Update Aircraft.cs 2023-06-02 17:33:00 +03:30
Meysam Hadeli
ab48a131ba
Update FakeCreateAircraftCommand.cs 2023-06-02 17:02:17 +03:30
Meysam Hadeli
efc9ded1eb
Update InvalidManufacturingYearException.cs 2023-06-02 17:01:25 +03:30
Meysam Hadeli
6b4596ef7c
Update ManufacturingYear.cs 2023-06-02 17:00:20 +03:30
Meysam Hadeli
b70a6568dd
Update Aircraft.cs 2023-06-02 16:59:42 +03:30
Meysam Hadeli
54a0cb282f
Update Passenger.cs 2023-06-02 16:58:23 +03:30
Meysam Hadeli
eb82094919
Update Age.cs 2023-06-02 16:57:17 +03:30
Meysam Hadeli
cd1d4fa7a0
Update FlightMappingTests.cs 2023-06-02 01:55:58 +03:30
Meysam Hadeli
da4b48498f
Update FlightMappingTests.cs 2023-06-02 01:48:31 +03:30
Pc
1a6a9b5b3c Merge branch 'develop' 2023-06-01 22:16:58 +03:30
Meysam Hadeli
ee2936fa86
Merge pull request #264 from meysamhadeli/refactor/remove_migration_in_message_processor
refactor: Remove migration from message processor
2023-06-01 22:16:32 +03:30
Pc
017a419f6b refactor: Remove migration from message processor 2023-06-01 21:30:45 +03:30
amir.gholami
fd913df555 Merge branch 'RefactorModel' of https://github.com/amirhossein18121380/booking-microservices into RefactorModel 2023-06-01 20:57:08 +03:30
AmirHossein
6e723b559c
Merge branch 'main' into RefactorModel 2023-06-01 20:46:58 +03:30
amir.gholami
d3a2023629 fix valueobject 2023-06-01 20:43:00 +03:30
Pc
f2490e2a0c Merge remote-tracking branch 'origin/main' 2023-06-01 17:28:05 +03:30
Meysam Hadeli
8a02c0a234
Merge pull request #263 from meysamhadeli/refactor/refactor-message-processor
refactor: Refactor persist message processor
2023-06-01 17:26:11 +03:30
Pc
31a6d9f6e9 refactor: Refactor persist message processor 2023-06-01 16:55:31 +03:30
amir.gholami
78f4a764f7 Apply Chnages in Comment 2023-05-27 23:47:12 +03:30
amir.gholami
f639619940 Complete changes needed for valueObjects 2023-05-27 01:08:08 +03:30
amir.gholami
5c5be8eef8 Add Value Objects 2023-05-21 19:29:06 +03:30
Meysam Hadeli
0d8f52b573
Merge pull request #261 from meysamhadeli/develop
Develop
2023-05-21 13:10:42 +03:30
Meysam Hadeli
6b954750bd
Update README.md 2023-05-21 13:10:15 +03:30
Meysam Hadeli
bcf46fc0c8
Update README.md 2023-05-21 13:07:39 +03:30
Meysam Hadeli
43c0b62926
Create CONTRIBUTION.md 2023-05-21 13:03:33 +03:30
Meysam Hadeli
f6639d772f
Merge pull request #260 from meysamhadeli/fix/fix-scope-validation-in-apis
fix: Fix scope validation in claims for all endpoints
2023-05-19 02:44:50 +03:30
Pc
0cd22aebd2 fix: Fix scope validation in claims in tests 2023-05-19 02:30:16 +03:30
Pc
6e1cea7ebc fix: Fix scope validation in claims for all endpoints 2023-05-19 01:52:57 +03:30
Pc
993c44a890 chore: Update microservices diagram 2023-05-15 23:44:50 +03:30
Pc
ea88b64b15 chore: Update microservices diagram 2023-05-15 23:42:36 +03:30
Meysam Hadeli
df554b1f14
Merge pull request #259 from meysamhadeli/fix/fix-null-reference-exception-in-swagger-default-value
fix: Fix null reference exception in swagger default value
2023-05-15 21:49:19 +03:30
Pc
d81c5c85db fix: Fix null reference exception in swagger default value 2023-05-15 21:40:32 +03:30
Meysam Hadeli
5b0c72380f
Merge pull request #258 from meysamhadeli/refactor/refactor-masstransit-base
refactor: Refactor and remove unnecessary code in masstransit base
2023-05-14 23:19:34 +03:30
Pc
c6eff3a8b6 refactor: Refactor and remove unnecessary code in masstransit base 2023-05-14 22:06:04 +03:30
Meysam Hadeli
ad174d1be8
Merge pull request #257 from meysamhadeli/refactor/refactor-db-context-base
refactor: Refactor db-context base
2023-05-13 00:06:17 +03:30
Pc
a6167b3a47 refactor: Refactor db-context base 2023-05-12 23:16:03 +03:30
Pc
c3db13141b chore: Add some logging for test consumers 2023-05-12 01:34:48 +03:30
Meysam Hadeli
5233a21ab4
Merge pull request #256 from meysamhadeli/feat/add-distributed-transaction-to-ef-tx_behavior
feat: add distributed transaction to EfTxBehavior
2023-05-12 01:32:31 +03:30
Pc
24d1ca2d65 feat: Add add distributed transaction to EfTxBehavior 2023-05-12 01:13:03 +03:30
Meysam Hadeli
d59c17671e
Merge pull request #255 from meysamhadeli/fix/fix-problem-persist-message-background-job
fix: Fix problem run persist-message background job service in test-base
2023-05-09 01:55:49 +03:30
Pc
f24c3c9c4f fix: Fix problem run persist-message background job service in test-base 2023-05-09 01:29:10 +03:30
Meysam Hadeli
7bee6581e4
Merge pull request #254 from meysamhadeli/refactor/refactor-tests-read-side
refactor: Refactor tests read-side
2023-05-08 19:26:49 +03:30
Meysam Hadeli
10c8d4784a
Merge pull request #253 from meysamhadeli/develop
Develop
2023-05-08 18:37:26 +03:30
Pc
607d72eef7 refactor: Refactor tests read-side 2023-05-08 18:37:10 +03:30
Meysam Hadeli
c93bd2902a
Merge pull request #251 from meysamhadeli/refactor/refactor-core-domain
refactor: Refactor core domain in building-blocks
2023-05-08 17:17:52 +03:30
Pc
95ac22d3b8 refactor: Refactor core domain in building-blocks 2023-05-08 15:46:08 +03:30
Meysam Hadeli
7c29e8fa07
Merge pull request #250 from meysamhadeli/develop
Update README.md
2023-04-24 18:46:01 +03:30
Meysam Hadeli
8de99c1386
Update README.md 2023-04-24 16:51:36 +03:30
Pc
e69d3d856c Merge branch 'develop' 2023-04-22 23:59:27 +03:30
Meysam Hadeli
98baec1cb8
Merge pull request #248 from meysamhadeli/test/add-performance-test
test: Add Performance tests
2023-04-22 23:58:51 +03:30
Pc
c562ec70d3 test: Add Performance tests 2023-04-22 23:42:08 +03:30
Pc
1ea107d316 Merge branch 'develop' 2023-04-07 23:28:51 +03:30
Pc
f72e0f02b7 chore: Update problem details extensions for more additional info 2023-04-07 20:14:27 +03:30
Pc
0af996eabc Merge branch 'develop' 2023-04-07 17:19:25 +03:30
Meysam Hadeli
5954846d69
Merge pull request #246 from meysamhadeli/chore/update_problem_details_extensions
chore: Update problem details extensions for more additional info
2023-04-07 17:19:01 +03:30
Pc
ab9f7a2af1 chore: Update problem details extensions for more additional info 2023-04-07 17:18:00 +03:30
Pc
5929232df6 Merge branch 'develop' 2023-04-03 21:40:49 +03:30
Meysam Hadeli
e095cfb9fc
Merge pull request #245 from meysamhadeli/fix/fix-problem-details-type
fix: Fix problem details type
2023-04-03 21:40:18 +03:30
Pc
050c9d2b24 fix: Fix problem details type 2023-04-03 19:12:42 +03:30
Pc
6a49a324b1 Merge branch 'develop' 2023-04-02 17:53:12 +03:30
Meysam Hadeli
89f9033bfa
Merge pull request #244 from meysamhadeli/feat/add-required-keyword-for-objects
feat: Add required keyword to models for handle mandatory property in…
2023-04-02 17:52:33 +03:30
Pc
c46958935d feat: Add required keyword to models for handle mandatory property in initialization 2023-04-02 17:40:59 +03:30
Pc
3a0c0edfe1 Merge branch 'develop' 2023-04-02 14:34:16 +03:30
Meysam Hadeli
bd44072362
Merge pull request #243 from meysamhadeli/refactor/refactor-minimal-apis
refactor: Refactor minimal apis to new fluent syntax
2023-04-02 14:30:12 +03:30
Pc
4e12559d9f refactor: Refactor minimal apis to new fluent syntax 2023-04-02 14:07:24 +03:30
Pc
ee1e72fe61 Merge branch 'develop' 2023-04-01 21:05:27 +03:30
Meysam Hadeli
9ca0a273ce
Update README.md 2023-04-01 21:04:41 +03:30
Pc
5258d0fc0e Merge branch 'develop' 2023-04-01 13:51:29 +03:30
Meysam Hadeli
22c305e3df
Merge pull request #242 from meysamhadeli/feat/Use_NewId_instead_of_IdGen
feat: Use NewId instead of IdGen for generate Id for unique id in dis…
2023-04-01 13:50:32 +03:30
Pc
55a5f98dc9 fix: Fix run parallel to sequentially test in flight end-to-end test 2023-04-01 13:39:24 +03:30
Pc
c60af19a0a feat: Use NewId instead of IdGen for generate Id for unique id in distributed system 2023-04-01 02:03:05 +03:30
Pc
5eb20bdc8a Merge remote-tracking branch 'origin/main' 2023-03-31 01:28:22 +03:30
Meysam Hadeli
e1d99a6f24
Merge pull request #241 from meysamhadeli/feat/Use-builtin-problem-details-dotnet-7
feat: Use built-in problem-details .Net 7 instead of Hellang.Middlewa…
2023-03-31 01:26:58 +03:30
Pc
bc6ac3f26b Merge remote-tracking branch 'origin/feat/Use-builtin-problem-details-dotnet-7' into feat/Use-builtin-problem-details-dotnet-7 2023-03-31 01:16:50 +03:30
Pc
eb3f700adc fix: Fix route name 2023-03-31 01:16:42 +03:30
Meysam Hadeli
a76920e6fc
Merge branch 'develop' into feat/Use-builtin-problem-details-dotnet-7 2023-03-30 23:05:50 +03:30
Pc
7c3e650467 feat: Use built-in problem-details .Net 7 instead of Hellang.Middleware.ProblemDetails 2023-03-30 23:04:24 +03:30
Meysam Hadeli
7a330884ef
Merge pull request #240 from meysamhadeli/develop
Update README.md
2023-03-30 12:55:36 +03:30
Meysam Hadeli
3bb4bd0542
Update README.md 2023-03-30 12:55:12 +03:30
Meysam Hadeli
021e218671
Merge pull request #239 from meysamhadeli/refactor/refactor-id-genrator
Refactor/refactor id genrator
2023-03-30 12:20:09 +03:30
Pc
805f017af1 refactor: Refactor SnowflakeIdGenerator helper 2023-03-30 01:26:05 +03:30
Pc
132da758b6 Merge branch 'develop' 2023-03-22 18:12:01 +04:30
Meysam Hadeli
1e6f5b8ce3
Merge pull request #236 from meysamhadeli/feat/add-result-model-for-handlers
feat: Add result model for handlers for better structure in vertical …
2023-03-22 17:11:19 +03:30
Meysam Hadeli
6cb2563112
Merge branch 'develop' into feat/add-result-model-for-handlers 2023-03-22 16:58:36 +03:30
Pc
0c7baf0c73 feat: Add result model for handlers for better structure in vertical slice architecture 2023-03-22 17:56:24 +04:30
Meysam Hadeli
217736ccef
Merge pull request #235 from meysamhadeli/develop
Update README.md
2023-03-21 16:32:30 +03:30
Meysam Hadeli
113278051a
Update README.md 2023-03-21 16:31:53 +03:30
Pc
450a0411e0 Merge branch 'develop' 2023-03-21 02:24:05 +03:30
Meysam Hadeli
e03f7f07ee
Merge pull request #234 from meysamhadeli/refactor/refactor-feature-folder-structure
refactor: Refactor feature folder structure in vertical slice archite…
2023-03-21 02:23:22 +03:30
Pc
249b3015b5 refactor: Refactor feature folder structure in vertical slice architecture 2023-03-21 02:13:18 +03:30
Meysam Hadeli
8926bd6800
Update README.md 2023-03-12 14:15:54 +03:30
Meysam Hadeli
50d02910df
Merge pull request #233 from meysamhadeli/develop
Develop
2023-03-11 21:55:43 +03:30
Meysam Hadeli
414ae0d305
Merge pull request #232 from meysamhadeli/fix/fix-bug-event-store-options
fix: Fix bug event-store for load configuration options
2023-03-11 21:54:59 +03:30
Pc
4fee16e3b8 fix: Fix bug event-store for load configuration options 2023-03-11 21:53:19 +03:30
Pc
f10fc930d6 chore: try fo fix event-store in ci-cd 2023-03-11 19:59:30 +03:30
Pc
fe8c0f444d refactor: refactor persist message processor 2023-03-11 19:45:02 +03:30
Meysam Hadeli
44abe970b9
Merge pull request #231 from meysamhadeli/develop
Develop
2023-03-11 19:17:23 +03:30
Meysam Hadeli
eab6386f3d
Merge pull request #230 from meysamhadeli/test/add-event-store-test-container
Test/add event store test container
2023-03-11 19:16:58 +03:30
Pc
db0da365b0 test: Update test-container to v3.0.0 for support event-store 2023-03-11 19:15:50 +03:30
Pc
e25c5f5dff Merge branch 'develop' 2023-03-10 16:44:06 +03:30
Pc
7669ad4768 chore: Update README.md 2023-03-10 16:41:07 +03:30
Meysam Hadeli
7fb089afa2
Merge pull request #229 from meysamhadeli/develop
Develop
2023-03-10 16:10:27 +03:30
Meysam Hadeli
43139f36e6
Merge pull request #228 from meysamhadeli/ci/add-let's-encript
ci: Add LetsEncrypt for handle certificate in cert-manager
2023-03-10 16:10:08 +03:30
Pc
dd762da973 ci: Add LetsEncrypt for handle certificate in cert-manager 2023-03-10 16:08:46 +03:30
Pc
a3d4fba111 Merge branch 'develop' 2023-02-28 22:39:07 +03:30
Meysam Hadeli
9119dcfe0c
Update ci.yml 2023-02-28 22:38:16 +03:30
Meysam Hadeli
2359b38e93
Merge pull request #223 from meysamhadeli/develop
Update README.md
2023-02-27 22:59:35 +03:30
Meysam Hadeli
09311394d2
Update README.md 2023-02-27 22:59:06 +03:30
Meysam Hadeli
09a6852370
Merge pull request #222 from meysamhadeli/develop
Develop
2023-02-27 22:45:15 +03:30
Meysam Hadeli
1553085dcc
Merge pull request #221 from meysamhadeli/ci/add-cert-manager-for-kubernetes
ci: Add cert-manager for handle TLS in kubernetes cluster
2023-02-27 22:30:43 +03:30
Pc
9bf2170871 ci: Add cert-manager for handle TLS in kubernetes cluster 2023-02-27 22:29:32 +03:30
Meysam Hadeli
8b9f9269d9
Merge pull request #220 from meysamhadeli/develop
Update ci.yml
2023-02-27 01:03:42 +03:30
Meysam Hadeli
5a7fec5217
Update ci.yml 2023-02-27 00:55:27 +03:30
Meysam Hadeli
5e0a0074cf
Merge pull request #219 from meysamhadeli/develop
Update README.md
2023-02-26 23:15:59 +03:30
Meysam Hadeli
38ec5fae5a
Update README.md 2023-02-26 23:15:14 +03:30
Meysam Hadeli
4a1c655e53
Merge pull request #218 from meysamhadeli/develop
chore: Update diagram vertical slice architecture
2023-02-26 23:10:13 +03:30
Pc
530a8479c1 chore: Update diagram vertical slice architecture 2023-02-26 23:09:36 +03:30
Meysam Hadeli
780f3b78ff
Merge pull request #217 from meysamhadeli/develop
Update README.md
2023-02-26 19:17:58 +03:30
Meysam Hadeli
41661409a8
Update README.md 2023-02-26 19:17:36 +03:30
Meysam Hadeli
9504afdd6d
Merge pull request #216 from meysamhadeli/develop
Update README.md
2023-02-26 19:10:13 +03:30
Meysam Hadeli
107612d206
Update README.md 2023-02-26 19:09:23 +03:30
Meysam Hadeli
f785c9b560
Merge pull request #215 from meysamhadeli/develop
Develop
2023-02-26 18:30:03 +03:30
Meysam Hadeli
41504a37b0
Merge pull request #214 from meysamhadeli/ci/add-reusable-actions-for-build-test
ci: Add Reusable actions for build and test
2023-02-26 18:29:38 +03:30
Pc
860b25429c chore: Update ci.yml 2023-02-26 18:17:32 +03:30
Pc
25b4f55d9a ci: Add Reusable actions for build and test 2023-02-26 18:14:19 +03:30
Meysam Hadeli
09d25d23a6
Merge pull request #213 from meysamhadeli/develop
Develop
2023-02-26 17:00:41 +03:30
Meysam Hadeli
e914b68220
Merge pull request #212 from meysamhadeli/refactor/refactor-yarp-api-gateway
Refactor/refactor yarp api gateway
2023-02-26 17:00:15 +03:30
Meysam Hadeli
37fac813d4 refactor: Refactor Yarp api gateway 2023-02-26 13:29:25 +00:00
Meysam Hadeli
a46d838591
Merge pull request #211 from meysamhadeli/develop
Update README.md
2023-02-26 02:08:39 +03:30
Meysam Hadeli
484e2b30f8
Update README.md 2023-02-26 02:08:02 +03:30
Meysam Hadeli
73fd4837f4
Merge pull request #210 from meysamhadeli/develop
Develop
2023-02-26 02:05:36 +03:30
Meysam Hadeli
da398b3c96
Merge branch 'main' into develop 2023-02-26 02:05:29 +03:30
Meysam Hadeli
3a7185e431
Update README.md 2023-02-26 02:00:52 +03:30
Meysam Hadeli
9a798c3e3c
Update README.md 2023-02-26 01:59:27 +03:30
Pc
d1dba4254e chore: Update README.md 2023-02-26 01:51:25 +03:30
Meysam Hadeli
e117e8136c
Merge pull request #209 from meysamhadeli/develop
Develop
2023-02-26 01:11:18 +03:30
Meysam Hadeli
e8d61d5231
Merge pull request #208 from meysamhadeli/ci/add-kubernetes
ci: Add kubernetes
2023-02-26 01:10:55 +03:30
Pc
20d9891f2e ci: Add kubernetes 2023-02-26 01:09:20 +03:30
Meysam Hadeli
5cc97938e1
Merge pull request #207 from meysamhadeli/develop
chore: Update kubernetes configs
2023-02-25 01:00:28 +03:30
Pc
24a6608f9c chore: Update kubernetes configs 2023-02-25 00:59:27 +03:30
Meysam Hadeli
2464cde8ad
Merge pull request #206 from meysamhadeli/develop
fix: Fix tls error in kubernetes
2023-02-25 00:15:53 +03:30
Pc
954d062453 fix: Fix tls error in kubernetes 2023-02-25 00:14:05 +03:30
Meysam Hadeli
97d9f831af
Merge pull request #205 from meysamhadeli/develop
refactor: Refactor kubernetes configs
2023-02-24 23:31:40 +03:30
Pc
4a31ffbb0b refactor: Refactor kubernetes configs 2023-02-24 23:31:05 +03:30
Meysam Hadeli
6e5f28487f
Merge pull request #204 from meysamhadeli/develop
fix: Fix 401 in gateway
2023-02-24 13:57:16 +03:30
Pc
af4b9866a8 fix: Fix 401 in gateway 2023-02-24 13:56:10 +03:30
Meysam Hadeli
005d6f562f
Merge pull request #203 from meysamhadeli/develop
chore: Update Dockerfiles
2023-02-24 02:08:45 +03:30
Pc
a70320b705 chore: Update Dockerfiles 2023-02-24 02:07:50 +03:30
Meysam Hadeli
49d31d1857
Update README.md 2023-02-24 00:01:06 +03:30
Meysam Hadeli
1de7b9a761
Merge pull request #202 from meysamhadeli/develop
chore: Update docker-compose.yaml
2023-02-23 23:57:23 +03:30
Pc
a142a2e789 chore: Update docker-compose.yaml 2023-02-23 23:56:12 +03:30
Meysam Hadeli
1395a97ba5
Merge pull request #201 from meysamhadeli/develop
chore: Update identity server
2023-02-22 17:06:47 +03:30
Pc
13deb2869c chore: Update identity server 2023-02-22 17:06:26 +03:30
Pc
b68488894a chore: Update identity server 2023-02-22 17:01:42 +03:30
Meysam Hadeli
7a1f946dee
Update README.md 2023-02-22 14:20:17 +03:30
Meysam Hadeli
6dc4a5f41a
Merge pull request #199 from meysamhadeli/develop
chore: Update identity server
2023-02-22 01:59:42 +03:30
Pc
be46876f3b chore: Update identity server 2023-02-22 01:58:38 +03:30
Meysam Hadeli
8eacbd0337
Merge pull request #198 from meysamhadeli/develop
chore: Update identity server
2023-02-22 01:52:31 +03:30
Pc
020273343e chore: Update identity server 2023-02-22 01:50:52 +03:30
Meysam Hadeli
e8cbc10acb
Merge pull request #197 from meysamhadeli/develop
chore: Update identity server
2023-02-22 00:47:14 +03:30
Pc
e4ddcc1a4b chore: Update identity server 2023-02-22 00:46:30 +03:30
Meysam Hadeli
5ceb2d5058
Merge pull request #196 from meysamhadeli/develop
chore: Update identity server
2023-02-21 23:38:38 +03:30
Pc
7fa458f87e chore: Update identity server 2023-02-21 23:37:54 +03:30
Meysam Hadeli
a6af02e86a
Merge pull request #195 from meysamhadeli/develop
chore: Update kubernetes configs
2023-02-21 23:21:17 +03:30
Pc
b5d98699c1 chore: Update kubernetes configs 2023-02-21 23:20:41 +03:30
Meysam Hadeli
8df1cbed4d
Merge pull request #194 from meysamhadeli/develop
chore: Update kubernetes configs
2023-02-21 22:20:31 +03:30
Pc
20795825a3 chore: Update kubernetes configs 2023-02-21 22:19:42 +03:30
Meysam Hadeli
3d256980b5
Merge pull request #192 from meysamhadeli/develop
chore: fix dockerfile
2023-02-14 18:38:17 +03:30
meysamhadeli
5b940857f1 chore: fix dockerfile 2023-02-14 18:37:29 +03:30
Meysam Hadeli
21ef510051
Merge pull request #191 from meysamhadeli/develop
add k8s deployments
2023-02-14 15:44:05 +03:30
meysamhadeli
eaab6ea9fb add k8s deployments 2023-02-14 15:42:58 +03:30
Meysam Hadeli
4262169a74
Merge pull request #190 from meysamhadeli/develop
chore: Update identity server
2023-02-14 05:39:20 +03:30
meysamhadeli
e2da97877c chore: Update identity server 2023-02-14 05:38:45 +03:30
Meysam Hadeli
e9839e1a0d
Merge pull request #189 from meysamhadeli/develop
chore: Update identity server
2023-02-14 05:34:32 +03:30
meysamhadeli
2a19076f7a chore: Update identity server 2023-02-14 05:33:47 +03:30
Meysam Hadeli
342a738152
Merge pull request #188 from meysamhadeli/develop
chore: Update identity server
2023-02-14 05:17:16 +03:30
meysamhadeli
afab1906d1 chore: Update identity server 2023-02-14 05:16:52 +03:30
Meysam Hadeli
8d1d9d3bc3
Merge pull request #187 from meysamhadeli/develop
chore: Update identity server
2023-02-14 03:49:31 +03:30
meysamhadeli
634219bc3e chore: Update identity server 2023-02-14 03:48:54 +03:30
Meysam Hadeli
900d24ef6e
Merge pull request #186 from meysamhadeli/develop
chore: Update identity server
2023-02-14 02:53:02 +03:30
meysamhadeli
30dea9d641 chore: Update identity server 2023-02-14 02:52:24 +03:30
Meysam Hadeli
a35e0c2a54
Merge pull request #185 from meysamhadeli/develop
chore: Update identity server
2023-02-14 01:36:18 +03:30
meysamhadeli
218a49e66b chore: Update identity server 2023-02-14 01:35:21 +03:30
Meysam Hadeli
2cde2c220c
Merge pull request #184 from meysamhadeli/develop
chore: Update identity server
2023-02-14 00:30:24 +03:30
meysamhadeli
696ed74b75 chore: Update identity server 2023-02-14 00:29:30 +03:30
Meysam Hadeli
1e2ea92465
Merge pull request #183 from meysamhadeli/develop
chore: Update identity server
2023-02-14 00:21:58 +03:30
meysamhadeli
562cf183b9 chore: Update identity server 2023-02-14 00:21:14 +03:30
Meysam Hadeli
54bdd63d21
Merge pull request #182 from meysamhadeli/develop
Develop
2023-02-14 00:10:04 +03:30
meysamhadeli
9fd251bb99 chore: Update identity server 2023-02-14 00:09:10 +03:30
meysamhadeli
2c2e2ca546 chore: Update identity server 2023-02-14 00:08:27 +03:30
Meysam Hadeli
b688d6259d
Merge pull request #181 from meysamhadeli/develop
Develop
2023-02-13 22:44:30 +03:30
Meysam Hadeli
7a649acf21
Merge pull request #180 from meysamhadeli/chore/update-identity-server
chore: Update identity server
2023-02-13 22:44:02 +03:30
meysamhadeli
109a9b27cf chore: Update identity server 2023-02-13 22:43:18 +03:30
Meysam Hadeli
fa78e341b6
Merge pull request #179 from meysamhadeli/develop
Develop
2023-02-13 20:40:47 +03:30
Meysam Hadeli
e1e7123e77
Merge pull request #178 from meysamhadeli/chore/update-identity-server
chore: Update identity server
2023-02-13 20:40:12 +03:30
meysamhadeli
b844ff35d2 chore: Update identity server 2023-02-13 20:39:18 +03:30
Meysam Hadeli
095f36eff9
Merge pull request #177 from meysamhadeli/develop
Develop
2023-02-13 16:57:21 +03:30
Meysam Hadeli
fb3117ef94
Merge pull request #176 from meysamhadeli/feat/config-identitiy-server-for-revers-proxy
feat: Config identity server for ingress revers proxy
2023-02-13 16:56:54 +03:30
meysamhadeli
27ef1ee87d feat: Config identity server for ingress revers proxy 2023-02-13 16:56:23 +03:30
Meysam Hadeli
d883ebd626
Merge pull request #175 from meysamhadeli/develop
chore: Update flight service
2023-02-13 02:03:00 +03:30
meysamhadeli
940c807c51 chore: Update flight service 2023-02-13 02:02:16 +03:30
708 changed files with 31187 additions and 22457 deletions

3
.aspire/settings.json Normal file
View File

@ -0,0 +1,3 @@
{
"appHostPath": "../src/Aspire/src/AppHost/AppHost.csproj"
}

30
.config/dotnet-tools.json Normal file
View File

@ -0,0 +1,30 @@
{
"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"
]
}
}
}

View File

@ -22,6 +22,9 @@
**/.tye/
**/secrets.dev.yaml
**/values.dev.yaml
**/*.jwk
**/keys
LICENSE
README.md
CHANGELOG.md

File diff suppressed because it is too large Load Diff

64
.gitattributes vendored Normal file
View File

@ -0,0 +1,64 @@
###############################################################################
# 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 Normal file
View File

@ -0,0 +1,59 @@
# 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 Normal file
View File

@ -0,0 +1,69 @@
# 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

View File

@ -34,6 +34,11 @@ 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 Normal file
View File

@ -0,0 +1,85 @@
# 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: "'

View File

@ -1,39 +0,0 @@
<!-- 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.
-->

View File

@ -28,7 +28,7 @@ categories:
- title: 👷 CI
labels:
- ci
- title: ♻️ Changes
- title: ♻️ Refactor
labels:
- changed
- enhancement
@ -91,9 +91,7 @@ autolabeler:
body:
- '/JIRA-[0-9]{1,4}/'
change-template: '- $TITLE (#$NUMBER)'
exclude-contributors:
- 'meysamhadeli'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
version-resolver:
major:

View File

@ -2,41 +2,83 @@ name: CI
on:
push:
branches: [ "main" , "develop" ]
branches: [ "main"]
paths-ignore:
- "README.md"
pull_request:
branches: [ "main" , "develop" ]
branches: [ "main"]
paths-ignore:
- "README.md"
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.sha }}
cancel-in-progress: true
jobs:
build:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v2
- name: Build and Test Flight Microservice
uses: ./.github/actions/build-test
if: success()
id: build-test-flight-step
with:
dotnet-version: 7.0.x
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 }}
- name: Cache NuGet Packages
uses: actions/cache@v3
- name: Build and Test Identity Microservice
uses: ./.github/actions/build-test
if: success()
id: build-test-identity-step
with:
key: ${{ runner.os }}-dotnet-nuget
path: ~/.nuget/packages
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 }}
- 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: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build -c Release --no-restore
- name: Test
run: dotnet test -c Release --no-restore
- 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: Update Release Drafter
if: ${{ github.ref == 'refs/heads/main' && success() }}
@ -45,7 +87,11 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Publish Identity to Docker
- name: Release Version Info
run:
echo "Release version is:" ${{ steps.last_release.outputs.tag_name }}
- name: Build and Publish Identity Microservice to Docker
if: ${{ github.ref == 'refs/heads/main' && success() }}
uses: ./.github/actions/docker-build-publish
with:
@ -55,7 +101,7 @@ jobs:
dockerfile-path: 'src/Services/Identity/Dockerfile'
image-name: 'booking-microservices-identity'
- name: Build and Publish Flight to Docker
- name: Build and Publish Flight Microservice to Docker
if: ${{ github.ref == 'refs/heads/main' && success() }}
uses: ./.github/actions/docker-build-publish
with:
@ -65,7 +111,7 @@ jobs:
dockerfile-path: 'src/Services/Flight/Dockerfile'
image-name: 'booking-microservices-flight'
- name: Build and Publish Passenger to Docker
- name: Build and Publish Passenger Microservice to Docker
if: ${{ github.ref == 'refs/heads/main' && success() }}
uses: ./.github/actions/docker-build-publish
with:
@ -75,7 +121,7 @@ jobs:
dockerfile-path: 'src/Services/Passenger/Dockerfile'
image-name: 'booking-microservices-passenger'
- name: Build and Publish Booking to Docker
- name: Build and Publish Booking Microservice to Docker
if: ${{ github.ref == 'refs/heads/main' && success() }}
uses: ./.github/actions/docker-build-publish
with:

11
.gitignore vendored
View File

@ -226,7 +226,6 @@ ClientBin/
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
@ -432,4 +431,12 @@ fabric.properties
*.sln.iml
# Tye
.tye/
.tye/
*.jwk
# Monitoring
**/grafana-data
# EventStore
**/eventstore

1
.gitpod.Dockerfile vendored
View File

@ -1 +0,0 @@
FROM gitpod/workspace-dotnet:latest

View File

@ -1,30 +0,0 @@
# 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
.husky/commit-msg Normal file
View File

@ -0,0 +1 @@
npx --no -- commitlint --edit ${1}

2
.husky/pre-commit Normal file
View File

@ -0,0 +1,2 @@
npm run format
npm run ci-format

26
CONTRIBUTION.md Normal file
View File

@ -0,0 +1,26 @@
## 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)

View File

@ -1,8 +1,48 @@
<?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>
<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" />
<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>
</ItemGroup>
<PropertyGroup>
<RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<CodeAnalysisTreatWarningsAsErrors>false</CodeAnalysisTreatWarningsAsErrors>
<AnalysisLevel>latest-Recommended</AnalysisLevel>
<AnalysisMode>Recommended</AnalysisMode>
</PropertyGroup>
</Project>

241
README.md
View File

@ -2,90 +2,128 @@
<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>
> **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.** 🚀
> 🚀 **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>
# 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 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 `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 `CQRS` implementation with `MediatR` library.
- :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 `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 `Fluent Validation` and a `Validation Pipeline Behaviour` on top of `MediatR`.
- :sparkle: Using `Minimal API` for all endpoints.
- :sparkle: Using `Health Check` for reporting the health of app infrastructure components.
- :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 `Docker-Compose` and `Kubernetes` for our deployment mechanism.
- :sparkle: Using `OpenTelemetry` for distributed tracing.
- :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 `IdentityServer` for authentication and authorization base on `OpenID-Connect` and `OAuth2`.
- :sparkle: Using `Yarp` as a microservices gateway.
- :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.
## Plan
> 🌀This project is a work in progress, new features will be added over time.🌀
## Technologies - Libraries
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
- ✔️ **[`.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.
- ✔️ **[`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
- ✔️ **[`Swagger & 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.
- ✔️ **[`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.
- ✔️ **[`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
- ✔️ **[`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
- ✔️ **[`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.
- ✔️ **[`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
@ -99,26 +137,19 @@ High-level plan is represented in the table
![](./assets/booking-microservices.png)
## Structure of Project
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.
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.
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.
![](./assets/Vertical-Slice-Architecture.jpg)
<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.
@ -132,43 +163,111 @@ 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 for [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 to [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
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:
### 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:
```bash
docker-compose -f ./deployments/docker-compose/docker-compose.yaml up -d
```
Also we have a seprate docker file for up and running [infrastracture.yaml](./deployments/docker-compose/infrastracture.yaml) independently:
> ### 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.
```bash
docker-compose -f ./deployments/docker-compose/infrastracture.yaml up -d
kubectl apply -f ./deployments/kubernetes/booking-cert-manager.yml
```
### Kubernetes - TODO
To apply all necessary `deployments`, `pods`, `services`, `ingress`, and `config maps`, please run the following command:
### Documentation Apis
```bash
kubectl apply -f ./deployments/kubernetes/booking-microservices.yml
```
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).
> ### 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`.
# Support
@ -180,7 +279,9 @@ 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.
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.
## Project References & Credits
@ -188,9 +289,7 @@ Thanks to all [contributors](https://github.com/meysamhadeli/booking-microservic
- [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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 643 KiB

View File

@ -0,0 +1,431 @@
{
"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.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -1,175 +0,0 @@

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

348
booking-microservices.sln Normal file
View File

@ -0,0 +1,348 @@
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

View File

@ -1,12 +1,15 @@
# https://github.com/Huachao/vscode-restclient
## uncommnet this line for use kubernetes ingress controller instead of Yarp
//@api-gateway=https://booking-microservices.com
@api-gateway=https://localhost:5000
@identity-api=https://localhost:5005
@flight-api=https://localhost:5003
@passenger-api=https://localhost:5012
@booking-api=https://localhost:5010
@identity-api=http://localhost:6005
@flight-api=http://localhost:5004
@passenger-api=http://localhost:6012
@booking-api=http://localhost:6010
@contentType = application/json
@flightid = 1
@passengerId = 1
@flightid = "3c5c0000-97c6-fc34-2eb9-08db322230c9"
@passengerId = "8c9c0000-97c6-fc34-2eb9-66db322230c9"
################################# Identity API #################################
@ -18,7 +21,7 @@ GET {{identity-api}}
###
# @name Authenticate
POST {{api-gateway}}/connect/token
POST {{api-gateway}}/identity/connect/token
Content-Type: application/x-www-form-urlencoded
grant_type=password
@ -26,14 +29,16 @@ grant_type=password
&client_secret=secret
&username=samh
&password=Admin@123456
&scope=flight-api
&scope=flight-api role
### change scope base on microservices scope (eg. passenger-api, ...)
###
###
# @name Register_New_User
POST {{api-gateway}}/api/v1/identity/register-user
POST {{api-gateway}}/identity/api/v1/identity/register-user
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -42,7 +47,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
"firstName": "John",
"lastName": "Do",
"username": "admin",
"passportNumber": "412900000000",
"passportNumber": "41290000",
"email": "admin@admin.com",
"password": "Admin@12345",
"confirmPassword": "Admin@12345"
@ -58,7 +63,7 @@ GET {{flight-api}}
###
# @name Create_Seat
Post {{api-gateway}}/api/v1/flight/seat
Post {{api-gateway}}/flight/api/v1/flight/seat
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -67,20 +72,20 @@ authorization: bearer {{Authenticate.response.body.access_token}}
"seatNumber": "1255",
"type": 1,
"class": 1,
"flightId": 1
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9"
}
###
###
# @name Reserve_Seat
Post {{api-gateway}}/api/v1/flight/reserve-seat
Post {{api-gateway}}/flight/api/v1/flight/reserve-seat
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
{
"flightId": 1,
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9",
"seatNumber": "1255"
}
###
@ -88,7 +93,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Get_Available_Seats
GET {{api-gateway}}/api/v1/flight/get-available-seats/{{flightid}}
GET {{api-gateway}}/flight/api/v1/flight/get-available-seats/{{flightid}}
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -97,7 +102,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Get_Flight_By_Id
GET {{api-gateway}}/api/v1/flight/{{flightid}}
GET {{api-gateway}}/flight/api/v1/flight/{{flightid}}
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -106,7 +111,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Get_Available_Flights
GET {{api-gateway}}/api/v1/flight/get-available-flights
GET {{api-gateway}}/flight/api/v1/flight/get-available-flights
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -115,18 +120,18 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Create_Flights
POST {{api-gateway}}/api/v1/flight
POST {{api-gateway}}/flight/api/v1/flight
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
{
"flightNumber": "12BB",
"aircraftId": 1,
"departureAirportId": 1,
"aircraftId": "3c5c0000-97c6-fc34-fcd3-08db322230c8",
"departureAirportId": "3c5c0000-97c6-fc34-a0cb-08db322230c8",
"departureDate": "2022-03-01T14:55:41.255Z",
"arriveDate": "2022-03-01T14:55:41.255Z",
"arriveAirportId": 2,
"arriveAirportId": "3c5c0000-97c6-fc34-fc3c-08db322230c8",
"durationMinutes": 120,
"flightDate": "2022-03-01T14:55:41.255Z",
"status": 1,
@ -137,7 +142,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Update_Flights
PUT {{api-gateway}}/api/v1/flight
PUT {{api-gateway}}/flight/api/v1/flight
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -145,11 +150,11 @@ authorization: bearer {{Authenticate.response.body.access_token}}
{
"id": 1,
"flightNumber": "BD467",
"aircraftId": 1,
"departureAirportId": 1,
"aircraftId": "3c5c0000-97c6-fc34-fcd3-08db322230c8",
"departureAirportId": "3c5c0000-97c6-fc34-a0cb-08db322230c8",
"departureDate": "2022-04-23T12:17:45.140Z",
"arriveDate": "2022-04-23T12:17:45.140Z",
"arriveAirportId": 2,
"arriveAirportId": "3c5c0000-97c6-fc34-fc3c-08db322230c8",
"durationMinutes": 120,
"flightDate": "2022-04-23T12:17:45.140Z",
"status": 4,
@ -161,7 +166,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Delete_Flights
DELETE {{api-gateway}}/api/v1/flight/{{flightid}}
DELETE {{api-gateway}}/flight/api/v1/flight/{{flightid}}
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -170,7 +175,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Create_Airport
POST {{api-gateway}}/api/v1/flight/airport
POST {{api-gateway}}/flight/api/v1/flight/airport
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -186,7 +191,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Create_Aircraft
POST {{api-gateway}}/api/v1/flight/aircraft
POST {{api-gateway}}/flight/api/v1/flight/aircraft
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -209,13 +214,13 @@ GET {{passenger-api}}
###
# @name Complete_Registration_Passenger
POST {{api-gateway}}/api/v1/passenger/complete-registration
POST {{api-gateway}}/passenger/api/v1/passenger/complete-registration
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
{
"passportNumber": "412900000000",
"passportNumber": "41290000",
"passengerType": 1,
"age": 30
}
@ -224,7 +229,7 @@ authorization: bearer {{Authenticate.response.body.access_token}}
###
# @name Get_Passenger_By_Id
GET {{api-gateway}}/api/v1/passenger/{{passengerId}}
GET {{api-gateway}}/passenger/api/v1/passenger/{{passengerId}}
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
@ -241,14 +246,14 @@ GET {{booking-api}}
###
# @name Create_Booking
POST {{api-gateway}}/api/v1/booking
POST {{api-gateway}}/booking/api/v1/booking
accept: application/json
Content-Type: application/json
authorization: bearer {{Authenticate.response.body.access_token}}
{
"passengerId": 8765596234940416,
"flightId": 1,
"passengerId": "8c9c0000-97c6-fc34-2eb9-66db322230c9",
"flightId": "3c5c0000-97c6-fc34-2eb9-08db322230c9",
"description": "I want to fly to iran"
}
###

3
commitlint.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
extends: ["@commitlint/config-conventional"],
}

View File

View File

@ -0,0 +1,8 @@
# 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/)

View File

@ -0,0 +1,908 @@
{
"__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

View File

@ -0,0 +1,892 @@
{
"__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

View File

@ -0,0 +1,14 @@
# 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

View File

@ -0,0 +1,88 @@
# 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

View File

@ -0,0 +1,44 @@
# 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

View File

@ -0,0 +1,131 @@
# 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 its 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]

View File

@ -0,0 +1,48 @@
# 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' ]

View File

@ -0,0 +1,49 @@
# 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

View File

@ -0,0 +1,362 @@
# 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:

View File

@ -1,31 +1,372 @@
version: "3.3"
name: booking-microservices
services:
#######################################################
# Gateway
# rabbitmq
#######################################################
gateway:
image: 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
build:
args:
Version: "1"
context: ../../
dockerfile: src/ApiGateway/Dockerfile
container_name: booking-gateway
container_name: api-gateway
ports:
- "5001:80"
- "5000:443"
depends_on:
- postgres
- rabbitmq
- jaeger
- elasticsearch
- kibana
volumes:
- ~/.aspnet/https:/https:ro
environment:
- 'ASPNETCORE_URLS=https://+;http://+'
- ASPNETCORE_HTTPS_PORT=5001
- ASPNETCORE_ENVIRONMENT=docker
- ASPNETCORE_URLS=https://+;http://+
- ASPNETCORE_HTTPS_PORT=5000
- ASPNETCORE_HTTP_PORT=5001
- ASPNETCORE_Kestrel__Certificates__Default__Password=password
- ASPNETCORE_Kestrel__Certificates__Default__Path=/https/aspnetapp.pfx
networks:
@ -46,24 +387,18 @@ services:
ports:
- 5004:80
- 5003:443
depends_on:
- postgres
- rabbitmq
- jaeger
- elasticsearch
- kibana
- mongo
volumes:
- ~/.aspnet/https:/https:ro
environment:
- 'ASPNETCORE_URLS=https://+;http://+'
- ASPNETCORE_ENVIRONMENT=docker
- 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
#######################################################
@ -78,17 +413,13 @@ services:
ports:
- 6005:80
- 5005:443
depends_on:
- postgres
- rabbitmq
- jaeger
- elasticsearch
- kibana
volumes:
- ~/.aspnet/https:/https:ro
environment:
- 'ASPNETCORE_URLS=https://+;http://+'
- ASPNETCORE_ENVIRONMENT=docker
- 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:
@ -109,18 +440,13 @@ services:
ports:
- 6012:80
- 5012:443
depends_on:
- postgres
- rabbitmq
- jaeger
- elasticsearch
- kibana
- mongo
volumes:
- ~/.aspnet/https:/https:ro
environment:
- 'ASPNETCORE_URLS=https://+;http://+'
- ASPNETCORE_ENVIRONMENT=docker
- 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:
@ -141,154 +467,26 @@ services:
ports:
- 6010:80
- 5010:443
depends_on:
- postgres
- rabbitmq
- jaeger
- eventstore
- elasticsearch
- kibana
- mongo
volumes:
- ~/.aspnet/https:/https:ro
environment:
- 'ASPNETCORE_URLS=https://+;http://+'
- ASPNETCORE_ENVIRONMENT=docker
- 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:
elasticsearch-data:
elastic-data:
postgres-data:

View File

@ -1,152 +0,0 @@
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:

View File

@ -0,0 +1,16 @@
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

View File

@ -1,45 +0,0 @@
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

6
global.json Normal file
View File

@ -0,0 +1,6 @@
{
"sdk": {
"version": "10.0.103",
"rollForward": "latestFeature"
}
}

1346
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,19 @@
{
"version": "0.0.0"
{
"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"
}
}

View File

@ -1,37 +1,38 @@
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS builder
# ---------- Build Stage ----------
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
WORKDIR /src
# Setup working directory for the project
WORKDIR /src
COPY ./src/BuildingBlocks/BuildingBlocks.csproj ./BuildingBlocks/
COPY ./src/ApiGateway/src/ApiGateway.csproj ./ApiGateway/src/
# Copy solution-level files
COPY .editorconfig .
COPY global.json .
COPY Directory.Build.props .
# 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 nuget packages
RUN dotnet restore ./ApiGateway/src/ApiGateway.csproj
# Restore dependencies
RUN dotnet restore src/ApiGateway/src/ApiGateway.csproj
# Copy project files
COPY ./src/BuildingBlocks ./BuildingBlocks/
COPY ./src/ApiGateway/src ./ApiGateway/src/
# Copy the rest of the source code
COPY src ./src
# Build project with Release configuration
# and no restore, as we did it already
# Publish (build included)
RUN dotnet publish src/ApiGateway/src/ApiGateway.csproj \
-c Release \
-o /app/publish \
--no-restore
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
# ---------- Runtime Stage ----------
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
WORKDIR /app
COPY --from=builder /src/ApiGateway/src/out .
EXPOSE 80
EXPOSE 443
ENTRYPOINT ["dotnet", "ApiGateway.dll"]
COPY --from=build /app/publish .
ENV ASPNETCORE_URLS=http://+:80
ENV ASPNETCORE_ENVIRONMENT=docker
EXPOSE 80
ENTRYPOINT ["dotnet", "ApiGateway.dll"]

View File

@ -1,21 +1,5 @@
<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>

View File

@ -1,9 +1,6 @@
using BuildingBlocks.Jwt;
using BuildingBlocks.Logging;
using BuildingBlocks.Web;
using Figgle;
using Microsoft.AspNetCore.Authentication;
using Serilog;
using Figgle.Fonts;
var builder = WebApplication.CreateBuilder(args);
var env = builder.Environment;
@ -11,9 +8,6 @@ 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();
@ -21,7 +15,6 @@ builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSecti
var app = builder.Build();
app.UseSerilogRequestLogging();
app.UseCorrelationId();
app.UseRouting();
app.UseHttpsRedirection();
@ -31,18 +24,9 @@ app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
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);
});
});
endpoints.MapReverseProxy();
});
app.MapGet("/", x => x.Response.WriteAsync(appOptions.Name));
app.Run();
app.Run();

View File

@ -1,13 +1,5 @@
{
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:17191",
"sslPort": 44352
}
},
"profiles": {
"ApiGateway": {
"commandName": "Project",
@ -17,14 +9,6 @@
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -1,24 +1,36 @@
{
"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"
"address": "http://flight:80"
}
}
},
"identity": {
"destinations": {
"destination1": {
"address": "http://identity:80"
}
}
},
"passenger": {
"destinations": {
"destination1": {
"address": "http://passenger"
"address": "http://passenger:80"
}
}
},
"booking": {
"destinations": {
"destination1": {
"address": "http://booking"
"address": "http://booking:80"
}
}
}

View File

@ -15,61 +15,78 @@
"identity": {
"clusterId": "identity",
"match": {
"path": "/{**catch-all}"
"path": "identity/{**catch-all}"
},
"Transforms": [
{
"PathRemovePrefix": "identity"
}
]
},
"flight": {
"clusterId": "flight",
"match": {
"path": "api/{version}/flight/{**catch-all}"
}
"path": "flight/{**catch-all}"
},
"Transforms": [
{
"PathRemovePrefix": "flight"
}
]
},
"passenger": {
"clusterId": "passenger",
"match": {
"path": "api/{version}/passenger/{**catch-all}"
}
"path": "passenger/{**catch-all}"
},
"Transforms": [
{
"PathRemovePrefix": "passenger"
}
]
},
"booking": {
"clusterId": "booking",
"match": {
"path": "api/{version}/booking/{**catch-all}"
}
"path": "booking/{**catch-all}"
},
"Transforms": [
{
"PathRemovePrefix": "booking"
}
]
}
},
"clusters": {
"flight": {
"destinations": {
"destination1": {
"address": "https://localhost:5003"
"address": "http://localhost:5004"
}
}
},
"identity": {
"destinations": {
"destination1": {
"address": "https://localhost:5005"
"address": "http://localhost:6005"
}
}
},
"passenger": {
"destinations": {
"destination1": {
"address": "https://localhost:5012"
"address": "http://localhost:6012"
}
}
},
"booking": {
"destinations": {
"destination1": {
"address": "https://localhost:5010"
"address": "http://localhost:6010"
}
}
}
}
},
"Jwt": {
"Authority": "https://localhost:5005"
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,33 @@
<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>

View File

@ -0,0 +1,366 @@
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();

View File

@ -0,0 +1,18 @@
{
"$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"
}
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,41 @@
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;
}
}

View File

@ -0,0 +1,13 @@
<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>

View File

@ -1,160 +1,110 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<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="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="Grpc.Core.Testing" Version="2.46.6" />
<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="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="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="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="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="EventStore.Client.Grpc.Streams" Version="23.3.9" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
<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="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.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" />
<PackageReference Include="Google.Protobuf" Version="3.33.5" />
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.76.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Contracts" />
<Folder Include="EventStoreDB\BackgroundWorkers" />
<Folder Include="PersistMessageProcessor\Data\Configurations" />
<Folder Include="PersistMessageProcessor\Data\Migrations" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>

View File

@ -1,55 +0,0 @@
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;
}
}

View File

@ -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;
}
}
}

View File

@ -4,4 +4,4 @@ public interface ICacheRequest
{
string CacheKey { get; }
DateTime? AbsoluteExpirationRelativeToNow { get; }
}
}

View File

@ -4,4 +4,4 @@ namespace BuildingBlocks.Caching
{
string CacheKey { get; }
}
}
}

View File

@ -36,4 +36,4 @@ namespace BuildingBlocks.Caching
return response;
}
}
}
}

View File

@ -0,0 +1,10 @@
namespace BuildingBlocks.Constants;
public static class IdentityConstant
{
public static class Role
{
public const string Admin = "admin";
public const string User = "user";
}
}

View File

@ -2,10 +2,10 @@ using BuildingBlocks.Core.Event;
namespace BuildingBlocks.Contracts.EventBus.Messages;
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;
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;

View File

@ -2,4 +2,4 @@ using BuildingBlocks.Core.Event;
namespace BuildingBlocks.Contracts.EventBus.Messages;
public record UserCreated(long Id, string Name, string PassportNumber) : IIntegrationEvent;
public record UserCreated(Guid Id, string Name, string PassportNumber) : IIntegrationEvent;

View File

@ -2,5 +2,5 @@ using BuildingBlocks.Core.Event;
namespace BuildingBlocks.Contracts.EventBus.Messages;
public record PassengerRegistrationCompleted(long Id) : IIntegrationEvent;
public record PassengerCreated(long Id) : IIntegrationEvent;
public record PassengerRegistrationCompleted(Guid Id) : IIntegrationEvent;
public record PassengerCreated(Guid Id) : IIntegrationEvent;

View File

@ -2,4 +2,4 @@ using BuildingBlocks.Core.Event;
namespace BuildingBlocks.Contracts.EventBus.Messages;
public record BookingCreated(long Id) : IIntegrationEvent;
public record BookingCreated(Guid Id) : IIntegrationEvent;

View File

@ -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
{
}
}

View File

@ -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
{
}
}

View File

@ -1,8 +1,8 @@
using MediatR;
using MediatR;
namespace BuildingBlocks.Core.CQRS;
public interface IQuery<out T> : IRequest<T>
where T : notnull
{
}
}

View File

@ -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
{
}
}

View File

@ -0,0 +1,37 @@
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;
}
}

View File

@ -6,4 +6,4 @@ public enum EventType
DomainEvent = 1,
IntegrationEvent = 2,
InternalCommand = 4
}
}

View File

@ -2,4 +2,4 @@ namespace BuildingBlocks.Core.Event;
public interface IDomainEvent : IEvent
{
}
}

View File

@ -1,11 +1,12 @@
using BuildingBlocks.IdsGenerator;
using MediatR;
namespace BuildingBlocks.Core.Event;
using global::MassTransit;
public interface IEvent : INotification
{
long EventId => SnowFlakIdGenerator.NewId();
Guid EventId => NewId.NextGuid();
public DateTime OccurredOn => DateTime.Now;
public string EventType => GetType().AssemblyQualifiedName;
}
}

View File

@ -5,4 +5,4 @@ namespace BuildingBlocks.Core.Event;
[ExcludeFromTopology]
public interface IIntegrationEvent : IEvent
{
}
}

View File

@ -1,5 +1,5 @@
namespace BuildingBlocks.Core.Event;
namespace BuildingBlocks.Core.Event;
public interface IInternalCommand : IEvent
{
}
}

View File

@ -1,6 +1,5 @@
using BuildingBlocks.Core.CQRS;
using BuildingBlocks.IdsGenerator;
using BuildingBlocks.Core.CQRS;
namespace BuildingBlocks.Core.Event;
public record InternalCommand : IInternalCommand, ICommand;
public record InternalCommand : IInternalCommand, ICommand;

View File

@ -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; }
}
}

View File

@ -9,30 +9,17 @@ using MessageEnvelope = BuildingBlocks.Core.Event.MessageEnvelope;
namespace BuildingBlocks.Core;
public sealed class EventDispatcher : IEventDispatcher
public sealed class EventDispatcher(
IServiceScopeFactory serviceScopeFactory,
IEventMapper eventMapper,
ILogger<EventDispatcher> logger,
IPersistMessageProcessor persistMessageProcessor,
IHttpContextAccessor httpContextAccessor
)
: 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)
@ -45,7 +32,7 @@ public sealed class EventDispatcher : IEventDispatcher
{
foreach (var integrationEvent in integrationEvents)
{
await _persistMessageProcessor.PublishMessageAsync(
await persistMessageProcessor.PublishMessageAsync(
new MessageEnvelope(integrationEvent, SetHeaders()),
cancellationToken);
}
@ -54,13 +41,13 @@ public sealed class EventDispatcher : IEventDispatcher
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);
@ -74,7 +61,7 @@ public sealed class EventDispatcher : IEventDispatcher
foreach (var internalMessage in internalMessages)
{
await _persistMessageProcessor.AddInternalMessageAsync(internalMessage, cancellationToken);
await persistMessageProcessor.AddInternalMessageAsync(internalMessage, cancellationToken);
}
}
}
@ -83,33 +70,34 @@ public sealed class EventDispatcher : IEventDispatcher
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);
}
@ -118,23 +106,24 @@ public sealed class EventDispatcher : IEventDispatcher
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);
}
@ -157,10 +146,10 @@ public sealed class EventDispatcher : IEventDispatcher
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;
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -3,4 +3,4 @@ using BuildingBlocks.Core.Event;
namespace BuildingBlocks.Core;
public record IntegrationEventWrapper<TDomainEventType>(TDomainEventType DomainEvent) : IIntegrationEvent
where TDomainEventType : IDomainEvent;
where TDomainEventType : IDomainEvent;

View File

@ -1,32 +1,23 @@
using BuildingBlocks.Core.Event;
using BuildingBlocks.Core.Event;
namespace BuildingBlocks.Core.Model
namespace BuildingBlocks.Core.Model;
public abstract record Aggregate<TId> : Entity<TId>, IAggregate<TId>
{
public abstract record Aggregate : Aggregate<long>
private readonly List<IDomainEvent> _domainEvents = new();
public IReadOnlyList<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
public void AddDomainEvent(IDomainEvent domainEvent)
{
_domainEvents.Add(domainEvent);
}
public abstract record Aggregate<TId> : Audit, IAggregate<TId>
public IEvent[] ClearDomainEvents()
{
private readonly List<IDomainEvent> _domainEvents = new();
public IReadOnlyList<IDomainEvent> DomainEvents => _domainEvents.AsReadOnly();
IEvent[] dequeuedEvents = _domainEvents.ToArray();
public void AddDomainEvent(IDomainEvent domainEvent)
{
_domainEvents.Add(domainEvent);
}
_domainEvents.Clear();
public IEvent[] ClearDomainEvents()
{
IEvent[] dequeuedEvents = _domainEvents.ToArray();
_domainEvents.Clear();
return dequeuedEvents;
}
public long Version { get; set; }
public TId Id { get; set; }
return dequeuedEvents;
}
}
}

View File

@ -1,10 +1,12 @@
namespace BuildingBlocks.Core.Model;
public interface IAudit
public abstract record Entity<T> : IEntity<T>
{
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; }
}

View File

@ -1,19 +1,13 @@
using BuildingBlocks.Core.Event;
using BuildingBlocks.Core.Event;
namespace BuildingBlocks.Core.Model;
public interface IAggregate : IAudit, IVersion
public interface IAggregate<T> : IAggregate, IEntity<T>
{
}
public interface IAggregate : IEntity
{
IReadOnlyList<IDomainEvent> DomainEvents { get; }
IEvent[] ClearDomainEvents();
}
public interface IAggregate<out T> : IAggregate
{
T Id { get; }
}
public interface IVersion
{
long Version { get; set; }
}
}

View File

@ -1,10 +1,15 @@
namespace BuildingBlocks.Core.Model;
public abstract record Audit : IAudit
public interface IEntity<T> : IEntity
{
public T Id { get; set; }
}
public interface IEntity : IVersion
{
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; }
}
}

View File

@ -0,0 +1,7 @@
namespace BuildingBlocks.Core.Model;
// For handling optimistic concurrency
public interface IVersion
{
long Version { get; set; }
}

View File

@ -0,0 +1,36 @@
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);
}
}

View File

@ -0,0 +1,16 @@
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; }
}

View File

@ -0,0 +1,7 @@
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