Compare commits
417 Commits
migration/
...
dev
Author | SHA1 | Date | |
---|---|---|---|
|
47643eb2d0 | ||
|
7a5e502428 | ||
|
47d4d3cff6 | ||
|
becce91a7c | ||
|
06d5164532 | ||
|
67d4c06b6d | ||
|
508fa593d7 | ||
|
3b9560c26e | ||
|
c7c2d1ca2f | ||
|
5d13c097d3 | ||
|
42e161d1f9 | ||
|
fd76f390ef | ||
|
3169a93344 | ||
|
df4eb4c124 | ||
|
e4b94decb2 | ||
|
6f4ae509f1 | ||
|
dbef61fdaf | ||
|
6ebde3fb5c | ||
|
8f9f9d168f | ||
|
f5218e8087 | ||
|
72c8167ec0 | ||
|
8c9524c771 | ||
|
9c2b972cc9 | ||
|
3858d7ccf7 | ||
|
a87efdef32 | ||
|
52cdd1645a | ||
|
89a42e6c8f | ||
|
d5533c0ff9 | ||
|
8debda5c67 | ||
|
6ad5e8fb09 | ||
|
bdebee70dc | ||
|
184ed15ef6 | ||
|
af42aab95e | ||
|
6933d9997d | ||
|
992b58d4bc | ||
|
a7cdb1df68 | ||
|
0a07aea4ff | ||
|
8c2ca8dbd9 | ||
|
40315c69d7 | ||
|
62a6f17595 | ||
|
64a2d69e92 | ||
|
69476a3175 | ||
|
758d4bbe88 | ||
|
bd745121b2 | ||
|
84c6b11c69 | ||
|
561d48bc62 | ||
|
6a2fceb57c | ||
|
c3efea0293 | ||
|
30ed0011cb | ||
|
06d74d1658 | ||
|
50952bed10 | ||
|
f76a8c61db | ||
|
5a2d38575e | ||
|
670a9452e1 | ||
|
69b28c6add | ||
|
d0c710ebdc | ||
|
e1ec790ddf | ||
|
6b8992153a | ||
|
d086d278e8 | ||
|
3c00be38f9 | ||
|
031996d87c | ||
|
5ea034106c | ||
|
acd9a6d04b | ||
|
7027967568 | ||
|
e166b28a0a | ||
|
bcb1374d1e | ||
|
57d9baf106 | ||
|
a37b0430b2 | ||
|
2a4a6abf9b | ||
|
c41cd3830c | ||
|
0cb6b08300 | ||
|
9743c83221 | ||
|
6e69a2472e | ||
|
3357c70bc1 | ||
|
909f08675b | ||
|
a41560544c | ||
|
08e7c3424d | ||
|
7681405eaf | ||
|
ccaad9dc20 | ||
|
cf02e90aad | ||
|
5397e8d5c8 | ||
|
0fd20ee962 | ||
|
34fc9496fd | ||
|
a381a6923c | ||
|
3056418c92 | ||
|
917764273b | ||
|
e2d8590a26 | ||
|
f8abb36bc6 | ||
|
16b63001df | ||
|
83200f9331 | ||
|
fea08c78bb | ||
|
b9f48faf99 | ||
|
02c163246b | ||
|
da024f9812 | ||
|
8da0a81514 | ||
|
5342c86af0 | ||
|
3f5f0b94ed | ||
|
7d28625959 | ||
|
d96e4db08c | ||
|
c59e66861f | ||
|
56d47db91e | ||
|
b48ba7b74b | ||
|
41056e54d8 | ||
|
45a04e4a6d | ||
|
bff808016e | ||
|
48f640088b | ||
|
4e743ef666 | ||
|
366019aaa3 | ||
|
d4319bdd47 | ||
|
c565a8f799 | ||
|
794c546d2e | ||
|
f46b03cb36 | ||
|
d1372cba64 | ||
|
7da7e98a55 | ||
|
9d52426a49 | ||
|
57a93f63f0 | ||
|
8a40e9fb48 | ||
|
3fee612e68 | ||
|
00fc3d8a65 | ||
|
9af6d6342d | ||
|
e7e0eed9cc | ||
|
c7edd50b38 | ||
|
233b6e56c1 | ||
|
d4c2f17c36 | ||
|
746e5da7fa | ||
|
f3d2843166 | ||
|
91247ec52e | ||
|
d62ebcb791 | ||
|
109853983d | ||
|
d91da03665 | ||
|
746363bfd3 | ||
|
3ae0cefbcf | ||
|
451d79f7b9 | ||
|
9d38de0c83 | ||
|
65e2f13ca2 | ||
|
7e2a966dbf | ||
|
24858e50b7 | ||
|
52fb849b84 | ||
|
7d06508e22 | ||
|
ce5a165dd0 | ||
|
9a707ecaa1 | ||
|
9759596899 | ||
|
b9e585b2e4 | ||
|
ff78bb7577 | ||
|
212343f274 | ||
|
433419b583 | ||
|
c0cc12ad0c | ||
|
ee673d9180 | ||
|
e1fc28be8b | ||
|
fee79c40a4 | ||
|
c8f1e0f148 | ||
|
bb4307478c | ||
|
19217e0939 | ||
|
4a86d5e93f | ||
|
d6ea0cbdf5 | ||
|
e9351bfb2c | ||
|
0740fd42b1 | ||
|
88a9a49da4 | ||
|
390a37aca2 | ||
|
f92e02f3dd | ||
|
a0adc4bbf3 | ||
|
98635a3e93 | ||
|
3097651747 | ||
|
10a783c5b4 | ||
|
8552d3ada6 | ||
|
631a64940e | ||
|
0cbd7b24e8 | ||
|
a2c45956a3 | ||
|
dbee1dad6d | ||
|
7a6e07cb64 | ||
|
242cbeabaf | ||
|
e43cf8effa | ||
|
68d0df2e2f | ||
|
77ea8ef352 | ||
|
f7f4259147 | ||
|
049c4af196 | ||
|
85ad916fcb | ||
|
b5d9d9653d | ||
|
2c94c38269 | ||
|
faeebd3e2b | ||
|
fed2b179eb | ||
|
4f58e58d46 | ||
|
9c655ff9f0 | ||
|
c0d58305b3 | ||
|
2231774e70 | ||
|
8bd43a4db4 | ||
|
5ca9c997b7 | ||
|
a04b214705 | ||
|
5ccbce36b5 | ||
|
47f9559de0 | ||
|
d9d0bd2302 | ||
|
0fd7b932fc | ||
|
2a26c4be10 | ||
|
042d6ce621 | ||
|
286971e60c | ||
|
bb554c1706 | ||
|
7cf90e06fd | ||
|
98e7e53636 | ||
|
3e991acc50 | ||
|
fa9e955a2b | ||
|
50d945a395 | ||
|
ea54e4482f | ||
|
e3715d0213 | ||
|
678c80cf98 | ||
|
676d138962 | ||
|
dabdcac3bd | ||
|
9a914889fd | ||
|
ad8c8054fe | ||
|
4119fe06dc | ||
|
368952d432 | ||
|
72cf029258 | ||
|
e15a62270c | ||
|
79c4d06747 | ||
|
29241ec3d2 | ||
|
dd18f8df55 | ||
|
8bfb1bd06b | ||
|
0f2ade49fb | ||
|
9a5ea85223 | ||
|
365077a191 | ||
|
e4f2b62b5e | ||
|
a464a6996e | ||
|
6a00e8bb9b | ||
|
892da8b2c2 | ||
|
3a03508f8a | ||
|
b90d2d1cd4 | ||
|
c10fff488c | ||
|
9b3e00d756 | ||
|
b5b667b385 | ||
|
4596d7aa99 | ||
|
b8cc0d2cff | ||
|
2e7f6823ab | ||
|
c80ee1ea62 | ||
|
70a2548d8b | ||
|
2f2cf83167 | ||
|
74830148f5 | ||
|
911d7329b0 | ||
|
970f63cbe1 | ||
|
956f80a4ce | ||
|
2de2ddc041 | ||
|
390d737235 | ||
|
218759a5de | ||
|
e38abbfba8 | ||
|
ea24ac57bf | ||
|
8438a6a652 | ||
|
efb39deea2 | ||
|
7554b037e9 | ||
|
e8e6e24d6b | ||
|
a339e213ba | ||
|
4857831269 | ||
|
1807e952cf | ||
|
94c300b604 | ||
|
acac295afc | ||
|
ce50bb8a2f | ||
|
ea16ccbe9d | ||
|
e5abbd5f22 | ||
|
12ee00d660 | ||
|
e565a4ead4 | ||
|
d719444e61 | ||
|
8c1de99091 | ||
|
f14efba677 | ||
|
cdf073a53d | ||
|
fe1b9218e0 | ||
|
c863b143d7 | ||
|
6d26221979 | ||
|
d835809dc4 | ||
|
657584cbfe | ||
|
7b7f65e755 | ||
|
8c564a6edc | ||
|
d295ed4909 | ||
|
42f16acd9f | ||
|
37474024fa | ||
|
de90e6e198 | ||
|
3170b3e7ce | ||
|
9817c865f3 | ||
|
d5b5d6cca7 | ||
|
27445a34f3 | ||
|
f026de60cf | ||
|
7252faaff0 | ||
|
59805331cd | ||
|
dd7d2bc086 | ||
|
3af7133157 | ||
|
e9f53d2c69 | ||
|
e378d757a5 | ||
|
7f1c6c9c5d | ||
|
3f7a2faae8 | ||
|
8270b7e0bb | ||
|
303c958e43 | ||
|
981507dccb | ||
|
91c71528f6 | ||
|
5fd180a00d | ||
|
750d2db417 | ||
|
a24354bff2 | ||
|
9ee85f0d2c | ||
|
4458a096c9 | ||
|
4ecd27ccf6 | ||
|
231da1c10b | ||
|
2170f23bd1 | ||
|
4ac25bf58d | ||
|
548a0ecaf2 | ||
|
48dbb225d7 | ||
|
77c117e014 | ||
|
8ed7a0066f | ||
|
57bc496879 | ||
|
97550d5f19 | ||
|
4bdcbd4318 | ||
|
73cc967879 | ||
|
a254b1f8a9 | ||
|
a73c216858 | ||
|
59d10375f0 | ||
|
56233eb10e | ||
|
67b60b5368 | ||
|
05f7a3cc85 | ||
|
acb16cd454 | ||
|
074e91a5f8 | ||
|
9a67f0a3ab | ||
|
dc91064986 | ||
|
2685ed07d2 | ||
|
d141ee6aa2 | ||
|
c1cf5a1d84 | ||
|
3669a73651 | ||
|
79863be51e | ||
|
a8c7b746d1 | ||
|
967d009219 | ||
|
d7d288831b | ||
|
5270d3de35 | ||
|
5f17aec741 | ||
|
7185809ab8 | ||
|
5f649db4ae | ||
|
346bab2225 | ||
|
9e5cd835b4 | ||
|
145357de1e | ||
|
630cb35cfb | ||
|
42abcad37e | ||
|
e8611da6b6 | ||
|
99f15a13b2 | ||
|
c357aeac63 | ||
|
46219957ef | ||
|
2cf8fa7ce1 | ||
|
93383de096 | ||
|
8807359057 | ||
|
e57a97d515 | ||
|
464b8fc0fd | ||
|
71994d0ad8 | ||
|
9a9b8fbc6f | ||
|
86579613ec | ||
|
9e4ded9c61 | ||
|
2e1f327eea | ||
|
99ec828339 | ||
|
39f9c9cadb | ||
|
3cc9d320ed | ||
|
9a2e9ece04 | ||
|
3b05d5d2a3 | ||
|
3fbd8b4775 | ||
|
dc2edea974 | ||
|
9ca3262760 | ||
|
6d7d67577e | ||
|
20673ad72b | ||
|
144769722d | ||
|
2faec10388 | ||
|
a15e2957dc | ||
|
f3169ed424 | ||
|
ec3063c23f | ||
|
3c064df1db | ||
|
2169c690da | ||
|
4140b99534 | ||
|
df63d9ca9b | ||
|
3f0c46741a | ||
|
4d76ba42aa | ||
|
a98e65886f | ||
|
901847624d | ||
|
7a2f41aaf8 | ||
|
6ce3769d4c | ||
|
52829097ba | ||
|
9788f099f5 | ||
|
6326194680 | ||
|
134af2a755 | ||
|
adc6678b0e | ||
|
03a824fd90 | ||
|
3abc38acf4 | ||
|
e2d6b5ce5f | ||
|
4b08492a3e | ||
|
3082e72dc1 | ||
|
97061748ec | ||
|
d7f14447ed | ||
|
3e81555963 | ||
|
17637141c0 | ||
|
fd757f0af7 | ||
|
034cfdcda0 | ||
|
f43ebe53ee | ||
|
7b1174a66f | ||
|
fc85e345fd | ||
|
2059d9c2c7 | ||
|
7c30eb4f10 | ||
|
b7a07ae119 | ||
|
7fe4a9c490 | ||
|
613a45d7e0 | ||
|
e4107260db | ||
|
c52b4447a2 | ||
|
9984f2a9a5 | ||
|
0f1c179a5b | ||
|
33d9075a7a | ||
|
ba6f483061 | ||
|
dc1ac3a541 | ||
|
f0af8b9f3d | ||
|
93cfacde69 | ||
|
7d6c8f8f92 | ||
|
8c25f2028c | ||
|
2e8e335fdc | ||
|
a75d46fc26 | ||
|
a7394be2bc | ||
|
84bbd10d65 | ||
|
1c23986e8a | ||
|
31cd206e7a | ||
|
20183721fd | ||
|
d833251519 | ||
|
3a73cf22a2 | ||
|
8676343f66 |
132
.editorconfig
Normal file
132
.editorconfig
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
###############################
|
||||||
|
# Core EditorConfig Options #
|
||||||
|
###############################
|
||||||
|
root = true
|
||||||
|
# All files
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
# XML project files
|
||||||
|
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# XML config files
|
||||||
|
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
# Code files
|
||||||
|
[*.{cs,csx,vb,vbx}]
|
||||||
|
indent_size = 4
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8-bom
|
||||||
|
###############################
|
||||||
|
# .NET Coding Conventions #
|
||||||
|
###############################
|
||||||
|
[*.{cs,vb}]
|
||||||
|
# Organize usings
|
||||||
|
dotnet_sort_system_directives_first = true
|
||||||
|
# this. preferences
|
||||||
|
dotnet_style_qualification_for_field = false:silent
|
||||||
|
dotnet_style_qualification_for_property = false:silent
|
||||||
|
dotnet_style_qualification_for_method = false:silent
|
||||||
|
dotnet_style_qualification_for_event = 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_relational_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
|
||||||
|
# Modifier preferences
|
||||||
|
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
|
||||||
|
dotnet_style_readonly_field = true:suggestion
|
||||||
|
# Expression-level preferences
|
||||||
|
dotnet_style_object_initializer = true:suggestion
|
||||||
|
dotnet_style_collection_initializer = true:suggestion
|
||||||
|
dotnet_style_explicit_tuple_names = true:suggestion
|
||||||
|
dotnet_style_null_propagation = true:suggestion
|
||||||
|
dotnet_style_coalesce_expression = true:suggestion
|
||||||
|
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent
|
||||||
|
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||||
|
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||||
|
dotnet_style_prefer_auto_properties = true:silent
|
||||||
|
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
|
||||||
|
dotnet_style_prefer_conditional_expression_over_return = true:silent
|
||||||
|
###############################
|
||||||
|
# Naming Conventions #
|
||||||
|
###############################
|
||||||
|
# Style Definitions
|
||||||
|
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
|
||||||
|
# Use PascalCase for constant fields
|
||||||
|
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.applicable_accessibilities = *
|
||||||
|
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||||
|
###############################
|
||||||
|
# C# Coding Conventions #
|
||||||
|
###############################
|
||||||
|
[*.cs]
|
||||||
|
# var preferences
|
||||||
|
csharp_style_var_for_built_in_types = true:silent
|
||||||
|
csharp_style_var_when_type_is_apparent = true:silent
|
||||||
|
csharp_style_var_elsewhere = true:silent
|
||||||
|
# Expression-bodied members
|
||||||
|
csharp_style_expression_bodied_methods = false:silent
|
||||||
|
csharp_style_expression_bodied_constructors = false:silent
|
||||||
|
csharp_style_expression_bodied_operators = false:silent
|
||||||
|
csharp_style_expression_bodied_properties = true:silent
|
||||||
|
csharp_style_expression_bodied_indexers = true:silent
|
||||||
|
csharp_style_expression_bodied_accessors = true:silent
|
||||||
|
# Pattern matching preferences
|
||||||
|
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||||
|
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||||
|
# Null-checking preferences
|
||||||
|
csharp_style_throw_expression = true:suggestion
|
||||||
|
csharp_style_conditional_delegate_call = true:suggestion
|
||||||
|
# Modifier preferences
|
||||||
|
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||||
|
# Expression-level preferences
|
||||||
|
csharp_prefer_braces = true:silent
|
||||||
|
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||||
|
csharp_prefer_simple_default_expression = true:suggestion
|
||||||
|
csharp_style_prefer_local_over_anonymous_function = true:suggestion
|
||||||
|
csharp_style_inlined_variable_declaration = true:suggestion
|
||||||
|
###############################
|
||||||
|
# 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_finally = true
|
||||||
|
csharp_new_line_before_members_in_object_initializers = true
|
||||||
|
csharp_new_line_before_members_in_anonymous_types = true
|
||||||
|
csharp_new_line_between_query_expression_clauses = true
|
||||||
|
# Indentation preferences
|
||||||
|
csharp_indent_case_contents = true
|
||||||
|
csharp_indent_switch_labels = true
|
||||||
|
csharp_indent_labels = flush_left
|
||||||
|
# Space preferences
|
||||||
|
csharp_space_after_cast = false
|
||||||
|
csharp_space_after_keywords_in_control_flow_statements = true
|
||||||
|
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_parentheses = false
|
||||||
|
csharp_space_before_colon_in_inheritance_clause = true
|
||||||
|
csharp_space_after_colon_in_inheritance_clause = true
|
||||||
|
csharp_space_around_binary_operators = before_and_after
|
||||||
|
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||||
|
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||||
|
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||||
|
# Wrapping preferences
|
||||||
|
csharp_preserve_single_line_statements = true
|
||||||
|
csharp_preserve_single_line_blocks = true
|
||||||
|
###############################
|
||||||
|
# VB Coding Conventions #
|
||||||
|
###############################
|
||||||
|
[*.vb]
|
||||||
|
# Modifier preferences
|
||||||
|
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion
|
31
.github/workflows/basket-api-deploy.yml
vendored
31
.github/workflows/basket-api-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
102
.github/workflows/basket-api.yml
vendored
102
.github/workflows/basket-api.yml
vendored
@ -22,7 +22,6 @@ on:
|
|||||||
env:
|
env:
|
||||||
SERVICE: basket-api
|
SERVICE: basket-api
|
||||||
IMAGE: basket.api
|
IMAGE: basket.api
|
||||||
DOTNET_VERSION: 5.0.x
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@ -30,97 +29,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Setup dotnet
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
service: ${{ env.SERVICE }}
|
||||||
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
- name: Build and run unit tests
|
|
||||||
run: |
|
|
||||||
cd src
|
|
||||||
dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
|
||||||
cd Services/Basket/Basket.API
|
|
||||||
dotnet build --no-restore
|
|
||||||
cd -
|
|
||||||
cd Services/Basket/Basket.UnitTests
|
|
||||||
dotnet build --no-restore
|
|
||||||
dotnet test --no-build -v=normal
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Setup dotnet
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
service: ${{ env.SERVICE }}
|
||||||
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
- name: Build and run unit tests
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
run: |
|
image_name: ${{ env.IMAGE }}
|
||||||
cd src
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
cd Services/Basket/Basket.API
|
|
||||||
dotnet build --no-restore
|
|
||||||
cd -
|
|
||||||
cd Services/Basket/Basket.UnitTests
|
|
||||||
dotnet build --no-restore
|
|
||||||
dotnet test --no-build -v=normal
|
|
||||||
|
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
|
||||||
username: ${{ secrets.USERNAME }}
|
|
||||||
password: ${{ secrets.PASSWORD }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/catalog-api-deploy.yml
vendored
31
.github/workflows/catalog-api-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
108
.github/workflows/catalog-api.yml
vendored
108
.github/workflows/catalog-api.yml
vendored
@ -22,7 +22,9 @@ on:
|
|||||||
env:
|
env:
|
||||||
SERVICE: catalog-api
|
SERVICE: catalog-api
|
||||||
IMAGE: catalog.api
|
IMAGE: catalog.api
|
||||||
DOTNET_VERSION: 5.0.x
|
DOTNET_VERSION: 7.0.x
|
||||||
|
PROJECT_PATH: Services/Catalog/Catalog.API
|
||||||
|
TESTS_PATH: Services/Catalog/Catalog.UnitTests
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@ -30,97 +32,27 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-test
|
||||||
- name: Setup dotnet
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
service: ${{ env.SERVICE }}
|
||||||
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
- name: Build and run unit tests
|
dotnet_version: ${{ env.DOTNET_VERSION }}
|
||||||
run: |
|
project_path: ${{ env.PROJECT_PATH }}
|
||||||
cd src
|
tests_path: ${{ env.TESTS_PATH }}
|
||||||
dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
|
||||||
cd Services/Catalog/Catalog.API
|
|
||||||
dotnet build --no-restore
|
|
||||||
cd -
|
|
||||||
cd Services/Catalog/Catalog.UnitTests
|
|
||||||
dotnet build --no-restore
|
|
||||||
dotnet test --no-build -v=normal
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Setup dotnet
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
service: ${{ env.SERVICE }}
|
||||||
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
- name: Build and run unit tests
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
run: |
|
image_name: ${{ env.IMAGE }}
|
||||||
cd src
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
cd Services/Catalog/Catalog.API
|
|
||||||
dotnet build --no-restore
|
|
||||||
cd -
|
|
||||||
cd Services/Catalog/Catalog.UnitTests
|
|
||||||
dotnet build --no-restore
|
|
||||||
dotnet test --no-build -v=normal
|
|
||||||
|
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
|
||||||
username: ${{ secrets.USERNAME }}
|
|
||||||
password: ${{ secrets.PASSWORD }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
71
.github/workflows/composite/build-push/action.yml
vendored
Normal file
71
.github/workflows/composite/build-push/action.yml
vendored
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
name: "Build and push image"
|
||||||
|
description: "Builds and pushes an image to a registry"
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
service:
|
||||||
|
description: "Service to build"
|
||||||
|
required: true
|
||||||
|
registry_host:
|
||||||
|
description: "Image registry host e.g. myacr.azureacr.io"
|
||||||
|
required: true
|
||||||
|
registry_endpoint:
|
||||||
|
description: "Image registry repo e.g. myacr.azureacr.io/eshop"
|
||||||
|
required: true
|
||||||
|
image_name:
|
||||||
|
description: "Name of image"
|
||||||
|
required: true
|
||||||
|
registry_username:
|
||||||
|
description: "Registry username"
|
||||||
|
required: true
|
||||||
|
registry_password:
|
||||||
|
description: "Registry password"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Enable experimental features for the Docker daemon and CLI
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
||||||
|
mkdir -p ~/.docker
|
||||||
|
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
||||||
|
sudo service docker restart
|
||||||
|
docker version -f '{{.Client.Experimental}}'
|
||||||
|
docker version -f '{{.Server.Experimental}}'
|
||||||
|
|
||||||
|
- name: Login to Container Registry
|
||||||
|
uses: docker/login-action@v1
|
||||||
|
with:
|
||||||
|
registry: ${{ inputs.registry_host }}
|
||||||
|
username: ${{ inputs.registry_username }}
|
||||||
|
password: ${{ inputs.registry_password }}
|
||||||
|
|
||||||
|
- name: Set branch name as env variable
|
||||||
|
run: |
|
||||||
|
currentbranch=$(echo ${GITHUB_REF##*/})
|
||||||
|
echo "running on $currentbranch"
|
||||||
|
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Compose build ${{ inputs.service }}
|
||||||
|
shell: bash
|
||||||
|
run: sudo -E docker-compose build ${{ inputs.service }}
|
||||||
|
working-directory: ./src
|
||||||
|
env:
|
||||||
|
TAG: ${{ env.BRANCH }}
|
||||||
|
REGISTRY: ${{ inputs.registry_endpoint }}
|
||||||
|
|
||||||
|
- name: Compose push ${{ inputs.service }}
|
||||||
|
shell: bash
|
||||||
|
run: sudo -E docker-compose push ${{ inputs.service }}
|
||||||
|
working-directory: ./src
|
||||||
|
env:
|
||||||
|
TAG: ${{ env.BRANCH }}
|
||||||
|
REGISTRY: ${{ inputs.registry_endpoint }}
|
||||||
|
|
||||||
|
- name: Create multiarch manifest
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
docker --config ~/.docker manifest create ${{ inputs.registry_endpoint }}/${{ inputs.image_name }}:${{ env.BRANCH }} ${{ inputs.registry_endpoint }}/${{ inputs.image_name }}:linux-${{ env.BRANCH }}
|
||||||
|
docker --config ~/.docker manifest push ${{ inputs.registry_endpoint }}/${{ inputs.image_name }}:${{ env.BRANCH }}
|
47
.github/workflows/composite/build-test/action.yml
vendored
Normal file
47
.github/workflows/composite/build-test/action.yml
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
name: "Build for PRe"
|
||||||
|
description: "Builds a docker image without pushing"
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
service:
|
||||||
|
description: "Service to build"
|
||||||
|
required: true
|
||||||
|
registry_endpoint:
|
||||||
|
description: "Image registry repo e.g. myacr.azureacr.io/eshop"
|
||||||
|
required: true
|
||||||
|
dotnet_version:
|
||||||
|
description: "Version of dotnet to use for testing"
|
||||||
|
required: true
|
||||||
|
project_path:
|
||||||
|
description: "Path to project to test e.g. Services/Catalog/Catalog.API"
|
||||||
|
required: true
|
||||||
|
tests_path:
|
||||||
|
description: "Path to test project e.g. Services/Catalog/Catalog.UnitTests"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Setup dotnet
|
||||||
|
uses: actions/setup-dotnet@v1
|
||||||
|
with:
|
||||||
|
dotnet-version: ${{ inputs.dotnet_version }}
|
||||||
|
|
||||||
|
- name: Build and run unit tests
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
cd src
|
||||||
|
dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
||||||
|
cd ${{ inputs.project_path }}
|
||||||
|
dotnet build --no-restore
|
||||||
|
cd -
|
||||||
|
cd ${{ inputs.tests_path }}
|
||||||
|
dotnet build --no-restore
|
||||||
|
dotnet test --no-build -v=normal
|
||||||
|
|
||||||
|
- name: Compose build ${{ inputs.service }}
|
||||||
|
shell: bash
|
||||||
|
run: sudo -E docker-compose build ${{ inputs.service }}
|
||||||
|
working-directory: ./src
|
||||||
|
env:
|
||||||
|
TAG: ${{ env.BRANCH }}
|
||||||
|
REGISTRY: ${{ inputs.registry_endpoint }}
|
21
.github/workflows/composite/build/action.yml
vendored
Normal file
21
.github/workflows/composite/build/action.yml
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
name: "Build for PRe"
|
||||||
|
description: "Builds a docker image without pushing"
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
service:
|
||||||
|
description: "Service to build"
|
||||||
|
required: true
|
||||||
|
registry_endpoint:
|
||||||
|
description: "Image registry repo e.g. myacr.azureacr.io/eshop"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Compose build ${{ inputs.service }}
|
||||||
|
shell: bash
|
||||||
|
run: sudo -E docker-compose build ${{ inputs.service }}
|
||||||
|
working-directory: ./src
|
||||||
|
env:
|
||||||
|
TAG: ${{ env.BRANCH }}
|
||||||
|
REGISTRY: ${{ inputs.registry_endpoint }}
|
54
.github/workflows/composite/deploy-helm/action.yml
vendored
Normal file
54
.github/workflows/composite/deploy-helm/action.yml
vendored
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
name: "Deploy Helm to AKS"
|
||||||
|
description: "Deploys a helm chart to AKS"
|
||||||
|
|
||||||
|
inputs:
|
||||||
|
azure_credentials:
|
||||||
|
description: "Credentials to connect to AKS"
|
||||||
|
required: true
|
||||||
|
cluster_name:
|
||||||
|
description: "Name of AKS cluster"
|
||||||
|
required: true
|
||||||
|
resource_group:
|
||||||
|
description: "Resource group of AKS cluster"
|
||||||
|
required: true
|
||||||
|
registry_host:
|
||||||
|
description: "Image registry host e.g. myacr.azureacr.io"
|
||||||
|
required: true
|
||||||
|
chart:
|
||||||
|
description: "Chart name"
|
||||||
|
required: true
|
||||||
|
chart_root:
|
||||||
|
description: "Root folder of chart"
|
||||||
|
required: true
|
||||||
|
namespace:
|
||||||
|
description: "Namespace to deploy to"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- uses: azure/login@v1
|
||||||
|
with:
|
||||||
|
creds: ${{ inputs.azure_credentials }}
|
||||||
|
|
||||||
|
- uses: azure/aks-set-context@v1
|
||||||
|
name: Set AKS context
|
||||||
|
with:
|
||||||
|
creds: '${{ inputs.azure_credentials }}'
|
||||||
|
cluster-name: ${{ inputs.cluster_name }}
|
||||||
|
resource-group: ${{ inputs.resource_group }}
|
||||||
|
|
||||||
|
- name: Set branch name as env variable
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
currentbranch=$(echo ${GITHUB_REF##*/})
|
||||||
|
echo "running on $currentbranch"
|
||||||
|
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Deploy Chart
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
./deploy-chart.sh -c ${{ inputs.chart }} --dns aks --aks-name ${{ inputs.clusteR_name }} --aks-rg ${{ inputs.resource_group }} -r ${{ inputs.registry_host }} -t $TAG --namespace ${{ inputs.namespace }} --acr-connected
|
||||||
|
env:
|
||||||
|
TAG: ${{ env.BRANCH }}
|
||||||
|
working-directory: ${{ inputs.chart_root }}
|
31
.github/workflows/identity-api-deploy.yml
vendored
31
.github/workflows/identity-api-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/identity-api.yml
vendored
72
.github/workflows/identity-api.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: identity-api
|
name: identity-api
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -28,65 +29,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/mobileshoppingagg-deploy.yml
vendored
31
.github/workflows/mobileshoppingagg-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/mobileshoppingagg.yml
vendored
72
.github/workflows/mobileshoppingagg.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: mobileshoppingagg
|
name: mobileshoppingagg
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -26,65 +27,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/ordering-api-deploy.yml
vendored
31
.github/workflows/ordering-api-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
108
.github/workflows/ordering-api.yml
vendored
108
.github/workflows/ordering-api.yml
vendored
@ -22,7 +22,9 @@ on:
|
|||||||
env:
|
env:
|
||||||
SERVICE: ordering-api
|
SERVICE: ordering-api
|
||||||
IMAGE: ordering.api
|
IMAGE: ordering.api
|
||||||
DOTNET_VERSION: 5.0.x
|
DOTNET_VERSION: 7.0.x
|
||||||
|
PROJECT_PATH: Services/Ordering/Ordering.API
|
||||||
|
TESTS_PATH: Services/Ordering/Ordering.UnitTests
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
@ -30,97 +32,27 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-test
|
||||||
- name: Setup dotnet
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
service: ${{ env.SERVICE }}
|
||||||
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
- name: Build and run unit tests
|
dotnet_version: ${{ env.DOTNET_VERSION }}
|
||||||
run: |
|
project_path: ${{ env.PROJECT_PATH }}
|
||||||
cd src
|
tests_path: ${{ env.TESTS_PATH }}
|
||||||
dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
|
||||||
cd Services/Ordering/Ordering.API
|
|
||||||
dotnet build --no-restore
|
|
||||||
cd -
|
|
||||||
cd Services/Ordering/Ordering.UnitTests
|
|
||||||
dotnet build --no-restore
|
|
||||||
dotnet test --no-build -v=normal
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Setup dotnet
|
|
||||||
uses: actions/setup-dotnet@v1
|
|
||||||
with:
|
with:
|
||||||
dotnet-version: ${{ env.DOTNET_VERSION }}
|
service: ${{ env.SERVICE }}
|
||||||
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
- name: Build and run unit tests
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
run: |
|
image_name: ${{ env.IMAGE }}
|
||||||
cd src
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
cd Services/Ordering/Ordering.API
|
|
||||||
dotnet build --no-restore
|
|
||||||
cd -
|
|
||||||
cd Services/Ordering/Ordering.UnitTests
|
|
||||||
dotnet build --no-restore
|
|
||||||
dotnet test --no-build -v=normal
|
|
||||||
|
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
|
||||||
username: ${{ secrets.USERNAME }}
|
|
||||||
password: ${{ secrets.PASSWORD }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/ordering-backgroundtasks.yml
vendored
72
.github/workflows/ordering-backgroundtasks.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: ordering-backgroundtasks
|
name: ordering-backgroundtasks
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -28,65 +29,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/ordering-signalrhub-deploy.yml
vendored
31
.github/workflows/ordering-signalrhub-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/ordering-signalrhub.yml
vendored
72
.github/workflows/ordering-signalrhub.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: ordering-signalrhub
|
name: ordering-signalrhub
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -28,65 +29,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/payment-api-deploy.yml
vendored
31
.github/workflows/payment-api-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/payment-api.yml
vendored
72
.github/workflows/payment-api.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: payment-api
|
name: payment-api
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -28,65 +29,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/webhooks-api-deploy.yml
vendored
31
.github/workflows/webhooks-api-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/webhooks-api.yml
vendored
72
.github/workflows/webhooks-api.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: webhooks-api
|
name: webhooks-api
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -28,65 +29,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
72
.github/workflows/webhooks-client.yml
vendored
72
.github/workflows/webhooks-client.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: webhooks-client
|
name: webhooks-client
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -28,65 +29,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
27
.github/workflows/webmvc-deploy.yml
vendored
27
.github/workflows/webmvc-deploy.yml
vendored
@ -28,23 +28,12 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
|
||||||
- uses: azure/aks-set-context@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
name: Set AKS context
|
|
||||||
with:
|
with:
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
- name: Set branch name as env variable
|
chart: ${{ env.CHART }}
|
||||||
run: |
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
namespace: ${{ env.NAMESPACE }}
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/webmvc.yml
vendored
72
.github/workflows/webmvc.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: webmvc
|
name: webmvc
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -29,65 +30,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/webshoppingagg-deploy.yml
vendored
31
.github/workflows/webshoppingagg-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/webshoppingagg.yml
vendored
72
.github/workflows/webshoppingagg.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: webshoppingagg
|
name: webshoppingagg
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -26,65 +27,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/webspa-deploy.yml
vendored
31
.github/workflows/webspa-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/webspa.yml
vendored
72
.github/workflows/webspa.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: webspa
|
name: webspa
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -28,65 +29,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
31
.github/workflows/webstatus-deploy.yml
vendored
31
.github/workflows/webstatus-deploy.yml
vendored
@ -24,27 +24,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
|
|
||||||
- uses: azure/login@v1
|
- uses: ./.github/workflows/composite/deploy-helm
|
||||||
with:
|
with:
|
||||||
creds: ${{ secrets.AZURE_CREDENTIALS }}
|
azure_credentials: ${{ secrets.AZURE_CREDENTIALS }}
|
||||||
|
cluster_name: ${{ secrets.CLUSTER_NAME }}
|
||||||
- uses: azure/aks-set-context@v1
|
resource_group: ${{ secrets.RESOURCE_GROUP }}
|
||||||
name: Set AKS context
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
with:
|
chart: ${{ env.CHART }}
|
||||||
creds: '${{ secrets.AZURE_CREDENTIALS }}'
|
chart_root: ${{ env.CHART_ROOT }}
|
||||||
cluster-name: ${{ secrets.CLUSTER_NAME }}
|
namespace: ${{ env.NAMESPACE }}
|
||||||
resource-group: ${{ secrets.RESOURCE_GROUP }}
|
|
||||||
|
|
||||||
- name: Set branch name as env variable
|
|
||||||
run: |
|
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Deploy Chart
|
|
||||||
run: |
|
|
||||||
./deploy-chart.sh -c ${{ env.CHART }} --dns aks --aks-name ${{ secrets.CLUSTER_NAME }} --aks-rg ${{ secrets.RESOURCE_GROUP }} -r ${{ secrets.REGISTRY_HOST }} -t $TAG --namespace ${{ env.NAMESPACE }} --acr-connected
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
working-directory: ${{ env.CHART_ROOT }}
|
|
||||||
|
72
.github/workflows/webstatus.yml
vendored
72
.github/workflows/webstatus.yml
vendored
@ -1,6 +1,7 @@
|
|||||||
name: webstatus
|
name: webstatus
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -29,65 +30,24 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
with:
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
service: ${{ env.SERVICE }}
|
||||||
working-directory: ./src
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
BuildLinux:
|
BuildLinux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
steps:
|
steps:
|
||||||
- name: 'Checkout Github Action'
|
- name: Checkout code
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@v2
|
||||||
|
- uses: ./.github/workflows/composite/build-push
|
||||||
- name: Enable experimental features for the Docker daemon and CLI
|
|
||||||
run: |
|
|
||||||
echo $'{\n "experimental": true\n}' | sudo tee /etc/docker/daemon.json
|
|
||||||
mkdir -p ~/.docker
|
|
||||||
echo $'{\n "experimental": "enabled"\n}' | sudo tee ~/.docker/config.json
|
|
||||||
sudo service docker restart
|
|
||||||
docker version -f '{{.Client.Experimental}}'
|
|
||||||
docker version -f '{{.Server.Experimental}}'
|
|
||||||
|
|
||||||
- name: Login to Container Registry
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
registry: ${{ secrets.REGISTRY_HOST }}
|
service: ${{ env.SERVICE }}
|
||||||
username: ${{ secrets.USERNAME }}
|
registry_host: ${{ secrets.REGISTRY_HOST }}
|
||||||
password: ${{ secrets.PASSWORD }}
|
registry_endpoint: ${{ secrets.REGISTRY_ENDPOINT }}
|
||||||
|
image_name: ${{ env.IMAGE }}
|
||||||
- name: Set branch name as env variable
|
registry_username: ${{ secrets.USERNAME }}
|
||||||
run: |
|
registry_password: ${{ secrets.PASSWORD }}
|
||||||
currentbranch=$(echo ${GITHUB_REF##*/})
|
|
||||||
echo "running on $currentbranch"
|
|
||||||
echo "BRANCH=$currentbranch" >> $GITHUB_ENV
|
|
||||||
shell: bash
|
|
||||||
|
|
||||||
- name: Compose build ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose build ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Compose push ${{ env.SERVICE }}
|
|
||||||
run: sudo -E docker-compose push ${{ env.SERVICE }}
|
|
||||||
working-directory: ./src
|
|
||||||
shell: bash
|
|
||||||
env:
|
|
||||||
TAG: ${{ env.BRANCH }}
|
|
||||||
REGISTRY: ${{ secrets.REGISTRY_ENDPOINT }}
|
|
||||||
|
|
||||||
- name: Create multiarch manifest
|
|
||||||
run: |
|
|
||||||
docker --config ~/.docker manifest create ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }} ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:linux-${{ env.BRANCH }}
|
|
||||||
docker --config ~/.docker manifest push ${{ secrets.REGISTRY_ENDPOINT }}/${{ env.IMAGE }}:${{ env.BRANCH }}
|
|
||||||
shell: bash
|
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -281,3 +281,5 @@ pub/
|
|||||||
src/**/app.yaml
|
src/**/app.yaml
|
||||||
src/**/inf.yaml
|
src/**/inf.yaml
|
||||||
|
|
||||||
|
.angular/
|
||||||
|
/src/Services/Identity/Identity.API/keys/*.json
|
||||||
|
@ -47,7 +47,7 @@ All contributions must be submitted as a [Pull Request (PR)](https://help.github
|
|||||||
The main branches are **`dev`** and **`master`**:
|
The main branches are **`dev`** and **`master`**:
|
||||||
|
|
||||||
- **`dev`**: Contains the latest code **and it is the branch actively developed**.
|
- **`dev`**: Contains the latest code **and it is the branch actively developed**.
|
||||||
**All PRs must be against `dev` branch to be considered**. This branch is developed using `.NET 5`
|
**All PRs must be against `dev` branch to be considered**. This branch is developed using `.NET 7`
|
||||||
|
|
||||||
- **`main`**: Synced from time to time from **`dev`**. It contains "stable" code.This branch contains changes specific to `.NET Core 3.1` (**Keep in mind "stable" does not mean PRODUCTION-READY!**)
|
- **`main`**: Synced from time to time from **`dev`**. It contains "stable" code.This branch contains changes specific to `.NET Core 3.1` (**Keep in mind "stable" does not mean PRODUCTION-READY!**)
|
||||||
|
|
||||||
|
20
README.md
20
README.md
@ -56,25 +56,25 @@ The basic scenario can be run locally using docker-compose, and also deployed to
|
|||||||
|
|
||||||
### Advanced scenario
|
### Advanced scenario
|
||||||
|
|
||||||
The Advanced scenario can be run only in a Kubernetes cluster. Currently this scenario is the same as a basic scenario with the following differences:
|
The Advanced scenario can be run only in a Kubernetes cluster. Currently, this scenario is the same as a basic scenario with the following differences:
|
||||||
|
|
||||||
- [Deploy to AKS with a Service Mesh for resiliency](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Deploy-to-Azure-Kubernetes-Service-(AKS))
|
- [Deploy to AKS with a Service Mesh for resiliency](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Deploy-to-Azure-Kubernetes-Service-(AKS))
|
||||||
|
|
||||||
In the future more features will be implemented in the advanced scenario.
|
In the future, more features will be implemented in the advanced scenario.
|
||||||
|
|
||||||
|
|
||||||
## IMPORTANT NOTES!
|
## IMPORTANT NOTES!
|
||||||
|
|
||||||
**You can use either the latest version of Visual Studio or simply Docker CLI and .NET CLI for Windows, Mac and Linux**.
|
**You can use either the latest version of Visual Studio or simply Docker CLI and .NET CLI for Windows, Mac, and Linux**.
|
||||||
|
|
||||||
**Note for Pull Requests (PRs)**: We accept pull request from the community. When doing it, please do it onto the **DEV branch** which is the consolidated work-in-progress branch. Do not request it onto **master** branch.
|
**Note for Pull Requests (PRs)**: We accept pull requests from the community. When doing it, please do it onto the **DEV branch** which is the consolidated work-in-progress branch. Do not request it onto **main** branch.
|
||||||
|
|
||||||
**NEWS / ANNOUNCEMENTS**
|
**NEWS / ANNOUNCEMENTS**
|
||||||
Do you want to be up-to-date on .NET Architecture guidance and reference apps like eShopOnContainers? --> Subscribe by "WATCHING" this new GitHub repo: https://github.com/dotnet-architecture/News
|
Do you want to be up-to-date on .NET Architecture guidance and reference apps like eShopOnContainers? --> Subscribe by "WATCHING" this new GitHub repo: https://github.com/dotnet-architecture/News
|
||||||
|
|
||||||
## Updated for .NET 5
|
## Updated for .NET 7
|
||||||
|
|
||||||
eShopOnContainers is updated to .NET 5 "wave" of technologies. Not just compilation but also new recommended code in EF Core, ASP.NET Core, and other new related versions with several significant changes.
|
eShopOnContainers is updated to .NET 7 "wave" of technologies. Not just compilation but also new recommended code in EF Core, ASP.NET Core, and other new related versions with several significant changes.
|
||||||
|
|
||||||
**See more details in the [Release notes](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Release-notes) wiki page**.
|
**See more details in the [Release notes](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Release-notes) wiki page**.
|
||||||
|
|
||||||
@ -86,15 +86,15 @@ eShopOnContainers is updated to .NET 5 "wave" of technologies. Not just compilat
|
|||||||
|
|
||||||
### Architecture overview
|
### Architecture overview
|
||||||
|
|
||||||
This reference application is cross-platform at the server and client side, thanks to .NET 5 services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS or Windows/UWP plus any browser for the client web apps.
|
This reference application is cross-platform at the server and client-side, thanks to .NET 7 services capable of running on Linux or Windows containers depending on your Docker host, and to Xamarin for mobile apps running on Android, iOS, or Windows/UWP plus any browser for the client web apps.
|
||||||
The architecture proposes a microservice oriented architecture implementation with multiple autonomous microservices (each one owning its own data/db) and implementing different approaches within each microservice (simple CRUD vs. DDD/CQRS patterns) using Http as the communication protocol between the client apps and the microservices and supports asynchronous communication for data updates propagation across multiple services based on Integration Events and an Event Bus (a light message broker, to choose between RabbitMQ or Azure Service Bus, underneath) plus other features defined at the [roadmap](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Roadmap).
|
The architecture proposes a microservice oriented architecture implementation with multiple autonomous microservices (each one owning its own data/db) and implementing different approaches within each microservice (simple CRUD vs. DDD/CQRS patterns) using HTTP as the communication protocol between the client apps and the microservices and supports asynchronous communication for data updates propagation across multiple services based on Integration Events and an Event Bus (a light message broker, to choose between RabbitMQ or Azure Service Bus, underneath) plus other features defined at the [roadmap](https://github.com/dotnet-architecture/eShopOnContainers/wiki/Roadmap).
|
||||||
|
|
||||||

|

|
||||||

|

|
||||||
|
|
||||||
## Related documentation and guidance
|
## Related documentation and guidance
|
||||||
|
|
||||||
You can find the related reference **Guide/eBook** focusing on **architecting and developing containerized and microservice based .NET Applications** (download link available below) which explains in detail how to develop this kind of architectural style (microservices, Docker containers, Domain-Driven Design for certain microservices) plus other simpler architectural styles, like monolithic apps that can also live as Docker containers.
|
You can find the related reference **Guide/eBook** focusing on **architecting and developing containerized and microservice-based .NET Applications** (download link available below) which explains in detail how to develop this kind of architectural style (microservices, Docker containers, Domain-Driven Design for certain microservices) plus other simpler architectural styles, like monolithic apps that can also live as Docker containers.
|
||||||
|
|
||||||
There are also additional eBooks focusing on Containers/Docker lifecycle (DevOps, CI/CD, etc.) with Microsoft Tools, already published plus an additional eBook focusing on Enterprise Apps Patterns with Xamarin.Forms.
|
There are also additional eBooks focusing on Containers/Docker lifecycle (DevOps, CI/CD, etc.) with Microsoft Tools, already published plus an additional eBook focusing on Enterprise Apps Patterns with Xamarin.Forms.
|
||||||
You can download them and start reviewing these Guides/eBooks here:
|
You can download them and start reviewing these Guides/eBooks here:
|
||||||
@ -107,7 +107,7 @@ You can download them and start reviewing these Guides/eBooks here:
|
|||||||
For more free e-Books check out [.NET Architecture center](https://dot.net/architecture). If you have an e-book feedback, let us know by creating a new issue here: <https://github.com/dotnet-architecture/ebooks/issues>
|
For more free e-Books check out [.NET Architecture center](https://dot.net/architecture). If you have an e-book feedback, let us know by creating a new issue here: <https://github.com/dotnet-architecture/ebooks/issues>
|
||||||
|
|
||||||
## Are you new to **microservices** and **cloud-native development**?
|
## Are you new to **microservices** and **cloud-native development**?
|
||||||
Take a look at the free course [Create and deploy a cloud-native ASP.NET Core microservice](https://docs.microsoft.com/en-us/learn/modules/microservices-aspnet-core/) on MS Learn. This module explains microservices concepts, cloud-native technologies, and reduce the friction in getting started with `eShopOnContainers`.
|
Take a look at the free course [Create and deploy a cloud-native ASP.NET Core microservice](https://docs.microsoft.com/en-us/learn/modules/microservices-aspnet-core/) on MS Learn. This module explains microservices concepts, cloud-native technologies, and reduces the friction in getting started with `eShopOnContainers`.
|
||||||
|
|
||||||
## Read further
|
## Read further
|
||||||
|
|
||||||
|
@ -2,8 +2,12 @@
|
|||||||
|
|
||||||
Following are the most important branches:
|
Following are the most important branches:
|
||||||
|
|
||||||
- `dev`: Contains the latest code **and it is the branch actively developed**. Note that **all PRs must be against the `dev` branch to be considered**. This branch is developed using `.NET 5`
|
- `dev`: Contains the latest code **and it is the branch actively developed**. Note that **all PRs must be against the `dev` branch to be considered**. This branch is developed using `.NET 7`
|
||||||
- `main`: Synced time to time from `dev`.It contains "stable" code, although not the latest one. Right now, this branch contains changes specific to `.NET Core 3.1`
|
- `release/net-6`: Contains the code changes specific to the `.NET 6`
|
||||||
|
- `release/net-5`: Contains the code changes specific to the `.NET 5`
|
||||||
|
- `release/net-3.1.1`: Contains the code changes specific to the `.NET 3.1`
|
||||||
|
|
||||||
|
> [!DISCLAIMER]: The `main` branch contains the old code base and will get obsolete in the future. So it's recommended to refer to different [tags](https://github.com/dotnet-architecture/eShopOnContainers/tags) to avoid any confusion.
|
||||||
|
|
||||||
Any other branch is considered temporary and could be deleted at any time. Do not submit any PR against them!
|
Any other branch is considered temporary and could be deleted at any time. Do not submit any PR against them!
|
||||||
|
|
||||||
|
@ -31,5 +31,3 @@ $services |% {
|
|||||||
Write-Host "Setting ACR build $bname ($bimg)"
|
Write-Host "Setting ACR build $bname ($bimg)"
|
||||||
az acr build-task create --registry $acrName --name $bname --image ${bimg}:$gitBranch --context $gitContext --branch $gitBranch --git-access-token $patToken --file $bfile
|
az acr build-task create --registry $acrName --name $bname --image ${bimg}:$gitBranch --context $gitContext --branch $gitBranch --git-access-token $patToken --file $bfile
|
||||||
}
|
}
|
||||||
|
|
||||||
# Basket.API
|
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
"OrderingSubscriptionName": "Ordering",
|
"OrderingSubscriptionName": "Ordering",
|
||||||
"GracePeriodSubscriptionName": "GracePeriod",
|
"GracePeriodSubscriptionName": "GracePeriod",
|
||||||
"PaymentSubscriptionName": "Payment",
|
"PaymentSubscriptionName": "Payment",
|
||||||
|
"BackgroundTaskSubscriptionName": "backgroundtasks",
|
||||||
|
"OrderingSignalrHubSubscriptionName": "Ordering.signalrhub",
|
||||||
|
"WebhooksSubscriptionName": "Webhooks",
|
||||||
"location": "[resourceGroup().location]",
|
"location": "[resourceGroup().location]",
|
||||||
"sbVersion": "2015-08-01",
|
"sbVersion": "2015-08-01",
|
||||||
"defaultSASKeyName": "Root",
|
"defaultSASKeyName": "Root",
|
||||||
@ -172,6 +175,66 @@
|
|||||||
"autoDeleteOnIdle": "10675199.02:48:05.4775807",
|
"autoDeleteOnIdle": "10675199.02:48:05.4775807",
|
||||||
"entityAvailabilityStatus": "Available"
|
"entityAvailabilityStatus": "Available"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"apiVersion": "[variables('sbVersion')]",
|
||||||
|
"name": "[variables('BackgroundTaskSubscriptionName')]",
|
||||||
|
"type": "Subscriptions",
|
||||||
|
"dependsOn": [
|
||||||
|
"[variables('serviceBusTopicName')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"lockDuration": "00:00:30",
|
||||||
|
"requiresSession": false,
|
||||||
|
"defaultMessageTimeToLive": "14.00:00:00",
|
||||||
|
"deadLetteringOnMessageExpiration": true,
|
||||||
|
"deadLetteringOnFilterEvaluationExceptions": true,
|
||||||
|
"maxDeliveryCount": 10,
|
||||||
|
"enableBatchedOperations": false,
|
||||||
|
"status": "Active",
|
||||||
|
"autoDeleteOnIdle": "10675199.02:48:05.4775807",
|
||||||
|
"entityAvailabilityStatus": "Available"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"apiVersion": "[variables('sbVersion')]",
|
||||||
|
"name": "[variables('OrderingSignalrHubSubscriptionName')]",
|
||||||
|
"type": "Subscriptions",
|
||||||
|
"dependsOn": [
|
||||||
|
"[variables('serviceBusTopicName')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"lockDuration": "00:00:30",
|
||||||
|
"requiresSession": false,
|
||||||
|
"defaultMessageTimeToLive": "14.00:00:00",
|
||||||
|
"deadLetteringOnMessageExpiration": true,
|
||||||
|
"deadLetteringOnFilterEvaluationExceptions": true,
|
||||||
|
"maxDeliveryCount": 10,
|
||||||
|
"enableBatchedOperations": false,
|
||||||
|
"status": "Active",
|
||||||
|
"autoDeleteOnIdle": "10675199.02:48:05.4775807",
|
||||||
|
"entityAvailabilityStatus": "Available"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"apiVersion": "[variables('sbVersion')]",
|
||||||
|
"name": "[variables('WebhooksSubscriptionName')]",
|
||||||
|
"type": "Subscriptions",
|
||||||
|
"dependsOn": [
|
||||||
|
"[variables('serviceBusTopicName')]"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"lockDuration": "00:00:30",
|
||||||
|
"requiresSession": false,
|
||||||
|
"defaultMessageTimeToLive": "14.00:00:00",
|
||||||
|
"deadLetteringOnMessageExpiration": true,
|
||||||
|
"deadLetteringOnFilterEvaluationExceptions": true,
|
||||||
|
"maxDeliveryCount": 10,
|
||||||
|
"enableBatchedOperations": false,
|
||||||
|
"status": "Active",
|
||||||
|
"autoDeleteOnIdle": "10675199.02:48:05.4775807",
|
||||||
|
"entityAvailabilityStatus": "Available"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ Write-Host "Creating AKS $resourceGroupName/$serviceName" -ForegroundColor Yello
|
|||||||
az aks create --resource-group=$resourceGroupName --name=$serviceName --dns-name-prefix=$dnsNamePrefix --generate-ssh-keys --node-count=$nodeCount --node-vm-size=$nodeVMSize --vm-set-type $vmSetType
|
az aks create --resource-group=$resourceGroupName --name=$serviceName --dns-name-prefix=$dnsNamePrefix --generate-ssh-keys --node-count=$nodeCount --node-vm-size=$nodeVMSize --vm-set-type $vmSetType
|
||||||
|
|
||||||
if ($enableHttpApplicationAddon) {
|
if ($enableHttpApplicationAddon) {
|
||||||
Write-Host "Enabling Http Applciation Routing in AKS $serviceName" -ForegroundColor Yellow
|
Write-Host "Enabling Http Application Routing in AKS $serviceName" -ForegroundColor Yellow
|
||||||
az aks enable-addons --resource-group $resourceGroupName --name $serviceName --addons http_application_routing
|
az aks enable-addons --resource-group $resourceGroupName --name $serviceName --addons http_application_routing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,19 +9,20 @@ static_resources:
|
|||||||
- address:
|
- address:
|
||||||
socket_address:
|
socket_address:
|
||||||
address: 0.0.0.0
|
address: 0.0.0.0
|
||||||
port_value: 80
|
port_value: 8080
|
||||||
filter_chains:
|
filter_chains:
|
||||||
- filters:
|
- filters:
|
||||||
- name: envoy.http_connection_manager
|
- name: envoy.filters.network.http_connection_manager
|
||||||
config:
|
typed_config:
|
||||||
codec_type: auto
|
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
|
||||||
stat_prefix: ingress_http
|
stat_prefix: ingress_http
|
||||||
|
codec_type: AUTO
|
||||||
route_config:
|
route_config:
|
||||||
name: eshop_backend_route
|
name: eshop_backend_route
|
||||||
virtual_hosts:
|
virtual_hosts:
|
||||||
- name: eshop_backend
|
- name: eshop_backend
|
||||||
domains:
|
domains:
|
||||||
- "*"
|
- ["*"]
|
||||||
routes:
|
routes:
|
||||||
- name: "c-short"
|
- name: "c-short"
|
||||||
match:
|
match:
|
||||||
@ -77,63 +78,70 @@ static_resources:
|
|||||||
prefix_rewrite: "/"
|
prefix_rewrite: "/"
|
||||||
cluster: shoppingagg
|
cluster: shoppingagg
|
||||||
http_filters:
|
http_filters:
|
||||||
- name: envoy.router
|
- name: envoy.filters.http.router
|
||||||
access_log:
|
|
||||||
- name: envoy.file_access_log
|
|
||||||
filter:
|
|
||||||
not_health_check_filter: {}
|
|
||||||
config:
|
|
||||||
json_format:
|
|
||||||
time: "%START_TIME%"
|
|
||||||
protocol: "%PROTOCOL%"
|
|
||||||
duration: "%DURATION%"
|
|
||||||
request_method: "%REQ(:METHOD)%"
|
|
||||||
request_host: "%REQ(HOST)%"
|
|
||||||
path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
|
|
||||||
response_flags: "%RESPONSE_FLAGS%"
|
|
||||||
route_name: "%ROUTE_NAME%"
|
|
||||||
upstream_host: "%UPSTREAM_HOST%"
|
|
||||||
upstream_cluster: "%UPSTREAM_CLUSTER%"
|
|
||||||
upstream_local_address: "%UPSTREAM_LOCAL_ADDRESS%"
|
|
||||||
path: "/tmp/access.log"
|
|
||||||
clusters:
|
clusters:
|
||||||
- name: shoppingagg
|
- name: shoppingagg
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: shoppingagg
|
||||||
address: webshoppingagg
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: webshoppingagg
|
||||||
|
port_value: 80
|
||||||
- name: catalog
|
- name: catalog
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: catalog
|
||||||
address: catalog-api
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: catalog-api
|
||||||
|
port_value: 80
|
||||||
- name: basket
|
- name: basket
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: basket
|
||||||
address: basket-api
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: basket-api
|
||||||
|
port_value: 80
|
||||||
- name: ordering
|
- name: ordering
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: ordering
|
||||||
address: ordering-api
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: ordering-api
|
||||||
|
port_value: 80
|
||||||
- name: signalr-hub
|
- name: signalr-hub
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: signalr-hub
|
||||||
address: ordering-signalrhub
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: ordering-signalrhub
|
||||||
|
port_value: 80
|
||||||
|
@ -27,6 +27,10 @@ spec:
|
|||||||
linkerd.io/inject: enabled
|
linkerd.io/inject: enabled
|
||||||
{{- end }}
|
{{- end }}
|
||||||
spec:
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 2000
|
||||||
|
runAsGroup: 3000
|
||||||
|
fsGroup: 2000
|
||||||
{{ if .Values.inf.registry -}}
|
{{ if .Values.inf.registry -}}
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
- name: {{ .Values.inf.registry.secretName }}
|
- name: {{ .Values.inf.registry.secretName }}
|
||||||
@ -88,7 +92,7 @@ spec:
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
containerPort: 80
|
containerPort: 8080
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
- name: admin
|
- name: admin
|
||||||
containerPort: 8001
|
containerPort: 8001
|
||||||
|
@ -39,7 +39,7 @@ spec:
|
|||||||
- host: {{ . }}
|
- host: {{ . }}
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: {{ $ingressPath }}
|
- path: {{ $ingressPath }}(/|$)(.*)
|
||||||
pathType: Prefix
|
pathType: Prefix
|
||||||
backend:
|
backend:
|
||||||
service:
|
service:
|
||||||
|
@ -4,7 +4,7 @@ pathBase: /mobileshoppingapigw
|
|||||||
|
|
||||||
image:
|
image:
|
||||||
repository: envoyproxy/envoy
|
repository: envoyproxy/envoy
|
||||||
tag: v1.11.1
|
tag: v1.21.0
|
||||||
|
|
||||||
service:
|
service:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
@ -14,8 +14,9 @@ service:
|
|||||||
ingress:
|
ingress:
|
||||||
enabled: true
|
enabled: true
|
||||||
annotations:
|
annotations:
|
||||||
nginx.ingress.kubernetes.io/rewrite-target: "/"
|
kubernetes.io/ingress.class: nginx
|
||||||
ingress.kubernetes.io/rewrite-target: "/"
|
nginx.ingress.kubernetes.io/rewrite-target: /$2
|
||||||
|
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||||
tls: []
|
tls: []
|
||||||
|
|
||||||
resources: {}
|
resources: {}
|
||||||
|
@ -9,19 +9,20 @@ static_resources:
|
|||||||
- address:
|
- address:
|
||||||
socket_address:
|
socket_address:
|
||||||
address: 0.0.0.0
|
address: 0.0.0.0
|
||||||
port_value: 80
|
port_value: 8080
|
||||||
filter_chains:
|
filter_chains:
|
||||||
- filters:
|
- filters:
|
||||||
- name: envoy.http_connection_manager
|
- name: envoy.filters.network.http_connection_manager
|
||||||
config:
|
typed_config:
|
||||||
codec_type: auto
|
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
|
||||||
stat_prefix: ingress_http
|
stat_prefix: ingress_http
|
||||||
|
codec_type: AUTO
|
||||||
route_config:
|
route_config:
|
||||||
name: eshop_backend_route
|
name: eshop_backend_route
|
||||||
virtual_hosts:
|
virtual_hosts:
|
||||||
- name: eshop_backend
|
- name: eshop_backend
|
||||||
domains:
|
domains:
|
||||||
- "*"
|
- ["*"]
|
||||||
routes:
|
routes:
|
||||||
- name: "c-short"
|
- name: "c-short"
|
||||||
match:
|
match:
|
||||||
@ -80,63 +81,70 @@ static_resources:
|
|||||||
prefix_rewrite: "/"
|
prefix_rewrite: "/"
|
||||||
cluster: shoppingagg
|
cluster: shoppingagg
|
||||||
http_filters:
|
http_filters:
|
||||||
- name: envoy.router
|
- name: envoy.filters.http.router
|
||||||
access_log:
|
|
||||||
- name: envoy.file_access_log
|
|
||||||
filter:
|
|
||||||
not_health_check_filter: {}
|
|
||||||
config:
|
|
||||||
json_format:
|
|
||||||
time: "%START_TIME%"
|
|
||||||
protocol: "%PROTOCOL%"
|
|
||||||
duration: "%DURATION%"
|
|
||||||
request_method: "%REQ(:METHOD)%"
|
|
||||||
request_host: "%REQ(HOST)%"
|
|
||||||
path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
|
|
||||||
response_flags: "%RESPONSE_FLAGS%"
|
|
||||||
route_name: "%ROUTE_NAME%"
|
|
||||||
upstream_host: "%UPSTREAM_HOST%"
|
|
||||||
upstream_cluster: "%UPSTREAM_CLUSTER%"
|
|
||||||
upstream_local_address: "%UPSTREAM_LOCAL_ADDRESS%"
|
|
||||||
path: "/tmp/access.log"
|
|
||||||
clusters:
|
clusters:
|
||||||
- name: shoppingagg
|
- name: shoppingagg
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: shoppingagg
|
||||||
address: webshoppingagg
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: webshoppingagg
|
||||||
|
port_value: 80
|
||||||
- name: catalog
|
- name: catalog
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: catalog
|
||||||
address: catalog-api
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: catalog-api
|
||||||
|
port_value: 80
|
||||||
- name: basket
|
- name: basket
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: basket
|
||||||
address: basket-api
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: basket-api
|
||||||
|
port_value: 80
|
||||||
- name: ordering
|
- name: ordering
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: ordering
|
||||||
address: ordering-api
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: ordering-api
|
||||||
|
port_value: 80
|
||||||
- name: signalr-hub
|
- name: signalr-hub
|
||||||
connect_timeout: 0.25s
|
connect_timeout: 0.25s
|
||||||
type: strict_dns
|
type: strict_dns
|
||||||
lb_policy: round_robin
|
lb_policy: round_robin
|
||||||
hosts:
|
load_assignment:
|
||||||
- socket_address:
|
cluster_name: signalr-hub
|
||||||
address: ordering-signalrhub
|
endpoints:
|
||||||
port_value: 80
|
- lb_endpoints:
|
||||||
|
- endpoint:
|
||||||
|
address:
|
||||||
|
socket_address:
|
||||||
|
address: ordering-signalrhub
|
||||||
|
port_value: 80
|
@ -26,6 +26,10 @@ spec:
|
|||||||
linkerd.io/inject: enabled
|
linkerd.io/inject: enabled
|
||||||
{{- end }}
|
{{- end }}
|
||||||
spec:
|
spec:
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 2000
|
||||||
|
runAsGroup: 3000
|
||||||
|
fsGroup: 2000
|
||||||
{{ if .Values.inf.registry -}}
|
{{ if .Values.inf.registry -}}
|
||||||
imagePullSecrets:
|
imagePullSecrets:
|
||||||
- name: {{ .Values.inf.registry.secretName }}
|
- name: {{ .Values.inf.registry.secretName }}
|
||||||
@ -87,7 +91,7 @@ spec:
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
containerPort: 80
|
containerPort: 8080
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
- name: admin
|
- name: admin
|
||||||
containerPort: 8001
|
containerPort: 8001
|
||||||
|
@ -38,7 +38,7 @@ spec:
|
|||||||
- host: {{ . }}
|
- host: {{ . }}
|
||||||
http:
|
http:
|
||||||
paths:
|
paths:
|
||||||
- path: {{ $ingressPath }}
|
- path: {{ $ingressPath }}(/|$)(.*)
|
||||||
pathType: Prefix
|
pathType: Prefix
|
||||||
backend:
|
backend:
|
||||||
service:
|
service:
|
||||||
|
@ -4,7 +4,7 @@ pathBase: /webshoppingapigw
|
|||||||
|
|
||||||
image:
|
image:
|
||||||
repository: envoyproxy/envoy
|
repository: envoyproxy/envoy
|
||||||
tag: v1.11.1
|
tag: v1.21.0
|
||||||
|
|
||||||
service:
|
service:
|
||||||
type: ClusterIP
|
type: ClusterIP
|
||||||
@ -14,8 +14,9 @@ service:
|
|||||||
ingress:
|
ingress:
|
||||||
enabled: true
|
enabled: true
|
||||||
annotations:
|
annotations:
|
||||||
nginx.ingress.kubernetes.io/rewrite-target: "/"
|
kubernetes.io/ingress.class: nginx
|
||||||
ingress.kubernetes.io/rewrite-target: "/"
|
nginx.ingress.kubernetes.io/rewrite-target: /$2
|
||||||
|
nginx.ingress.kubernetes.io/use-regex: "true"
|
||||||
tls: []
|
tls: []
|
||||||
|
|
||||||
resources: {}
|
resources: {}
|
||||||
|
@ -13,7 +13,7 @@ metadata:
|
|||||||
release: {{ .Release.Name }}
|
release: {{ .Release.Name }}
|
||||||
heritage: {{ .Release.Service }}
|
heritage: {{ .Release.Service }}
|
||||||
data:
|
data:
|
||||||
catalog__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.catalog.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
|
catalog__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.catalog.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};TrustServerCertificate={{ .Values.inf.sql.common.TrustServerCertificate }};
|
||||||
catalog__PicBaseUrl: {{ $protocol }}://{{ $webshoppingapigw }}/c/api/v1/catalog/items/[0]/pic/
|
catalog__PicBaseUrl: {{ $protocol }}://{{ $webshoppingapigw }}/c/api/v1/catalog/items/[0]/pic/
|
||||||
catalog__AzureStorageEnabled: "{{ .Values.inf.misc.useAzureStorage }}"
|
catalog__AzureStorageEnabled: "{{ .Values.inf.misc.useAzureStorage }}"
|
||||||
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
|
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
|
||||||
|
@ -43,6 +43,10 @@ Parameters:
|
|||||||
The Docker username used to logon to the custom registry, supplied using the -r parameter.
|
The Docker username used to logon to the custom registry, supplied using the -r parameter.
|
||||||
--use-local-k8s
|
--use-local-k8s
|
||||||
Deploy to a locally installed Kubernetes (default: false).
|
Deploy to a locally installed Kubernetes (default: false).
|
||||||
|
--use-mesh
|
||||||
|
Use Linkerd as service mesh
|
||||||
|
--image-pull-policy <policy>
|
||||||
|
Image Pull Policy: Always, IfNotPresent, Never (default: Always)
|
||||||
|
|
||||||
It is assumed that the Kubernetes cluster has been granted access to the container registry.
|
It is assumed that the Kubernetes cluster has been granted access to the container registry.
|
||||||
If using AKS and ACR see link for more info:
|
If using AKS and ACR see link for more info:
|
||||||
@ -72,6 +76,9 @@ push_images=''
|
|||||||
skip_infrastructure=''
|
skip_infrastructure=''
|
||||||
use_local_k8s=''
|
use_local_k8s=''
|
||||||
namespace='eshop'
|
namespace='eshop'
|
||||||
|
use_mesh='false'
|
||||||
|
ingressMeshAnnotationsFile='ingress_values_linkerd.yaml'
|
||||||
|
imagePullPolicy='Always'
|
||||||
|
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case "$1" in
|
case "$1" in
|
||||||
@ -107,12 +114,21 @@ while [[ $# -gt 0 ]]; do
|
|||||||
use_local_k8s='yes'; shift ;;
|
use_local_k8s='yes'; shift ;;
|
||||||
--namespace )
|
--namespace )
|
||||||
namespace="$2"; shift 2;;
|
namespace="$2"; shift 2;;
|
||||||
|
--use-mesh )
|
||||||
|
use_mesh='true'; shift ;;
|
||||||
|
--image-pull-policy )
|
||||||
|
imagePullPolicy="$2"; shift 2;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown option $1"
|
echo "Unknown option $1"
|
||||||
usage; exit 2 ;;
|
usage; exit 2 ;;
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
|
if [[ $imagePullPolicy != "Always" && $imagePullPolicy != "Never" && $imagePullPolicy != "IfNotPresent" ]]; then
|
||||||
|
echo "--image-pull-policy needs to be a valid value: Always, IfNotPresent, Never"
|
||||||
|
usage; exit 2;
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ $build_solution ]]; then
|
if [[ $build_solution ]]; then
|
||||||
echo "#################### Building $app_name solution ####################"
|
echo "#################### Building $app_name solution ####################"
|
||||||
dotnet publish -o obj/Docker/publish ../../eShopOnContainers-ServicesAndWebApps.sln
|
dotnet publish -o obj/Docker/publish ../../eShopOnContainers-ServicesAndWebApps.sln
|
||||||
@ -201,7 +217,7 @@ if [[ $clean ]]; then
|
|||||||
if [[ -z $(helm ls -q --namespace $namespace) ]]; then
|
if [[ -z $(helm ls -q --namespace $namespace) ]]; then
|
||||||
echo "No previous releases found"
|
echo "No previous releases found"
|
||||||
else
|
else
|
||||||
helm uninstall $(helm ls -q --namespace $namespace)
|
helm --namespace $namespace uninstall $(helm ls -q --namespace $namespace)
|
||||||
echo "Previous releases deleted"
|
echo "Previous releases deleted"
|
||||||
waitsecs=10; while [ $waitsecs -gt 0 ]; do echo -ne "$waitsecs\033[0K\r"; sleep 1; : $((waitsecs--)); done
|
waitsecs=10; while [ $waitsecs -gt 0 ]; do echo -ne "$waitsecs\033[0K\r"; sleep 1; : $((waitsecs--)); done
|
||||||
fi
|
fi
|
||||||
@ -209,13 +225,14 @@ fi
|
|||||||
|
|
||||||
echo "#################### Begin $app_name installation using Helm ####################"
|
echo "#################### Begin $app_name installation using Helm ####################"
|
||||||
infras=(sql-data nosql-data rabbitmq keystore-data basket-data)
|
infras=(sql-data nosql-data rabbitmq keystore-data basket-data)
|
||||||
charts=(eshop-common apigwms apigwws basket-api catalog-api identity-api mobileshoppingagg ordering-api ordering-backgroundtasks ordering-signalrhub payment-api webmvc webshoppingagg webspa webstatus webhooks-api webhooks-web)
|
charts=(eshop-common basket-api catalog-api identity-api mobileshoppingagg ordering-api ordering-backgroundtasks ordering-signalrhub payment-api webmvc webshoppingagg webspa webstatus webhooks-api webhooks-web)
|
||||||
|
gateways=(apigwms apigwws)
|
||||||
|
|
||||||
if [[ !$skip_infrastructure ]]; then
|
if [[ !$skip_infrastructure ]]; then
|
||||||
for infra in "${infras[@]}"
|
for infra in "${infras[@]}"
|
||||||
do
|
do
|
||||||
echo "Installing infrastructure: $infra"
|
echo "Installing infrastructure: $infra"
|
||||||
helm install "$app_name-$infra" --namespace $namespace --set "ingress.hosts={$dns}" --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns $infra
|
helm install "$app_name-$infra" --namespace $namespace --set "ingress.hosts={$dns}" --values app.yaml --values inf.yaml --values $ingress_values_file --values $ingressMeshAnnotationsFile --set app.name=$app_name --set inf.k8s.dns=$dns $infra --set inf.mesh.enabled=$use_mesh
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -223,10 +240,16 @@ for chart in "${charts[@]}"
|
|||||||
do
|
do
|
||||||
echo "Installing: $chart"
|
echo "Installing: $chart"
|
||||||
if [[ $use_custom_registry ]]; then
|
if [[ $use_custom_registry ]]; then
|
||||||
helm install "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --set inf.registry.server=$container_registry --set inf.registry.login=$docker_username --set inf.registry.pwd=$docker_password --set inf.registry.secretName=eshop-docker-scret --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always $chart
|
helm install "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --set inf.registry.server=$container_registry --set inf.registry.login=$docker_username --set inf.registry.pwd=$docker_password --set inf.registry.secretName=eshop-docker-scret --values app.yaml --values inf.yaml --values $ingress_values_file --values $ingressMeshAnnotationsFile --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=$imagePullPolicy $chart --set inf.mesh.enabled=$use_mesh
|
||||||
elif [[ $chart != "eshop-common" ]]; then # eshop-common is ignored when no secret must be deployed
|
elif [[ $chart != "eshop-common" ]]; then # eshop-common is ignored when no secret must be deployed
|
||||||
helm install "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=Always $chart
|
helm install "$app_name-$chart" --namespace $namespace --set "ingress.hosts={$dns}" --values app.yaml --values inf.yaml --values $ingress_values_file --values $ingressMeshAnnotationsFile --set app.name=$app_name --set inf.k8s.dns=$dns --set image.tag=$image_tag --set image.pullPolicy=$imagePullPolicy $chart --set inf.mesh.enabled=$use_mesh
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
for gw in "${gateways[@]}"
|
||||||
|
do
|
||||||
|
echo "Installing gateway: $gw"
|
||||||
|
helm install "$app_name-$gw" --namespace $namespace --set "ingress.hosts={$dns}" --values app.yaml --values inf.yaml --values $ingress_values_file --set app.name=$app_name --set inf.k8s.dns=$dns --set image.pullPolicy=$imagePullPolicy $gw
|
||||||
|
done
|
||||||
|
|
||||||
echo "FINISHED: Helm charts installed."
|
echo "FINISHED: Helm charts installed."
|
@ -20,7 +20,7 @@ metadata:
|
|||||||
release: {{ .Release.Name }}
|
release: {{ .Release.Name }}
|
||||||
heritage: {{ .Release.Service }}
|
heritage: {{ .Release.Service }}
|
||||||
data:
|
data:
|
||||||
identity__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.identity.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
|
identity__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.identity.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};TrustServerCertificate={{ .Values.inf.sql.common.TrustServerCertificate }};
|
||||||
identity__keystore: {{ .Values.inf.redis.keystore.constr }}
|
identity__keystore: {{ .Values.inf.redis.keystore.constr }}
|
||||||
all__InstrumentationKey: "{{ .Values.inf.appinsights.key }}"
|
all__InstrumentationKey: "{{ .Values.inf.appinsights.key }}"
|
||||||
mvc_e: http://{{ $mvc_url }}
|
mvc_e: http://{{ $mvc_url }}
|
||||||
|
@ -13,6 +13,7 @@ inf:
|
|||||||
user: sa # SQL user
|
user: sa # SQL user
|
||||||
pwd: Pass@word # SQL pwd
|
pwd: Pass@word # SQL pwd
|
||||||
pid: Developer
|
pid: Developer
|
||||||
|
TrustServerCertificate: true
|
||||||
catalog: # inf.sql.catalog: settings for the catalog-api sql (user, pwd, db)
|
catalog: # inf.sql.catalog: settings for the catalog-api sql (user, pwd, db)
|
||||||
db: CatalogDb # Catalog API SQL db name
|
db: CatalogDb # Catalog API SQL db name
|
||||||
ordering: # inf.sql.ordering: settings for the ordering-api sql (user, pwd, db)
|
ordering: # inf.sql.ordering: settings for the ordering-api sql (user, pwd, db)
|
||||||
|
@ -11,7 +11,7 @@ metadata:
|
|||||||
release: {{ .Release.Name }}
|
release: {{ .Release.Name }}
|
||||||
heritage: {{ .Release.Service }}
|
heritage: {{ .Release.Service }}
|
||||||
data:
|
data:
|
||||||
ordering__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.ordering.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
|
ordering__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.ordering.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};TrustServerCertificate={{ .Values.inf.sql.common.TrustServerCertificate }};
|
||||||
urls__IdentityUrl: http://{{ .Values.app.svc.identity }}
|
urls__IdentityUrl: http://{{ .Values.app.svc.identity }}
|
||||||
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
|
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
|
||||||
all__InstrumentationKey: "{{ .Values.inf.appinsights.key }}"
|
all__InstrumentationKey: "{{ .Values.inf.appinsights.key }}"
|
||||||
|
@ -12,7 +12,7 @@ metadata:
|
|||||||
release: {{ .Release.Name }}
|
release: {{ .Release.Name }}
|
||||||
heritage: {{ .Release.Service }}
|
heritage: {{ .Release.Service }}
|
||||||
data:
|
data:
|
||||||
ordering__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.ordering.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
|
ordering__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.ordering.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};TrustServerCertificate={{ .Values.inf.sql.common.TrustServerCertificate }};
|
||||||
ordering__EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
|
ordering__EnableLoadTest: "{{ .Values.inf.misc.useLoadTest }}"
|
||||||
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
|
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
|
||||||
all__InstrumentationKey: "{{ .Values.inf.appinsights.key }}"
|
all__InstrumentationKey: "{{ .Values.inf.appinsights.key }}"
|
||||||
|
@ -13,7 +13,7 @@ metadata:
|
|||||||
release: {{ .Release.Name }}
|
release: {{ .Release.Name }}
|
||||||
heritage: {{ .Release.Service }}
|
heritage: {{ .Release.Service }}
|
||||||
data:
|
data:
|
||||||
webhooks__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.webhooks.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};
|
webhooks__ConnectionString: Server={{ $sqlsrv }};Initial Catalog={{ .Values.inf.sql.webhooks.db }};User Id={{ .Values.inf.sql.common.user }};Password={{ .Values.inf.sql.common.pwd }};TrustServerCertificate={{ .Values.inf.sql.common.TrustServerCertificate }};
|
||||||
urls__IdentityUrl: http://{{ $identity }}
|
urls__IdentityUrl: http://{{ $identity }}
|
||||||
urls__IdentityUrlExternal: {{ $protocol }}://{{ $identity }}
|
urls__IdentityUrlExternal: {{ $protocol }}://{{ $identity }}
|
||||||
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
|
all__EventBusConnection: {{ .Values.inf.eventbus.constr }}
|
||||||
|
@ -4,7 +4,7 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: ingress-nginx
|
app.kubernetes.io/name: ingress-nginx
|
||||||
app.kubernetes.io/part-of: ingress-nginx
|
app.kubernetes.io/part-of: ingress-nginx
|
||||||
name: nginx-configuration
|
name: ingress-nginx-controller
|
||||||
namespace: ingress-nginx
|
namespace: ingress-nginx
|
||||||
data:
|
data:
|
||||||
proxy-buffer-size: "128k"
|
proxy-buffer-size: "128k"
|
||||||
|
@ -11,15 +11,16 @@ metadata:
|
|||||||
namespace: default
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
rules:
|
rules:
|
||||||
http:
|
- host: localhost
|
||||||
paths:
|
http:
|
||||||
- path: /webmvc
|
paths:
|
||||||
pathType: Prefix
|
- path: /webmvc
|
||||||
backend:
|
pathType: Prefix
|
||||||
service:
|
backend:
|
||||||
name: webmvc
|
service:
|
||||||
port:
|
name: webmvc
|
||||||
number: 80
|
port:
|
||||||
|
number: 80
|
||||||
---
|
---
|
||||||
apiVersion: networking.k8s.io/v1
|
apiVersion: networking.k8s.io/v1
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
@ -34,12 +35,13 @@ metadata:
|
|||||||
namespace: default
|
namespace: default
|
||||||
spec:
|
spec:
|
||||||
rules:
|
rules:
|
||||||
http:
|
- host: localhost
|
||||||
paths:
|
http:
|
||||||
- path: /identity
|
paths:
|
||||||
pathType: Prefix
|
- path: /identity
|
||||||
backend:
|
pathType: Prefix
|
||||||
service:
|
backend:
|
||||||
name: identity
|
service:
|
||||||
port:
|
name: identity
|
||||||
number: 80
|
port:
|
||||||
|
number: 80
|
||||||
|
BIN
gothrough docs.docx
Normal file
BIN
gothrough docs.docx
Normal file
Binary file not shown.
6
src/.env
6
src/.env
@ -6,15 +6,15 @@
|
|||||||
|
|
||||||
# Use this values to run the app locally in Windows
|
# Use this values to run the app locally in Windows
|
||||||
ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal
|
ESHOP_EXTERNAL_DNS_NAME_OR_IP=host.docker.internal
|
||||||
ESHOP_STORAGE_CATALOG_URL=http://host.docker.internal:5202/c/api/v1/catalog/items/[0]/pic/
|
ESHOP_STORAGE_CATALOG_URL=http://host.docker.internal:5121/c/api/v1/catalog/items/[0]/pic/
|
||||||
|
|
||||||
# Use this values to run the app locally in Mac
|
# Use this values to run the app locally in Mac
|
||||||
# ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.mac.localhost
|
# ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.mac.localhost
|
||||||
# ESHOP_STORAGE_CATALOG_URL=http://docker.for.mac.localhost:5202/c/api/v1/catalog/items/[0]/pic/
|
# ESHOP_STORAGE_CATALOG_URL=http://docker.for.mac.localhost:5121/c/api/v1/catalog/items/[0]/pic/
|
||||||
|
|
||||||
# Use this values to run the app locally in Linux
|
# Use this values to run the app locally in Linux
|
||||||
# ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.linux.localhost
|
# ESHOP_EXTERNAL_DNS_NAME_OR_IP=docker.for.linux.localhost
|
||||||
# ESHOP_STORAGE_CATALOG_URL=http://docker.for.linux.localhost:5202/c/api/v1/catalog/items/[0]/pic/
|
# ESHOP_STORAGE_CATALOG_URL=http://docker.for.linux.localhost:5121/c/api/v1/catalog/items/[0]/pic/
|
||||||
|
|
||||||
# Configure this values to the cloud storage locations
|
# Configure this values to the cloud storage locations
|
||||||
# ESHOP_STORAGE_CATALOG_URL=<YourAzureStorage_Catalog_BLOB_URL>
|
# ESHOP_STORAGE_CATALOG_URL=<YourAzureStorage_Catalog_BLOB_URL>
|
||||||
|
@ -1,139 +0,0 @@
|
|||||||
admin:
|
|
||||||
access_log_path: "/dev/null"
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: 0.0.0.0
|
|
||||||
port_value: 8001
|
|
||||||
static_resources:
|
|
||||||
listeners:
|
|
||||||
- address:
|
|
||||||
socket_address:
|
|
||||||
address: 0.0.0.0
|
|
||||||
port_value: 80
|
|
||||||
filter_chains:
|
|
||||||
- filters:
|
|
||||||
- name: envoy.http_connection_manager
|
|
||||||
config:
|
|
||||||
codec_type: auto
|
|
||||||
stat_prefix: ingress_http
|
|
||||||
route_config:
|
|
||||||
name: eshop_backend_route
|
|
||||||
virtual_hosts:
|
|
||||||
- name: eshop_backend
|
|
||||||
domains:
|
|
||||||
- "*"
|
|
||||||
routes:
|
|
||||||
- name: "c-short"
|
|
||||||
match:
|
|
||||||
prefix: "/c/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
prefix_rewrite: "/catalog-api/"
|
|
||||||
cluster: catalog
|
|
||||||
- name: "c-long"
|
|
||||||
match:
|
|
||||||
prefix: "/catalog-api/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
cluster: catalog
|
|
||||||
- name: "o-short"
|
|
||||||
match:
|
|
||||||
prefix: "/o/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
prefix_rewrite: "/ordering-api/"
|
|
||||||
cluster: ordering
|
|
||||||
- name: "o-long"
|
|
||||||
match:
|
|
||||||
prefix: "/ordering-api/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
cluster: ordering
|
|
||||||
- name: "h-long"
|
|
||||||
match:
|
|
||||||
prefix: "/hub/notificationhub"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
cluster: signalr-hub
|
|
||||||
timeout: 300s
|
|
||||||
- name: "b-short"
|
|
||||||
match:
|
|
||||||
prefix: "/b/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
prefix_rewrite: "/basket-api/"
|
|
||||||
cluster: basket
|
|
||||||
- name: "b-long"
|
|
||||||
match:
|
|
||||||
prefix: "/basket-api/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
cluster: basket
|
|
||||||
- name: "agg"
|
|
||||||
match:
|
|
||||||
prefix: "/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
prefix_rewrite: "/"
|
|
||||||
cluster: shoppingagg
|
|
||||||
http_filters:
|
|
||||||
- name: envoy.router
|
|
||||||
access_log:
|
|
||||||
- name: envoy.file_access_log
|
|
||||||
filter:
|
|
||||||
not_health_check_filter: {}
|
|
||||||
config:
|
|
||||||
json_format:
|
|
||||||
time: "%START_TIME%"
|
|
||||||
protocol: "%PROTOCOL%"
|
|
||||||
duration: "%DURATION%"
|
|
||||||
request_method: "%REQ(:METHOD)%"
|
|
||||||
request_host: "%REQ(HOST)%"
|
|
||||||
path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
|
|
||||||
response_flags: "%RESPONSE_FLAGS%"
|
|
||||||
route_name: "%ROUTE_NAME%"
|
|
||||||
upstream_host: "%UPSTREAM_HOST%"
|
|
||||||
upstream_cluster: "%UPSTREAM_CLUSTER%"
|
|
||||||
upstream_local_address: "%UPSTREAM_LOCAL_ADDRESS%"
|
|
||||||
path: "/tmp/access.log"
|
|
||||||
clusters:
|
|
||||||
- name: shoppingagg
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: mobileshoppingagg
|
|
||||||
port_value: 80
|
|
||||||
- name: catalog
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: catalog-api
|
|
||||||
port_value: 80
|
|
||||||
- name: basket
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: basket-api
|
|
||||||
port_value: 80
|
|
||||||
- name: ordering
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: ordering-api
|
|
||||||
port_value: 80
|
|
||||||
- name: signalr-hub
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: ordering-signalrhub
|
|
||||||
port_value: 80
|
|
@ -1,142 +0,0 @@
|
|||||||
admin:
|
|
||||||
access_log_path: "/dev/null"
|
|
||||||
address:
|
|
||||||
socket_address:
|
|
||||||
address: 0.0.0.0
|
|
||||||
port_value: 8001
|
|
||||||
static_resources:
|
|
||||||
listeners:
|
|
||||||
- address:
|
|
||||||
socket_address:
|
|
||||||
address: 0.0.0.0
|
|
||||||
port_value: 80
|
|
||||||
filter_chains:
|
|
||||||
- filters:
|
|
||||||
- name: envoy.http_connection_manager
|
|
||||||
config:
|
|
||||||
codec_type: auto
|
|
||||||
stat_prefix: ingress_http
|
|
||||||
route_config:
|
|
||||||
name: eshop_backend_route
|
|
||||||
virtual_hosts:
|
|
||||||
- name: eshop_backend
|
|
||||||
domains:
|
|
||||||
- "*"
|
|
||||||
routes:
|
|
||||||
- name: "c-short"
|
|
||||||
match:
|
|
||||||
prefix: "/c/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
prefix_rewrite: "/catalog-api/"
|
|
||||||
cluster: catalog
|
|
||||||
- name: "c-long"
|
|
||||||
match:
|
|
||||||
prefix: "/catalog-api/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
cluster: catalog
|
|
||||||
- name: "o-short"
|
|
||||||
match:
|
|
||||||
prefix: "/o/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
prefix_rewrite: "/ordering-api/"
|
|
||||||
cluster: ordering
|
|
||||||
- name: "o-long"
|
|
||||||
match:
|
|
||||||
prefix: "/ordering-api/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
cluster: ordering
|
|
||||||
- name: "h-long"
|
|
||||||
match:
|
|
||||||
prefix: "/hub/notificationhub"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
cluster: signalr-hub
|
|
||||||
timeout: 300s
|
|
||||||
upgrade_configs:
|
|
||||||
upgrade_type: "websocket"
|
|
||||||
enabled: true
|
|
||||||
- name: "b-short"
|
|
||||||
match:
|
|
||||||
prefix: "/b/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
prefix_rewrite: "/basket-api/"
|
|
||||||
cluster: basket
|
|
||||||
- name: "b-long"
|
|
||||||
match:
|
|
||||||
prefix: "/basket-api/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
cluster: basket
|
|
||||||
- name: "agg"
|
|
||||||
match:
|
|
||||||
prefix: "/"
|
|
||||||
route:
|
|
||||||
auto_host_rewrite: true
|
|
||||||
prefix_rewrite: "/"
|
|
||||||
cluster: shoppingagg
|
|
||||||
http_filters:
|
|
||||||
- name: envoy.router
|
|
||||||
access_log:
|
|
||||||
- name: envoy.file_access_log
|
|
||||||
filter:
|
|
||||||
not_health_check_filter: {}
|
|
||||||
config:
|
|
||||||
json_format:
|
|
||||||
time: "%START_TIME%"
|
|
||||||
protocol: "%PROTOCOL%"
|
|
||||||
duration: "%DURATION%"
|
|
||||||
request_method: "%REQ(:METHOD)%"
|
|
||||||
request_host: "%REQ(HOST)%"
|
|
||||||
path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
|
|
||||||
response_flags: "%RESPONSE_FLAGS%"
|
|
||||||
route_name: "%ROUTE_NAME%"
|
|
||||||
upstream_host: "%UPSTREAM_HOST%"
|
|
||||||
upstream_cluster: "%UPSTREAM_CLUSTER%"
|
|
||||||
upstream_local_address: "%UPSTREAM_LOCAL_ADDRESS%"
|
|
||||||
path: "/tmp/access.log"
|
|
||||||
clusters:
|
|
||||||
- name: shoppingagg
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: webshoppingagg
|
|
||||||
port_value: 80
|
|
||||||
- name: catalog
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: catalog-api
|
|
||||||
port_value: 80
|
|
||||||
- name: basket
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: basket-api
|
|
||||||
port_value: 80
|
|
||||||
- name: ordering
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: ordering-api
|
|
||||||
port_value: 80
|
|
||||||
- name: signalr-hub
|
|
||||||
connect_timeout: 0.25s
|
|
||||||
type: strict_dns
|
|
||||||
lb_policy: round_robin
|
|
||||||
hosts:
|
|
||||||
- socket_address:
|
|
||||||
address: ordering-signalrhub
|
|
||||||
port_value: 80
|
|
@ -1,38 +1,35 @@
|
|||||||
using System.Collections.Generic;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config
|
public class UrlsConfig
|
||||||
{
|
{
|
||||||
public class UrlsConfig
|
public class CatalogOperations
|
||||||
{
|
{
|
||||||
public class CatalogOperations
|
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}";
|
||||||
{
|
|
||||||
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}";
|
|
||||||
|
|
||||||
public static string GetItemsById(IEnumerable<int> ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}";
|
public static string GetItemsById(IEnumerable<int> ids) => $"/api/v1/catalog/items?ids={string.Join(',', ids)}";
|
||||||
}
|
|
||||||
|
|
||||||
public class BasketOperations
|
|
||||||
{
|
|
||||||
public static string GetItemById(string id) => $"/api/v1/basket/{id}";
|
|
||||||
|
|
||||||
public static string UpdateBasket() => "/api/v1/basket";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OrdersOperations
|
|
||||||
{
|
|
||||||
public static string GetOrderDraft() => "/api/v1/orders/draft";
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Basket { get; set; }
|
|
||||||
|
|
||||||
public string Catalog { get; set; }
|
|
||||||
|
|
||||||
public string Orders { get; set; }
|
|
||||||
|
|
||||||
public string GrpcBasket { get; set; }
|
|
||||||
|
|
||||||
public string GrpcCatalog { get; set; }
|
|
||||||
|
|
||||||
public string GrpcOrdering { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BasketOperations
|
||||||
|
{
|
||||||
|
public static string GetItemById(string id) => $"/api/v1/basket/{id}";
|
||||||
|
|
||||||
|
public static string UpdateBasket() => "/api/v1/basket";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OrdersOperations
|
||||||
|
{
|
||||||
|
public static string GetOrderDraft() => "/api/v1/orders/draft";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Basket { get; set; }
|
||||||
|
|
||||||
|
public string Catalog { get; set; }
|
||||||
|
|
||||||
|
public string Orders { get; set; }
|
||||||
|
|
||||||
|
public string GrpcBasket { get; set; }
|
||||||
|
|
||||||
|
public string GrpcCatalog { get; set; }
|
||||||
|
|
||||||
|
public string GrpcOrdering { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,156 +1,143 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
|
[Route("api/v1/[controller]")]
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
public class BasketController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/v1/[controller]")]
|
private readonly ICatalogService _catalog;
|
||||||
[Authorize]
|
private readonly IBasketService _basket;
|
||||||
[ApiController]
|
|
||||||
public class BasketController : ControllerBase
|
public BasketController(ICatalogService catalogService, IBasketService basketService)
|
||||||
{
|
{
|
||||||
private readonly ICatalogService _catalog;
|
_catalog = catalogService;
|
||||||
private readonly IBasketService _basket;
|
_basket = basketService;
|
||||||
|
}
|
||||||
|
|
||||||
public BasketController(ICatalogService catalogService, IBasketService basketService)
|
[HttpPost]
|
||||||
|
[HttpPut]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<BasketData>> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data)
|
||||||
|
{
|
||||||
|
if (data.Items == null || !data.Items.Any())
|
||||||
{
|
{
|
||||||
_catalog = catalogService;
|
return BadRequest("Need to pass at least one basket line");
|
||||||
_basket = basketService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
// Retrieve the current basket
|
||||||
[HttpPut]
|
var basket = await _basket.GetByIdAsync(data.BuyerId) ?? new BasketData(data.BuyerId);
|
||||||
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
|
||||||
[ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)]
|
// group by product id to avoid duplicates
|
||||||
public async Task<ActionResult<BasketData>> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data)
|
var itemsCalculated = data
|
||||||
|
.Items
|
||||||
|
.GroupBy(x => x.ProductId, x => x, (k, i) => new { productId = k, items = i })
|
||||||
|
.Select(groupedItem =>
|
||||||
|
{
|
||||||
|
var item = groupedItem.items.First();
|
||||||
|
item.Quantity = groupedItem.items.Sum(i => i.Quantity);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var bitem in itemsCalculated)
|
||||||
{
|
{
|
||||||
if (data.Items == null || !data.Items.Any())
|
var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId);
|
||||||
|
if (catalogItem == null)
|
||||||
{
|
{
|
||||||
return BadRequest("Need to pass at least one basket line");
|
return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the current basket
|
var itemInBasket = basket.Items.FirstOrDefault(x => x.ProductId == bitem.ProductId);
|
||||||
var basket = await _basket.GetById(data.BuyerId) ?? new BasketData(data.BuyerId);
|
if (itemInBasket == null)
|
||||||
|
|
||||||
var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
|
|
||||||
// group by product id to avoid duplicates
|
|
||||||
var itemsCalculated = data
|
|
||||||
.Items
|
|
||||||
.GroupBy(x => x.ProductId, x => x, (k, i) => new { productId = k, items = i })
|
|
||||||
.Select(groupedItem =>
|
|
||||||
{
|
|
||||||
var item = groupedItem.items.First();
|
|
||||||
item.Quantity = groupedItem.items.Sum(i => i.Quantity);
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var bitem in itemsCalculated)
|
|
||||||
{
|
{
|
||||||
var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId);
|
basket.Items.Add(new BasketDataItem()
|
||||||
if (catalogItem == null)
|
|
||||||
{
|
{
|
||||||
return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})");
|
Id = bitem.Id,
|
||||||
}
|
ProductId = catalogItem.Id,
|
||||||
|
ProductName = catalogItem.Name,
|
||||||
var itemInBasket = basket.Items.FirstOrDefault(x => x.ProductId == bitem.ProductId);
|
PictureUrl = catalogItem.PictureUri,
|
||||||
if (itemInBasket == null)
|
UnitPrice = catalogItem.Price,
|
||||||
{
|
Quantity = bitem.Quantity
|
||||||
basket.Items.Add(new BasketDataItem()
|
});
|
||||||
{
|
}
|
||||||
Id = bitem.Id,
|
else
|
||||||
ProductId = catalogItem.Id,
|
{
|
||||||
ProductName = catalogItem.Name,
|
itemInBasket.Quantity = bitem.Quantity;
|
||||||
PictureUrl = catalogItem.PictureUri,
|
|
||||||
UnitPrice = catalogItem.Price,
|
|
||||||
Quantity = bitem.Quantity
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
itemInBasket.Quantity = bitem.Quantity;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await _basket.UpdateAsync(basket);
|
|
||||||
|
|
||||||
return basket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPut]
|
await _basket.UpdateAsync(basket);
|
||||||
[Route("items")]
|
|
||||||
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
return basket;
|
||||||
[ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)]
|
}
|
||||||
public async Task<ActionResult<BasketData>> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data)
|
|
||||||
|
[HttpPut]
|
||||||
|
[Route("items")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<BasketData>> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data)
|
||||||
|
{
|
||||||
|
if (!data.Updates.Any())
|
||||||
{
|
{
|
||||||
if (!data.Updates.Any())
|
return BadRequest("No updates sent");
|
||||||
{
|
|
||||||
return BadRequest("No updates sent");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the current basket
|
|
||||||
var currentBasket = await _basket.GetById(data.BasketId);
|
|
||||||
if (currentBasket == null)
|
|
||||||
{
|
|
||||||
return BadRequest($"Basket with id {data.BasketId} not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update with new quantities
|
|
||||||
foreach (var update in data.Updates)
|
|
||||||
{
|
|
||||||
var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId);
|
|
||||||
|
|
||||||
if (basketItem == null)
|
|
||||||
{
|
|
||||||
return BadRequest($"Basket item with id {update.BasketItemId} not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
basketItem.Quantity = update.NewQty;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the updated basket
|
|
||||||
await _basket.UpdateAsync(currentBasket);
|
|
||||||
|
|
||||||
return currentBasket;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
// Retrieve the current basket
|
||||||
[Route("items")]
|
var currentBasket = await _basket.GetByIdAsync(data.BasketId);
|
||||||
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
if (currentBasket == null)
|
||||||
[ProducesResponseType((int)HttpStatusCode.OK)]
|
|
||||||
public async Task<ActionResult> AddBasketItemAsync([FromBody] AddBasketItemRequest data)
|
|
||||||
{
|
{
|
||||||
if (data == null || data.Quantity == 0)
|
return BadRequest($"Basket with id {data.BasketId} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update with new quantities
|
||||||
|
foreach (var update in data.Updates)
|
||||||
|
{
|
||||||
|
var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId);
|
||||||
|
|
||||||
|
if (basketItem == null)
|
||||||
{
|
{
|
||||||
return BadRequest("Invalid payload");
|
return BadRequest($"Basket item with id {update.BasketItemId} not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 1: Get the item from catalog
|
basketItem.Quantity = update.NewQty;
|
||||||
var item = await _catalog.GetCatalogItemAsync(data.CatalogItemId);
|
|
||||||
|
|
||||||
//item.PictureUri =
|
|
||||||
|
|
||||||
// Step 2: Get current basket status
|
|
||||||
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
|
|
||||||
// Step 3: Merge current status with new product
|
|
||||||
currentBasket.Items.Add(new BasketDataItem()
|
|
||||||
{
|
|
||||||
UnitPrice = item.Price,
|
|
||||||
PictureUrl = item.PictureUri,
|
|
||||||
ProductId = item.Id,
|
|
||||||
ProductName = item.Name,
|
|
||||||
Quantity = data.Quantity,
|
|
||||||
Id = Guid.NewGuid().ToString()
|
|
||||||
});
|
|
||||||
|
|
||||||
// Step 4: Update basket
|
|
||||||
await _basket.UpdateAsync(currentBasket);
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save the updated basket
|
||||||
|
await _basket.UpdateAsync(currentBasket);
|
||||||
|
|
||||||
|
return currentBasket;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("items")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult> AddBasketItemAsync([FromBody] AddBasketItemRequest data)
|
||||||
|
{
|
||||||
|
if (data == null || data.Quantity == 0)
|
||||||
|
{
|
||||||
|
return BadRequest("Invalid payload");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: Get the item from catalog
|
||||||
|
var item = await _catalog.GetCatalogItemAsync(data.CatalogItemId);
|
||||||
|
|
||||||
|
//item.PictureUri =
|
||||||
|
|
||||||
|
// Step 2: Get current basket status
|
||||||
|
var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId);
|
||||||
|
// Step 3: Merge current status with new product
|
||||||
|
currentBasket.Items.Add(new BasketDataItem()
|
||||||
|
{
|
||||||
|
UnitPrice = item.Price,
|
||||||
|
PictureUrl = item.PictureUri,
|
||||||
|
ProductId = item.Id,
|
||||||
|
ProductName = item.Name,
|
||||||
|
Quantity = data.Quantity,
|
||||||
|
Id = Guid.NewGuid().ToString()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Step 4: Update basket
|
||||||
|
await _basket.UpdateAsync(currentBasket);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
|
|
||||||
{
|
|
||||||
[Route("")]
|
|
||||||
public class HomeController : Controller
|
|
||||||
{
|
|
||||||
[HttpGet()]
|
|
||||||
public IActionResult Index()
|
|
||||||
{
|
|
||||||
return new RedirectResult("~/swagger");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +1,36 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
|
||||||
using System.Net;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Controllers
|
[Route("api/v1/[controller]")]
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
public class OrderController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/v1/[controller]")]
|
private readonly IBasketService _basketService;
|
||||||
[Authorize]
|
private readonly IOrderingService _orderingService;
|
||||||
[ApiController]
|
|
||||||
public class OrderController : ControllerBase
|
public OrderController(IBasketService basketService, IOrderingService orderingService)
|
||||||
{
|
{
|
||||||
private readonly IBasketService _basketService;
|
_basketService = basketService;
|
||||||
private readonly IOrderingService _orderingService;
|
_orderingService = orderingService;
|
||||||
|
}
|
||||||
|
|
||||||
public OrderController(IBasketService basketService, IOrderingService orderingService)
|
[Route("draft/{basketId}")]
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<OrderData>> GetOrderDraftAsync(string basketId)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(basketId))
|
||||||
{
|
{
|
||||||
_basketService = basketService;
|
return BadRequest("Need a valid basketid");
|
||||||
_orderingService = orderingService;
|
}
|
||||||
|
// Get the basket data and build a order draft based on it
|
||||||
|
var basket = await _basketService.GetByIdAsync(basketId);
|
||||||
|
|
||||||
|
if (basket == null)
|
||||||
|
{
|
||||||
|
return BadRequest($"No basket found for id {basketId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("draft/{basketId}")]
|
return await _orderingService.GetOrderDraftAsync(basket);
|
||||||
[HttpGet]
|
|
||||||
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
|
||||||
[ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<ActionResult<OrderData>> GetOrderDraftAsync(string basketId)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(basketId))
|
|
||||||
{
|
|
||||||
return BadRequest("Need a valid basketid");
|
|
||||||
}
|
|
||||||
// Get the basket data and build a order draft based on it
|
|
||||||
var basket = await _basketService.GetById(basketId);
|
|
||||||
|
|
||||||
if (basket == null)
|
|
||||||
{
|
|
||||||
return BadRequest($"No basket found for id {basketId}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return await _orderingService.GetOrderDraftAsync(basket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
|
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
|
|
||||||
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
|
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
|
|
||||||
# It's important to keep lines from here down to "COPY . ." identical in all Dockerfiles
|
# It's important to keep lines from here down to "COPY . ." identical in all Dockerfiles
|
||||||
@ -11,7 +11,6 @@ COPY "eShopOnContainers-ServicesAndWebApps.sln" "eShopOnContainers-ServicesAndWe
|
|||||||
|
|
||||||
COPY "ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj" "ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj"
|
COPY "ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj" "ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj"
|
||||||
COPY "ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj" "ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj"
|
COPY "ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj" "ApiGateways/Web.Bff.Shopping/aggregator/Web.Shopping.HttpAggregator.csproj"
|
||||||
COPY "BuildingBlocks/Devspaces.Support/Devspaces.Support.csproj" "BuildingBlocks/Devspaces.Support/Devspaces.Support.csproj"
|
|
||||||
COPY "BuildingBlocks/EventBus/EventBus/EventBus.csproj" "BuildingBlocks/EventBus/EventBus/EventBus.csproj"
|
COPY "BuildingBlocks/EventBus/EventBus/EventBus.csproj" "BuildingBlocks/EventBus/EventBus/EventBus.csproj"
|
||||||
COPY "BuildingBlocks/EventBus/EventBus.Tests/EventBus.Tests.csproj" "BuildingBlocks/EventBus/EventBus.Tests/EventBus.Tests.csproj"
|
COPY "BuildingBlocks/EventBus/EventBus.Tests/EventBus.Tests.csproj" "BuildingBlocks/EventBus/EventBus.Tests/EventBus.Tests.csproj"
|
||||||
COPY "BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj" "BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj"
|
COPY "BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj" "BuildingBlocks/EventBus/EventBusRabbitMQ/EventBusRabbitMQ.csproj"
|
||||||
@ -33,6 +32,8 @@ COPY "Services/Ordering/Ordering.Infrastructure/Ordering.Infrastructure.csproj"
|
|||||||
COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj"
|
COPY "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj" "Services/Ordering/Ordering.SignalrHub/Ordering.SignalrHub.csproj"
|
||||||
COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj"
|
COPY "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj" "Services/Ordering/Ordering.UnitTests/Ordering.UnitTests.csproj"
|
||||||
COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj"
|
COPY "Services/Payment/Payment.API/Payment.API.csproj" "Services/Payment/Payment.API/Payment.API.csproj"
|
||||||
|
COPY "Services/Services.Common/Services.Common.csproj" "Services/Services.Common/Services.Common.csproj"
|
||||||
|
COPY "Services/Contact/Contact.API/Contact.API.csproj" "Services/Contact/Contact.API/Contact.API.csproj"
|
||||||
COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj"
|
COPY "Services/Webhooks/Webhooks.API/Webhooks.API.csproj" "Services/Webhooks/Webhooks.API/Webhooks.API.csproj"
|
||||||
COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj"
|
COPY "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj" "Tests/Services/Application.FunctionalTests/Application.FunctionalTests.csproj"
|
||||||
COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj"
|
COPY "Web/WebhookClient/WebhookClient.csproj" "Web/WebhookClient/WebhookClient.csproj"
|
||||||
@ -42,6 +43,7 @@ COPY "Web/WebStatus/WebStatus.csproj" "Web/WebStatus/WebStatus.csproj"
|
|||||||
|
|
||||||
COPY "docker-compose.dcproj" "docker-compose.dcproj"
|
COPY "docker-compose.dcproj" "docker-compose.dcproj"
|
||||||
|
|
||||||
|
COPY "Directory.Packages.props" "Directory.Packages.props"
|
||||||
COPY "NuGet.config" "NuGet.config"
|
COPY "NuGet.config" "NuGet.config"
|
||||||
|
|
||||||
RUN dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
RUN dotnet restore "eShopOnContainers-ServicesAndWebApps.sln"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
FROM mcr.microsoft.com/dotnet/sdk:5.0
|
FROM mcr.microsoft.com/dotnet/sdk:7.0
|
||||||
ARG BUILD_CONFIGURATION=Debug
|
ARG BUILD_CONFIGURATION=Debug
|
||||||
ENV ASPNETCORE_ENVIRONMENT=Development
|
ENV ASPNETCORE_ENVIRONMENT=Development
|
||||||
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
|
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
|
||||||
@ -6,7 +6,6 @@ EXPOSE 80
|
|||||||
|
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY ["src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj", "src/ApiGateways/Mobile.Bff.Shopping/aggregator/"]
|
COPY ["src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj", "src/ApiGateways/Mobile.Bff.Shopping/aggregator/"]
|
||||||
COPY ["src/BuildingBlocks/Devspaces.Support/Devspaces.Support.csproj", "src/BuildingBlocks/Devspaces.Support/"]
|
|
||||||
COPY ["src/NuGet.config", "src/NuGet.config"]
|
COPY ["src/NuGet.config", "src/NuGet.config"]
|
||||||
|
|
||||||
RUN dotnet restore src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj -nowarn:msb3202,nu1503
|
RUN dotnet restore src/ApiGateways/Mobile.Bff.Shopping/aggregator/Mobile.Shopping.HttpAggregator.csproj -nowarn:msb3202,nu1503
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
internal static class Extensions
|
||||||
|
{
|
||||||
|
public static IServiceCollection AddReverseProxy(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
services.AddReverseProxy().LoadFromConfig(configuration.GetRequiredSection("ReverseProxy"));
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration)
|
||||||
|
{
|
||||||
|
services.AddHealthChecks()
|
||||||
|
.AddUrlGroup(_ => new Uri(configuration.GetRequiredValue("CatalogUrlHC")), name: "catalogapi-check", tags: new string[] { "catalogapi" })
|
||||||
|
.AddUrlGroup(_ => new Uri(configuration.GetRequiredValue("OrderingUrlHC")), name: "orderingapi-check", tags: new string[] { "orderingapi" })
|
||||||
|
.AddUrlGroup(_ => new Uri(configuration.GetRequiredValue("BasketUrlHC")), name: "basketapi-check", tags: new string[] { "basketapi" })
|
||||||
|
.AddUrlGroup(_ => new Uri(configuration.GetRequiredValue("IdentityUrlHC")), name: "identityapi-check", tags: new string[] { "identityapi" });
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddApplicationServices(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
// Register delegating handlers
|
||||||
|
services.AddTransient<HttpClientAuthorizationDelegatingHandler>();
|
||||||
|
|
||||||
|
// Register http services
|
||||||
|
services.AddHttpClient<IOrderApiClient, OrderApiClient>()
|
||||||
|
.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IServiceCollection AddGrpcServices(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddTransient<GrpcExceptionInterceptor>();
|
||||||
|
|
||||||
|
services.AddScoped<IBasketService, BasketService>();
|
||||||
|
|
||||||
|
services.AddGrpcClient<Basket.BasketClient>((services, options) =>
|
||||||
|
{
|
||||||
|
var basketApi = services.GetRequiredService<IOptions<UrlsConfig>>().Value.GrpcBasket;
|
||||||
|
options.Address = new Uri(basketApi);
|
||||||
|
}).AddInterceptor<GrpcExceptionInterceptor>();
|
||||||
|
|
||||||
|
services.AddScoped<ICatalogService, CatalogService>();
|
||||||
|
|
||||||
|
services.AddGrpcClient<Catalog.CatalogClient>((services, options) =>
|
||||||
|
{
|
||||||
|
var catalogApi = services.GetRequiredService<IOptions<UrlsConfig>>().Value.GrpcCatalog;
|
||||||
|
options.Address = new Uri(catalogApi);
|
||||||
|
}).AddInterceptor<GrpcExceptionInterceptor>();
|
||||||
|
|
||||||
|
services.AddScoped<IOrderingService, OrderingService>();
|
||||||
|
|
||||||
|
services.AddGrpcClient<GrpcOrdering.OrderingGrpc.OrderingGrpcClient>((services, options) =>
|
||||||
|
{
|
||||||
|
var orderingApi = services.GetRequiredService<IOptions<UrlsConfig>>().Value.GrpcOrdering;
|
||||||
|
options.Address = new Uri(orderingApi);
|
||||||
|
}).AddInterceptor<GrpcExceptionInterceptor>();
|
||||||
|
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
@ -1,40 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace Basket.API.Infrastructure.Filters
|
|
||||||
{
|
|
||||||
public class AuthorizeCheckOperationFilter : IOperationFilter
|
|
||||||
{
|
|
||||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
|
||||||
{
|
|
||||||
// Check for authorize attribute
|
|
||||||
var hasAuthorize = context.MethodInfo.DeclaringType.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any() ||
|
|
||||||
context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Any();
|
|
||||||
|
|
||||||
if (!hasAuthorize) return;
|
|
||||||
|
|
||||||
operation.Responses.TryAdd("401", new OpenApiResponse { Description = "Unauthorized" });
|
|
||||||
operation.Responses.TryAdd("403", new OpenApiResponse { Description = "Forbidden" });
|
|
||||||
|
|
||||||
var oAuthScheme = new OpenApiSecurityScheme
|
|
||||||
{
|
|
||||||
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
|
|
||||||
};
|
|
||||||
|
|
||||||
operation.Security = new List<OpenApiSecurityRequirement>
|
|
||||||
{
|
|
||||||
new OpenApiSecurityRequirement
|
|
||||||
{
|
|
||||||
[ oAuthScheme ] = new [] { "Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator" }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,13 @@
|
|||||||
|
global using System.Text.Json;
|
||||||
|
global using CatalogApi;
|
||||||
|
global using Grpc.Core;
|
||||||
|
global using Grpc.Core.Interceptors;
|
||||||
|
global using GrpcBasket;
|
||||||
|
global using Microsoft.AspNetCore.Authorization;
|
||||||
|
global using Microsoft.AspNetCore.Mvc;
|
||||||
|
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
||||||
|
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
|
||||||
|
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
global using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
|
global using Microsoft.Extensions.Options;
|
||||||
|
global using Services.Common;
|
@ -1,41 +1,35 @@
|
|||||||
using Grpc.Core;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
|
||||||
using Grpc.Core.Interceptors;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure
|
public class GrpcExceptionInterceptor : Interceptor
|
||||||
{
|
{
|
||||||
public class GrpcExceptionInterceptor : Interceptor
|
private readonly ILogger<GrpcExceptionInterceptor> _logger;
|
||||||
|
|
||||||
|
public GrpcExceptionInterceptor(ILogger<GrpcExceptionInterceptor> logger)
|
||||||
{
|
{
|
||||||
private readonly ILogger<GrpcExceptionInterceptor> _logger;
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
public GrpcExceptionInterceptor(ILogger<GrpcExceptionInterceptor> logger)
|
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
|
||||||
|
TRequest request,
|
||||||
|
ClientInterceptorContext<TRequest, TResponse> context,
|
||||||
|
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
|
||||||
|
{
|
||||||
|
var call = continuation(request, context);
|
||||||
|
|
||||||
|
return new AsyncUnaryCall<TResponse>(HandleResponse(call.ResponseAsync), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
_logger = logger;
|
var response = await t;
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
catch (RpcException e)
|
||||||
public override AsyncUnaryCall<TResponse> AsyncUnaryCall<TRequest, TResponse>(
|
|
||||||
TRequest request,
|
|
||||||
ClientInterceptorContext<TRequest, TResponse> context,
|
|
||||||
AsyncUnaryCallContinuation<TRequest, TResponse> continuation)
|
|
||||||
{
|
{
|
||||||
var call = continuation(request, context);
|
_logger.LogError(e, "Error calling via gRPC: {Status}", e.Status);
|
||||||
|
return default;
|
||||||
return new AsyncUnaryCall<TResponse>(HandleResponse(call.ResponseAsync), call.ResponseHeadersAsync, call.GetStatus, call.GetTrailers, call.Dispose);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<TResponse> HandleResponse<TResponse>(Task<TResponse> t)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await t;
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
catch (RpcException e)
|
|
||||||
{
|
|
||||||
_logger.LogError("Error calling via grpc: {Status} - {Message}", e.Status, e.Message);
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure
|
|
||||||
{
|
|
||||||
public class HttpClientAuthorizationDelegatingHandler : DelegatingHandler
|
|
||||||
{
|
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
|
||||||
private readonly ILogger<HttpClientAuthorizationDelegatingHandler> _logger;
|
|
||||||
|
|
||||||
public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccessor, ILogger<HttpClientAuthorizationDelegatingHandler> logger)
|
|
||||||
{
|
|
||||||
_httpContextAccessor = httpContextAccessor;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
request.Version = new System.Version(2, 0);
|
|
||||||
request.Method = HttpMethod.Get;
|
|
||||||
|
|
||||||
var authorizationHeader = _httpContextAccessor.HttpContext
|
|
||||||
.Request.Headers["Authorization"];
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(authorizationHeader))
|
|
||||||
{
|
|
||||||
request.Headers.Add("Authorization", new List<string>() { authorizationHeader });
|
|
||||||
}
|
|
||||||
|
|
||||||
var token = await GetToken();
|
|
||||||
|
|
||||||
if (token != null)
|
|
||||||
{
|
|
||||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await base.SendAsync(request, cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task<string> GetToken()
|
|
||||||
{
|
|
||||||
const string ACCESS_TOKEN = "access_token";
|
|
||||||
|
|
||||||
return await _httpContextAccessor.HttpContext
|
|
||||||
.GetTokenAsync(ACCESS_TOKEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +1,23 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
<AssemblyName>Mobile.Shopping.HttpAggregator</AssemblyName>
|
<AssemblyName>Mobile.Shopping.HttpAggregator</AssemblyName>
|
||||||
<RootNamespace>Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator</RootNamespace>
|
<RootNamespace>Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator</RootNamespace>
|
||||||
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
<DockerComposeProjectPath>..\..\..\docker-compose.dcproj</DockerComposeProjectPath>
|
||||||
<GenerateErrorForMissingTargetingPacks>false</GenerateErrorForMissingTargetingPacks>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
|
|
||||||
<LangVersion>preview</LangVersion>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="wwwroot\" />
|
<PackageReference Include="Yarp.ReverseProxy" />
|
||||||
|
<PackageReference Include="AspNetCore.HealthChecks.Uris" />
|
||||||
|
<PackageReference Include="Google.Protobuf" />
|
||||||
|
<PackageReference Include="Grpc.AspNetCore.Server.ClientFactory" />
|
||||||
|
<PackageReference Include="Grpc.Tools" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.UI.Client" Version="5.0.1" />
|
<ProjectReference Include="..\..\..\Services\Services.Common\Services.Common.csproj" />
|
||||||
<PackageReference Include="AspNetCore.HealthChecks.Uris" Version="5.0.1" />
|
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.14.0" />
|
|
||||||
<PackageReference Include="Grpc.AspNetCore.Server.ClientFactory" Version="2.34.0" />
|
|
||||||
<PackageReference Include="Grpc.Core" Version="2.34.0" />
|
|
||||||
<PackageReference Include="Grpc.Net.ClientFactory" Version="2.34.0" />
|
|
||||||
<PackageReference Include="Grpc.Tools" Version="2.34.0" PrivateAssets="All" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.2" />
|
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.HealthChecks" Version="2.2.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="5.0.2" />
|
|
||||||
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
|
||||||
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0-dev-00834" />
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\..\BuildingBlocks\Devspaces.Support\Devspaces.Support.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
|
public class AddBasketItemRequest
|
||||||
{
|
{
|
||||||
public class AddBasketItemRequest
|
public int CatalogItemId { get; set; }
|
||||||
|
|
||||||
|
public string BasketId { get; set; }
|
||||||
|
|
||||||
|
public int Quantity { get; set; }
|
||||||
|
|
||||||
|
public AddBasketItemRequest()
|
||||||
{
|
{
|
||||||
public int CatalogItemId { get; set; }
|
Quantity = 1;
|
||||||
|
|
||||||
public string BasketId { get; set; }
|
|
||||||
|
|
||||||
public int Quantity { get; set; }
|
|
||||||
|
|
||||||
public AddBasketItemRequest()
|
|
||||||
{
|
|
||||||
Quantity = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,17 @@
|
|||||||
using System.Collections.Generic;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
public class BasketData
|
||||||
{
|
{
|
||||||
|
public string BuyerId { get; set; }
|
||||||
|
|
||||||
public class BasketData
|
public List<BasketDataItem> Items { get; set; } = new();
|
||||||
|
|
||||||
|
public BasketData()
|
||||||
{
|
{
|
||||||
public string BuyerId { get; set; }
|
|
||||||
|
|
||||||
public List<BasketDataItem> Items { get; set; } = new List<BasketDataItem>();
|
|
||||||
|
|
||||||
public BasketData()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public BasketData(string buyerId)
|
|
||||||
{
|
|
||||||
BuyerId = buyerId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BasketData(string buyerId)
|
||||||
|
{
|
||||||
|
BuyerId = buyerId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
|
public class BasketDataItem
|
||||||
{
|
{
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
public class BasketDataItem
|
public int ProductId { get; set; }
|
||||||
{
|
|
||||||
public string Id { get; set; }
|
|
||||||
|
|
||||||
public int ProductId { get; set; }
|
public string ProductName { get; set; }
|
||||||
|
|
||||||
public string ProductName { get; set; }
|
public decimal UnitPrice { get; set; }
|
||||||
|
|
||||||
public decimal UnitPrice { get; set; }
|
public decimal OldUnitPrice { get; set; }
|
||||||
|
|
||||||
public decimal OldUnitPrice { get; set; }
|
public int Quantity { get; set; }
|
||||||
|
|
||||||
public int Quantity { get; set; }
|
|
||||||
|
|
||||||
public string PictureUrl { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public string PictureUrl { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
|
public class CatalogItem
|
||||||
{
|
{
|
||||||
public class CatalogItem
|
public int Id { get; set; }
|
||||||
{
|
|
||||||
public int Id { get; set; }
|
|
||||||
|
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
|
||||||
public decimal Price { get; set; }
|
public decimal Price { get; set; }
|
||||||
|
|
||||||
public string PictureUri { get; set; }
|
public string PictureUri { get; set; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,42 @@
|
|||||||
using System;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
public class OrderData
|
||||||
{
|
{
|
||||||
|
public string OrderNumber { get; set; }
|
||||||
|
|
||||||
public class OrderData
|
public DateTime Date { get; set; }
|
||||||
{
|
|
||||||
public string OrderNumber { get; set; }
|
|
||||||
|
|
||||||
public DateTime Date { get; set; }
|
public string Status { get; set; }
|
||||||
|
|
||||||
public string Status { get; set; }
|
public decimal Total { get; set; }
|
||||||
|
|
||||||
public decimal Total { get; set; }
|
public string Description { get; set; }
|
||||||
|
|
||||||
public string Description { get; set; }
|
public string City { get; set; }
|
||||||
|
|
||||||
public string City { get; set; }
|
public string Street { get; set; }
|
||||||
|
|
||||||
public string Street { get; set; }
|
public string State { get; set; }
|
||||||
|
|
||||||
public string State { get; set; }
|
public string Country { get; set; }
|
||||||
|
|
||||||
public string Country { get; set; }
|
public string ZipCode { get; set; }
|
||||||
|
|
||||||
public string ZipCode { get; set; }
|
public string CardNumber { get; set; }
|
||||||
|
|
||||||
public string CardNumber { get; set; }
|
public string CardHolderName { get; set; }
|
||||||
|
|
||||||
public string CardHolderName { get; set; }
|
public bool IsDraft { get; set; }
|
||||||
|
|
||||||
public bool IsDraft { get; set; }
|
public DateTime CardExpiration { get; set; }
|
||||||
|
|
||||||
public DateTime CardExpiration { get; set; }
|
public string CardExpirationShort { get; set; }
|
||||||
|
|
||||||
public string CardExpirationShort { get; set; }
|
public string CardSecurityNumber { get; set; }
|
||||||
|
|
||||||
public string CardSecurityNumber { get; set; }
|
public int CardTypeId { get; set; }
|
||||||
|
|
||||||
public int CardTypeId { get; set; }
|
public string Buyer { get; set; }
|
||||||
|
|
||||||
public string Buyer { get; set; }
|
|
||||||
|
|
||||||
public List<OrderItemData> OrderItems { get; } = new List<OrderItemData>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public List<OrderItemData> OrderItems { get; } = new();
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
|
public class OrderItemData
|
||||||
{
|
{
|
||||||
|
public int ProductId { get; set; }
|
||||||
|
|
||||||
public class OrderItemData
|
public string ProductName { get; set; }
|
||||||
{
|
|
||||||
public int ProductId { get; set; }
|
|
||||||
|
|
||||||
public string ProductName { get; set; }
|
public decimal UnitPrice { get; set; }
|
||||||
|
|
||||||
public decimal UnitPrice { get; set; }
|
public decimal Discount { get; set; }
|
||||||
|
|
||||||
public decimal Discount { get; set; }
|
public int Units { get; set; }
|
||||||
|
|
||||||
public int Units { get; set; }
|
|
||||||
|
|
||||||
public string PictureUrl { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public string PictureUrl { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
|
public class UpdateBasketItemData
|
||||||
{
|
{
|
||||||
|
public string BasketItemId { get; set; }
|
||||||
|
|
||||||
public class UpdateBasketItemData
|
public int NewQty { get; set; }
|
||||||
|
|
||||||
|
public UpdateBasketItemData()
|
||||||
{
|
{
|
||||||
public string BasketItemId { get; set; }
|
NewQty = 0;
|
||||||
|
|
||||||
public int NewQty { get; set; }
|
|
||||||
|
|
||||||
public UpdateBasketItemData()
|
|
||||||
{
|
|
||||||
NewQty = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,13 @@
|
|||||||
using System.Collections.Generic;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
public class UpdateBasketItemsRequest
|
||||||
{
|
{
|
||||||
|
public string BasketId { get; set; }
|
||||||
|
|
||||||
public class UpdateBasketItemsRequest
|
public ICollection<UpdateBasketItemData> Updates { get; set; }
|
||||||
|
|
||||||
|
public UpdateBasketItemsRequest()
|
||||||
{
|
{
|
||||||
|
Updates = new List<UpdateBasketItemData>();
|
||||||
public string BasketId { get; set; }
|
|
||||||
|
|
||||||
public ICollection<UpdateBasketItemData> Updates { get; set; }
|
|
||||||
|
|
||||||
public UpdateBasketItemsRequest()
|
|
||||||
{
|
|
||||||
Updates = new List<UpdateBasketItemData>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
using System.Collections.Generic;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
public class UpdateBasketRequest
|
||||||
{
|
{
|
||||||
|
public string BuyerId { get; set; }
|
||||||
|
|
||||||
public class UpdateBasketRequest
|
public IEnumerable<UpdateBasketRequestItemData> Items { get; set; }
|
||||||
{
|
|
||||||
public string BuyerId { get; set; }
|
|
||||||
|
|
||||||
public IEnumerable<UpdateBasketRequestItemData> Items { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,13 +1,10 @@
|
|||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
||||||
|
|
||||||
|
public class UpdateBasketRequestItemData
|
||||||
{
|
{
|
||||||
|
public string Id { get; set; } // Basket id
|
||||||
|
|
||||||
public class UpdateBasketRequestItemData
|
public int ProductId { get; set; } // Catalog item id
|
||||||
{
|
|
||||||
public string Id { get; set; } // Basket id
|
|
||||||
|
|
||||||
public int ProductId { get; set; } // Catalog item id
|
|
||||||
|
|
||||||
public int Quantity { get; set; } // Quantity
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public int Quantity { get; set; } // Quantity
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,24 @@
|
|||||||
using Microsoft.AspNetCore;
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator;
|
|
||||||
using Serilog;
|
|
||||||
|
|
||||||
|
builder.AddServiceDefaults();
|
||||||
|
|
||||||
BuildWebHost(args).Run();
|
builder.Services.AddReverseProxy(builder.Configuration);
|
||||||
IWebHost BuildWebHost(string[] args) =>
|
builder.Services.AddControllers();
|
||||||
WebHost
|
|
||||||
.CreateDefaultBuilder(args)
|
builder.Services.AddHealthChecks(builder.Configuration);
|
||||||
.ConfigureAppConfiguration(cb =>
|
|
||||||
{
|
builder.Services.AddApplicationServices();
|
||||||
var sources = cb.Sources;
|
builder.Services.AddGrpcServices();
|
||||||
sources.Insert(3, new Microsoft.Extensions.Configuration.Json.JsonConfigurationSource()
|
|
||||||
{
|
builder.Services.Configure<UrlsConfig>(builder.Configuration.GetSection("urls"));
|
||||||
Optional = true,
|
|
||||||
Path = "appsettings.localhost.json",
|
var app = builder.Build();
|
||||||
ReloadOnChange = false
|
|
||||||
});
|
app.UseServiceDefaults();
|
||||||
})
|
|
||||||
.UseStartup<Startup>()
|
app.UseHttpsRedirection();
|
||||||
.UseSerilog((builderContext, config) =>
|
|
||||||
{
|
app.MapControllers();
|
||||||
config
|
app.MapReverseProxy();
|
||||||
.MinimumLevel.Information()
|
|
||||||
.Enrich.FromLogContext()
|
await app.RunAsync();
|
||||||
.WriteTo.Console();
|
|
||||||
})
|
|
||||||
.Build();
|
|
||||||
|
@ -24,13 +24,6 @@
|
|||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
},
|
},
|
||||||
"applicationUrl": "http://localhost:61632/"
|
"applicationUrl": "http://localhost:61632/"
|
||||||
},
|
|
||||||
"Azure Dev Spaces": {
|
|
||||||
"commandName": "AzureDevSpaces",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"resourceGroup": "eshoptestedu",
|
|
||||||
"aksName": "eshoptestedu",
|
|
||||||
"subscriptionId": "e3035ac1-c06c-4daf-8939-57b3c5f1f759"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,90 +1,83 @@
|
|||||||
using GrpcBasket;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
public class BasketService : IBasketService
|
||||||
{
|
{
|
||||||
public class BasketService : IBasketService
|
private readonly Basket.BasketClient _basketClient;
|
||||||
|
private readonly ILogger<BasketService> _logger;
|
||||||
|
|
||||||
|
public BasketService(Basket.BasketClient basketClient, ILogger<BasketService> logger)
|
||||||
{
|
{
|
||||||
private readonly Basket.BasketClient _basketClient;
|
_basketClient = basketClient;
|
||||||
private readonly ILogger<BasketService> _logger;
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
public BasketService(Basket.BasketClient basketClient, ILogger<BasketService> logger)
|
public async Task<BasketData> GetByIdAsync(string id)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("grpc client created, request = {@id}", id);
|
||||||
|
var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id });
|
||||||
|
_logger.LogDebug("grpc response {@response}", response);
|
||||||
|
|
||||||
|
return MapToBasketData(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UpdateAsync(BasketData currentBasket)
|
||||||
|
{
|
||||||
|
_logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket);
|
||||||
|
var request = MapToCustomerBasketRequest(currentBasket);
|
||||||
|
_logger.LogDebug("Grpc update basket request {@request}", request);
|
||||||
|
|
||||||
|
await _basketClient.UpdateBasketAsync(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest)
|
||||||
|
{
|
||||||
|
if (customerBasketRequest == null)
|
||||||
{
|
{
|
||||||
_basketClient = basketClient;
|
return null;
|
||||||
_logger = logger;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<BasketData> GetById(string id)
|
var map = new BasketData
|
||||||
{
|
{
|
||||||
_logger.LogDebug("grpc client created, request = {@id}", id);
|
BuyerId = customerBasketRequest.Buyerid
|
||||||
var response = await _basketClient.GetBasketByIdAsync(new BasketRequest { Id = id });
|
};
|
||||||
_logger.LogDebug("grpc response {@response}", response);
|
|
||||||
|
|
||||||
return MapToBasketData(response);
|
customerBasketRequest.Items.ToList().ForEach(item => map.Items.Add(new BasketDataItem
|
||||||
|
{
|
||||||
|
Id = item.Id,
|
||||||
|
OldUnitPrice = (decimal)item.Oldunitprice,
|
||||||
|
PictureUrl = item.Pictureurl,
|
||||||
|
ProductId = item.Productid,
|
||||||
|
ProductName = item.Productname,
|
||||||
|
Quantity = item.Quantity,
|
||||||
|
UnitPrice = (decimal)item.Unitprice
|
||||||
|
}));
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CustomerBasketRequest MapToCustomerBasketRequest(BasketData basketData)
|
||||||
|
{
|
||||||
|
if (basketData == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateAsync(BasketData currentBasket)
|
var map = new CustomerBasketRequest
|
||||||
{
|
{
|
||||||
_logger.LogDebug("Grpc update basket currentBasket {@currentBasket}", currentBasket);
|
Buyerid = basketData.BuyerId
|
||||||
var request = MapToCustomerBasketRequest(currentBasket);
|
};
|
||||||
_logger.LogDebug("Grpc update basket request {@request}", request);
|
|
||||||
|
|
||||||
await _basketClient.UpdateBasketAsync(request);
|
basketData.Items.ToList().ForEach(item => map.Items.Add(new BasketItemResponse
|
||||||
}
|
|
||||||
|
|
||||||
private BasketData MapToBasketData(CustomerBasketResponse customerBasketRequest)
|
|
||||||
{
|
{
|
||||||
if (customerBasketRequest == null)
|
Id = item.Id,
|
||||||
{
|
Oldunitprice = (double)item.OldUnitPrice,
|
||||||
return null;
|
Pictureurl = item.PictureUrl,
|
||||||
}
|
Productid = item.ProductId,
|
||||||
|
Productname = item.ProductName,
|
||||||
|
Quantity = item.Quantity,
|
||||||
|
Unitprice = (double)item.UnitPrice
|
||||||
|
}));
|
||||||
|
|
||||||
var map = new BasketData
|
return map;
|
||||||
{
|
|
||||||
BuyerId = customerBasketRequest.Buyerid
|
|
||||||
};
|
|
||||||
|
|
||||||
customerBasketRequest.Items.ToList().ForEach(item => map.Items.Add(new BasketDataItem
|
|
||||||
{
|
|
||||||
Id = item.Id,
|
|
||||||
OldUnitPrice = (decimal)item.Oldunitprice,
|
|
||||||
PictureUrl = item.Pictureurl,
|
|
||||||
ProductId = item.Productid,
|
|
||||||
ProductName = item.Productname,
|
|
||||||
Quantity = item.Quantity,
|
|
||||||
UnitPrice = (decimal)item.Unitprice
|
|
||||||
}));
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CustomerBasketRequest MapToCustomerBasketRequest(BasketData basketData)
|
|
||||||
{
|
|
||||||
if (basketData == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var map = new CustomerBasketRequest
|
|
||||||
{
|
|
||||||
Buyerid = basketData.BuyerId
|
|
||||||
};
|
|
||||||
|
|
||||||
basketData.Items.ToList().ForEach(item => map.Items.Add(new BasketItemResponse
|
|
||||||
{
|
|
||||||
Id = item.Id,
|
|
||||||
Oldunitprice = (double)item.OldUnitPrice,
|
|
||||||
Pictureurl = item.PictureUrl,
|
|
||||||
Productid = item.ProductId,
|
|
||||||
Productname = item.ProductName,
|
|
||||||
Quantity = item.Quantity,
|
|
||||||
Unitprice = (double)item.UnitPrice
|
|
||||||
}));
|
|
||||||
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,36 @@
|
|||||||
using CatalogApi;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
public class CatalogService : ICatalogService
|
||||||
{
|
{
|
||||||
public class CatalogService : ICatalogService
|
private readonly Catalog.CatalogClient _client;
|
||||||
|
|
||||||
|
public CatalogService(Catalog.CatalogClient client)
|
||||||
{
|
{
|
||||||
private readonly Catalog.CatalogClient _client;
|
_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
public CatalogService(Catalog.CatalogClient client)
|
public async Task<CatalogItem> GetCatalogItemAsync(int id)
|
||||||
{
|
{
|
||||||
_client = client;
|
var request = new CatalogItemRequest { Id = id };
|
||||||
}
|
var response = await _client.GetItemByIdAsync(request);
|
||||||
|
return MapToCatalogItemResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<CatalogItem> GetCatalogItemAsync(int id)
|
public async Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids)
|
||||||
{
|
{
|
||||||
var request = new CatalogItemRequest { Id = id };
|
var request = new CatalogItemsRequest { Ids = string.Join(",", ids), PageIndex = 1, PageSize = 10 };
|
||||||
var response = await _client.GetItemByIdAsync(request);
|
var response = await _client.GetItemsByIdsAsync(request);
|
||||||
return MapToCatalogItemResponse(response);
|
return response.Data.Select(MapToCatalogItemResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids)
|
private CatalogItem MapToCatalogItemResponse(CatalogItemResponse catalogItemResponse)
|
||||||
|
{
|
||||||
|
return new CatalogItem
|
||||||
{
|
{
|
||||||
var request = new CatalogItemsRequest { Ids = string.Join(",", ids), PageIndex = 1, PageSize = 10 };
|
Id = catalogItemResponse.Id,
|
||||||
var response = await _client.GetItemsByIdsAsync(request);
|
Name = catalogItemResponse.Name,
|
||||||
return response.Data.Select(MapToCatalogItemResponse);
|
PictureUri = catalogItemResponse.PictureUri,
|
||||||
}
|
Price = (decimal)catalogItemResponse.Price
|
||||||
|
};
|
||||||
private CatalogItem MapToCatalogItemResponse(CatalogItemResponse catalogItemResponse)
|
|
||||||
{
|
|
||||||
return new CatalogItem
|
|
||||||
{
|
|
||||||
Id = catalogItemResponse.Id,
|
|
||||||
Name = catalogItemResponse.Name,
|
|
||||||
PictureUri = catalogItemResponse.PictureUri,
|
|
||||||
Price = (decimal)catalogItemResponse.Price
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
public interface IBasketService
|
||||||
{
|
{
|
||||||
public interface IBasketService
|
Task<BasketData> GetByIdAsync(string id);
|
||||||
{
|
|
||||||
Task<BasketData> GetById(string id);
|
|
||||||
|
|
||||||
Task UpdateAsync(BasketData currentBasket);
|
Task UpdateAsync(BasketData currentBasket);
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
public interface ICatalogService
|
||||||
{
|
{
|
||||||
public interface ICatalogService
|
Task<CatalogItem> GetCatalogItemAsync(int id);
|
||||||
{
|
|
||||||
Task<CatalogItem> GetCatalogItemAsync(int id);
|
|
||||||
|
|
||||||
Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids);
|
Task<IEnumerable<CatalogItem>> GetCatalogItemsAsync(IEnumerable<int> ids);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
public interface IOrderApiClient
|
||||||
{
|
{
|
||||||
public interface IOrderApiClient
|
Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket);
|
||||||
{
|
|
||||||
Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
public interface IOrderingService
|
||||||
{
|
{
|
||||||
public interface IOrderingService
|
Task<OrderData> GetOrderDraftAsync(BasketData basketData);
|
||||||
{
|
|
||||||
Task<OrderData> GetOrderDraftAsync(BasketData basketData);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,40 +1,28 @@
|
|||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Text.Json;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
public class OrderApiClient : IOrderApiClient
|
||||||
{
|
{
|
||||||
public class OrderApiClient : IOrderApiClient
|
private readonly HttpClient _apiClient;
|
||||||
|
private readonly ILogger<OrderApiClient> _logger;
|
||||||
|
private readonly UrlsConfig _urls;
|
||||||
|
|
||||||
|
public OrderApiClient(HttpClient httpClient, ILogger<OrderApiClient> logger, IOptions<UrlsConfig> config)
|
||||||
{
|
{
|
||||||
private readonly HttpClient _apiClient;
|
_apiClient = httpClient;
|
||||||
private readonly ILogger<OrderApiClient> _logger;
|
_logger = logger;
|
||||||
private readonly UrlsConfig _urls;
|
_urls = config.Value;
|
||||||
|
}
|
||||||
|
|
||||||
public OrderApiClient(HttpClient httpClient, ILogger<OrderApiClient> logger, IOptions<UrlsConfig> config)
|
public async Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket)
|
||||||
{
|
{
|
||||||
_apiClient = httpClient;
|
var uri = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
|
||||||
_logger = logger;
|
var content = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json");
|
||||||
_urls = config.Value;
|
var response = await _apiClient.PostAsync(uri, content);
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<OrderData> GetOrderDraftFromBasketAsync(BasketData basket)
|
response.EnsureSuccessStatusCode();
|
||||||
{
|
|
||||||
var uri = _urls.Orders + UrlsConfig.OrdersOperations.GetOrderDraft();
|
|
||||||
var content = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json");
|
|
||||||
var response = await _apiClient.PostAsync(uri, content);
|
|
||||||
|
|
||||||
response.EnsureSuccessStatusCode();
|
var ordersDraftResponse = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
var ordersDraftResponse = await response.Content.ReadAsStringAsync();
|
return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, JsonDefaults.CaseInsensitiveOptions);
|
||||||
|
|
||||||
return JsonSerializer.Deserialize<OrderData>(ordersDraftResponse, new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
PropertyNameCaseInsensitive = true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,79 +1,72 @@
|
|||||||
using GrpcOrdering;
|
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Models;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services
|
public class OrderingService : IOrderingService
|
||||||
{
|
{
|
||||||
public class OrderingService : IOrderingService
|
private readonly GrpcOrdering.OrderingGrpc.OrderingGrpcClient _orderingGrpcClient;
|
||||||
|
private readonly ILogger<OrderingService> _logger;
|
||||||
|
|
||||||
|
public OrderingService(GrpcOrdering.OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger<OrderingService> logger)
|
||||||
{
|
{
|
||||||
private readonly OrderingGrpc.OrderingGrpcClient _orderingGrpcClient;
|
_orderingGrpcClient = orderingGrpcClient;
|
||||||
private readonly ILogger<OrderingService> _logger;
|
_logger = logger;
|
||||||
|
|
||||||
public OrderingService(OrderingGrpc.OrderingGrpcClient orderingGrpcClient, ILogger<OrderingService> logger)
|
|
||||||
{
|
|
||||||
_orderingGrpcClient = orderingGrpcClient;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<OrderData> GetOrderDraftAsync(BasketData basketData)
|
|
||||||
{
|
|
||||||
_logger.LogDebug(" grpc client created, basketData={@basketData}", basketData);
|
|
||||||
|
|
||||||
var command = MapToOrderDraftCommand(basketData);
|
|
||||||
var response = await _orderingGrpcClient.CreateOrderDraftFromBasketDataAsync(command);
|
|
||||||
_logger.LogDebug(" grpc response: {@response}", response);
|
|
||||||
|
|
||||||
return MapToResponse(response, basketData);
|
|
||||||
}
|
|
||||||
|
|
||||||
private OrderData MapToResponse(GrpcOrdering.OrderDraftDTO orderDraft, BasketData basketData)
|
|
||||||
{
|
|
||||||
if (orderDraft == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var data = new OrderData
|
|
||||||
{
|
|
||||||
Buyer = basketData.BuyerId,
|
|
||||||
Total = (decimal)orderDraft.Total,
|
|
||||||
};
|
|
||||||
|
|
||||||
orderDraft.OrderItems.ToList().ForEach(o => data.OrderItems.Add(new OrderItemData
|
|
||||||
{
|
|
||||||
Discount = (decimal)o.Discount,
|
|
||||||
PictureUrl = o.PictureUrl,
|
|
||||||
ProductId = o.ProductId,
|
|
||||||
ProductName = o.ProductName,
|
|
||||||
UnitPrice = (decimal)o.UnitPrice,
|
|
||||||
Units = o.Units,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData)
|
|
||||||
{
|
|
||||||
var command = new CreateOrderDraftCommand
|
|
||||||
{
|
|
||||||
BuyerId = basketData.BuyerId,
|
|
||||||
};
|
|
||||||
|
|
||||||
basketData.Items.ForEach(i => command.Items.Add(new BasketItem
|
|
||||||
{
|
|
||||||
Id = i.Id,
|
|
||||||
OldUnitPrice = (double)i.OldUnitPrice,
|
|
||||||
PictureUrl = i.PictureUrl,
|
|
||||||
ProductId = i.ProductId,
|
|
||||||
ProductName = i.ProductName,
|
|
||||||
Quantity = i.Quantity,
|
|
||||||
UnitPrice = (double)i.UnitPrice,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return command;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<OrderData> GetOrderDraftAsync(BasketData basketData)
|
||||||
|
{
|
||||||
|
_logger.LogDebug(" grpc client created, basketData={@basketData}", basketData);
|
||||||
|
|
||||||
|
var command = MapToOrderDraftCommand(basketData);
|
||||||
|
var response = await _orderingGrpcClient.CreateOrderDraftFromBasketDataAsync(command);
|
||||||
|
_logger.LogDebug(" grpc response: {@response}", response);
|
||||||
|
|
||||||
|
return MapToResponse(response, basketData);
|
||||||
|
}
|
||||||
|
|
||||||
|
private OrderData MapToResponse(GrpcOrdering.OrderDraftDTO orderDraft, BasketData basketData)
|
||||||
|
{
|
||||||
|
if (orderDraft == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var data = new OrderData
|
||||||
|
{
|
||||||
|
Buyer = basketData.BuyerId,
|
||||||
|
Total = (decimal)orderDraft.Total,
|
||||||
|
};
|
||||||
|
|
||||||
|
orderDraft.OrderItems.ToList().ForEach(o => data.OrderItems.Add(new OrderItemData
|
||||||
|
{
|
||||||
|
Discount = (decimal)o.Discount,
|
||||||
|
PictureUrl = o.PictureUrl,
|
||||||
|
ProductId = o.ProductId,
|
||||||
|
ProductName = o.ProductName,
|
||||||
|
UnitPrice = (decimal)o.UnitPrice,
|
||||||
|
Units = o.Units,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private GrpcOrdering.CreateOrderDraftCommand MapToOrderDraftCommand(BasketData basketData)
|
||||||
|
{
|
||||||
|
var command = new GrpcOrdering.CreateOrderDraftCommand
|
||||||
|
{
|
||||||
|
BuyerId = basketData.BuyerId,
|
||||||
|
};
|
||||||
|
|
||||||
|
basketData.Items.ForEach(i => command.Items.Add(new GrpcOrdering.BasketItem
|
||||||
|
{
|
||||||
|
Id = i.Id,
|
||||||
|
OldUnitPrice = (double)i.OldUnitPrice,
|
||||||
|
PictureUrl = i.PictureUrl,
|
||||||
|
ProductId = i.ProductId,
|
||||||
|
ProductName = i.ProductName,
|
||||||
|
Quantity = i.Quantity,
|
||||||
|
UnitPrice = (double)i.UnitPrice,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,222 +0,0 @@
|
|||||||
using CatalogApi;
|
|
||||||
using Devspaces.Support;
|
|
||||||
using GrpcBasket;
|
|
||||||
using GrpcOrdering;
|
|
||||||
using HealthChecks.UI.Client;
|
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Config;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Filters.Basket.API.Infrastructure.Filters;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Infrastructure;
|
|
||||||
using Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator.Services;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Mobile.Shopping.HttpAggregator
|
|
||||||
{
|
|
||||||
public class Startup
|
|
||||||
{
|
|
||||||
public Startup(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
Configuration = configuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IConfiguration Configuration { get; }
|
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to add services to the container.
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddHealthChecks()
|
|
||||||
.AddCheck("self", () => HealthCheckResult.Healthy())
|
|
||||||
.AddUrlGroup(new Uri(Configuration["CatalogUrlHC"]), name: "catalogapi-check", tags: new string[] { "catalogapi" })
|
|
||||||
.AddUrlGroup(new Uri(Configuration["OrderingUrlHC"]), name: "orderingapi-check", tags: new string[] { "orderingapi" })
|
|
||||||
.AddUrlGroup(new Uri(Configuration["BasketUrlHC"]), name: "basketapi-check", tags: new string[] { "basketapi" })
|
|
||||||
.AddUrlGroup(new Uri(Configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" })
|
|
||||||
.AddUrlGroup(new Uri(Configuration["PaymentUrlHC"]), name: "paymentapi-check", tags: new string[] { "paymentapi" });
|
|
||||||
|
|
||||||
services.AddCustomMvc(Configuration)
|
|
||||||
.AddCustomAuthentication(Configuration)
|
|
||||||
.AddDevspaces()
|
|
||||||
.AddHttpServices()
|
|
||||||
.AddGrpcServices();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
|
|
||||||
{
|
|
||||||
var pathBase = Configuration["PATH_BASE"];
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(pathBase))
|
|
||||||
{
|
|
||||||
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase);
|
|
||||||
app.UsePathBase(pathBase);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (env.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseDeveloperExceptionPage();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseSwagger().UseSwaggerUI(c =>
|
|
||||||
{
|
|
||||||
c.SwaggerEndpoint($"{ (!string.IsNullOrEmpty(pathBase) ? pathBase : string.Empty) }/swagger/v1/swagger.json", "Purchase BFF V1");
|
|
||||||
|
|
||||||
c.OAuthClientId("mobileshoppingaggswaggerui");
|
|
||||||
c.OAuthClientSecret(string.Empty);
|
|
||||||
c.OAuthRealm(string.Empty);
|
|
||||||
c.OAuthAppName("Purchase BFF Swagger UI");
|
|
||||||
});
|
|
||||||
|
|
||||||
app.UseRouting();
|
|
||||||
app.UseCors("CorsPolicy");
|
|
||||||
app.UseAuthentication();
|
|
||||||
app.UseAuthorization();
|
|
||||||
app.UseEndpoints(endpoints =>
|
|
||||||
{
|
|
||||||
endpoints.MapDefaultControllerRoute();
|
|
||||||
endpoints.MapControllers();
|
|
||||||
endpoints.MapHealthChecks("/hc", new HealthCheckOptions()
|
|
||||||
{
|
|
||||||
Predicate = _ => true,
|
|
||||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
|
|
||||||
});
|
|
||||||
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions
|
|
||||||
{
|
|
||||||
Predicate = r => r.Name.Contains("self")
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ServiceCollectionExtensions
|
|
||||||
{
|
|
||||||
public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
services.AddOptions();
|
|
||||||
services.Configure<UrlsConfig>(configuration.GetSection("urls"));
|
|
||||||
|
|
||||||
services.AddControllers()
|
|
||||||
.AddJsonOptions(options => options.JsonSerializerOptions.WriteIndented = true);
|
|
||||||
|
|
||||||
services.AddSwaggerGen(options =>
|
|
||||||
{
|
|
||||||
options.DescribeAllEnumsAsStrings();
|
|
||||||
options.SwaggerDoc("v1", new OpenApiInfo
|
|
||||||
{
|
|
||||||
Title = "Shopping Aggregator for Mobile Clients",
|
|
||||||
Version = "v1",
|
|
||||||
Description = "Shopping Aggregator for Mobile Clients"
|
|
||||||
});
|
|
||||||
options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
|
|
||||||
{
|
|
||||||
Type = SecuritySchemeType.OAuth2,
|
|
||||||
Flows = new OpenApiOAuthFlows()
|
|
||||||
{
|
|
||||||
Implicit = new OpenApiOAuthFlow()
|
|
||||||
{
|
|
||||||
AuthorizationUrl = new Uri($"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/authorize"),
|
|
||||||
TokenUrl = new Uri($"{configuration.GetValue<string>("IdentityUrlExternal")}/connect/token"),
|
|
||||||
|
|
||||||
Scopes = new Dictionary<string, string>()
|
|
||||||
{
|
|
||||||
{ "mobileshoppingagg", "Shopping Aggregator for Mobile Clients" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
options.OperationFilter<AuthorizeCheckOperationFilter>();
|
|
||||||
});
|
|
||||||
|
|
||||||
services.AddCors(options =>
|
|
||||||
{
|
|
||||||
options.AddPolicy("CorsPolicy",
|
|
||||||
builder => builder
|
|
||||||
.AllowAnyMethod()
|
|
||||||
.AllowAnyHeader()
|
|
||||||
.SetIsOriginAllowed((host) => true)
|
|
||||||
.AllowCredentials());
|
|
||||||
});
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration)
|
|
||||||
{
|
|
||||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub");
|
|
||||||
|
|
||||||
var identityUrl = configuration.GetValue<string>("urls:identity");
|
|
||||||
|
|
||||||
services.AddAuthentication(options =>
|
|
||||||
{
|
|
||||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
|
|
||||||
})
|
|
||||||
.AddJwtBearer(options =>
|
|
||||||
{
|
|
||||||
options.Authority = identityUrl;
|
|
||||||
options.RequireHttpsMetadata = false;
|
|
||||||
options.Audience = "mobileshoppingagg";
|
|
||||||
});
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddHttpServices(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
//register delegating handlers
|
|
||||||
services.AddTransient<HttpClientAuthorizationDelegatingHandler>();
|
|
||||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
|
||||||
|
|
||||||
//register http services
|
|
||||||
|
|
||||||
services.AddHttpClient<IOrderApiClient, OrderApiClient>()
|
|
||||||
.AddDevspacesSupport();
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IServiceCollection AddGrpcServices(this IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddTransient<GrpcExceptionInterceptor>();
|
|
||||||
|
|
||||||
services.AddScoped<IBasketService, BasketService>();
|
|
||||||
|
|
||||||
services.AddGrpcClient<Basket.BasketClient>((services, options) =>
|
|
||||||
{
|
|
||||||
var basketApi = services.GetRequiredService<IOptions<UrlsConfig>>().Value.GrpcBasket;
|
|
||||||
options.Address = new Uri(basketApi);
|
|
||||||
}).AddInterceptor<GrpcExceptionInterceptor>();
|
|
||||||
|
|
||||||
services.AddScoped<ICatalogService, CatalogService>();
|
|
||||||
|
|
||||||
services.AddGrpcClient<Catalog.CatalogClient>((services, options) =>
|
|
||||||
{
|
|
||||||
var catalogApi = services.GetRequiredService<IOptions<UrlsConfig>>().Value.GrpcCatalog;
|
|
||||||
options.Address = new Uri(catalogApi);
|
|
||||||
}).AddInterceptor<GrpcExceptionInterceptor>();
|
|
||||||
|
|
||||||
services.AddScoped<IOrderingService, OrderingService>();
|
|
||||||
|
|
||||||
services.AddGrpcClient<OrderingGrpc.OrderingGrpcClient>((services, options) =>
|
|
||||||
{
|
|
||||||
var orderingApi = services.GetRequiredService<IOptions<UrlsConfig>>().Value.GrpcOrdering;
|
|
||||||
options.Address = new Uri(orderingApi);
|
|
||||||
}).AddInterceptor<GrpcExceptionInterceptor>();
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +1,138 @@
|
|||||||
{
|
{
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
"LogLevel": {
|
||||||
"Debug": {
|
"Default": "Information",
|
||||||
"LogLevel": {
|
"Microsoft.AspNetCore": "Warning",
|
||||||
"Default": "Warning"
|
"System.Net.Http": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"OpenApi": {
|
||||||
|
"Endpoint": {
|
||||||
|
"Name": "Purchase BFF V1"
|
||||||
|
},
|
||||||
|
"Document": {
|
||||||
|
"Description": "Shopping Aggregator for Mobile Clients",
|
||||||
|
"Title": "Shopping Aggregator for Mobile Clients",
|
||||||
|
"Version": "v1"
|
||||||
|
},
|
||||||
|
"Auth": {
|
||||||
|
"ClientId": "mobileshoppingaggswaggerui",
|
||||||
|
"AppName": "Mobile shopping BFF Swagger UI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Identity": {
|
||||||
|
"Url": "http://localhost:5223",
|
||||||
|
"Audience": "mobileshoppingagg",
|
||||||
|
"Scopes": {
|
||||||
|
"webshoppingagg": "Shopping Aggregator for Mobile Clients"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ReverseProxy": {
|
||||||
|
"Routes": {
|
||||||
|
"c-short": {
|
||||||
|
"ClusterId": "catalog",
|
||||||
|
"Match": {
|
||||||
|
"Path": "c/{**catch-all}"
|
||||||
|
},
|
||||||
|
"Transforms": [
|
||||||
|
{ "PathRemovePrefix": "/c" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"c-long": {
|
||||||
|
"ClusterId": "catalog",
|
||||||
|
"Match": {
|
||||||
|
"Path": "catalog-api/{**catch-all}"
|
||||||
|
},
|
||||||
|
"Transforms": [
|
||||||
|
{ "PathRemovePrefix": "/catalog-api" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"b-short": {
|
||||||
|
"ClusterId": "basket",
|
||||||
|
"Match": {
|
||||||
|
"Path": "b/{**catch-all}"
|
||||||
|
},
|
||||||
|
"Transforms": [
|
||||||
|
{ "PathRemovePrefix": "/b" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"b-long": {
|
||||||
|
"ClusterId": "basket",
|
||||||
|
"Match": {
|
||||||
|
"Path": "basket-api/{**catch-all}"
|
||||||
|
},
|
||||||
|
"Transforms": [
|
||||||
|
{ "PathRemovePrefix": "/basket-api" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"o-short": {
|
||||||
|
"ClusterId": "orders",
|
||||||
|
"Match": {
|
||||||
|
"Path": "o/{**catch-all}"
|
||||||
|
},
|
||||||
|
"Transforms": [
|
||||||
|
{ "PathRemovePrefix": "/o" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"o-long": {
|
||||||
|
"ClusterId": "orders",
|
||||||
|
"Match": {
|
||||||
|
"Path": "ordering-api/{**catch-all}"
|
||||||
|
},
|
||||||
|
"Transforms": [
|
||||||
|
{ "PathRemovePrefix": "/ordering-api" }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"h-long": {
|
||||||
|
"ClusterId": "signalr",
|
||||||
|
"Match": {
|
||||||
|
"Path": "hub/notificationhub/{**catch-all}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Console": {
|
"Clusters": {
|
||||||
"LogLevel": {
|
"basket": {
|
||||||
"Default": "Warning"
|
"Destinations": {
|
||||||
|
"destination0": {
|
||||||
|
"Address": "http://localhost:5221"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"catalog": {
|
||||||
|
"Destinations": {
|
||||||
|
"destination0": {
|
||||||
|
"Address": "http://localhost:5222"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"orders": {
|
||||||
|
"Destinations": {
|
||||||
|
"destination0": {
|
||||||
|
"Address": "http://localhost:5224"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"signalr": {
|
||||||
|
"Destinations": {
|
||||||
|
"destination0": {
|
||||||
|
"Address": "http://localhost:5225"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"Urls": {
|
||||||
|
"Basket": "http://localhost:5221",
|
||||||
|
"Catalog": "http://localhost:5222",
|
||||||
|
"Orders": "http://localhost:5224",
|
||||||
|
"Identity": "http://localhost:5223",
|
||||||
|
"Signalr": "http://localhost:5225",
|
||||||
|
"GrpcBasket": "http://localhost:6221",
|
||||||
|
"GrpcCatalog": "http://localhost:6222",
|
||||||
|
"GrpcOrdering": "http://localhost:6224"
|
||||||
|
},
|
||||||
|
"CatalogUrlHC": "http://localhost:5222/hc",
|
||||||
|
"OrderingUrlHC": "http://localhost:5224/hc",
|
||||||
|
"BasketUrlHC": "http://localhost:5221/hc",
|
||||||
|
"IdentityUrlHC": "http://localhost:5223/hc"
|
||||||
}
|
}
|
||||||
|
@ -8,16 +8,19 @@
|
|||||||
"grpcCatalog": "http://localhost:81",
|
"grpcCatalog": "http://localhost:81",
|
||||||
"grpcOrdering": "http://localhost:5581"
|
"grpcOrdering": "http://localhost:5581"
|
||||||
},
|
},
|
||||||
"IdentityUrlExternal": "http://localhost:5105",
|
"Identity": {
|
||||||
"IdentityUrl": "http://localhost:5105",
|
"ExternalUrl": "http://localhost:5105",
|
||||||
|
"Url": "http://localhost:5105",
|
||||||
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"IncludeScopes": false,
|
|
||||||
"Debug": {
|
"Debug": {
|
||||||
|
"IncludeScopes": false,
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Debug"
|
"Default": "Debug"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Console": {
|
"Console": {
|
||||||
|
"IncludeScopes": false,
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
"Default": "Debug"
|
"Default": "Debug"
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
kind: helm-release
|
|
||||||
apiVersion: 1.1
|
|
||||||
build:
|
|
||||||
context: ..\..\..\..
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
install:
|
|
||||||
chart: ../../../../k8s/helm/mobileshoppingagg
|
|
||||||
set:
|
|
||||||
image:
|
|
||||||
tag: $(tag)
|
|
||||||
pullPolicy: Never
|
|
||||||
ingress:
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/ingress.class: traefik-azds
|
|
||||||
hosts:
|
|
||||||
# This expands to [space.s.]apigwms.<guid>.<region>.aksapp.io
|
|
||||||
- $(spacePrefix)eshop$(hostSuffix)
|
|
||||||
inf:
|
|
||||||
k8s:
|
|
||||||
dns: $(spacePrefix)eshop$(hostSuffix)
|
|
||||||
values:
|
|
||||||
- values.dev.yaml?
|
|
||||||
- secrets.dev.yaml?
|
|
||||||
- app.yaml
|
|
||||||
- inf.yaml
|
|
||||||
configurations:
|
|
||||||
develop:
|
|
||||||
build:
|
|
||||||
useGitIgnore: true
|
|
||||||
dockerfile: Dockerfile.develop
|
|
||||||
container:
|
|
||||||
syncTarget: /src
|
|
||||||
sync:
|
|
||||||
- '**/Pages/**'
|
|
||||||
- '**/Views/**'
|
|
||||||
- '**/wwwroot/**'
|
|
||||||
- '!**/*.{sln,csproj}'
|
|
||||||
command:
|
|
||||||
- dotnet
|
|
||||||
- run
|
|
||||||
- --no-restore
|
|
||||||
- --no-build
|
|
||||||
- --no-launch-profile
|
|
||||||
- -c
|
|
||||||
- ${Configuration:-Debug}
|
|
||||||
iterate:
|
|
||||||
processesToKill:
|
|
||||||
- dotnet
|
|
||||||
- vsdbg
|
|
||||||
buildCommands:
|
|
||||||
- - dotnet
|
|
||||||
- build
|
|
||||||
- --no-restore
|
|
||||||
- -c
|
|
||||||
- ${Configuration:-Debug}
|
|
@ -1,45 +1,41 @@
|
|||||||
using System.Collections.Generic;
|
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config;
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Config
|
public class UrlsConfig
|
||||||
{
|
{
|
||||||
|
|
||||||
public class UrlsConfig
|
public class CatalogOperations
|
||||||
{
|
{
|
||||||
|
// grpc call under REST must go trough port 80
|
||||||
|
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}";
|
||||||
|
|
||||||
public class CatalogOperations
|
public static string GetItemById(string ids) => $"/api/v1/catalog/items/ids/{string.Join(',', ids)}";
|
||||||
{
|
|
||||||
// grpc call under REST must go trough port 80
|
|
||||||
public static string GetItemById(int id) => $"/api/v1/catalog/items/{id}";
|
|
||||||
|
|
||||||
public static string GetItemById(string ids) => $"/api/v1/catalog/items/ids/{string.Join(',', ids)}";
|
// REST call standard must go through port 5000
|
||||||
|
public static string GetItemsById(IEnumerable<int> ids) => $":5000/api/v1/catalog/items?ids={string.Join(',', ids)}";
|
||||||
// REST call standard must go through port 5000
|
|
||||||
public static string GetItemsById(IEnumerable<int> ids) => $":5000/api/v1/catalog/items?ids={string.Join(',', ids)}";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class BasketOperations
|
|
||||||
{
|
|
||||||
public static string GetItemById(string id) => $"/api/v1/basket/{id}";
|
|
||||||
|
|
||||||
public static string UpdateBasket() => "/api/v1/basket";
|
|
||||||
}
|
|
||||||
|
|
||||||
public class OrdersOperations
|
|
||||||
{
|
|
||||||
public static string GetOrderDraft() => "/api/v1/orders/draft";
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Basket { get; set; }
|
|
||||||
|
|
||||||
public string Catalog { get; set; }
|
|
||||||
|
|
||||||
public string Orders { get; set; }
|
|
||||||
|
|
||||||
public string GrpcBasket { get; set; }
|
|
||||||
|
|
||||||
public string GrpcCatalog { get; set; }
|
|
||||||
|
|
||||||
public string GrpcOrdering { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class BasketOperations
|
||||||
|
{
|
||||||
|
public static string GetItemById(string id) => $"/api/v1/basket/{id}";
|
||||||
|
|
||||||
|
public static string UpdateBasket() => "/api/v1/basket";
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OrdersOperations
|
||||||
|
{
|
||||||
|
public static string GetOrderDraft() => "/api/v1/orders/draft";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Basket { get; set; }
|
||||||
|
|
||||||
|
public string Catalog { get; set; }
|
||||||
|
|
||||||
|
public string Orders { get; set; }
|
||||||
|
|
||||||
|
public string GrpcBasket { get; set; }
|
||||||
|
|
||||||
|
public string GrpcCatalog { get; set; }
|
||||||
|
|
||||||
|
public string GrpcOrdering { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,164 +1,152 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
|
|
||||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
|
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
|
[Route("api/v1/[controller]")]
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
public class BasketController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/v1/[controller]")]
|
private readonly ICatalogService _catalog;
|
||||||
[Authorize]
|
private readonly IBasketService _basket;
|
||||||
[ApiController]
|
|
||||||
public class BasketController : ControllerBase
|
public BasketController(ICatalogService catalogService, IBasketService basketService)
|
||||||
{
|
{
|
||||||
private readonly ICatalogService _catalog;
|
_catalog = catalogService;
|
||||||
private readonly IBasketService _basket;
|
_basket = basketService;
|
||||||
|
}
|
||||||
|
|
||||||
public BasketController(ICatalogService catalogService, IBasketService basketService)
|
[HttpPost]
|
||||||
|
[HttpPut]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<BasketData>> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data)
|
||||||
|
{
|
||||||
|
if (data.Items == null || !data.Items.Any())
|
||||||
{
|
{
|
||||||
_catalog = catalogService;
|
return BadRequest("Need to pass at least one basket line");
|
||||||
_basket = basketService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
// Retrieve the current basket
|
||||||
[HttpPut]
|
var basket = await _basket.GetByIdAsync(data.BuyerId) ?? new BasketData(data.BuyerId);
|
||||||
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
|
||||||
[ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<ActionResult<BasketData>> UpdateAllBasketAsync([FromBody] UpdateBasketRequest data)
|
// group by product id to avoid duplicates
|
||||||
|
var itemsCalculated = data
|
||||||
|
.Items
|
||||||
|
.GroupBy(x => x.ProductId, x => x, (k, i) => new { productId = k, items = i })
|
||||||
|
.Select(groupedItem =>
|
||||||
|
{
|
||||||
|
var item = groupedItem.items.First();
|
||||||
|
item.Quantity = groupedItem.items.Sum(i => i.Quantity);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
foreach (var bitem in itemsCalculated)
|
||||||
{
|
{
|
||||||
if (data.Items == null || !data.Items.Any())
|
var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId);
|
||||||
|
if (catalogItem == null)
|
||||||
{
|
{
|
||||||
return BadRequest("Need to pass at least one basket line");
|
return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the current basket
|
var itemInBasket = basket.Items.FirstOrDefault(x => x.ProductId == bitem.ProductId);
|
||||||
var basket = await _basket.GetById(data.BuyerId) ?? new BasketData(data.BuyerId);
|
if (itemInBasket == null)
|
||||||
var catalogItems = await _catalog.GetCatalogItemsAsync(data.Items.Select(x => x.ProductId));
|
|
||||||
|
|
||||||
// group by product id to avoid duplicates
|
|
||||||
var itemsCalculated = data
|
|
||||||
.Items
|
|
||||||
.GroupBy(x => x.ProductId, x => x, (k, i) => new { productId = k, items = i })
|
|
||||||
.Select(groupedItem =>
|
|
||||||
{
|
|
||||||
var item = groupedItem.items.First();
|
|
||||||
item.Quantity = groupedItem.items.Sum(i => i.Quantity);
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
|
|
||||||
foreach (var bitem in itemsCalculated)
|
|
||||||
{
|
{
|
||||||
var catalogItem = catalogItems.SingleOrDefault(ci => ci.Id == bitem.ProductId);
|
basket.Items.Add(new BasketDataItem()
|
||||||
if (catalogItem == null)
|
|
||||||
{
|
{
|
||||||
return BadRequest($"Basket refers to a non-existing catalog item ({bitem.ProductId})");
|
Id = bitem.Id,
|
||||||
}
|
ProductId = catalogItem.Id,
|
||||||
|
ProductName = catalogItem.Name,
|
||||||
var itemInBasket = basket.Items.FirstOrDefault(x => x.ProductId == bitem.ProductId);
|
PictureUrl = catalogItem.PictureUri,
|
||||||
if (itemInBasket == null)
|
UnitPrice = catalogItem.Price,
|
||||||
{
|
Quantity = bitem.Quantity
|
||||||
basket.Items.Add(new BasketDataItem()
|
});
|
||||||
{
|
|
||||||
Id = bitem.Id,
|
|
||||||
ProductId = catalogItem.Id,
|
|
||||||
ProductName = catalogItem.Name,
|
|
||||||
PictureUrl = catalogItem.PictureUri,
|
|
||||||
UnitPrice = catalogItem.Price,
|
|
||||||
Quantity = bitem.Quantity
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
itemInBasket.Quantity = bitem.Quantity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await _basket.UpdateAsync(basket);
|
|
||||||
|
|
||||||
return basket;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPut]
|
|
||||||
[Route("items")]
|
|
||||||
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
|
||||||
[ProducesResponseType(typeof(BasketData), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<ActionResult<BasketData>> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data)
|
|
||||||
{
|
|
||||||
if (!data.Updates.Any())
|
|
||||||
{
|
|
||||||
return BadRequest("No updates sent");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the current basket
|
|
||||||
var currentBasket = await _basket.GetById(data.BasketId);
|
|
||||||
if (currentBasket == null)
|
|
||||||
{
|
|
||||||
return BadRequest($"Basket with id {data.BasketId} not found.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update with new quantities
|
|
||||||
foreach (var update in data.Updates)
|
|
||||||
{
|
|
||||||
var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId);
|
|
||||||
if (basketItem == null)
|
|
||||||
{
|
|
||||||
return BadRequest($"Basket item with id {update.BasketItemId} not found");
|
|
||||||
}
|
|
||||||
basketItem.Quantity = update.NewQty;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the updated basket
|
|
||||||
await _basket.UpdateAsync(currentBasket);
|
|
||||||
|
|
||||||
return currentBasket;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost]
|
|
||||||
[Route("items")]
|
|
||||||
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
|
||||||
[ProducesResponseType((int)HttpStatusCode.OK)]
|
|
||||||
public async Task<ActionResult> AddBasketItemAsync([FromBody] AddBasketItemRequest data)
|
|
||||||
{
|
|
||||||
if (data == null || data.Quantity == 0)
|
|
||||||
{
|
|
||||||
return BadRequest("Invalid payload");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 1: Get the item from catalog
|
|
||||||
var item = await _catalog.GetCatalogItemAsync(data.CatalogItemId);
|
|
||||||
|
|
||||||
//item.PictureUri =
|
|
||||||
|
|
||||||
// Step 2: Get current basket status
|
|
||||||
var currentBasket = (await _basket.GetById(data.BasketId)) ?? new BasketData(data.BasketId);
|
|
||||||
// Step 3: Search if exist product into basket
|
|
||||||
var product = currentBasket.Items.SingleOrDefault(i => i.ProductId == item.Id);
|
|
||||||
if (product != null)
|
|
||||||
{
|
|
||||||
// Step 4: Update quantity for product
|
|
||||||
product.Quantity += data.Quantity;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Step 4: Merge current status with new product
|
itemInBasket.Quantity = bitem.Quantity;
|
||||||
currentBasket.Items.Add(new BasketDataItem()
|
|
||||||
{
|
|
||||||
UnitPrice = item.Price,
|
|
||||||
PictureUrl = item.PictureUri,
|
|
||||||
ProductId = item.Id,
|
|
||||||
ProductName = item.Name,
|
|
||||||
Quantity = data.Quantity,
|
|
||||||
Id = Guid.NewGuid().ToString()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 5: Update basket
|
|
||||||
await _basket.UpdateAsync(currentBasket);
|
|
||||||
|
|
||||||
return Ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await _basket.UpdateAsync(basket);
|
||||||
|
|
||||||
|
return basket;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPut]
|
||||||
|
[Route("items")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<BasketData>> UpdateQuantitiesAsync([FromBody] UpdateBasketItemsRequest data)
|
||||||
|
{
|
||||||
|
if (!data.Updates.Any())
|
||||||
|
{
|
||||||
|
return BadRequest("No updates sent");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the current basket
|
||||||
|
var currentBasket = await _basket.GetByIdAsync(data.BasketId);
|
||||||
|
if (currentBasket == null)
|
||||||
|
{
|
||||||
|
return BadRequest($"Basket with id {data.BasketId} not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update with new quantities
|
||||||
|
foreach (var update in data.Updates)
|
||||||
|
{
|
||||||
|
var basketItem = currentBasket.Items.SingleOrDefault(bitem => bitem.Id == update.BasketItemId);
|
||||||
|
if (basketItem == null)
|
||||||
|
{
|
||||||
|
return BadRequest($"Basket item with id {update.BasketItemId} not found");
|
||||||
|
}
|
||||||
|
basketItem.Quantity = update.NewQty;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the updated basket
|
||||||
|
await _basket.UpdateAsync(currentBasket);
|
||||||
|
|
||||||
|
return currentBasket;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("items")]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||||
|
public async Task<ActionResult> AddBasketItemAsync([FromBody] AddBasketItemRequest data)
|
||||||
|
{
|
||||||
|
if (data == null || data.Quantity == 0)
|
||||||
|
{
|
||||||
|
return BadRequest("Invalid payload");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 1: Get the item from catalog
|
||||||
|
var item = await _catalog.GetCatalogItemAsync(data.CatalogItemId);
|
||||||
|
|
||||||
|
//item.PictureUri =
|
||||||
|
|
||||||
|
// Step 2: Get current basket status
|
||||||
|
var currentBasket = (await _basket.GetByIdAsync(data.BasketId)) ?? new BasketData(data.BasketId);
|
||||||
|
// Step 3: Search if exist product into basket
|
||||||
|
var product = currentBasket.Items.SingleOrDefault(i => i.ProductId == item.Id);
|
||||||
|
if (product != null)
|
||||||
|
{
|
||||||
|
// Step 4: Update quantity for product
|
||||||
|
product.Quantity += data.Quantity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Step 4: Merge current status with new product
|
||||||
|
currentBasket.Items.Add(new BasketDataItem()
|
||||||
|
{
|
||||||
|
UnitPrice = item.Price,
|
||||||
|
PictureUrl = item.PictureUri,
|
||||||
|
ProductId = item.Id,
|
||||||
|
ProductName = item.Name,
|
||||||
|
Quantity = data.Quantity,
|
||||||
|
Id = Guid.NewGuid().ToString()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 5: Update basket
|
||||||
|
await _basket.UpdateAsync(currentBasket);
|
||||||
|
|
||||||
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
|
|
||||||
{
|
|
||||||
[Route("")]
|
|
||||||
public class HomeController : Controller
|
|
||||||
{
|
|
||||||
[HttpGet()]
|
|
||||||
public IActionResult Index()
|
|
||||||
{
|
|
||||||
return new RedirectResult("~/swagger");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +1,36 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Models;
|
|
||||||
using Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Services;
|
|
||||||
using System.Net;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Microsoft.eShopOnContainers.Web.Shopping.HttpAggregator.Controllers
|
[Route("api/v1/[controller]")]
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
public class OrderController : ControllerBase
|
||||||
{
|
{
|
||||||
[Route("api/v1/[controller]")]
|
private readonly IBasketService _basketService;
|
||||||
[Authorize]
|
private readonly IOrderingService _orderingService;
|
||||||
[ApiController]
|
|
||||||
public class OrderController : ControllerBase
|
public OrderController(IBasketService basketService, IOrderingService orderingService)
|
||||||
{
|
{
|
||||||
private readonly IBasketService _basketService;
|
_basketService = basketService;
|
||||||
private readonly IOrderingService _orderingService;
|
_orderingService = orderingService;
|
||||||
public OrderController(IBasketService basketService, IOrderingService orderingService)
|
}
|
||||||
|
|
||||||
|
[Route("draft/{basketId}")]
|
||||||
|
[HttpGet]
|
||||||
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
||||||
|
public async Task<ActionResult<OrderData>> GetOrderDraftAsync(string basketId)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(basketId))
|
||||||
{
|
{
|
||||||
_basketService = basketService;
|
return BadRequest("Need a valid basketid");
|
||||||
_orderingService = orderingService;
|
}
|
||||||
|
// Get the basket data and build a order draft based on it
|
||||||
|
var basket = await _basketService.GetByIdAsync(basketId);
|
||||||
|
|
||||||
|
if (basket == null)
|
||||||
|
{
|
||||||
|
return BadRequest($"No basket found for id {basketId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("draft/{basketId}")]
|
return await _orderingService.GetOrderDraftAsync(basket);
|
||||||
[HttpGet]
|
|
||||||
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
|
|
||||||
[ProducesResponseType(typeof(OrderData), (int)HttpStatusCode.OK)]
|
|
||||||
public async Task<ActionResult<OrderData>> GetOrderDraftAsync(string basketId)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(basketId))
|
|
||||||
{
|
|
||||||
return BadRequest("Need a valid basketid");
|
|
||||||
}
|
|
||||||
// Get the basket data and build a order draft based on it
|
|
||||||
var basket = await _basketService.GetById(basketId);
|
|
||||||
|
|
||||||
if (basket == null)
|
|
||||||
{
|
|
||||||
return BadRequest($"No basket found for id {basketId}");
|
|
||||||
}
|
|
||||||
|
|
||||||
return await _orderingService.GetOrderDraftAsync(basket);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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