mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-10 17:59:38 +08:00
Compare commits
481 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d99d1a9a9a | ||
|
|
6e1fe61a65 | ||
|
|
a882b3cfe2 | ||
|
|
14cc9e7c96 | ||
|
|
0f66c14299 | ||
|
|
7f9cf8b922 | ||
|
|
23d4babd52 | ||
|
|
8d4819624e | ||
|
|
043c20002c | ||
|
|
94a22dfc23 | ||
|
|
3ce312891a | ||
|
|
a62177a6c4 | ||
|
|
b67d000580 | ||
|
|
2a5909bdbd | ||
|
|
786fbb121f | ||
|
|
b9b3c26edc | ||
|
|
9dcd6625b2 | ||
|
|
43666a7dd3 | ||
|
|
23b14eabe7 | ||
|
|
9164c770b5 | ||
|
|
3bdcc6341f | ||
|
|
20e49770b2 | ||
|
|
e259b64476 | ||
|
|
7476502e50 | ||
|
|
64dfee4224 | ||
|
|
bd94742d18 | ||
|
|
d5e9f75dfc | ||
|
|
eef8aead7e | ||
|
|
38c339c1aa | ||
|
|
20bd2ac0bc | ||
|
|
3b86cf7917 | ||
|
|
d1dbe6209c | ||
|
|
475fa90e1c | ||
|
|
0dd7941136 | ||
|
|
29a1e47a2d | ||
|
|
68f768d687 | ||
|
|
e2fbd27222 | ||
|
|
d6e313a560 | ||
|
|
57000c5802 | ||
|
|
b3ce2889b2 | ||
|
|
a3c6f670e1 | ||
|
|
3bd8cb1db3 | ||
|
|
b9e1a1b949 | ||
|
|
e76353c2df | ||
|
|
44e408258f | ||
|
|
10627f8de6 | ||
|
|
61d90da20e | ||
|
|
be13a0ac27 | ||
|
|
aba06b9675 | ||
|
|
a887b0406e | ||
|
|
da1a3df324 | ||
|
|
756f166711 | ||
|
|
0809701fe7 | ||
|
|
ab512476d0 | ||
|
|
b2e6d4c834 | ||
|
|
a67909d109 | ||
|
|
11e3bb3904 | ||
|
|
e3154c23bc | ||
|
|
89589c2c72 | ||
|
|
406d3e16e7 | ||
|
|
aeb19e2f4b | ||
|
|
2e02f1b3bf | ||
|
|
c33eaf4d07 | ||
|
|
afbe8ffeff | ||
|
|
05fcc24bc8 | ||
|
|
768178b153 | ||
|
|
ca7ee3833b | ||
|
|
b0da80bfff | ||
|
|
93850aaf2f | ||
|
|
d26115ccc5 | ||
|
|
1bf20a8334 | ||
|
|
157d9e24d0 | ||
|
|
a6b9d1c948 | ||
|
|
dedf6086fc | ||
|
|
eb5bf1da61 | ||
|
|
879fde8d80 | ||
|
|
5115e0daec | ||
|
|
774866e9ad | ||
|
|
444b96bc73 | ||
|
|
ba0bcc120e | ||
|
|
fadd128d1f | ||
|
|
f3b96dab73 | ||
|
|
68d9db7849 | ||
|
|
1fb9558227 | ||
|
|
c91538493b | ||
|
|
660cac9ee5 | ||
|
|
628257ba6c | ||
|
|
a1f12f7129 | ||
|
|
c7a92d7391 | ||
|
|
4b4eca5a8f | ||
|
|
d04169e6c2 | ||
|
|
92fac775ba | ||
|
|
5dde8aab42 | ||
|
|
c9c2478bbf | ||
|
|
566f9bd8b7 | ||
|
|
56f3a1cc94 | ||
|
|
24b1f08901 | ||
|
|
c8faa3097f | ||
|
|
33c2f9cf81 | ||
|
|
ab579347c6 | ||
|
|
c9b1767b41 | ||
|
|
5e2c92fda6 | ||
|
|
d705ff12f2 | ||
|
|
d469663559 | ||
|
|
4417096bae | ||
|
|
e2ae2c237b | ||
|
|
8ad716f850 | ||
|
|
16109bf052 | ||
|
|
20a8363103 | ||
|
|
d5fa86cdaf | ||
|
|
d5312430ac | ||
|
|
ff8badcd4a | ||
|
|
95123ee6b2 | ||
|
|
d278e36fd2 | ||
|
|
27d25aa47d | ||
|
|
0d4dfb3459 | ||
|
|
871620d18c | ||
|
|
f8041f4d12 | ||
|
|
ecfcccf36e | ||
|
|
e783f726e5 | ||
|
|
c3c20710a2 | ||
|
|
c503186b69 | ||
|
|
105826202e | ||
|
|
97c121a51e | ||
|
|
da39702e33 | ||
|
|
33553ad15b | ||
|
|
1d7eb5057e | ||
|
|
b9e76e7183 | ||
|
|
28651fe9b1 | ||
|
|
8abd53e02f | ||
|
|
19ed23482e | ||
|
|
adb47d25a9 | ||
|
|
5841d8c331 | ||
|
|
12658f6b0c | ||
|
|
97637ac9dd | ||
|
|
e8b1c2783e | ||
|
|
3d5326a22f | ||
|
|
ccce0faef1 | ||
|
|
76551a21f2 | ||
|
|
7eb8c73002 | ||
|
|
28ff69a8e2 | ||
|
|
abe4860a1c | ||
|
|
3bf8733f5e | ||
|
|
9f284b3604 | ||
|
|
6ed7ee7409 | ||
|
|
c3471f8229 | ||
|
|
3844e42cc8 | ||
|
|
3efe4c0261 | ||
|
|
1cfb9fb8cc | ||
|
|
05a4416da1 | ||
|
|
8ac5a0a536 | ||
|
|
668869dbef | ||
|
|
2e050fb328 | ||
|
|
1e9391ad1f | ||
|
|
29d734427f | ||
|
|
b7fdbc22fa | ||
|
|
6c9d183970 | ||
|
|
68a9185070 | ||
|
|
321b7ce901 | ||
|
|
b9aa18a043 | ||
|
|
cc8989a6b3 | ||
|
|
bd345ae949 | ||
|
|
e871a37217 | ||
|
|
671816cd63 | ||
|
|
4785a680da | ||
|
|
42c300fd96 | ||
|
|
69751df021 | ||
|
|
0bb7462d66 | ||
|
|
092ecdef72 | ||
|
|
cd802762b9 | ||
|
|
b6dc2c5449 | ||
|
|
93428042d2 | ||
|
|
15af03ddb4 | ||
|
|
8568a89432 | ||
|
|
b349d5e585 | ||
|
|
fa3b1842a8 | ||
|
|
dda4a3f92b | ||
|
|
352982be9e | ||
|
|
f9eb00c880 | ||
|
|
89657e832b | ||
|
|
6da82e39ce | ||
|
|
f28e809033 | ||
|
|
31db8aa1ba | ||
|
|
21c99e0a9f | ||
|
|
aa112bceb9 | ||
|
|
9544b95ce3 | ||
|
|
bb86232fef | ||
|
|
05683c70c4 | ||
|
|
1ce4da33fa | ||
|
|
68b3c2ed43 | ||
|
|
17fbcde9c6 | ||
|
|
8f7492915b | ||
|
|
d2f3b022b3 | ||
|
|
d565de403e | ||
|
|
9465c4d2d4 | ||
|
|
d256b8ed21 | ||
|
|
9c5ac6fdb9 | ||
|
|
6685cc0882 | ||
|
|
2c3438f2f8 | ||
|
|
3466de4231 | ||
|
|
a718a47de7 | ||
|
|
590b2e78d5 | ||
|
|
00f036873a | ||
|
|
32702e505e | ||
|
|
006ad9f508 | ||
|
|
965eb55f96 | ||
|
|
5d88cfccdd | ||
|
|
ccd6fccc7f | ||
|
|
75414c7a92 | ||
|
|
9cc8259db2 | ||
|
|
b56f2526b8 | ||
|
|
c49bdfa898 | ||
|
|
6bcf68a06f | ||
|
|
43b6653e3a | ||
|
|
04f7f13e54 | ||
|
|
d6698275af | ||
|
|
5aab7b28cd | ||
|
|
53077d1965 | ||
|
|
b014ee333d | ||
|
|
0812aa8f27 | ||
|
|
28be8c52c1 | ||
|
|
39626a29c0 | ||
|
|
8c50440839 | ||
|
|
2f604ae333 | ||
|
|
41387cf653 | ||
|
|
00e400cfd1 | ||
|
|
525830c5c9 | ||
|
|
cc16caaa0c | ||
|
|
15f10c06ec | ||
|
|
692d3d1d1b | ||
|
|
e06c40116f | ||
|
|
9570a9bac7 | ||
|
|
69eccbebc1 | ||
|
|
08eba2850c | ||
|
|
638de4478e | ||
|
|
98ef515d08 | ||
|
|
9dc09c1a2f | ||
|
|
9d63043257 | ||
|
|
1274853016 | ||
|
|
5123934ccc | ||
|
|
7234ef169a | ||
|
|
3698ab517c | ||
|
|
c10fc5db98 | ||
|
|
4d505554a0 | ||
|
|
e2bf3f0203 | ||
|
|
818d9e2e8e | ||
|
|
5b30430ed1 | ||
|
|
a75ac09648 | ||
|
|
ef72d64700 | ||
|
|
668991d006 | ||
|
|
93bce8c359 | ||
|
|
b4fd4d512b | ||
|
|
25230eed1c | ||
|
|
12625661e6 | ||
|
|
bb7aaa2edb | ||
|
|
0b47559441 | ||
|
|
05025591c5 | ||
|
|
af4d03441d | ||
|
|
c3697e4d04 | ||
|
|
17269df649 | ||
|
|
161f1fed09 | ||
|
|
ef53893263 | ||
|
|
728b8a7a57 | ||
|
|
11fc165a80 | ||
|
|
7348c2c6ac | ||
|
|
188a121ad5 | ||
|
|
d324e87301 | ||
|
|
5e715b2983 | ||
|
|
343d0d63c6 | ||
|
|
cc710292a3 | ||
|
|
7e9cea74f6 | ||
|
|
9e27099ef2 | ||
|
|
66cd7c54be | ||
|
|
39bee67fa1 | ||
|
|
aefb114e50 | ||
|
|
f928dc2506 | ||
|
|
d71bf7200c | ||
|
|
827089858e | ||
|
|
70d009e323 | ||
|
|
04a71dd1f4 | ||
|
|
5e70400563 | ||
|
|
ab48a131ba | ||
|
|
efc9ded1eb | ||
|
|
6b4596ef7c | ||
|
|
b70a6568dd | ||
|
|
54a0cb282f | ||
|
|
eb82094919 | ||
|
|
cd1d4fa7a0 | ||
|
|
da4b48498f | ||
|
|
1a6a9b5b3c | ||
|
|
ee2936fa86 | ||
|
|
017a419f6b | ||
|
|
fd913df555 | ||
|
|
6e723b559c | ||
|
|
d3a2023629 | ||
|
|
f2490e2a0c | ||
|
|
8a02c0a234 | ||
|
|
31a6d9f6e9 | ||
|
|
78f4a764f7 | ||
|
|
f639619940 | ||
|
|
5c5be8eef8 | ||
|
|
0d8f52b573 | ||
|
|
6b954750bd | ||
|
|
bcf46fc0c8 | ||
|
|
43c0b62926 | ||
|
|
f6639d772f | ||
|
|
0cd22aebd2 | ||
|
|
6e1cea7ebc | ||
|
|
993c44a890 | ||
|
|
ea88b64b15 | ||
|
|
df554b1f14 | ||
|
|
d81c5c85db | ||
|
|
5b0c72380f | ||
|
|
c6eff3a8b6 | ||
|
|
ad174d1be8 | ||
|
|
a6167b3a47 | ||
|
|
c3db13141b | ||
|
|
5233a21ab4 | ||
|
|
24d1ca2d65 | ||
|
|
d59c17671e | ||
|
|
f24c3c9c4f | ||
|
|
7bee6581e4 | ||
|
|
10c8d4784a | ||
|
|
607d72eef7 | ||
|
|
c93bd2902a | ||
|
|
95ac22d3b8 | ||
|
|
7c29e8fa07 | ||
|
|
8de99c1386 | ||
|
|
e69d3d856c | ||
|
|
98baec1cb8 | ||
|
|
c562ec70d3 | ||
|
|
1ea107d316 | ||
|
|
f72e0f02b7 | ||
|
|
0af996eabc | ||
|
|
5954846d69 | ||
|
|
ab9f7a2af1 | ||
|
|
5929232df6 | ||
|
|
e095cfb9fc | ||
|
|
050c9d2b24 | ||
|
|
6a49a324b1 | ||
|
|
89f9033bfa | ||
|
|
c46958935d | ||
|
|
3a0c0edfe1 | ||
|
|
bd44072362 | ||
|
|
4e12559d9f | ||
|
|
ee1e72fe61 | ||
|
|
9ca0a273ce | ||
|
|
5258d0fc0e | ||
|
|
22c305e3df | ||
|
|
55a5f98dc9 | ||
|
|
c60af19a0a | ||
|
|
5eb20bdc8a | ||
|
|
e1d99a6f24 | ||
|
|
bc6ac3f26b | ||
|
|
eb3f700adc | ||
|
|
a76920e6fc | ||
|
|
7c3e650467 | ||
|
|
7a330884ef | ||
|
|
3bb4bd0542 | ||
|
|
021e218671 | ||
|
|
805f017af1 | ||
|
|
132da758b6 | ||
|
|
1e6f5b8ce3 | ||
|
|
6cb2563112 | ||
|
|
0c7baf0c73 | ||
|
|
217736ccef | ||
|
|
113278051a | ||
|
|
450a0411e0 | ||
|
|
e03f7f07ee | ||
|
|
249b3015b5 | ||
|
|
8926bd6800 | ||
|
|
50d02910df | ||
|
|
414ae0d305 | ||
|
|
4fee16e3b8 | ||
|
|
f10fc930d6 | ||
|
|
fe8c0f444d | ||
|
|
44abe970b9 | ||
|
|
eab6386f3d | ||
|
|
db0da365b0 | ||
|
|
e25c5f5dff | ||
|
|
7669ad4768 | ||
|
|
7fb089afa2 | ||
|
|
43139f36e6 | ||
|
|
dd762da973 | ||
|
|
a3d4fba111 | ||
|
|
9119dcfe0c | ||
|
|
2359b38e93 | ||
|
|
09311394d2 | ||
|
|
09a6852370 | ||
|
|
1553085dcc | ||
|
|
9bf2170871 | ||
|
|
8b9f9269d9 | ||
|
|
5a7fec5217 | ||
|
|
5e0a0074cf | ||
|
|
38ec5fae5a | ||
|
|
4a1c655e53 | ||
|
|
530a8479c1 | ||
|
|
780f3b78ff | ||
|
|
41661409a8 | ||
|
|
9504afdd6d | ||
|
|
107612d206 | ||
|
|
f785c9b560 | ||
|
|
41504a37b0 | ||
|
|
860b25429c | ||
|
|
25b4f55d9a | ||
|
|
09d25d23a6 | ||
|
|
e914b68220 | ||
|
|
37fac813d4 | ||
|
|
a46d838591 | ||
|
|
484e2b30f8 | ||
|
|
73fd4837f4 | ||
|
|
da398b3c96 | ||
|
|
3a7185e431 | ||
|
|
9a798c3e3c | ||
|
|
d1dba4254e | ||
|
|
e117e8136c | ||
|
|
e8d61d5231 | ||
|
|
20d9891f2e | ||
|
|
5cc97938e1 | ||
|
|
24a6608f9c | ||
|
|
2464cde8ad | ||
|
|
954d062453 | ||
|
|
97d9f831af | ||
|
|
4a31ffbb0b | ||
|
|
6e5f28487f | ||
|
|
af4b9866a8 | ||
|
|
005d6f562f | ||
|
|
a70320b705 | ||
|
|
49d31d1857 | ||
|
|
1de7b9a761 | ||
|
|
a142a2e789 | ||
|
|
1395a97ba5 | ||
|
|
13deb2869c | ||
|
|
b68488894a | ||
|
|
7a1f946dee | ||
|
|
6dc4a5f41a | ||
|
|
be46876f3b | ||
|
|
8eacbd0337 | ||
|
|
020273343e | ||
|
|
e8cbc10acb | ||
|
|
e4ddcc1a4b | ||
|
|
5ceb2d5058 | ||
|
|
7fa458f87e | ||
|
|
a6af02e86a | ||
|
|
b5d98699c1 | ||
|
|
8df1cbed4d | ||
|
|
20795825a3 | ||
|
|
3d256980b5 | ||
|
|
5b940857f1 | ||
|
|
21ef510051 | ||
|
|
eaab6ea9fb | ||
|
|
4262169a74 | ||
|
|
e2da97877c | ||
|
|
e9839e1a0d | ||
|
|
2a19076f7a | ||
|
|
342a738152 | ||
|
|
afab1906d1 | ||
|
|
8d1d9d3bc3 | ||
|
|
634219bc3e | ||
|
|
900d24ef6e | ||
|
|
30dea9d641 | ||
|
|
a35e0c2a54 | ||
|
|
218a49e66b | ||
|
|
2cde2c220c | ||
|
|
696ed74b75 | ||
|
|
1e2ea92465 | ||
|
|
562cf183b9 | ||
|
|
54bdd63d21 | ||
|
|
9fd251bb99 | ||
|
|
2c2e2ca546 | ||
|
|
b688d6259d | ||
|
|
7a649acf21 | ||
|
|
109a9b27cf | ||
|
|
fa78e341b6 | ||
|
|
e1e7123e77 | ||
|
|
b844ff35d2 | ||
|
|
095f36eff9 | ||
|
|
fb3117ef94 | ||
|
|
27ef1ee87d | ||
|
|
d883ebd626 | ||
|
|
940c807c51 |
3
.aspire/settings.json
Normal file
3
.aspire/settings.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"appHostPath": "../src/Aspire/src/AppHost/AppHost.csproj"
|
||||
}
|
||||
30
.config/dotnet-tools.json
Normal file
30
.config/dotnet-tools.json
Normal 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"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,9 @@
|
||||
**/.tye/
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
**/*.jwk
|
||||
**/keys
|
||||
LICENSE
|
||||
README.md
|
||||
CHANGELOG.md
|
||||
|
||||
|
||||
1362
.editorconfig
1362
.editorconfig
File diff suppressed because it is too large
Load Diff
64
.gitattributes
vendored
Normal file
64
.gitattributes
vendored
Normal 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
59
.github/actions/build-test/action.yml
vendored
Normal 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
69
.github/actions/build/action.yml
vendored
Normal 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
|
||||
@ -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
85
.github/actions/test/action.yml
vendored
Normal 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: "'
|
||||
39
.github/pull_request_template.md
vendored
39
.github/pull_request_template.md
vendored
@ -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.
|
||||
-->
|
||||
6
.github/release-drafter.yml
vendored
6
.github/release-drafter.yml
vendored
@ -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:
|
||||
|
||||
92
.github/workflows/ci.yml
vendored
92
.github/workflows/ci.yml
vendored
@ -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
11
.gitignore
vendored
@ -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
1
.gitpod.Dockerfile
vendored
@ -1 +0,0 @@
|
||||
FROM gitpod/workspace-dotnet:latest
|
||||
30
.gitpod.yml
30
.gitpod.yml
@ -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
1
.husky/commit-msg
Normal file
@ -0,0 +1 @@
|
||||
npx --no -- commitlint --edit ${1}
|
||||
2
.husky/pre-commit
Normal file
2
.husky/pre-commit
Normal file
@ -0,0 +1,2 @@
|
||||
npm run format
|
||||
npm run ci-format
|
||||
26
CONTRIBUTION.md
Normal file
26
CONTRIBUTION.md
Normal 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)
|
||||
@ -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
241
README.md
@ -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
|
||||
|
||||

