mirror of
https://github.com/meysamhadeli/booking-microservices.git
synced 2026-04-10 17:59:38 +08:00
Compare commits
165 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 |
3
.aspire/settings.json
Normal file
3
.aspire/settings.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"appHostPath": "../src/Aspire/src/AppHost/AppHost.csproj"
|
||||
}
|
||||
@ -3,18 +3,28 @@
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"dotnet-outdated-tool": {
|
||||
"version": "4.6.4",
|
||||
"version": "4.6.9",
|
||||
"commands": [
|
||||
"dotnet-outdated"
|
||||
],
|
||||
"rollForward": false
|
||||
]
|
||||
},
|
||||
"dotnet-ef": {
|
||||
"version": "8.0.8",
|
||||
"version": "10.0.3",
|
||||
"commands": [
|
||||
"dotnet-ef"
|
||||
],
|
||||
"rollForward": false
|
||||
]
|
||||
},
|
||||
"aspire.cli": {
|
||||
"version": "13.1.1",
|
||||
"commands": [
|
||||
"aspire"
|
||||
]
|
||||
},
|
||||
"csharpier": {
|
||||
"version": "0.30.6",
|
||||
"commands": [
|
||||
"dotnet-csharpier"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
651
.editorconfig
651
.editorconfig
@ -9,127 +9,167 @@
|
||||
## https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/
|
||||
## https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/
|
||||
## Microsoft Rules
|
||||
##
|
||||
|
||||
root = true
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
|
||||
# Global settings
|
||||
# All files
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
# Xml project files
|
||||
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
|
||||
indent_style = space
|
||||
|
||||
# Xml files
|
||||
[*.xml]
|
||||
indent_size = 2
|
||||
|
||||
# Xml config files
|
||||
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.{md,json}]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
max_line_length = 100
|
||||
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/csharp-formatting-options
|
||||
#### Core EditorConfig Options ####
|
||||
|
||||
# Indentation and spacing
|
||||
indent_size = 4
|
||||
tab_width = 4
|
||||
max_line_length = 120
|
||||
|
||||
# New line preferences
|
||||
insert_final_newline = false
|
||||
|
||||
#### .NET Coding Conventions ####
|
||||
[*.{cs,vb}]
|
||||
|
||||
# Organize usings
|
||||
dotnet_separate_import_directive_groups = false
|
||||
dotnet_sort_system_directives_first = true
|
||||
file_header_template = unset
|
||||
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/overview?#enable-on-build
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/language-rules#option-format
|
||||
# this. and Me. preferences
|
||||
dotnet_style_qualification_for_event = false:silent
|
||||
dotnet_style_qualification_for_field = false:silent
|
||||
dotnet_style_qualification_for_method = false:silent
|
||||
dotnet_style_qualification_for_property = false:silent
|
||||
|
||||
# Language keywords vs BCL types preferences
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||
dotnet_style_predefined_type_for_member_access = true:silent
|
||||
|
||||
# Parentheses preferences
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent
|
||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent
|
||||
|
||||
# Modifier preferences
|
||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||
|
||||
# Expression-level preferences
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_namespace_match_folder = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_operator_placement_when_wrapping = beginning_of_line
|
||||
dotnet_style_prefer_auto_properties = true:suggestion
|
||||
dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion
|
||||
dotnet_style_prefer_compound_assignment = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
|
||||
dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
|
||||
dotnet_style_prefer_simplified_interpolation = true:suggestion
|
||||
|
||||
# Field preferences
|
||||
dotnet_style_readonly_field = true:warning
|
||||
|
||||
# Parameter preferences
|
||||
dotnet_code_quality_unused_parameters = all:suggestion
|
||||
|
||||
# Suppression preferences
|
||||
dotnet_remove_unnecessary_suppression_exclusions = none
|
||||
|
||||
#### C# Coding Conventions ####
|
||||
[*.cs]
|
||||
|
||||
# var preferences
|
||||
csharp_style_var_elsewhere = false:silent
|
||||
csharp_style_var_for_built_in_types = false:silent
|
||||
csharp_style_var_when_type_is_apparent = false:silent
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_accessors = true:silent
|
||||
csharp_style_expression_bodied_constructors = false:silent
|
||||
csharp_style_expression_bodied_indexers = true:silent
|
||||
csharp_style_expression_bodied_lambdas = true:suggestion
|
||||
csharp_style_expression_bodied_local_functions = false:silent
|
||||
csharp_style_expression_bodied_methods = false:silent
|
||||
csharp_style_expression_bodied_operators = false:silent
|
||||
csharp_style_expression_bodied_properties = true:silent
|
||||
|
||||
# Pattern matching preferences
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_prefer_extended_property_pattern = true:suggestion
|
||||
csharp_style_prefer_not_pattern = true:suggestion
|
||||
csharp_style_prefer_pattern_matching = true:silent
|
||||
csharp_style_prefer_switch_expression = true:suggestion
|
||||
|
||||
# Null-checking preferences
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
|
||||
# Modifier preferences
|
||||
csharp_prefer_static_anonymous_function = true:suggestion
|
||||
csharp_prefer_static_local_function = true:warning
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,file,const,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async:suggestion
|
||||
csharp_style_prefer_readonly_struct = true:suggestion
|
||||
csharp_style_prefer_readonly_struct_member = true:suggestion
|
||||
|
||||
# Code-block preferences
|
||||
csharp_prefer_braces = true:silent
|
||||
csharp_prefer_simple_using_statement = true:suggestion
|
||||
csharp_style_namespace_declarations = file_scoped:suggestion
|
||||
csharp_style_prefer_method_group_conversion = true:silent
|
||||
csharp_style_prefer_primary_constructors = true:suggestion
|
||||
csharp_style_prefer_top_level_statements = true:silent
|
||||
|
||||
# Expression-level preferences
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
csharp_style_prefer_index_operator = true:suggestion
|
||||
csharp_style_prefer_local_over_anonymous_function = true:suggestion
|
||||
csharp_style_prefer_null_check_over_type_check = true:suggestion
|
||||
csharp_style_prefer_range_operator = true:suggestion
|
||||
csharp_style_prefer_tuple_swap = true:suggestion
|
||||
csharp_style_prefer_utf8_string_literals = true:suggestion
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_unused_value_assignment_preference = discard_variable:suggestion
|
||||
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
|
||||
|
||||
# 'using' directive preferences
|
||||
csharp_using_directive_placement = outside_namespace:silent
|
||||
|
||||
#### C# Formatting Rules ####
|
||||
|
||||
# New line preferences
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_members_in_anonymous_types = true
|
||||
csharp_new_line_before_members_in_object_initializers = true
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/csharp-formatting-options#indentation-options
|
||||
# Indentation preferences
|
||||
csharp_indent_block_contents = true
|
||||
csharp_indent_braces = false
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_labels = one_less_than_current
|
||||
|
||||
# avoid this. unless absolutely necessary
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
|
||||
# only use var when it's obvious what the variable type is
|
||||
# csharp_style_var_for_built_in_types = false:none
|
||||
# csharp_style_var_when_type_is_apparent = false:none
|
||||
# csharp_style_var_elsewhere = false:suggestion
|
||||
|
||||
# use language keywords instead of BCL types
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
|
||||
# name all constant fields using PascalCase
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
|
||||
|
||||
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||
|
||||
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_symbols.static_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.static_fields.required_modifiers = static
|
||||
|
||||
dotnet_naming_style.static_prefix_style.required_prefix = s_
|
||||
dotnet_naming_style.static_prefix_style.capitalization = camel_case
|
||||
|
||||
# internal and private fields should be _camelCase
|
||||
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
|
||||
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
|
||||
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
|
||||
|
||||
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
|
||||
|
||||
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
|
||||
dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
|
||||
|
||||
# Code style defaults
|
||||
dotnet_sort_system_directives_first = true
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = false
|
||||
|
||||
# Expression-level preferences
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_methods = false:none
|
||||
csharp_style_expression_bodied_constructors = false:none
|
||||
csharp_style_expression_bodied_operators = false:none
|
||||
csharp_style_expression_bodied_properties = true:none
|
||||
csharp_style_expression_bodied_indexers = true:none
|
||||
csharp_style_expression_bodied_accessors = true:none
|
||||
|
||||
# Pattern matching
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
|
||||
# Null checking preferences
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
csharp_indent_switch_labels = true
|
||||
|
||||
# Space preferences
|
||||
csharp_space_after_cast = false
|
||||
@ -139,6 +179,7 @@ csharp_space_after_dot = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_after_semicolon_in_for_statement = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_around_declaration_statements = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_before_comma = false
|
||||
csharp_space_before_dot = false
|
||||
@ -154,6 +195,200 @@ csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_parentheses = false
|
||||
csharp_space_between_square_brackets = false
|
||||
|
||||
# Wrapping preferences
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = true
|
||||
|
||||
#### Naming styles ####
|
||||
[*.{cs,vb}]
|
||||
|
||||
# Naming rules
|
||||
|
||||
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.symbols = types_and_namespaces
|
||||
dotnet_naming_rule.types_and_namespaces_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.interfaces_should_be_ipascalcase.severity = suggestion
|
||||
dotnet_naming_rule.interfaces_should_be_ipascalcase.symbols = interfaces
|
||||
dotnet_naming_rule.interfaces_should_be_ipascalcase.style = ipascalcase
|
||||
|
||||
dotnet_naming_rule.type_parameters_should_be_tpascalcase.severity = suggestion
|
||||
dotnet_naming_rule.type_parameters_should_be_tpascalcase.symbols = type_parameters
|
||||
dotnet_naming_rule.type_parameters_should_be_tpascalcase.style = tpascalcase
|
||||
|
||||
dotnet_naming_rule.methods_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.methods_should_be_pascalcase.symbols = methods
|
||||
dotnet_naming_rule.methods_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.properties_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.properties_should_be_pascalcase.symbols = properties
|
||||
dotnet_naming_rule.properties_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.events_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.events_should_be_pascalcase.symbols = events
|
||||
dotnet_naming_rule.events_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.local_variables_should_be_camelcase.severity = suggestion
|
||||
dotnet_naming_rule.local_variables_should_be_camelcase.symbols = local_variables
|
||||
dotnet_naming_rule.local_variables_should_be_camelcase.style = camelcase
|
||||
|
||||
dotnet_naming_rule.local_constants_should_be_camelcase.severity = suggestion
|
||||
dotnet_naming_rule.local_constants_should_be_camelcase.symbols = local_constants
|
||||
dotnet_naming_rule.local_constants_should_be_camelcase.style = camelcase
|
||||
|
||||
dotnet_naming_rule.parameters_should_be_camelcase.severity = suggestion
|
||||
dotnet_naming_rule.parameters_should_be_camelcase.symbols = parameters
|
||||
dotnet_naming_rule.parameters_should_be_camelcase.style = camelcase
|
||||
|
||||
dotnet_naming_rule.public_fields_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.public_fields_should_be_pascalcase.symbols = public_fields
|
||||
dotnet_naming_rule.public_fields_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.private_fields_should_be__camelcase.severity = suggestion
|
||||
dotnet_naming_rule.private_fields_should_be__camelcase.symbols = private_fields
|
||||
dotnet_naming_rule.private_fields_should_be__camelcase.style = _camelcase
|
||||
|
||||
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.severity = suggestion
|
||||
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.symbols = private_static_fields
|
||||
dotnet_naming_rule.private_static_fields_should_be_s_camelcase.style = s_camelcase
|
||||
|
||||
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.symbols = public_constant_fields
|
||||
dotnet_naming_rule.public_constant_fields_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.symbols = private_constant_fields
|
||||
dotnet_naming_rule.private_constant_fields_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.symbols = public_static_readonly_fields
|
||||
dotnet_naming_rule.public_static_readonly_fields_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.symbols = private_static_readonly_fields
|
||||
dotnet_naming_rule.private_static_readonly_fields_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.enums_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.enums_should_be_pascalcase.symbols = enums
|
||||
dotnet_naming_rule.enums_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.local_functions_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.local_functions_should_be_pascalcase.symbols = local_functions
|
||||
dotnet_naming_rule.local_functions_should_be_pascalcase.style = pascalcase
|
||||
|
||||
dotnet_naming_rule.non_field_members_should_be_pascalcase.severity = suggestion
|
||||
dotnet_naming_rule.non_field_members_should_be_pascalcase.symbols = non_field_members
|
||||
dotnet_naming_rule.non_field_members_should_be_pascalcase.style = pascalcase
|
||||
|
||||
# Symbol specifications
|
||||
|
||||
dotnet_naming_symbols.interfaces.applicable_kinds = interface
|
||||
dotnet_naming_symbols.interfaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.interfaces.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.enums.applicable_kinds = enum
|
||||
dotnet_naming_symbols.enums.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.enums.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.events.applicable_kinds = event
|
||||
dotnet_naming_symbols.events.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.events.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.methods.applicable_kinds = method
|
||||
dotnet_naming_symbols.methods.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.methods.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.properties.applicable_kinds = property
|
||||
dotnet_naming_symbols.properties.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.properties.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.public_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.public_fields.applicable_accessibilities = public, internal
|
||||
dotnet_naming_symbols.public_fields.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.private_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.private_fields.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.private_static_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.private_static_fields.required_modifiers = static
|
||||
|
||||
dotnet_naming_symbols.types_and_namespaces.applicable_kinds = namespace, class, struct, interface, enum
|
||||
dotnet_naming_symbols.types_and_namespaces.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.types_and_namespaces.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
|
||||
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.non_field_members.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.type_parameters.applicable_kinds = namespace
|
||||
dotnet_naming_symbols.type_parameters.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.type_parameters.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.private_constant_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_constant_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.private_constant_fields.required_modifiers = const
|
||||
|
||||
dotnet_naming_symbols.local_variables.applicable_kinds = local
|
||||
dotnet_naming_symbols.local_variables.applicable_accessibilities = local
|
||||
dotnet_naming_symbols.local_variables.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.local_constants.applicable_kinds = local
|
||||
dotnet_naming_symbols.local_constants.applicable_accessibilities = local
|
||||
dotnet_naming_symbols.local_constants.required_modifiers = const
|
||||
|
||||
dotnet_naming_symbols.parameters.applicable_kinds = parameter
|
||||
dotnet_naming_symbols.parameters.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.parameters.required_modifiers =
|
||||
|
||||
dotnet_naming_symbols.public_constant_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.public_constant_fields.applicable_accessibilities = public, internal
|
||||
dotnet_naming_symbols.public_constant_fields.required_modifiers = const
|
||||
|
||||
dotnet_naming_symbols.public_static_readonly_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.public_static_readonly_fields.applicable_accessibilities = public, internal
|
||||
dotnet_naming_symbols.public_static_readonly_fields.required_modifiers = readonly, static
|
||||
|
||||
dotnet_naming_symbols.private_static_readonly_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.private_static_readonly_fields.applicable_accessibilities = private, protected, protected_internal, private_protected
|
||||
dotnet_naming_symbols.private_static_readonly_fields.required_modifiers = readonly, static
|
||||
|
||||
dotnet_naming_symbols.local_functions.applicable_kinds = local_function
|
||||
dotnet_naming_symbols.local_functions.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.local_functions.required_modifiers =
|
||||
|
||||
# Naming styles
|
||||
|
||||
dotnet_naming_style.pascalcase.required_prefix =
|
||||
dotnet_naming_style.pascalcase.required_suffix =
|
||||
dotnet_naming_style.pascalcase.word_separator =
|
||||
dotnet_naming_style.pascalcase.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.ipascalcase.required_prefix = I
|
||||
dotnet_naming_style.ipascalcase.required_suffix =
|
||||
dotnet_naming_style.ipascalcase.word_separator =
|
||||
dotnet_naming_style.ipascalcase.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style.tpascalcase.required_prefix = T
|
||||
dotnet_naming_style.tpascalcase.required_suffix =
|
||||
dotnet_naming_style.tpascalcase.word_separator =
|
||||
dotnet_naming_style.tpascalcase.capitalization = pascal_case
|
||||
|
||||
dotnet_naming_style._camelcase.required_prefix = _
|
||||
dotnet_naming_style._camelcase.required_suffix =
|
||||
dotnet_naming_style._camelcase.word_separator =
|
||||
dotnet_naming_style._camelcase.capitalization = camel_case
|
||||
|
||||
dotnet_naming_style.camelcase.required_prefix =
|
||||
dotnet_naming_style.camelcase.required_suffix =
|
||||
dotnet_naming_style.camelcase.word_separator =
|
||||
dotnet_naming_style.camelcase.capitalization = camel_case
|
||||
|
||||
dotnet_naming_style.s_camelcase.required_prefix = s_
|
||||
dotnet_naming_style.s_camelcase.required_suffix =
|
||||
dotnet_naming_style.s_camelcase.word_separator =
|
||||
dotnet_naming_style.s_camelcase.capitalization = camel_case
|
||||
|
||||
##################################################################################
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/
|
||||
@ -175,7 +410,7 @@ dotnet_diagnostic.CA1304.severity = error
|
||||
# CA1307: Specify StringComparison for clarity
|
||||
dotnet_diagnostic.CA1307.severity = error
|
||||
# CA1308: Normalize strings to uppercase
|
||||
dotnet_diagnostic.CA1308.severity = error
|
||||
dotnet_diagnostic.CA1308.severity = none
|
||||
# CA1309: Use ordinal StringComparison
|
||||
dotnet_diagnostic.CA1309.severity = error
|
||||
# CA1724: Type names should not match namespaces
|
||||
@ -210,7 +445,18 @@ dotnet_diagnostic.ca1848.severity = Suggestion
|
||||
dotnet_diagnostic.ca1810.severity = Suggestion
|
||||
# CA1725: Parameter names should match base declaration
|
||||
dotnet_diagnostic.ca1725.severity = Suggestion
|
||||
# https://csharpier.com/docs/IntegratingWithLinters#code-analysis-rules
|
||||
# CA1515: Consider making public types internal
|
||||
dotnet_diagnostic.CA1515.severity = None
|
||||
# CA2000: Dispose objects before losing scope
|
||||
dotnet_diagnostic.CA2000.severity = Suggestion
|
||||
# CA1707: Identifiers should not contain underscores
|
||||
dotnet_diagnostic.CA1707.severity = None
|
||||
# CA1716: Identifiers should not match keywords
|
||||
dotnet_diagnostic.CA1716.severity = Suggestion
|
||||
# CA1032: Implement standard exception constructors
|
||||
dotnet_diagnostic.CA1032.severity = Suggestion
|
||||
# AV1500: A method should not exceed a predefined number (60-100 lines) of lines
|
||||
dotnet_diagnostic.AV1500.severity = none
|
||||
|
||||
##################################################################################
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/
|
||||
@ -220,7 +466,7 @@ dotnet_diagnostic.ca1725.severity = Suggestion
|
||||
dotnet_diagnostic.IDE0048.severity = Suggestion
|
||||
dotnet_diagnostic.IDE0028.severity = Suggestion
|
||||
dotnet_diagnostic.IDE0029.severity = Suggestion
|
||||
dotnet_diagnostic.IDE0030.severity = Suggestion
|
||||
dotnet_diagnostic.IDE0030 .severity = Suggestion
|
||||
dotnet_diagnostic.IDE0004.severity = error
|
||||
|
||||
# IDE0005: Remove unnecessary usings/imports
|
||||
@ -230,16 +476,21 @@ dotnet_diagnostic.IDE0005.severity = warning
|
||||
dotnet_diagnostic.IDE0051.severity = Suggestion
|
||||
|
||||
# IDE0052: Remove unread private members (writes but no reads)
|
||||
dotnet_diagnostic.IDE0052.severity = error
|
||||
dotnet_diagnostic.IDE0052.severity = warning
|
||||
|
||||
# Remove unnecessary using directives (IDE0005)
|
||||
dotnet_diagnostic.IDE0005.severity = none
|
||||
|
||||
# CS1574: XML comment on 'construct' has syntactically incorrect cref attribute 'name'
|
||||
dotnet_diagnostic.CS1574.severity = error
|
||||
|
||||
# IDE0055: Fix formatting
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/csharp-formatting-options
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/dotnet-formatting-options
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0055
|
||||
dotnet_diagnostic.IDE0055.severity = suggestion
|
||||
|
||||
# CS1574: XML comment on 'construct' has syntactically incorrect cref attribute 'name'
|
||||
dotnet_diagnostic.CS1574.severity = error
|
||||
# https://csharpier.com/docs/IntegratingWithLinters#code-analysis-rules
|
||||
dotnet_diagnostic.IDE0055.severity = none
|
||||
|
||||
##################################################################################
|
||||
# https://jetbrains.com.xy2401.com/help/resharper/EditorConfig_Index.html
|
||||
@ -373,59 +624,6 @@ resharper_blank_lines_before_multiline_statements = 1
|
||||
resharper_parentheses_non_obvious_operations = arithmetic, multiplicative, equality, relational, additive
|
||||
resharper_parentheses_redundancy_style = remove_if_not_clarifies_precedence
|
||||
|
||||
##################################################################################
|
||||
## https://github.com/bkoelman/CSharpGuidelinesAnalyzer
|
||||
## CSharpGuidelines
|
||||
##################################################################################
|
||||
|
||||
dotnet_diagnostic.AV1561.max_parameter_count = 5
|
||||
# AV1008: Class should be non-static or its name should be suffixed with Extensions
|
||||
dotnet_diagnostic.AV1008.severity = none
|
||||
# AV1010: Type hides inherited member
|
||||
dotnet_diagnostic.AV1010.severity = none
|
||||
# AV1115: Member or local function contains the word 'and', which suggests doing multiple things
|
||||
dotnet_diagnostic.AV1115.severity = suggestion
|
||||
# AV1130: Return type in signature for Type should be a collection interface instead of a concrete type
|
||||
dotnet_diagnostic.AV1130.severity = none
|
||||
# AV1135: null is returned from method which has return type of string, collection or task
|
||||
dotnet_diagnostic.AV1135.severity = none # re-enable if we can distinguish between string, collection and task
|
||||
# AV1210: Catch a specific exception instead of Exception, SystemException or ApplicationException
|
||||
dotnet_diagnostic.AV1210.severity = none
|
||||
# AV1250: Evaluate LINQ query before returning it
|
||||
dotnet_diagnostic.AV1250.severity = suggestion
|
||||
# AV1500: Method 'CallerIdentifier.DetermineCallerIdentity()' contains 10 statements, which exceeds the maximum of 7 statements
|
||||
dotnet_diagnostic.AV1500.severity = none
|
||||
# AV1532: Loop statement contains nested loop
|
||||
dotnet_diagnostic.AV1532.severity = suggestion
|
||||
# AV1535: Missing block in case or default clause of switch statement
|
||||
dotnet_diagnostic.AV1535.severity = none # re-enable if we can adjust the formatting to not indent the scope braces
|
||||
# AV1537: If-else-if construct should end with an unconditional else clause
|
||||
dotnet_diagnostic.AV1537.severity = suggestion
|
||||
# AV1551: Method overload with the most parameters should be virtual
|
||||
dotnet_diagnostic.AV1551.severity = none
|
||||
# AV1555: Avoid using non-(nullable-)boolean named arguments
|
||||
dotnet_diagnostic.AV1555.severity = suggestion
|
||||
# AV1561: Method contains 5 parameters, which exceeds the maximum of 3 parameters
|
||||
dotnet_diagnostic.AV1561.severity = suggestion
|
||||
# AV1564: Parameter in public or internal member is of type bool or bool?
|
||||
dotnet_diagnostic.AV1564.severity = suggestion
|
||||
# AV1554: Do not use optional parameters in interface methods or their concrete implementations
|
||||
dotnet_diagnostic.AV1554.severity = none
|
||||
# AV1580: Argument for parameter calls nested method
|
||||
dotnet_diagnostic.AV1580.severity = none
|
||||
# AV1706: Parameter 'p' should have a more descriptive name
|
||||
dotnet_diagnostic.AV1706.severity = warning
|
||||
# AV1708: Type name contains term that should be avoided
|
||||
dotnet_diagnostic.AV1708.severity = suggestion
|
||||
# AV1710: Field contains the name of its containing type
|
||||
dotnet_diagnostic.AV1710.severity = none
|
||||
# AV2202: Replace call to Nullable<T>.HasValue with null check
|
||||
dotnet_diagnostic.AV2202.severity = none
|
||||
# AV2305: Missing XML comment for internally visible type or member
|
||||
dotnet_diagnostic.AV2305.severity = none
|
||||
# AV2407: Region should be removed
|
||||
dotnet_diagnostic.AV2407.severity = none
|
||||
|
||||
##################################################################################
|
||||
## https://github.com/DotNetAnalyzers/StyleCopAnalyzers/tree/master/documentation
|
||||
## https://documentation.help/StyleCop/StyleCop.html
|
||||
@ -548,16 +746,85 @@ dotnet_diagnostic.sa1101.severity = None
|
||||
# The keywords within the declaration of an element do not follow a standard ordering scheme.
|
||||
dotnet_diagnostic.SA1206.severity = None
|
||||
|
||||
# A single-line comment within C# code is not preceded by a blank line.
|
||||
dotnet_diagnostic.SA1515.severity = Suggestion
|
||||
dotnet_diagnostic.SA1106.severity = None
|
||||
|
||||
# https://csharpier.com/docs/IntegratingWithLinters#stylecopanalyzers
|
||||
# IDE0055: Fix formatting
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/csharp-formatting-options
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/dotnet-formatting-options
|
||||
# https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0055
|
||||
|
||||
# StyleCopAnalyzers
|
||||
dotnet_diagnostic.SA1000.severity = none
|
||||
dotnet_diagnostic.SA1009.severity = none
|
||||
dotnet_diagnostic.SA1111.severity = none
|
||||
dotnet_diagnostic.SA1118.severity = none
|
||||
dotnet_diagnostic.SA1137.severity = none
|
||||
dotnet_diagnostic.SA1413.severity = none
|
||||
dotnet_diagnostic.SA1500.severity = none
|
||||
dotnet_diagnostic.SA1501.severity = none
|
||||
dotnet_diagnostic.SA1502.severity = none
|
||||
dotnet_diagnostic.SA1504.severity = none
|
||||
dotnet_diagnostic.SA1515.severity = none
|
||||
dotnet_diagnostic.SA1516.severity = none
|
||||
|
||||
# for csharpier <= 0.21.0
|
||||
dotnet_diagnostic.SA1127.severity = none
|
||||
dotnet_diagnostic.SA1128.severity = none
|
||||
|
||||
dotnet_diagnostic.SA1001.severity = none
|
||||
dotnet_diagnostic.SA1002.severity = none
|
||||
dotnet_diagnostic.SA1003.severity = none
|
||||
dotnet_diagnostic.SA1007.severity = none
|
||||
dotnet_diagnostic.SA1008.severity = none
|
||||
dotnet_diagnostic.SA1010.severity = none
|
||||
dotnet_diagnostic.SA1011.severity = none
|
||||
dotnet_diagnostic.SA1012.severity = none
|
||||
dotnet_diagnostic.SA1013.severity = none
|
||||
dotnet_diagnostic.SA1014.severity = none
|
||||
dotnet_diagnostic.SA1015.severity = none
|
||||
dotnet_diagnostic.SA1016.severity = none
|
||||
dotnet_diagnostic.SA1017.severity = none
|
||||
dotnet_diagnostic.SA1018.severity = none
|
||||
dotnet_diagnostic.SA1019.severity = none
|
||||
dotnet_diagnostic.SA1020.severity = none
|
||||
dotnet_diagnostic.SA1021.severity = none
|
||||
dotnet_diagnostic.SA1022.severity = none
|
||||
dotnet_diagnostic.SA1023.severity = none
|
||||
dotnet_diagnostic.SA1024.severity = none
|
||||
dotnet_diagnostic.SA1025.severity = none
|
||||
dotnet_diagnostic.SA1026.severity = none
|
||||
dotnet_diagnostic.SA1027.severity = none
|
||||
dotnet_diagnostic.SA1028.severity = none
|
||||
dotnet_diagnostic.SA1102.severity = none
|
||||
dotnet_diagnostic.SA1103.severity = none
|
||||
dotnet_diagnostic.SA1104.severity = none
|
||||
dotnet_diagnostic.SA1105.severity = none
|
||||
dotnet_diagnostic.SA1107.severity = none
|
||||
dotnet_diagnostic.SA1110.severity = none
|
||||
dotnet_diagnostic.SA1112.severity = none
|
||||
dotnet_diagnostic.SA1113.severity = none
|
||||
dotnet_diagnostic.SA1114.severity = none
|
||||
dotnet_diagnostic.SA1115.severity = none
|
||||
dotnet_diagnostic.SA1116.severity = none
|
||||
dotnet_diagnostic.SA1117.severity = none
|
||||
dotnet_diagnostic.SA1127.severity = none
|
||||
dotnet_diagnostic.SA1128.severity = none
|
||||
dotnet_diagnostic.SA1136.severity = none
|
||||
dotnet_diagnostic.SA1505.severity = none
|
||||
dotnet_diagnostic.SA1506.severity = none
|
||||
dotnet_diagnostic.SA1507.severity = none
|
||||
dotnet_diagnostic.SA1508.severity = none
|
||||
dotnet_diagnostic.SA1509.severity = none
|
||||
dotnet_diagnostic.SA1510.severity = none
|
||||
dotnet_diagnostic.SA1511.severity = none
|
||||
dotnet_diagnostic.SA1517.severity = none
|
||||
dotnet_diagnostic.SA1518.severity = none
|
||||
|
||||
##################################################################################
|
||||
## https://github.com/meziantou/Meziantou.Analyzer/tree/main/docs
|
||||
## Meziantou.Analyzer
|
||||
|
||||
# MA0049: Type name should not match containing namespace
|
||||
dotnet_diagnostic.ma0049.severity = Suggestion
|
||||
|
||||
# MA0048: File name must match type name
|
||||
dotnet_diagnostic.ma0048.severity = Suggestion
|
||||
|
||||
@ -611,11 +878,14 @@ dotnet_diagnostic.MA0047.severity = none
|
||||
# Use an overload of 'GetHashCode' that has a StringComparison parameter
|
||||
dotnet_diagnostic.MA0074.severity = none
|
||||
|
||||
# MA0049: Type name should not match containing namespace
|
||||
dotnet_diagnostic.MA0049.severity = none
|
||||
|
||||
##################################################################################
|
||||
## http://pihrt.net/Roslynator/Analyzers
|
||||
## http://pihrt.net/Roslynator/Refactorings
|
||||
## https://github.com/JosefPihrt/Roslynator/blob/main/docs/Configuration.md
|
||||
## https://josefpihrt.github.io/docs/
|
||||
## Roslynator
|
||||
##################################################################################
|
||||
|
||||
# RCS1036 - Remove redundant empty line.
|
||||
dotnet_diagnostic.rcs1036.severity = None
|
||||
@ -650,7 +920,6 @@ dotnet_diagnostic.rcs1047.severity = error
|
||||
# RCS1174: Remove redundant async/await
|
||||
dotnet_diagnostic.rcs1174.severity = Suggestion
|
||||
|
||||
|
||||
# Combine 'Enumerable.Where' method chain. It doesn't make it more readable in all cases.
|
||||
dotnet_diagnostic.RCS1112.severity = suggestion
|
||||
|
||||
@ -688,6 +957,30 @@ dotnet_diagnostic.RCS1237.severity = none
|
||||
# RCS1228: Unused element in documentation comment. (Equivalent to SA1614)
|
||||
dotnet_diagnostic.RCS1228.severity = suggestion
|
||||
|
||||
# RCS1047: Non-asynchronous method name should not end with 'Async'
|
||||
#dotnet_diagnostic.RCS1047.severity = suggestion
|
||||
|
||||
##################################################################################
|
||||
## https://github.com/semihokur/asyncfixer
|
||||
## AsyncFixer01
|
||||
##################################################################################
|
||||
|
||||
# https://cezarypiatek.github.io/post/async-analyzers-p1/#1-redundant-asyncawait
|
||||
# AsyncFixer01: Unnecessary async/await usage
|
||||
dotnet_diagnostic.asyncfixer01.severity = Suggestion
|
||||
|
||||
# https://cezarypiatek.github.io/post/async-analyzers-p1/#2-calling-synchronous-method-inside-the-async-method
|
||||
# AsyncFixer02: Long-running or blocking operations inside an async method
|
||||
dotnet_diagnostic.asyncfixer02.severity = error
|
||||
|
||||
# https://cezarypiatek.github.io/post/async-analyzers-p1/#3-async-void-method
|
||||
# AsyncFixer03: Fire & forget async void methods
|
||||
dotnet_diagnostic.asyncfixer03.severity = error
|
||||
|
||||
# https://cezarypiatek.github.io/post/async-analyzers-p1/#6-not-awaited-task-inside-the-using-block
|
||||
# AsyncFixer04: Fire & forget async call inside a using block
|
||||
dotnet_diagnostic.asyncfixer04.severity = error
|
||||
|
||||
##################################################################################
|
||||
## https://github.com/microsoft/vs-threading
|
||||
## Microsoft.VisualStudio.Threading.Analyzers
|
||||
@ -697,7 +990,6 @@ dotnet_diagnostic.RCS1228.severity = suggestion
|
||||
# VSTHRD103: Call async methods when in an async method
|
||||
dotnet_diagnostic.vsthrd103.severity = Suggestion
|
||||
|
||||
|
||||
# https://cezarypiatek.github.io/post/async-analyzers-p1/#3-async-void-method
|
||||
# VSTHRD100: Avoid async void methods
|
||||
dotnet_diagnostic.vsthrd100.severity = error
|
||||
@ -733,3 +1025,20 @@ dotnet_diagnostic.vsthrd200.severity = Suggestion
|
||||
# https://cezarypiatek.github.io/post/async-analyzers-p2/#12-non-asynchronous-method-names-shouldnt-end-with-async
|
||||
# VSTHRD200: Use "Async" suffix for async methods
|
||||
dotnet_diagnostic.vsthrd200.severity = Suggestion
|
||||
|
||||
# VSTHRD003 Avoid awaiting foreign Tasks
|
||||
dotnet_diagnostic.VSTHRD003.severity = Suggestion
|
||||
|
||||
|
||||
##################################################################################
|
||||
## https://github.com/hvanbakel/Asyncify-CSharp
|
||||
## Asyncify
|
||||
##################################################################################
|
||||
|
||||
# https://cezarypiatek.github.io/post/async-analyzers-p2/#8-synchronous-waits
|
||||
# AsyncifyInvocation: Use Task Async
|
||||
dotnet_diagnostic.asyncifyinvocation.severity = error
|
||||
|
||||
# https://cezarypiatek.github.io/post/async-analyzers-p2/#8-synchronous-waits
|
||||
# AsyncifyVariable: Use Task Async
|
||||
dotnet_diagnostic.asyncifyvariable.severity = error
|
||||
|
||||
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
|
||||
6
.github/actions/build/action.yml
vendored
6
.github/actions/build/action.yml
vendored
@ -25,14 +25,16 @@ runs:
|
||||
# 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@v3
|
||||
uses: actions/cache@v4
|
||||
if: success()
|
||||
with:
|
||||
path: ~/.nuget/packages
|
||||
key: ${{ runner.os }}-dotnet-nuget
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v3
|
||||
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
|
||||
|
||||
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
@ -18,9 +18,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build and Test Flight
|
||||
- name: Build and Test Flight Microservice
|
||||
uses: ./.github/actions/build-test
|
||||
if: success()
|
||||
id: build-test-flight-step
|
||||
@ -35,7 +35,7 @@ jobs:
|
||||
service-name: 'Flight'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and Test Identity
|
||||
- name: Build and Test Identity Microservice
|
||||
uses: ./.github/actions/build-test
|
||||
if: success()
|
||||
id: build-test-identity-step
|
||||
@ -50,7 +50,7 @@ jobs:
|
||||
service-name: 'Identity'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and Test Passenger
|
||||
- name: Build and Test Passenger Microservice
|
||||
uses: ./.github/actions/build-test
|
||||
if: success()
|
||||
id: build-test-passenger-step
|
||||
@ -65,7 +65,7 @@ jobs:
|
||||
service-name: 'Passenger'
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and Test Booking
|
||||
- name: Build and Test Booking Microservice
|
||||
uses: ./.github/actions/build-test
|
||||
if: success()
|
||||
id: build-test-booking-step
|
||||
@ -91,7 +91,7 @@ jobs:
|
||||
run:
|
||||
echo "Release version is:" ${{ steps.last_release.outputs.tag_name }}
|
||||
|
||||
- name: Build and Publish Identity to Docker
|
||||
- name: Build and Publish Identity Microservice to Docker
|
||||
if: ${{ github.ref == 'refs/heads/main' && success() }}
|
||||
uses: ./.github/actions/docker-build-publish
|
||||
with:
|
||||
@ -101,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:
|
||||
@ -111,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:
|
||||
@ -121,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:
|
||||
|
||||
1
.gitpod.Dockerfile
vendored
1
.gitpod.Dockerfile
vendored
@ -1 +0,0 @@
|
||||
FROM gitpod/workspace-dotnet:latest
|
||||
37
.gitpod.yml
37
.gitpod.yml
@ -1,37 +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
|
||||
|
||||
vscode:
|
||||
extensions:
|
||||
- muhammad-sammy.csharp
|
||||
- editorconfig.editorconfig
|
||||
- vivaxy.vscode-conventional-commits
|
||||
- humao.rest-client
|
||||
- ms-azuretools.vscode-docker
|
||||
- donjayamanne.githistory
|
||||
- pkief.material-icon-theme
|
||||
- emmanuelbeziat.vscode-great-icons
|
||||
|
||||
# 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
|
||||
@ -1 +1,2 @@
|
||||
npm run format
|
||||
npm run format
|
||||
npm run ci-format
|
||||
|
||||
@ -1,34 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<RepositoryRoot>$(MSBuildThisFileDirectory)</RepositoryRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StyleCop.Analyzers" PrivateAssets="all" Version="1.1.118">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Meziantou.Analyzer" PrivateAssets="all" Version="2.0.163">
|
||||
<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.12.5">
|
||||
<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.12.5">
|
||||
<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.12.5">
|
||||
<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.11.20">
|
||||
<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="8.0.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SerilogAnalyzer" PrivateAssets="all" Version="0.15.0">
|
||||
<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">
|
||||
|
||||
131
README.md
131
README.md
@ -6,13 +6,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
> 🚀 **A practical and imaginary microservices for 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 8.**
|
||||
> 🚀 **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.**
|
||||
|
||||
> 💡 **This project is not business-oriented and most of my focus was in the thechnical part for implement a distributed system with a sample project. In this project I implemented some concept in microservices like Messaging, Tracing, Event Driven Architecture, Vertical Slice Architecture, Event Sourcing, CQRS, DDD and gRpc.**
|
||||
## 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://gitpod.io/#https://github.com/meysamhadeli/booking-microservices"><img alt="Open in Gitpod" src="https://gitpod.io/button/open-in-gitpod.svg"/></a>
|
||||
</div>
|
||||
<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>
|
||||
@ -20,16 +19,19 @@
|
||||
# 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)
|
||||
- [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)
|
||||
@ -39,22 +41,24 @@
|
||||
- [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 `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 `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 `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 `Kibana` on top of `Serilog` for `logging`.
|
||||
@ -65,44 +69,31 @@
|
||||
- :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.🌀
|
||||
|
||||
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 ✔️ |
|
||||
|
||||
## 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
|
||||
- ✔️ **[`NewId`](https://github.com/phatboyg/NewId)** - NewId can be used as an embedded unique ID generator that produces 128 bit (16 bytes) sequential IDs
|
||||
- ✔️ **[`Yarp`](https://github.com/microsoft/reverse-proxy)** - Reverse proxy toolkit for building fast proxy servers in .NET
|
||||
- ✔️ **[`Tye`](https://github.com/dotnet/tye)** - Developer tool that makes developing, testing, and deploying microservices and distributed applications easier
|
||||
- ✔️ **[`Hellang.Middleware.ProblemDetails`](https://github.com/khellang/Middleware/tree/master/src/ProblemDetails)** - A middleware for handling exception in .Net Core.
|
||||
- ✔️ **[`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.
|
||||
@ -110,6 +101,29 @@ High-level plan is represented in the table
|
||||
- ✔️ **[`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
|
||||
|
||||
@ -123,19 +137,10 @@ 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`.
|
||||
@ -158,6 +163,7 @@ 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
|
||||
@ -171,8 +177,8 @@ 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).
|
||||
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
|
||||
@ -198,13 +204,24 @@ Run the following commands to [Config SSL](https://docs.microsoft.com/en-us/aspn
|
||||
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
|
||||
```
|
||||
|
||||
### 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
|
||||
|
||||
|
||||
@ -248,7 +265,7 @@ dotnet test
|
||||
|
||||
> ### Documentation Apis
|
||||
|
||||
Each microservice has a `Swagger OpenAPI`. Browse to `/swagger` for a list of endpoints.
|
||||
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`.
|
||||
|
||||
|
||||
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.3 MiB After Width: | Height: | Size: 643 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
|
||||
12
booking.rest
12
booking.rest
@ -1,7 +1,7 @@
|
||||
|
||||
## uncommnet this line for use kubernetes ingress controller instead of Yarp
|
||||
//@api-gateway=https://booking-microservices.com
|
||||
@api-gateway=https://localhost:5000
|
||||
//@api-gateway=https://booking-microservices.com
|
||||
@api-gateway=https://localhost:5000
|
||||
@identity-api=http://localhost:6005
|
||||
@flight-api=http://localhost:5004
|
||||
@passenger-api=http://localhost:6012
|
||||
@ -29,7 +29,9 @@ 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, ...)
|
||||
###
|
||||
|
||||
|
||||
@ -45,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"
|
||||
@ -218,7 +220,7 @@ Content-Type: application/json
|
||||
authorization: bearer {{Authenticate.response.body.access_token}}
|
||||
|
||||
{
|
||||
"passportNumber": "412900000000",
|
||||
"passportNumber": "41290000",
|
||||
"passengerType": 1,
|
||||
"age": 30
|
||||
}
|
||||
|
||||
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/)
|
||||
@ -905,4 +905,4 @@
|
||||
"uid": "NagEsjE4z",
|
||||
"version": 10,
|
||||
"weekStart": ""
|
||||
}
|
||||
}
|
||||
@ -1304,4 +1304,4 @@
|
||||
"uid": "KdDACDp4z",
|
||||
"version": 5,
|
||||
"weekStart": ""
|
||||
}
|
||||
}
|
||||
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,79 +1,49 @@
|
||||
version: "3.3"
|
||||
name: booking-microservices
|
||||
|
||||
services:
|
||||
|
||||
#######################################################
|
||||
# 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"
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
|
||||
#######################################################
|
||||
# SqlServer
|
||||
#######################################################
|
||||
# sql:
|
||||
# container_name: sql
|
||||
# image: mcr.microsoft.com/mssql/server
|
||||
# restart: unless-stopped
|
||||
# ports:
|
||||
# - "1433:1433"
|
||||
# environment:
|
||||
# SA_PASSWORD: "Password@1234"
|
||||
# ACCEPT_EULA: "Y"
|
||||
|
||||
|
||||
#######################################################
|
||||
# Rabbitmq
|
||||
#######################################################
|
||||
#######################################################
|
||||
# rabbitmq
|
||||
#######################################################
|
||||
rabbitmq:
|
||||
container_name: rabbitmq
|
||||
image: rabbitmq:management
|
||||
container_name: rabbitmq
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5672:5672
|
||||
- 15672:15672
|
||||
- "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
|
||||
|
||||
|
||||
#######################################################
|
||||
# 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
|
||||
#######################################################
|
||||
#######################################################
|
||||
# EventStoreDB
|
||||
#######################################################
|
||||
eventstore:
|
||||
container_name: eventstore
|
||||
image: eventstore/eventstore:latest
|
||||
@ -91,9 +61,9 @@ services:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# Mongo
|
||||
#######################################################
|
||||
#######################################################
|
||||
# Mongo
|
||||
#######################################################
|
||||
mongo:
|
||||
image: mongo:latest
|
||||
container_name: mongo
|
||||
@ -101,93 +71,260 @@ services:
|
||||
# environment:
|
||||
# - MONGO_INITDB_ROOT_USERNAME=root
|
||||
# - MONGO_INITDB_ROOT_PASSWORD=secret
|
||||
networks:
|
||||
- booking
|
||||
ports:
|
||||
- 27017:27017
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# Elastic Search
|
||||
#######################################################
|
||||
elasticsearch:
|
||||
container_name: elasticsearch
|
||||
image: elasticsearch:7.17.9
|
||||
|
||||
#######################################################
|
||||
# Redis
|
||||
#######################################################
|
||||
redis:
|
||||
image: redis
|
||||
container_name: redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 9200:9200
|
||||
- 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:
|
||||
- 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: kibana:7.17.9
|
||||
restart: unless-stopped
|
||||
- ./../configs/otel-collector-config.yaml:/etc/otelcol-contrib/config.yaml
|
||||
ports:
|
||||
- 5601:5601
|
||||
depends_on:
|
||||
- elasticsearch
|
||||
environment:
|
||||
- ELASTICSEARCH_URL=elasticsearch:9200
|
||||
- "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
|
||||
#######################################################
|
||||
|
||||
#######################################################
|
||||
# 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
|
||||
container_name: prometheus
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9090:9090"
|
||||
environment:
|
||||
- TZ=UTC
|
||||
volumes:
|
||||
- ./monitoring/prom/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# grafana
|
||||
#######################################################
|
||||
grafana:
|
||||
image: grafana/grafana
|
||||
container_name: grafana
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- ./monitoring/grafana-data/data:/var/lib/grafana
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# node_exporter
|
||||
#######################################################
|
||||
node_exporter:
|
||||
image: quay.io/prometheus/node-exporter:latest
|
||||
container_name: node_exporter
|
||||
restart: unless-stopped
|
||||
- ./../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:
|
||||
- '--path.rootfs=/host'
|
||||
pid: host
|
||||
- "--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
|
||||
#######################################################
|
||||
@ -208,17 +345,18 @@ services:
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
######################################################
|
||||
# Gateway
|
||||
# Api-Gateway
|
||||
######################################################
|
||||
gateway:
|
||||
image: gateway
|
||||
api-gateway:
|
||||
image: api-gateway
|
||||
build:
|
||||
args:
|
||||
Version: "1"
|
||||
context: ../../
|
||||
dockerfile: src/ApiGateway/dev.Dockerfile
|
||||
container_name: gateway
|
||||
dockerfile: src/ApiGateway/Dockerfile
|
||||
container_name: api-gateway
|
||||
ports:
|
||||
- "5001:80"
|
||||
- "5000:443"
|
||||
@ -244,7 +382,7 @@ services:
|
||||
args:
|
||||
Version: "1"
|
||||
context: ../../
|
||||
dockerfile: src/Services/Flight/dev.Dockerfile
|
||||
dockerfile: src/Services/Flight/Dockerfile
|
||||
container_name: flight
|
||||
ports:
|
||||
- 5004:80
|
||||
@ -270,7 +408,7 @@ services:
|
||||
args:
|
||||
Version: "1"
|
||||
context: ../../
|
||||
dockerfile: src/Services/Identity/dev.Dockerfile
|
||||
dockerfile: src/Services/Identity/Dockerfile
|
||||
container_name: identity
|
||||
ports:
|
||||
- 6005:80
|
||||
@ -297,7 +435,7 @@ services:
|
||||
args:
|
||||
Version: "1"
|
||||
context: ../../
|
||||
dockerfile: src/Services/Passenger/dev.Dockerfile
|
||||
dockerfile: src/Services/Passenger/Dockerfile
|
||||
container_name: passenger
|
||||
ports:
|
||||
- 6012:80
|
||||
@ -324,7 +462,7 @@ services:
|
||||
args:
|
||||
Version: "1"
|
||||
context: ../../
|
||||
dockerfile: src/Services/Booking/dev.Dockerfile
|
||||
dockerfile: src/Services/Booking/Dockerfile
|
||||
container_name: booking
|
||||
ports:
|
||||
- 6010:80
|
||||
@ -344,9 +482,11 @@ services:
|
||||
|
||||
networks:
|
||||
booking:
|
||||
name: booking
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
elasticsearch-data:
|
||||
|
||||
elastic-data:
|
||||
postgres-data:
|
||||
|
||||
|
||||
|
||||
@ -1,234 +0,0 @@
|
||||
version: "3.3"
|
||||
services:
|
||||
|
||||
#######################################################
|
||||
# Rabbitmq
|
||||
#######################################################
|
||||
rabbitmq:
|
||||
container_name: rabbitmq
|
||||
image: rabbitmq:management
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 5672:5672
|
||||
- 15672:15672
|
||||
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"
|
||||
networks:
|
||||
- booking
|
||||
|
||||
|
||||
#######################################################
|
||||
# SqlServer
|
||||
#######################################################
|
||||
# sql:
|
||||
# container_name: sql
|
||||
# image: mcr.microsoft.com/mssql/server
|
||||
# restart: unless-stopped
|
||||
# ports:
|
||||
# - "1433:1433"
|
||||
# environment:
|
||||
# SA_PASSWORD: "Password@1234"
|
||||
# ACCEPT_EULA: "Y"
|
||||
|
||||
|
||||
#######################################################
|
||||
# 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: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
|
||||
networks:
|
||||
- booking
|
||||
ports:
|
||||
- 27017:27017
|
||||
|
||||
|
||||
#######################################################
|
||||
# Elastic Search
|
||||
#######################################################
|
||||
elasticsearch:
|
||||
container_name: elasticsearch
|
||||
image: 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: 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
|
||||
|
||||
#######################################################
|
||||
# prometheus
|
||||
#######################################################
|
||||
prometheus:
|
||||
image: prom/prometheus:latest
|
||||
container_name: prometheus
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9090:9090"
|
||||
environment:
|
||||
- TZ=UTC
|
||||
volumes:
|
||||
- ./monitoring/prom/prometheus.yml:/etc/prometheus/prometheus.yml
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# grafana
|
||||
#######################################################
|
||||
grafana:
|
||||
image: grafana/grafana
|
||||
container_name: grafana
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:3000"
|
||||
volumes:
|
||||
- ./monitoring/grafana-data/data:/var/lib/grafana
|
||||
networks:
|
||||
- booking
|
||||
|
||||
#######################################################
|
||||
# node_exporter
|
||||
#######################################################
|
||||
node_exporter:
|
||||
image: quay.io/prometheus/node-exporter:latest
|
||||
container_name: node_exporter
|
||||
restart: unless-stopped
|
||||
command:
|
||||
- '--path.rootfs=/host'
|
||||
pid: host
|
||||
volumes:
|
||||
- /proc:/host/proc:ro
|
||||
- /sys:/host/sys:ro
|
||||
- /:/rootfs:ro
|
||||
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
|
||||
|
||||
|
||||
networks:
|
||||
booking:
|
||||
|
||||
volumes:
|
||||
elasticsearch-data:
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,69 +0,0 @@
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 10s
|
||||
evaluation_interval: 15s
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- scheme: http
|
||||
timeout: 10s
|
||||
api_version: v1
|
||||
static_configs:
|
||||
- targets: []
|
||||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
honor_timestamps: true
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 10s
|
||||
metrics_path: /metrics
|
||||
scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- localhost:9090
|
||||
- job_name: cadvisor
|
||||
static_configs:
|
||||
- targets:
|
||||
- cadvisor:8080
|
||||
- job_name: node_exporter
|
||||
static_configs:
|
||||
- targets:
|
||||
- node_exporter:9100
|
||||
- job_name: flight
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 10s
|
||||
metrics_path: /metrics
|
||||
scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- host.docker.internal:5004
|
||||
- job_name: identity
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 10s
|
||||
metrics_path: /metrics
|
||||
scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- host.docker.internal:6005
|
||||
- job_name: passenger
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 10s
|
||||
metrics_path: /metrics
|
||||
scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- host.docker.internal:6012
|
||||
- job_name: booking
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 10s
|
||||
metrics_path: /metrics
|
||||
scheme: http
|
||||
static_configs:
|
||||
- targets:
|
||||
- host.docker.internal:6010
|
||||
- job_name: gateway
|
||||
scrape_interval: 15s
|
||||
scrape_timeout: 10s
|
||||
metrics_path: /metrics
|
||||
scheme: https
|
||||
static_configs:
|
||||
- targets:
|
||||
- host.docker.internal:5000
|
||||
@ -13,4 +13,4 @@ spec:
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: nginx
|
||||
class: nginx
|
||||
|
||||
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
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "8.0.401",
|
||||
"version": "10.0.103",
|
||||
"rollForward": "latestFeature"
|
||||
}
|
||||
}
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "booking-microservices",
|
||||
"name": "monolith-to-cloud-architecture",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "booking-microservices",
|
||||
"name": "monolith-to-cloud-architecture",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"prepare": "husky && dotnet tool restore",
|
||||
"format": "dotnet format booking-microservices-sample.sln --severity error --verbosity detailed",
|
||||
"ci-format": "dotnet format booking-microservices-sample.sln --verify-no-changes --severity error --verbosity detailed",
|
||||
"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": {
|
||||
|
||||
@ -1,45 +1,38 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
|
||||
WORKDIR /
|
||||
# ---------- Build Stage ----------
|
||||
FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build
|
||||
WORKDIR /src
|
||||
|
||||
COPY ./.editorconfig ./
|
||||
COPY ./global.json ./
|
||||
COPY ./Directory.Build.props ./
|
||||
# Copy solution-level files
|
||||
COPY .editorconfig .
|
||||
COPY global.json .
|
||||
COPY Directory.Build.props .
|
||||
|
||||
# Setup working directory for the project
|
||||
COPY ./src/BuildingBlocks/BuildingBlocks.csproj ./BuildingBlocks/
|
||||
COPY ./src/ApiGateway/src/ApiGateway.csproj ./ApiGateway/src/
|
||||
# Copy project files first (better Docker caching)
|
||||
COPY src/BuildingBlocks/BuildingBlocks.csproj src/BuildingBlocks/
|
||||
COPY src/ApiGateway/src/ApiGateway.csproj src/ApiGateway/src/
|
||||
COPY src/Aspire/src/ServiceDefaults/ServiceDefaults.csproj src/Aspire/src/ServiceDefaults/
|
||||
|
||||
# Restore dependencies
|
||||
RUN dotnet restore src/ApiGateway/src/ApiGateway.csproj
|
||||
|
||||
# Restore nuget packages
|
||||
RUN dotnet restore ./ApiGateway/src/ApiGateway.csproj
|
||||
# Copy the rest of the source code
|
||||
COPY src ./src
|
||||
|
||||
# Copy project files
|
||||
COPY ./src/BuildingBlocks ./BuildingBlocks/
|
||||
COPY ./src/ApiGateway/src ./ApiGateway/src/
|
||||
# Publish (build included)
|
||||
RUN dotnet publish src/ApiGateway/src/ApiGateway.csproj \
|
||||
-c Release \
|
||||
-o /app/publish \
|
||||
--no-restore
|
||||
|
||||
# Build project with Release configuration
|
||||
# and no restore, as we did it already
|
||||
# ---------- Runtime Stage ----------
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS runtime
|
||||
WORKDIR /app
|
||||
|
||||
RUN ls
|
||||
RUN dotnet build -c Release --no-restore ./ApiGateway/src/ApiGateway.csproj
|
||||
COPY --from=build /app/publish .
|
||||
|
||||
WORKDIR /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:8.0
|
||||
|
||||
# Setup working directory for the project
|
||||
WORKDIR /
|
||||
COPY --from=builder /src/ApiGateway/src/out .
|
||||
|
||||
ENV ASPNETCORE_URLS https://*:443, http://*:80
|
||||
ENV ASPNETCORE_ENVIRONMENT docker
|
||||
ENV ASPNETCORE_URLS=http://+:80
|
||||
ENV ASPNETCORE_ENVIRONMENT=docker
|
||||
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
ENTRYPOINT ["dotnet", "ApiGateway.dll"]
|
||||
|
||||
ENTRYPOINT ["dotnet", "ApiGateway.dll"]
|
||||
@ -1,48 +0,0 @@
|
||||
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS builder
|
||||
WORKDIR /
|
||||
|
||||
COPY ./.editorconfig ./
|
||||
COPY ./global.json ./
|
||||
COPY ./Directory.Build.props ./
|
||||
|
||||
# Setup working directory for the project
|
||||
COPY ./src/BuildingBlocks/BuildingBlocks.csproj ./BuildingBlocks/
|
||||
COPY ./src/ApiGateway/src/ApiGateway.csproj ./ApiGateway/src/
|
||||
|
||||
|
||||
# Restore nuget packages
|
||||
RUN --mount=type=cache,id=gateway_nuget,target=/root/.nuget/packages \
|
||||
dotnet restore ./ApiGateway/src/ApiGateway.csproj
|
||||
|
||||
# Copy project files
|
||||
COPY ./src/BuildingBlocks ./BuildingBlocks/
|
||||
COPY ./src/ApiGateway/src ./ApiGateway/src/
|
||||
|
||||
# Build project with Release configuration
|
||||
# and no restore, as we did it already
|
||||
|
||||
RUN ls
|
||||
RUN --mount=type=cache,id=gateway_nuget,target=/root/.nuget/packages \
|
||||
dotnet build -c Release --no-restore ./ApiGateway/src/ApiGateway.csproj
|
||||
|
||||
WORKDIR /ApiGateway/src
|
||||
|
||||
# Publish project to output folder
|
||||
# and no build, as we did it already
|
||||
RUN --mount=type=cache,id=gateway_nuget,target=/root/.nuget/packages \
|
||||
dotnet publish -c Release --no-build -o out
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
||||
|
||||
# Setup working directory for the project
|
||||
WORKDIR /
|
||||
COPY --from=builder /src/ApiGateway/src/out .
|
||||
|
||||
ENV ASPNETCORE_URLS https://*:443, http://*:80
|
||||
ENV ASPNETCORE_ENVIRONMENT docker
|
||||
|
||||
EXPOSE 80
|
||||
EXPOSE 443
|
||||
|
||||
ENTRYPOINT ["dotnet", "ApiGateway.dll"]
|
||||
|
||||
@ -1,7 +1,5 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\BuildingBlocks\BuildingBlocks.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
using BuildingBlocks.Logging;
|
||||
using BuildingBlocks.Web;
|
||||
using Figgle;
|
||||
using Serilog;
|
||||
using Figgle.Fonts;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var env = builder.Environment;
|
||||
@ -9,8 +8,6 @@ var appOptions = builder.Services.GetOptions<AppOptions>("AppOptions");
|
||||
Console.WriteLine(FiggleFonts.Standard.Render(appOptions.Name));
|
||||
|
||||
|
||||
|
||||
builder.AddCustomSerilog(env);
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
|
||||
@ -18,7 +15,6 @@ builder.Services.AddReverseProxy().LoadFromConfig(builder.Configuration.GetSecti
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.UseSerilogRequestLogging();
|
||||
app.UseCorrelationId();
|
||||
app.UseRouting();
|
||||
app.UseHttpsRedirection();
|
||||
@ -33,4 +29,4 @@ app.UseEndpoints(endpoints =>
|
||||
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
"match": {
|
||||
"path": "identity/{**catch-all}"
|
||||
},
|
||||
"Transforms": [
|
||||
"Transforms": [
|
||||
{
|
||||
"PathRemovePrefix": "identity"
|
||||
}
|
||||
@ -28,7 +28,7 @@
|
||||
"match": {
|
||||
"path": "flight/{**catch-all}"
|
||||
},
|
||||
"Transforms": [
|
||||
"Transforms": [
|
||||
{
|
||||
"PathRemovePrefix": "flight"
|
||||
}
|
||||
@ -39,7 +39,7 @@
|
||||
"match": {
|
||||
"path": "passenger/{**catch-all}"
|
||||
},
|
||||
"Transforms": [
|
||||
"Transforms": [
|
||||
{
|
||||
"PathRemovePrefix": "passenger"
|
||||
}
|
||||
@ -50,7 +50,7 @@
|
||||
"match": {
|
||||
"path": "booking/{**catch-all}"
|
||||
},
|
||||
"Transforms": [
|
||||
"Transforms": [
|
||||
{
|
||||
"PathRemovePrefix": "booking"
|
||||
}
|
||||
|
||||
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,110 +1,110 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.GuardClauses" Version="4.6.0" />
|
||||
<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.0" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc" Version="8.1.0" />
|
||||
<PackageReference Include="Asp.Versioning.Mvc.ApiExplorer" Version="8.1.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="8.0.8" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI" Version="8.0.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="8.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.InMemory.Storage" Version="8.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Elasticsearch" Version="8.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.EventStore" Version="8.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.NpgSql" Version="8.0.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.Rabbitmq" Version="8.0.2" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.UI.SQLite.Storage" Version="8.0.1" />
|
||||
<PackageReference Include="AspNetCore.HealthChecks.MongoDb" 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="EasyCaching.Core" Version="1.9.2" />
|
||||
<PackageReference Include="EasyCaching.InMemory" Version="1.9.2" />
|
||||
<PackageReference Include="EasyNetQ.Management.Client" Version="3.0.0" />
|
||||
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
|
||||
<PackageReference Include="Figgle" Version="0.5.1" />
|
||||
<PackageReference Include="FluentValidation" Version="11.10.0" />
|
||||
<PackageReference Include="FluentValidation.AspNetCore" Version="11.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.1" />
|
||||
<PackageReference Include="Npgsql" Version="8.0.4" />
|
||||
<PackageReference Include="NSubstitute" Version="5.1.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.9.0-beta.2" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.9.0-beta.1" />
|
||||
<PackageReference Include="Polly" Version="8.4.1" />
|
||||
<PackageReference Include="Humanizer.Core" Version="2.14.1" />
|
||||
<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="12.4.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.28.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="OpenTelemetry.Contrib.Instrumentation.MassTransit" Version="1.0.0-beta2" />
|
||||
<PackageReference Include="Scrutor" Version="4.2.2" />
|
||||
<PackageReference Include="Sentry.Serilog" Version="4.10.2" />
|
||||
<PackageReference Include="Serilog" Version="4.0.1" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
|
||||
<PackageReference Include="Serilog.Enrichers.Span" Version="3.1.0" />
|
||||
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
|
||||
<PackageReference Include="Serilog.Formatting.Elasticsearch" Version="10.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Elasticsearch" Version="10.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Seq" Version="8.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.SpectreConsole" Version="0.3.3" />
|
||||
<PackageReference Include="Serilog.Sinks.XUnit" Version="3.0.5" />
|
||||
<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="6.7.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="6.7.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="6.7.3" />
|
||||
<PackageReference Include="MassTransit" Version="8.2.5" />
|
||||
<PackageReference Include="MassTransit.RabbitMQ" Version="8.2.5" />
|
||||
<PackageReference Include="Duende.IdentityServer" Version="7.0.6" />
|
||||
<PackageReference Include="Duende.IdentityServer.AspNetIdentity" Version="7.0.6" />
|
||||
<PackageReference Include="Duende.IdentityServer.EntityFramework" Version="7.0.6" />
|
||||
<PackageReference Include="Duende.IdentityServer.EntityFramework.Storage" Version="7.0.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.8" />
|
||||
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageReference Include="System.Linq.Async.Queryable" Version="6.0.1" />
|
||||
<PackageReference Include="Testcontainers" Version="3.10.0" />
|
||||
<PackageReference Include="Testcontainers.EventStoreDb" Version="3.10.0" />
|
||||
<PackageReference Include="Testcontainers.MongoDb" Version="3.10.0" />
|
||||
<PackageReference Include="Testcontainers.PostgreSql" Version="3.10.0" />
|
||||
<PackageReference Include="Testcontainers.RabbitMq" Version="3.10.0" />
|
||||
<PackageReference Include="Unchase.Swashbuckle.AspNetCore.Extensions" Version="2.7.1" />
|
||||
<PackageReference Include="Yarp.ReverseProxy" Version="2.2.0" />
|
||||
<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="prometheus-net" Version="8.2.1" />
|
||||
<PackageReference Include="prometheus-net.AspNetCore" Version="8.2.1" />
|
||||
<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.9.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.6.0-rc.1" />
|
||||
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
|
||||
<PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
|
||||
|
||||
<PackageReference Include="EventStore.Client.Grpc.Streams" Version="23.3.5" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
|
||||
<PackageReference Include="EventStore.Client.Grpc.Streams" Version="23.3.9" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
|
||||
|
||||
<PackageReference Include="AutoBogus" Version="2.13.1" />
|
||||
<PackageReference Include="Bogus" Version="35.6.1" />
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.1" />
|
||||
<PackageReference Include="Respawn" Version="6.2.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.8" />
|
||||
<PackageReference Include="WebMotions.Fake.Authentication.JwtBearer" Version="8.0.1" />
|
||||
<PackageReference Include="Bogus" Version="35.6.5" />
|
||||
<PackageReference Include="FluentAssertions" Version="8.8.0" />
|
||||
<PackageReference Include="Respawn" Version="7.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="10.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="10.0.3" />
|
||||
<PackageReference Include="WebMotions.Fake.Authentication.JwtBearer" Version="10.0.0" />
|
||||
|
||||
<PackageReference Include="Google.Protobuf" Version="3.28.1" />
|
||||
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.65.0" />
|
||||
<PackageReference Include="Google.Protobuf" Version="3.33.5" />
|
||||
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.76.0" />
|
||||
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@ -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";
|
||||
}
|
||||
}
|
||||
@ -8,4 +8,4 @@ public record FlightDeleted(Guid Id) : IIntegrationEvent;
|
||||
public record AircraftCreated(Guid Id) : IIntegrationEvent;
|
||||
public record AirportCreated(Guid Id) : IIntegrationEvent;
|
||||
public record SeatCreated(Guid Id) : IIntegrationEvent;
|
||||
public record SeatReserved(Guid Id) : IIntegrationEvent;
|
||||
public record SeatReserved(Guid Id) : IIntegrationEvent;
|
||||
@ -2,4 +2,4 @@ using BuildingBlocks.Core.Event;
|
||||
|
||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||
|
||||
public record UserCreated(Guid Id, string Name, string PassportNumber) : IIntegrationEvent;
|
||||
public record UserCreated(Guid Id, string Name, string PassportNumber) : IIntegrationEvent;
|
||||
@ -3,4 +3,4 @@ using BuildingBlocks.Core.Event;
|
||||
namespace BuildingBlocks.Contracts.EventBus.Messages;
|
||||
|
||||
public record PassengerRegistrationCompleted(Guid Id) : IIntegrationEvent;
|
||||
public record PassengerCreated(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(Guid Id) : IIntegrationEvent;
|
||||
public record BookingCreated(Guid Id) : IIntegrationEvent;
|
||||
@ -9,4 +9,4 @@ public interface ICommand : ICommand<Unit>
|
||||
public interface ICommand<out T> : IRequest<T>
|
||||
where T : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -11,4 +11,4 @@ public interface ICommandHandler<in TCommand, TResponse> : IRequestHandler<TComm
|
||||
where TCommand : ICommand<TResponse>
|
||||
where TResponse : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -5,4 +5,4 @@ namespace BuildingBlocks.Core.CQRS;
|
||||
public interface IQuery<out T> : IRequest<T>
|
||||
where T : notnull
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -9,4 +9,4 @@ public interface IEvent : INotification
|
||||
Guid EventId => NewId.NextGuid();
|
||||
public DateTime OccurredOn => DateTime.Now;
|
||||
public string EventType => GetType().AssemblyQualifiedName;
|
||||
}
|
||||
}
|
||||
@ -2,4 +2,4 @@ namespace BuildingBlocks.Core.Event;
|
||||
|
||||
public interface IHaveIntegrationEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -5,4 +5,4 @@ namespace BuildingBlocks.Core.Event;
|
||||
[ExcludeFromTopology]
|
||||
public interface IIntegrationEvent : IEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -2,4 +2,4 @@ namespace BuildingBlocks.Core.Event;
|
||||
|
||||
public interface IInternalCommand : IEvent
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -2,4 +2,4 @@ using BuildingBlocks.Core.CQRS;
|
||||
|
||||
namespace BuildingBlocks.Core.Event;
|
||||
|
||||
public record InternalCommand : IInternalCommand, ICommand;
|
||||
public record InternalCommand : IInternalCommand, ICommand;
|
||||
@ -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);
|
||||
}
|
||||
@ -74,7 +61,7 @@ public sealed class EventDispatcher : IEventDispatcher
|
||||
|
||||
foreach (var internalMessage in internalMessages)
|
||||
{
|
||||
await _persistMessageProcessor.AddInternalMessageAsync(internalMessage, cancellationToken);
|
||||
await persistMessageProcessor.AddInternalMessageAsync(internalMessage, cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,20 +76,20 @@ public sealed class EventDispatcher : IEventDispatcher
|
||||
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;
|
||||
@ -110,7 +97,7 @@ public sealed class EventDispatcher : IEventDispatcher
|
||||
integrationEvents.Add(integrationEvent);
|
||||
}
|
||||
|
||||
_logger.LogTrace("Processing integration events done...");
|
||||
logger.LogTrace("Processing integration events done...");
|
||||
|
||||
return Task.FromResult<IReadOnlyList<IIntegrationEvent>>(integrationEvents);
|
||||
}
|
||||
@ -119,16 +106,16 @@ 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;
|
||||
@ -136,7 +123,7 @@ public sealed class EventDispatcher : IEventDispatcher
|
||||
internalCommands.Add(integrationEvent);
|
||||
}
|
||||
|
||||
_logger.LogTrace("Processing internal message done...");
|
||||
logger.LogTrace("Processing internal message done...");
|
||||
|
||||
return Task.FromResult<IReadOnlyList<IInternalCommand>>(internalCommands);
|
||||
}
|
||||
@ -159,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;
|
||||
}
|
||||
}
|
||||
@ -6,4 +6,4 @@ public interface IEventMapper
|
||||
{
|
||||
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;
|
||||
@ -20,4 +20,4 @@ public abstract record Aggregate<TId> : Entity<TId>, IAggregate<TId>
|
||||
|
||||
return dequeuedEvents;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,4 +9,4 @@ public abstract record Entity<T> : IEntity<T>
|
||||
public long? LastModifiedBy { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
public long Version { get; set; }
|
||||
}
|
||||
}
|
||||
@ -10,4 +10,4 @@ public interface IAggregate : IEntity
|
||||
{
|
||||
IReadOnlyList<IDomainEvent> DomainEvents { get; }
|
||||
IEvent[] ClearDomainEvents();
|
||||
}
|
||||
}
|
||||
@ -12,4 +12,4 @@ public interface IEntity : IVersion
|
||||
public DateTime? LastModified { get; set; }
|
||||
public long? LastModifiedBy { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
}
|
||||
}
|
||||
@ -4,4 +4,4 @@ namespace BuildingBlocks.Core.Model;
|
||||
public interface IVersion
|
||||
{
|
||||
long Version { get; set; }
|
||||
}
|
||||
}
|
||||
@ -33,4 +33,4 @@ public static class Extensions
|
||||
|
||||
return PageList<TEntity>.Create(items.AsReadOnly(), pageRequest.PageNumber, pageRequest.PageSize, total);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,4 +13,4 @@ public interface IPageList<T>
|
||||
int TotalCount { get; init; }
|
||||
int PageNumber { get; init; }
|
||||
int PageSize { get; init; }
|
||||
}
|
||||
}
|
||||
@ -4,4 +4,4 @@ using MediatR;
|
||||
|
||||
public interface IPageQuery<out TResponse> : IPageRequest, IRequest<TResponse>
|
||||
where TResponse : class
|
||||
{ }
|
||||
{ }
|
||||
@ -6,4 +6,4 @@ public interface IPageRequest
|
||||
int PageSize { get; init; }
|
||||
string? Filters { get; init; }
|
||||
string? SortOrder { get; init; }
|
||||
}
|
||||
}
|
||||
@ -16,4 +16,4 @@ public record PageList<T>(IReadOnlyList<T> Items, int PageNumber, int PageSize,
|
||||
{
|
||||
return new PageList<T>(items, pageNumber, pageSize, totalItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,15 +1,14 @@
|
||||
namespace BuildingBlocks.EFCore;
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using Core.Event;
|
||||
using Core.Model;
|
||||
using BuildingBlocks.Core.Event;
|
||||
using BuildingBlocks.Core.Model;
|
||||
using BuildingBlocks.Web;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Storage;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Web;
|
||||
using Exception = System.Exception;
|
||||
using IsolationLevel = System.Data.IsolationLevel;
|
||||
|
||||
namespace BuildingBlocks.EFCore;
|
||||
|
||||
public abstract class AppDbContextBase : DbContext, IDbContext
|
||||
{
|
||||
private readonly ICurrentUserProvider? _currentUserProvider;
|
||||
@ -174,9 +173,9 @@ public abstract class AppDbContextBase : DbContext, IDbContext
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw new Exception("try for find IAggregate", ex);
|
||||
throw new System.Exception("try for find IAggregate", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,3 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@ -59,4 +57,4 @@ namespace BuildingBlocks.EFCore
|
||||
return CreateNewInstance(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,50 +1,39 @@
|
||||
using System.Text.Json;
|
||||
using System.Transactions;
|
||||
using BuildingBlocks.Core;
|
||||
using BuildingBlocks.PersistMessageProcessor;
|
||||
using BuildingBlocks.Polly;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BuildingBlocks.EFCore;
|
||||
|
||||
using System.Transactions;
|
||||
using PersistMessageProcessor;
|
||||
using Polly;
|
||||
|
||||
public class EfTxBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : notnull, IRequest<TResponse>
|
||||
where TResponse : notnull
|
||||
public class EfTxBehavior<TRequest, TResponse>(
|
||||
ILogger<EfTxBehavior<TRequest, TResponse>> logger,
|
||||
IDbContext dbContextBase,
|
||||
IPersistMessageDbContext persistMessageDbContext,
|
||||
IEventDispatcher eventDispatcher
|
||||
)
|
||||
: IPipelineBehavior<TRequest, TResponse>
|
||||
where TRequest : notnull, IRequest<TResponse>
|
||||
where TResponse : notnull
|
||||
{
|
||||
private readonly ILogger<EfTxBehavior<TRequest, TResponse>> _logger;
|
||||
private readonly IDbContext _dbContextBase;
|
||||
private readonly IPersistMessageDbContext _persistMessageDbContext;
|
||||
private readonly IEventDispatcher _eventDispatcher;
|
||||
|
||||
public EfTxBehavior(
|
||||
ILogger<EfTxBehavior<TRequest, TResponse>> logger,
|
||||
IDbContext dbContextBase,
|
||||
IPersistMessageDbContext persistMessageDbContext,
|
||||
IEventDispatcher eventDispatcher)
|
||||
{
|
||||
_logger = logger;
|
||||
_dbContextBase = dbContextBase;
|
||||
_persistMessageDbContext = persistMessageDbContext;
|
||||
_eventDispatcher = eventDispatcher;
|
||||
}
|
||||
|
||||
public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next,
|
||||
CancellationToken cancellationToken)
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation(
|
||||
logger.LogInformation(
|
||||
"{Prefix} Handled command {MediatrRequest}",
|
||||
nameof(EfTxBehavior<TRequest, TResponse>),
|
||||
typeof(TRequest).FullName);
|
||||
|
||||
_logger.LogDebug(
|
||||
logger.LogDebug(
|
||||
"{Prefix} Handled command {MediatrRequest} with content {RequestContent}",
|
||||
nameof(EfTxBehavior<TRequest, TResponse>),
|
||||
typeof(TRequest).FullName,
|
||||
JsonSerializer.Serialize(request));
|
||||
|
||||
_logger.LogInformation(
|
||||
logger.LogInformation(
|
||||
"{Prefix} Open the transaction for {MediatrRequest}",
|
||||
nameof(EfTxBehavior<TRequest, TResponse>),
|
||||
typeof(TRequest).FullName);
|
||||
@ -56,32 +45,32 @@ public class EfTxBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TRe
|
||||
|
||||
var response = await next();
|
||||
|
||||
_logger.LogInformation(
|
||||
logger.LogInformation(
|
||||
"{Prefix} Executed the {MediatrRequest} request",
|
||||
nameof(EfTxBehavior<TRequest, TResponse>),
|
||||
typeof(TRequest).FullName);
|
||||
|
||||
while (true)
|
||||
{
|
||||
var domainEvents = _dbContextBase.GetDomainEvents();
|
||||
var domainEvents = dbContextBase.GetDomainEvents();
|
||||
|
||||
if (domainEvents is null || !domainEvents.Any())
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
await _eventDispatcher.SendAsync(domainEvents.ToArray(), typeof(TRequest), cancellationToken);
|
||||
await eventDispatcher.SendAsync(domainEvents.ToArray(), typeof(TRequest), cancellationToken);
|
||||
|
||||
// Save data to database with some retry policy in distributed transaction
|
||||
await _dbContextBase.RetryOnFailure(async () =>
|
||||
await dbContextBase.RetryOnFailure(async () =>
|
||||
{
|
||||
await _dbContextBase.SaveChangesAsync(cancellationToken);
|
||||
await dbContextBase.SaveChangesAsync(cancellationToken);
|
||||
});
|
||||
|
||||
// Save data to database with some retry policy in distributed transaction
|
||||
await _persistMessageDbContext.RetryOnFailure(async () =>
|
||||
await persistMessageDbContext.RetryOnFailure(async () =>
|
||||
{
|
||||
await _persistMessageDbContext.SaveChangesAsync(cancellationToken);
|
||||
await persistMessageDbContext.SaveChangesAsync(cancellationToken);
|
||||
});
|
||||
|
||||
scope.Complete();
|
||||
@ -89,4 +78,4 @@ public class EfTxBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TRe
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,67 +1,65 @@
|
||||
using System.Linq.Expressions;
|
||||
using BuildingBlocks.Core.Model;
|
||||
using BuildingBlocks.Web;
|
||||
using Humanizer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Query;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BuildingBlocks.EFCore;
|
||||
|
||||
using Ardalis.GuardClauses;
|
||||
using Humanizer;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static IServiceCollection AddCustomDbContext<TContext>(this IServiceCollection services)
|
||||
public static IServiceCollection AddCustomDbContext<TContext>(this WebApplicationBuilder builder, string? connectionName = "")
|
||||
where TContext : DbContext, IDbContext
|
||||
{
|
||||
AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true);
|
||||
|
||||
services.AddValidateOptions<PostgresOptions>();
|
||||
builder.Services.AddValidateOptions<PostgresOptions>();
|
||||
|
||||
services.AddDbContext<TContext>(
|
||||
builder.Services.AddDbContext<TContext>(
|
||||
(sp, options) =>
|
||||
{
|
||||
var postgresOptions = sp.GetRequiredService<PostgresOptions>();
|
||||
var aspireConnectionString = builder.Configuration.GetConnectionString(connectionName.Kebaberize());
|
||||
var connectionString = aspireConnectionString ?? sp.GetRequiredService<PostgresOptions>().ConnectionString;
|
||||
|
||||
Guard.Against.Null(options, nameof(postgresOptions));
|
||||
ArgumentException.ThrowIfNullOrEmpty(connectionString);
|
||||
|
||||
options.UseNpgsql(
|
||||
postgresOptions?.ConnectionString,
|
||||
connectionString,
|
||||
dbOptions =>
|
||||
{
|
||||
dbOptions.MigrationsAssembly(typeof(TContext).Assembly.GetName().Name);
|
||||
})
|
||||
// https://github.com/efcore/EFCore.NamingConventions
|
||||
.UseSnakeCaseNamingConvention();
|
||||
|
||||
// Suppress warnings for pending model changes
|
||||
options.ConfigureWarnings(
|
||||
w => w.Ignore(RelationalEventId.PendingModelChangesWarning));
|
||||
});
|
||||
|
||||
services.AddScoped<IDbContext>(provider => provider.GetService<TContext>());
|
||||
builder.Services.AddScoped<ISeedManager, SeedManager>();
|
||||
builder.Services.AddScoped<IDbContext>(sp => sp.GetRequiredService<TContext>());
|
||||
|
||||
return services;
|
||||
return builder.Services;
|
||||
}
|
||||
|
||||
public static IApplicationBuilder UseMigration<TContext>(
|
||||
this IApplicationBuilder app,
|
||||
IWebHostEnvironment env
|
||||
)
|
||||
|
||||
public static IApplicationBuilder UseMigration<TContext>(this IApplicationBuilder app)
|
||||
where TContext : DbContext, IDbContext
|
||||
{
|
||||
MigrateDatabaseAsync<TContext>(app.ApplicationServices).GetAwaiter().GetResult();
|
||||
MigrateAsync<TContext>(app.ApplicationServices).GetAwaiter().GetResult();
|
||||
|
||||
if (!env.IsEnvironment("test"))
|
||||
{
|
||||
SeedDataAsync(app.ApplicationServices).GetAwaiter().GetResult();
|
||||
}
|
||||
SeedAsync(app.ApplicationServices).GetAwaiter().GetResult();
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
|
||||
// ref: https://github.com/pdevito3/MessageBusTestingInMemHarness/blob/main/RecipeManagement/src/RecipeManagement/Databases/RecipesDbContext.cs
|
||||
public static void FilterSoftDeletedProperties(this ModelBuilder modelBuilder)
|
||||
{
|
||||
@ -114,23 +112,30 @@ public static class Extensions
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task MigrateDatabaseAsync<TContext>(IServiceProvider serviceProvider)
|
||||
private static async Task MigrateAsync<TContext>(IServiceProvider serviceProvider)
|
||||
where TContext : DbContext, IDbContext
|
||||
{
|
||||
using var scope = serviceProvider.CreateScope();
|
||||
|
||||
await using var scope = serviceProvider.CreateAsyncScope();
|
||||
var context = scope.ServiceProvider.GetRequiredService<TContext>();
|
||||
await context.Database.MigrateAsync();
|
||||
}
|
||||
var logger = scope.ServiceProvider.GetRequiredService<ILogger<TContext>>();
|
||||
|
||||
private static async Task SeedDataAsync(IServiceProvider serviceProvider)
|
||||
{
|
||||
using var scope = serviceProvider.CreateScope();
|
||||
var seeders = scope.ServiceProvider.GetServices<IDataSeeder>();
|
||||
var pendingMigrations = await context.Database.GetPendingMigrationsAsync();
|
||||
|
||||
foreach (var seeder in seeders)
|
||||
if (pendingMigrations.Any())
|
||||
{
|
||||
await seeder.SeedAllAsync();
|
||||
logger.LogInformation("Applying {Count} pending migrations...", pendingMigrations.Count());
|
||||
|
||||
await context.Database.MigrateAsync();
|
||||
logger.LogInformation("Migrations applied successfully.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task SeedAsync(IServiceProvider serviceProvider)
|
||||
{
|
||||
await using var scope = serviceProvider.CreateAsyncScope();
|
||||
|
||||
var seedersManager = scope.ServiceProvider.GetRequiredService<ISeedManager>();
|
||||
|
||||
await seedersManager.ExecuteSeedAsync();
|
||||
}
|
||||
}
|
||||
@ -4,4 +4,9 @@ namespace BuildingBlocks.EFCore
|
||||
{
|
||||
Task SeedAllAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public interface ITestDataSeeder
|
||||
{
|
||||
Task SeedAllAsync();
|
||||
}
|
||||
}
|
||||
@ -15,4 +15,4 @@ public interface IDbContext
|
||||
Task RollbackTransactionAsync(CancellationToken cancellationToken = default);
|
||||
IExecutionStrategy CreateExecutionStrategy();
|
||||
Task ExecuteTransactionalAsync(CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
7
src/BuildingBlocks/EFCore/ISeedManager.cs
Normal file
7
src/BuildingBlocks/EFCore/ISeedManager.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace BuildingBlocks.EFCore;
|
||||
|
||||
public interface ISeedManager
|
||||
{
|
||||
Task ExecuteSeedAsync();
|
||||
Task ExecuteTestSeedAsync();
|
||||
}
|
||||
@ -3,4 +3,4 @@ namespace BuildingBlocks.EFCore;
|
||||
public class PostgresOptions
|
||||
{
|
||||
public string ConnectionString { get; set; }
|
||||
}
|
||||
}
|
||||
42
src/BuildingBlocks/EFCore/SeedManagers.cs
Normal file
42
src/BuildingBlocks/EFCore/SeedManagers.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BuildingBlocks.EFCore;
|
||||
|
||||
public class SeedManager(
|
||||
ILogger<SeedManager> logger,
|
||||
IWebHostEnvironment env,
|
||||
IServiceProvider serviceProvider
|
||||
) : ISeedManager
|
||||
{
|
||||
public async Task ExecuteSeedAsync()
|
||||
{
|
||||
if (!env.IsEnvironment("test"))
|
||||
{
|
||||
await using var scope = serviceProvider.CreateAsyncScope();
|
||||
var dataSeeders = scope.ServiceProvider.GetServices<IDataSeeder>();
|
||||
|
||||
foreach (var seeder in dataSeeders)
|
||||
{
|
||||
logger.LogInformation("Seed {SeederName} is started.", seeder.GetType().Name);
|
||||
await seeder.SeedAllAsync();
|
||||
logger.LogInformation("Seed {SeederName} is completed.", seeder.GetType().Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ExecuteTestSeedAsync()
|
||||
{
|
||||
await using var scope = serviceProvider.CreateAsyncScope();
|
||||
var testDataSeeders = scope.ServiceProvider.GetServices<ITestDataSeeder>();
|
||||
|
||||
foreach (var testSeeder in testDataSeeders)
|
||||
{
|
||||
logger.LogInformation("Seed {SeederName} is started.", testSeeder.GetType().Name);
|
||||
await testSeeder.SeedAllAsync();
|
||||
logger.LogInformation("Seed {SeederName} is completed.", testSeeder.GetType().Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -25,4 +25,4 @@ public class BackgroundWorker : BackgroundService
|
||||
await perform(stoppingToken);
|
||||
logger.LogInformation("Background worker stopped");
|
||||
}, stoppingToken);
|
||||
}
|
||||
}
|
||||
@ -24,15 +24,16 @@ public record EventStoreDBOptions(
|
||||
|
||||
public static class EventStoreDBConfigExtensions
|
||||
{
|
||||
public static IServiceCollection AddEventStoreDB(this IServiceCollection services, IConfiguration config,
|
||||
public static IServiceCollection AddEventStoreDB(this IServiceCollection services, IConfiguration configuration,
|
||||
EventStoreDBOptions? options = null)
|
||||
{
|
||||
|
||||
services
|
||||
.AddSingleton(x =>
|
||||
{
|
||||
var aspireConnectionString = configuration.GetConnectionString("eventstore");
|
||||
var eventStoreOptions = services.GetOptions<EventStoreOptions>(nameof(EventStoreOptions));
|
||||
return new EventStoreClient(EventStoreClientSettings.Create(eventStoreOptions.ConnectionString));
|
||||
return new EventStoreClient(EventStoreClientSettings.Create(aspireConnectionString ?? eventStoreOptions.ConnectionString));
|
||||
})
|
||||
.AddScoped(typeof(IEventStoreDBRepository<>), typeof(EventStoreDBRepository<>))
|
||||
.AddTransient<EventStoreDBSubscriptionToAll, EventStoreDBSubscriptionToAll>();
|
||||
@ -89,4 +90,4 @@ public static class EventStoreDBConfigExtensions
|
||||
.AsImplementedInterfaces()
|
||||
.WithTransientLifetime());
|
||||
}
|
||||
}
|
||||
}
|
||||
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