|
||||
|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
<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 |
471
assets/booking-microservices.drawio
Normal file
471
assets/booking-microservices.drawio
Normal file
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 |
431
assets/vertical-slice-architecture.excalidraw
Normal file
431
assets/vertical-slice-architecture.excalidraw
Normal 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": {}
|
||||
}
|
||||
BIN
assets/vertical-slice-architecture.png
Normal file
BIN
assets/vertical-slice-architecture.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
@ -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
348
booking-microservices.sln
Normal 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
|
||||
75
booking.rest
75
booking.rest
@ -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
3
commitlint.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: ["@commitlint/config-conventional"],
|
||||
}
|
||||
8
deployments/configs/dashboards.md
Normal file
8
deployments/configs/dashboards.md
Normal 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/)
|
||||
908
deployments/configs/grafana/dashboards/dotnet-core-endpoint.json
Normal file
908
deployments/configs/grafana/dashboards/dotnet-core-endpoint.json
Normal 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": ""
|
||||
}
|
||||
1307
deployments/configs/grafana/dashboards/dotnet-core.json
Normal file
1307
deployments/configs/grafana/dashboards/dotnet-core.json
Normal file
File diff suppressed because it is too large
Load Diff
892
deployments/configs/grafana/dashboards/node-exporter.json
Normal file
892
deployments/configs/grafana/dashboards/node-exporter.json
Normal 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."
|
||||
}
|
||||
1459
deployments/configs/grafana/dashboards/postgresql.json
Normal file
1459
deployments/configs/grafana/dashboards/postgresql.json
Normal file
File diff suppressed because it is too large
Load Diff
8209
deployments/configs/grafana/dashboards/rabbitmq.json
Normal file
8209
deployments/configs/grafana/dashboards/rabbitmq.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
@ -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
|
||||
44
deployments/configs/loki-config.yaml
Normal file
44
deployments/configs/loki-config.yaml
Normal 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
|
||||
|
||||
131
deployments/configs/otel-collector-config.yaml
Normal file
131
deployments/configs/otel-collector-config.yaml
Normal 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 it’s not enabled.
|
||||
# https://betterstack.com/community/guides/observability/opentelemetry-collector/#exploring-the-opentelemetry-collector-components
|
||||
# https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/README.md
|
||||
# https://opentelemetry.io/docs/collector/architecture/
|
||||
# https://opentelemetry.io/docs/collector/configuration/#service
|
||||
service:
|
||||
# The `service.extensions` subsection determines which of the configured extensions will be enabled
|
||||
extensions: [pprof, zpages, health_check]
|
||||
# The `service.pipeline` Each pipeline starts with one or more receivers collecting data, which is then processed sequentially by processors (applying transformations, filtering, or sampling).
|
||||
# The processed data is finally sent to all configured exporters, ensuring each receives a copy. Components must be pre-configured in their respective sections before being used in a pipeline.
|
||||
# pipeline activate predefined components, defined components are disabled by default
|
||||
pipelines:
|
||||
traces:
|
||||
receivers: [otlp]
|
||||
processors: [batch]
|
||||
# https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/#exporter-selection
|
||||
exporters: [debug, zipkin, otlp/jaeger, otlp/tempo]
|
||||
metrics:
|
||||
receivers: [otlp]
|
||||
processors: [batch]
|
||||
exporters: [debug, prometheusremotewrite, prometheus]
|
||||
logs:
|
||||
receivers: [otlp]
|
||||
processors: [batch]
|
||||
exporters: [otlphttp/loki, elasticsearch]
|
||||
48
deployments/configs/prometheus.yaml
Normal file
48
deployments/configs/prometheus.yaml
Normal 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' ]
|
||||
49
deployments/configs/tempo.yaml
Normal file
49
deployments/configs/tempo.yaml
Normal 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
|
||||
362
deployments/docker-compose/docker-compose.infrastructure.yaml
Normal file
362
deployments/docker-compose/docker-compose.infrastructure.yaml
Normal 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:
|
||||
@ -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:
|
||||
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
|
||||
|
||||
|
||||
16
deployments/kubernetes/booking-cert-manager.yml
Normal file
16
deployments/kubernetes/booking-cert-manager.yml
Normal 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
|
||||
1245
deployments/kubernetes/booking-microservices.yml
Normal file
1245
deployments/kubernetes/booking-microservices.yml
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
6
global.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "10.0.103",
|
||||
"rollForward": "latestFeature"
|
||||
}
|
||||
}
|
||||
1346
package-lock.json
generated
Normal file
1346
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"]
|
||||
@ -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>
|
||||
|
||||
@ -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();
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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": "*"
|
||||
}
|
||||
|
||||
33
src/Aspire/src/AppHost/AppHost.csproj
Normal file
33
src/Aspire/src/AppHost/AppHost.csproj
Normal 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>
|
||||
366
src/Aspire/src/AppHost/Program.cs
Normal file
366
src/Aspire/src/AppHost/Program.cs
Normal 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();
|
||||
18
src/Aspire/src/AppHost/Properties/launchSettings.json
Normal file
18
src/Aspire/src/AppHost/Properties/launchSettings.json
Normal 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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
src/Aspire/src/AppHost/appsettings.Development.json
Normal file
8
src/Aspire/src/AppHost/appsettings.Development.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
src/Aspire/src/AppHost/appsettings.json
Normal file
9
src/Aspire/src/AppHost/appsettings.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
}
|
||||
41
src/Aspire/src/ServiceDefaults/Extensions.cs
Normal file
41
src/Aspire/src/ServiceDefaults/Extensions.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
13
src/Aspire/src/ServiceDefaults/ServiceDefaults.csproj
Normal file
13
src/Aspire/src/ServiceDefaults/ServiceDefaults.csproj
Normal 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>
|
||||
@ -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>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
using EasyCaching.Core;
|
||||
using EasyCaching.Core;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
@ -47,4 +47,4 @@ public class CachingBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest,
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,4 +4,4 @@ public interface ICacheRequest
|
||||
{
|
||||
string CacheKey { get; }
|
||||
DateTime? AbsoluteExpirationRelativeToNow { get; }
|
||||
}
|
||||
}
|
||||
@ -4,4 +4,4 @@ namespace BuildingBlocks.Caching
|
||||
{
|
||||
string CacheKey { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,4 +36,4 @@ namespace BuildingBlocks.Caching
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/BuildingBlocks/Constants/IdentityConstant.cs
Normal file
10
src/BuildingBlocks/Constants/IdentityConstant.cs
Normal 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";
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -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;
|
||||
@ -1,4 +1,4 @@
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.CQRS;
|
||||
|
||||
@ -9,4 +9,4 @@ public interface ICommand : ICommand<Unit>
|
||||
public interface ICommand<out T> : IRequest<T>
|
||||
where T : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.CQRS;
|
||||
|
||||
@ -11,4 +11,4 @@ public interface ICommandHandler<in TCommand, TResponse> : IRequestHandler<TComm
|
||||
where TCommand : ICommand<TResponse>
|
||||
where TResponse : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,8 +1,8 @@
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.CQRS;
|
||||
|
||||
public interface IQuery<out T> : IRequest<T>
|
||||
where T : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
using MediatR;
|
||||
using MediatR;
|
||||
|
||||
namespace BuildingBlocks.Core.CQRS;
|
||||
|
||||
@ -6,4 +6,4 @@ public interface IQueryHandler<in TQuery, TResponse> : IRequestHandler<TQuery, T
|
||||
where TQuery : IQuery<TResponse>
|
||||
where TResponse : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
37
src/BuildingBlocks/Core/CompositeEventMapper.cs
Normal file
37
src/BuildingBlocks/Core/CompositeEventMapper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@ -6,4 +6,4 @@ public enum EventType
|
||||
DomainEvent = 1,
|
||||
IntegrationEvent = 2,
|
||||
InternalCommand = 4
|
||||
}
|
||||
}
|
||||
@ -2,4 +2,4 @@ namespace BuildingBlocks.Core.Event;
|
||||
|
||||
public interface IDomainEvent : IEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,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;
|
||||
}
|
||||
}
|
||||
@ -5,4 +5,4 @@ namespace BuildingBlocks.Core.Event;
|
||||
[ExcludeFromTopology]
|
||||
public interface IIntegrationEvent : IEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
|
||||
public interface IInternalCommand : IEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -1,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;
|
||||
@ -1,4 +1,4 @@
|
||||
using Google.Protobuf;
|
||||
using Google.Protobuf;
|
||||
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
|
||||
@ -23,4 +23,4 @@ public class MessageEnvelope<TMessage> : MessageEnvelope
|
||||
}
|
||||
|
||||
public new TMessage? Message { get; }
|
||||
}
|
||||
}
|
||||
@ -9,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -8,4 +8,4 @@ public interface IEventDispatcher
|
||||
where T : IEvent;
|
||||
public Task SendAsync<T>(T @event, Type type = null, CancellationToken cancellationToken = default)
|
||||
where T : IEvent;
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,6 @@ namespace BuildingBlocks.Core;
|
||||
|
||||
public interface IEventMapper
|
||||
{
|
||||
IIntegrationEvent MapToIntegrationEvent(IDomainEvent @event);
|
||||
IInternalCommand MapToInternalCommand(IDomainEvent @event);
|
||||
}
|
||||
IIntegrationEvent? MapToIntegrationEvent(IDomainEvent @event);
|
||||
IInternalCommand? MapToInternalCommand(IDomainEvent @event);
|
||||
}
|
||||
@ -3,4 +3,4 @@ using BuildingBlocks.Core.Event;
|
||||
namespace BuildingBlocks.Core;
|
||||
|
||||
public record IntegrationEventWrapper<TDomainEventType>(TDomainEventType DomainEvent) : IIntegrationEvent
|
||||
where TDomainEventType : IDomainEvent;
|
||||
where TDomainEventType : IDomainEvent;
|
||||
@ -1,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
}
|
||||
@ -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; }
|
||||
}
|
||||
}
|
||||
7
src/BuildingBlocks/Core/Model/IVersion.cs
Normal file
7
src/BuildingBlocks/Core/Model/IVersion.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace BuildingBlocks.Core.Model;
|
||||
|
||||
// For handling optimistic concurrency
|
||||
public interface IVersion
|
||||
{
|
||||
long Version { get; set; }
|
||||
}
|
||||
36
src/BuildingBlocks/Core/Pagination/Extensions.cs
Normal file
36
src/BuildingBlocks/Core/Pagination/Extensions.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
16
src/BuildingBlocks/Core/Pagination/IPageList.cs
Normal file
16
src/BuildingBlocks/Core/Pagination/IPageList.cs
Normal 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; }
|
||||
}
|
||||
7
src/BuildingBlocks/Core/Pagination/IPageQuery.cs
Normal file
7
src/BuildingBlocks/Core/Pagination/IPageQuery.cs
Normal 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
Loading…
x
Reference in New Issue
Block a user