├── .editorconfig
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ └── build.yml
├── .gitignore
├── CONTRIBUTING.md
├── Directory.Packages.props
├── LICENSE.txt
├── README.md
├── SECURITY.md
├── SkipStrongName.ps1
├── build.ps1
├── buildAll.proj
├── code.sln
├── nuget.config
├── nuget
└── NuGet.exe
├── nuprojs
├── SF.AspNetCore.Internal
│ └── SF.AspNetCore.Internal.nuproj
└── packages.config
├── properties
├── Key.snk
├── service_fabric_common.props
├── service_fabric_managed.targets
├── service_fabric_managed_common.props
├── service_fabric_managed_stylecop.props
├── service_fabric_nuget.props
├── service_fabric_nuget.targets
└── stylecop
│ ├── StylecopSuppressions.cs
│ └── stylecop.json
├── refs
└── readme.txt
├── src
├── Microsoft.ServiceFabric.AspNetCore.Configuration
│ ├── Microsoft.ServiceFabric.AspNetCore.Configuration.csproj
│ ├── SR.Designer.cs
│ ├── SR.resx
│ ├── ServiceFabricConfigurationExtensions.cs
│ ├── ServiceFabricConfigurationOptions.cs
│ ├── ServiceFabricConfigurationProvider.cs
│ └── ServiceFabricConfigurationSource.cs
├── Microsoft.ServiceFabric.AspNetCore.HttpSys
│ ├── HttpSysCommunicationListener.cs
│ ├── Microsoft.ServiceFabric.AspNetCore.HttpSys.csproj
│ ├── SR.Designer.cs
│ └── SR.resx
├── Microsoft.ServiceFabric.AspNetCore.Kestrel
│ ├── KestrelCommunicationListener.cs
│ ├── Microsoft.ServiceFabric.AspNetCore.Kestrel.csproj
│ ├── SR.Designer.cs
│ └── SR.resx
└── Microsoft.ServiceFabric.AspNetCore
│ ├── ApplicationBuilderExtensions.cs
│ ├── AspNetCoreCommunicationListener.cs
│ ├── Friend.cs
│ ├── GenericHostCommunicationListener.cs
│ ├── Microsoft.ServiceFabric.AspNetCore.csproj
│ ├── PathStringExtensions.cs
│ ├── SR.Designer.cs
│ ├── SR.resx
│ ├── ServiceFabricIntegrationOptions.cs
│ ├── ServiceFabricMiddleware.cs
│ ├── ServiceFabricReverseProxyIntegrationMiddleware.cs
│ ├── ServiceFabricSetupFilter.cs
│ ├── WebHostBuilderServiceFabricExtension.cs
│ └── WebHostCommunicationListener.cs
└── test
└── unittests
├── Microsoft.ServiceFabric.AspNetCore.Tests
├── AspNetCoreCommunicationListenerTests.cs
├── HttpSysCommunicationListenerTests.cs
├── KestrelCommunicationListenerTests.cs
├── KeyedCollectionImpl.cs
├── Microsoft.ServiceFabric.AspNetCore.Tests.csproj
├── Mocks
│ ├── MockConfigurationPackage.cs
│ ├── MockConfigurationProperties.cs
│ ├── MockConfigurationSections.cs
│ ├── TestCodePackageActivationContext.cs
│ └── TestHelper.cs
├── ServiceFabricConfigurationProviderTest.cs
├── ServiceFabricMiddlewareTests.cs
├── TestMocksRepository.cs
├── WebHostBuilderServiceFabricExtensionTests.cs
└── stylecop.json
└── default.runsettings
/.editorconfig:
--------------------------------------------------------------------------------
1 | ###############################
2 | # Core EditorConfig Options #
3 | ###############################
4 | root = true
5 |
6 | # All files
7 | [*]
8 | indent_style = space
9 | end_of_line = crlf
10 | end_of_file = crlf
11 |
12 | # Code files
13 | [*.{cs,csx,vb,vbx}]
14 | indent_size = 4
15 | insert_final_newline = true
16 | charset = utf-8
17 |
18 | # Xml build files
19 | [*.builds]
20 | indent_size = 2
21 |
22 | # Xml files
23 | [*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct,xml,stylecop}]
24 | indent_size = 2
25 |
26 | # Xml project files
27 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
28 | indent_size = 2
29 |
30 | # Json files
31 | [*.json]
32 | indent_size = 2
33 |
34 | # C++ Files
35 | [*.{cpp,h,in}]
36 | curly_bracket_next_line = true
37 | indent_brace_style = Allman
38 |
39 | # Shell scripts
40 | [*.sh]
41 | end_of_line = lf
42 | [*.{cmd, bat}]
43 | end_of_line = crlf
44 |
45 | ###############################
46 | # .NET OSS Coding Conventions #
47 | ###############################
48 | [*.{cs,vb}]
49 | # Organize usings
50 | dotnet_sort_system_directives_first = true
51 |
52 | # Use this.
53 | dotnet_style_qualification_for_field = true:warning
54 | dotnet_style_qualification_for_property = true:warning
55 | dotnet_style_qualification_for_method = true:warning
56 | dotnet_style_qualification_for_event = true:warning
57 |
58 | # Use language keywords instead of BCL types
59 | dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
60 | dotnet_style_predefined_type_for_member_access = true:suggestion
61 |
62 | # Expression-level preferences
63 | dotnet_style_object_initializer = true:none
64 | dotnet_style_collection_initializer = true:none
65 | dotnet_style_explicit_tuple_names = true:suggestion
66 | dotnet_style_null_propagation = false:error
67 | dotnet_style_coalesce_expression = true:suggestion
68 | dotnet_style_prefer_is_null_check_over_reference_equality_method = true:none
69 | dotnet_style_require_accessibility_modifiers = always:suggestion
70 | dotnet_prefer_inferred_tuple_names = true:suggestion
71 | dotnet_prefer_inferred_anonymous_type_member_names = true:suggestion
72 |
73 | [*.cs]
74 | # Expression-bodied members
75 | csharp_style_expression_bodied_methods = false:none
76 | csharp_style_expression_bodied_constructors = false:none
77 | csharp_style_expression_bodied_operators = false:none
78 |
79 | # SF-OSS: changed from true to false
80 | csharp_style_expression_bodied_properties = false:none
81 |
82 | csharp_style_expression_bodied_indexers = true:none
83 | csharp_style_expression_bodied_accessors = true:none
84 |
85 | # Pattern matching
86 | csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
87 | csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
88 | csharp_style_inlined_variable_declaration = true:suggestion
89 |
90 | # Null-checking preferences
91 | csharp_style_throw_expression = false:none
92 | csharp_style_conditional_delegate_call = false:none
93 |
94 | # Expression-level preferences
95 | csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
96 |
97 | [*.vb]
98 | 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
99 |
100 | ###############################
101 | # .NET Formatting Rules #
102 | ###############################
103 | [*.cs]
104 | # New line preferences
105 | csharp_new_line_before_open_brace = all
106 | csharp_new_line_before_else = true
107 | csharp_new_line_before_catch = true
108 | csharp_new_line_before_finally = true
109 | csharp_new_line_before_members_in_object_initializers = true
110 | csharp_new_line_before_members_in_anonymous_types = true
111 | csharp_new_line_between_query_expression_clauses = true
112 |
113 | # Indentation preferences
114 | csharp_indent_case_contents = true
115 | csharp_indent_switch_labels = true
116 | csharp_indent_labels = flush_left
117 |
118 | # Space preferences
119 | csharp_space_after_cast = false
120 | csharp_space_after_keywords_in_control_flow_statements = true
121 | csharp_space_between_method_call_parameter_list_parentheses = false
122 | csharp_space_between_method_declaration_parameter_list_parentheses = false
123 | csharp_space_between_parentheses = false
124 |
125 | ###############################
126 | # Roslyn-Specific Conventions #
127 | ###############################
128 | # Always use var
129 | csharp_style_var_for_built_in_types = true:suggestion
130 | csharp_style_var_when_type_is_apparent = true:suggestion
131 | csharp_style_var_elsewhere = true:suggestion
132 |
133 | # Expression-level preferences
134 | csharp_prefer_braces = true:suggestion
135 | csharp_style_deconstructed_variable_declaration = true:suggestion
136 | csharp_prefer_simple_default_expression = true:suggestion
137 | csharp_style_pattern_local_over_anonymous_function = true:none
138 |
139 | ###############################
140 | # Naming Conventions #
141 | ###############################
142 |
143 | # Style Definitions
144 | dotnet_naming_style.pascal_case_style.capitalization = pascal_case
145 |
146 | dotnet_naming_style.camel_case_style.capitalization = camel_case
147 |
148 | dotnet_naming_style.I_prefix_style.required_prefix = I
149 | dotnet_naming_style.I_prefix_style.capitalization = pascal_case
150 |
151 | # Use PascalCase for constant fields
152 | dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = warning
153 | dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
154 | dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
155 | dotnet_naming_symbols.constant_fields.applicable_kinds = field
156 | dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
157 | dotnet_naming_symbols.constant_fields.required_modifiers = const
158 |
159 | # Use PascalCase for static fields
160 | dotnet_naming_rule.static_fields_should_be_pascal_case.severity = warning
161 | dotnet_naming_rule.static_fields_should_be_pascal_case.symbols = static_fields
162 | dotnet_naming_rule.static_fields_should_be_pascal_case.style = pascal_case_style
163 | dotnet_naming_symbols.static_fields.applicable_kinds = field
164 | dotnet_naming_symbols.static_fields.applicable_accessibilities = *
165 | dotnet_naming_symbols.static_fields.required_modifiers = static
166 |
167 | # Use PascalCase for public fields
168 | dotnet_naming_rule.pascal_case_for_public_fields.severity = warning
169 | dotnet_naming_rule.pascal_case_for_public_fields.symbols = public_fields
170 | dotnet_naming_rule.pascal_case_for_public_fields.style = pascal_case_style
171 | dotnet_naming_symbols.public_fields.applicable_kinds = field
172 | dotnet_naming_symbols.public_fields.applicable_accessibilities = public
173 |
174 | # Use camelCase for all other fields
175 | dotnet_naming_rule.camel_case_for_other_fields.severity = warning
176 | dotnet_naming_rule.camel_case_for_other_fields.symbols = other_fields
177 | dotnet_naming_rule.camel_case_for_other_fields.style = camel_case_style
178 | dotnet_naming_symbols.other_fields.applicable_kinds = field
179 | dotnet_naming_symbols.other_fields.applicable_accessibilities = *
180 |
181 | # Interfaces must be PascalCase and have an I prefix
182 | dotnet_naming_rule.interfaces_start_with_I.severity = warning
183 | dotnet_naming_rule.interfaces_start_with_I.symbols = any_interface
184 | dotnet_naming_rule.interfaces_start_with_I.style = I_prefix_style
185 | dotnet_naming_symbols.any_interface.applicable_accessibilities = *
186 | dotnet_naming_symbols.any_interface.applicable_kinds = interface
187 |
188 | # Classes, structs, methods, enums, events, properties, namespaces, delegates must be PascalCase
189 | dotnet_naming_rule.general_naming.severity = warning
190 | dotnet_naming_rule.general_naming.symbols = general
191 | dotnet_naming_rule.general_naming.style = pascal_case_style
192 | dotnet_naming_symbols.general.applicable_kinds = class,struct,enum,property,method,event,namespace,delegate
193 | dotnet_naming_symbols.general.applicable_accessibilities = *
194 |
195 | # Everything else is camelCase
196 | dotnet_naming_rule.everything_else_naming.severity = warning
197 | dotnet_naming_rule.everything_else_naming.symbols = everything_else
198 | dotnet_naming_rule.everything_else_naming.style = camel_case_style
199 | dotnet_naming_symbols.everything_else.applicable_kinds = *
200 | dotnet_naming_symbols.everything_else.applicable_accessibilities = *
201 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **To Reproduce**
11 | Steps or code snippet to reproduce the behavior.
12 |
13 | **Expected behavior**
14 | A clear and concise description of what you expected to happen.
15 |
16 | **Additional context**
17 | Add any other context about the problem here.
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | **Is your feature request related to a problem? Please describe.**
8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Describe alternatives you've considered**
14 | A clear and concise description of any alternative solutions or features you've considered.
15 |
16 | **Additional context**
17 | Add any other context or screenshots about the feature request here.
18 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | branches:
6 | - develop
7 | - 'release_*'
8 |
9 | pull_request:
10 | branches:
11 | - develop
12 | - 'release_*'
13 |
14 | jobs:
15 | build:
16 | name: Build Test
17 | runs-on: windows-latest
18 | # info about windows-latest https://github.com/actions/runner-images
19 | env:
20 | DROP_DIR: drop
21 | TEST_RESULT_DIR: drop\testresults
22 | steps:
23 | - uses: actions/checkout@v1
24 | - name: Setup dotnet
25 | uses: actions/setup-dotnet@v4
26 | with:
27 | dotnet-version: '9.0.x'
28 | - name: Build Everything
29 | shell: powershell
30 | run: dotnet build buildAll.proj
31 | - name: Run Tests
32 | run: dotnet test code.sln --configuration release --nologo --settings test\unittests\default.runsettings --results-directory ${{ env.TEST_RESULT_DIR }} --logger trx
33 | - name: upload artifacts
34 | uses: actions/upload-artifact@master
35 | with:
36 | name: release_drop
37 | path: ${{ env.DROP_DIR }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Everything in the external/packages directory as nuget packages are restored here.
3 | /nuget/restored_packages/*
4 |
5 | # Build generated files in src
6 | /src/**/objd/**/*
7 | /src/**/obj/**/*
8 | /src/**/bin/**/*
9 | /src/**/gen/**/*
10 | /src/**/*.nuspec
11 | /src/**/StyleCop.Cache
12 |
13 | # MSBuild's log file
14 | msbuild.log
15 |
16 | # Build.exe
17 | *.err
18 | *.wrn
19 | *.log
20 | *.prf
21 | *.trc
22 | buildd.dbb
23 | build.dbb
24 | buildd.evt
25 | build.evt
26 |
27 | ###
28 | Repository Bloat Risks
29 | ###
30 | *.exe
31 | *.dll
32 | *.lib
33 | *.pdb
34 | *.wim
35 | *.zip
36 | *.gz
37 | *.meta
38 | *.obj
39 | *.tmp
40 | *.tmp_proj
41 | *.log
42 | .builds
43 |
44 | ## Ignore Visual Studio temporary files, build results, and
45 | ## files generated by popular Visual Studio add-ons.
46 | *.vs/
47 |
48 | # User-specific files
49 | *.suo
50 | *.user
51 | *.userosscache
52 | *.sln.docstates
53 |
54 | # Build results
55 | [Dd]ebug/
56 | [Dd]ebugPublic/
57 | [Rr]elease/
58 | [Rr]eleases/
59 | x64/
60 | x86/
61 | build/
62 | bld/
63 | [Bb]in/
64 | [Oo]bj/
65 |
66 | #drop folder
67 | /src/drop/**/*
68 |
69 | # Roslyn cache directories
70 | *.ide/
71 |
72 | # Visual Studio profiler
73 | *.psess
74 | *.vsp
75 | *.vspx
76 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributing code and content
2 | We welcome all forms of contributions from the community. Please read the following guidelines to maximize the chances of your PR being merged.
3 |
4 | ### Reporting security issues and bugs
5 | Security issues and bugs should be reported privately, via email, to the Microsoft Security Response Center (MSRC) secure@microsoft.com. You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Further information, including the MSRC PGP key, can be found in the [Security TechCenter](https://technet.microsoft.com/en-us/security/ff852094.aspx).
6 |
7 | ### Other discussions
8 | For general "how-to" and guidance questions about using Service Fabric to build and run applications, please use [Stack Overflow](http://stackoverflow.com/questions/tagged/azure-service-fabric) tagged with `azure-service-fabric`.
9 |
10 | ### Development process
11 | Please be sure to follow the usual process for submitting PRs:
12 |
13 | - Fork the repo
14 | - Create a pull request into correct branch (see branching information below).
15 | - Make sure your PR title is descriptive
16 | - Include a link back to an open issue in the PR description
17 |
18 | We reserve the right to close PRs that are not making progress. If no changes are made for 7 days, we'll close the PR. Closed PRs can be reopened again later and work can resume.
19 |
20 | ### Branching Information
21 | All development for future releases happen in the develop branch.
22 | A new branch is forked off of develop branch for each release to stabilize it before final release. (eg. release_4.0 branch represents the 4.0.* release).
23 | A bug fix in an already released version is made both to its release branch and to develop branch so that its available in refresh of the release and for future new releases.
24 |
25 | ### Contributor License Agreement
26 | Before you submit a pull request, a bot will prompt you to sign the [Microsoft Contributor License Agreement](https://cla.microsoft.com/). This needs to be done only once for any Microsoft-sponsored open source project - if you've signed the Microsoft CLA for any project sponsored by Microsoft, then you are good to go for all the repos sponsored by Microsoft.
27 |
28 | > **Important**: Note that there are **two** different CLAs commonly used by Microsoft projects: [Microsoft CLA](https://cla.microsoft.com/) and [.NET Foundation CLA](https://cla2.dotnetfoundation.org/). Service Fabric open source projects use the [Microsoft](https://cla.microsoft.com/) CLA. The .NET Foundation is treated as a separate entity, so if you've signed the .NET Foundation CLA in the past, you will still need to sign the Microsoft CLA to contribute to Service Fabric open source projects.
29 |
--------------------------------------------------------------------------------
/Directory.Packages.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 | true
5 |
6 |
7 |
8 |
9 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Service Fabric Reliable Services ASP.NET Core Integration
2 |
3 | Copyright (c) Microsoft Corporation
4 |
5 | All rights reserved.
6 |
7 | MIT License
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Azure/service-fabric-aspnetcore
2 |
3 | This repo contains ASP.NET Core integration for Service Fabric Reliable Services.
4 |
5 | The `Microsoft.ServiceFabric.Services.AspNetCore.*` NuGet packages contain implementations of `ICommunicationListener` that start the ASP.NET Core web host for either Kestrel or HttpSys in a Service Fabric Reliable Service. The `ICommunicationListener` allows you to configure `IWebHost`, and then it manages its lifetime.
6 |
7 | This repo builds the following packages:
8 | - Microsoft.ServiceFabric.AspNetCore.Abstractions
9 | - Microsoft.ServiceFabric.AspNetCore.HttpSys
10 | - Microsoft.ServiceFabric.AspNetCore.Kestrel
11 | - Microsoft.ServiceFabric.AspNetCore.Configuration
12 |
13 | These packages are documented [here](https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-aspnetcore).
14 |
15 | ## Getting Started
16 |
17 | ### Prerequesites
18 | Each project is a normal C# Visual Studio project. At minimum, you need [MSBuild 16](https://docs.microsoft.com/en-us/visualstudio/msbuild/whats-new-msbuild-16-0), [PowerShell](https://msdn.microsoft.com/powershell/mt173057.aspx), [.NET 6 SDK](https://dotnet.microsoft.com/download/dotnet/6.0) and [.NET Framework 4.6](https://www.microsoft.com/en-US/download/details.aspx?id=48130) to build and generate NuGet packages.
19 |
20 | We recommend installing Visual Studio 2022 which will set you up with all the .NET build tools and allow you to open the solution files. Currently VS 2022 is in preview which can also be used to build everything here.
21 |
22 | ### Build
23 | To build everything and generate NuGet packages, run the **build.ps1** script. NuGet packages will be dropped in a *drop* directory at the repo root.
24 |
25 | Each project can also be built individually directly through Visual Studio or by running the solution file through MSBuild.
26 |
27 | Binaries in the build are delay signed, these are fully signed in the official builds released by Microsoft. To use the binaries or to run unit tests from the build of this repository, strong name validation needs to be skipped for these assemblies. This can be done by running **SkipStrongName.ps1** script available in the root of the repository.
28 |
29 | For branches, please see [Branching Information](CONTRIBUTING.md#BranchingInformation)
30 |
31 | ## Development
32 | We are currently working on transitioning all development to GitHub. For the time being we are continuing to do our own development internally. Upon each release of the SDK, we will push our latest changes to GitHub. We intend to bring more of our development process and tools into the open over time.
33 |
34 | ## Releases and Support
35 | Official releases from Microsoft of the NuGet packages in this repo are released directly to NuGet and Web Platform Installer. Get the latest official release [here](http://www.microsoft.com/web/handlers/webpi.ashx?command=getinstallerredirect&appid=MicrosoftAzure-ServiceFabric-VS2015).
36 |
37 | **Only officially released NuGet packages from Microsoft are supported for use in production.** If you have a feature or bug fix that you would like to use in your application, please issue a pull request so we can get it into an official release.
38 |
39 | ## Reporting issues and feedback
40 | Please refer to [Contributing.md](https://github.com/Microsoft/service-fabric/blob/master/CONTRIBUTING.md) at the Service Fabric home repo for details on issue reporting and feedback.
41 |
42 | ## Contributing code
43 | If you would like to become an active contributor to this project please
44 | follow the instructions provided in [Microsoft Azure Projects Contribution Guidelines](http://azure.github.io/guidelines.html). For details, please refer to [Contributing.md](CONTRIBUTING.md).
45 |
46 | ## Documentation
47 | Service Fabric has a rich set of conceptual and reference documentation available at [https://docs.microsoft.com/azure/service-fabric](https://docs.microsoft.com/azure/service-fabric).
48 |
49 | The ASP.NET Core integration packages are documented at [https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-aspnetcore](https://docs.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-aspnetcore).
50 |
51 | ## Samples
52 | For Service Fabric sample code, check out the [Azure Code Sample gallery](https://azure.microsoft.com/en-us/resources/samples/?service=service-fabric) or go straight to [Azure-Samples on GitHub](https://github.com/Azure-Samples?q=service-fabric).
53 |
54 | ## License
55 | [MIT](License.txt)
56 |
57 | ---
58 | *This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.*
59 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/SkipStrongName.ps1:
--------------------------------------------------------------------------------
1 | # Register assemblies for strong name verification skipping
2 |
3 | $registryPath = "HKLM:\SOFTWARE\Microsoft\StrongName\Verification"
4 | $publicKeyToken="31bf3856ad364e35"
5 | $assemblies = "Microsoft.ServiceFabric.AspNetCore",
6 | "Microsoft.ServiceFabric.AspNetCore.Configuration",
7 | "Microsoft.ServiceFabric.AspNetCore.HttpSys",
8 | "Microsoft.ServiceFabric.AspNetCore.Kestrel",
9 | "Microsoft.ServiceFabric.AspNetCore.Tests"
10 |
11 | Write-Host "Registering assemblies generated by this repository for strong name verification skipping."
12 | foreach ($assembly in $assemblies)
13 | {
14 | $assemblyIdentity = "$assembly,$publicKeyToken"
15 | New-Item -Path "$registryPath\$assemblyIdentity" -Force | Out-Null
16 | }
17 |
--------------------------------------------------------------------------------
/build.ps1:
--------------------------------------------------------------------------------
1 | ##
2 | # Builds the source code and generates nuget packages. You can optionally just build the source code by opening individual solutions in Visual Studio.
3 | ##
4 |
5 | param
6 | (
7 | # Configuration to build.
8 | [ValidateSet('Debug', 'Release')]
9 | [string]$Configuration = "Release",
10 |
11 | # target to build.
12 | #Options are:
13 | # RebuildAll: Clean, Build all .csproj and Generate Nuget Packages. This is the default option.
14 | # BuildAll: Build all .csproj and Generate Nuget Packages.
15 | # BuildCode: Builds code, doesn't generates nuget packages.
16 | # GeneratePackages: Generates nuget packages, this target doesn't builds code, build must be done using BuildCode target before invoking this target.
17 | [ValidateSet('Rebuildall', 'BuildAll', 'BuildCode', 'GeneratePackages')]
18 | [string]$Target = "RebuildAll",
19 |
20 | # msbuild verbosity level.
21 | [ValidateSet('quiet','minimal', 'normal', 'detailed', 'diagnostic')]
22 | [string]$Verbosity = 'minimal',
23 |
24 | # path to msbuild
25 | [string]$MSBuildFullPath
26 | )
27 |
28 | if($MSBuildFullPath -ne "")
29 | {
30 | if (!(Test-Path $MSBuildFullPath))
31 | {
32 | throw "Unable to find MSBuild at the specified path, run the script again with correct path to msbuild."
33 | }
34 | }
35 |
36 | # msbuild path not provided, find msbuild for VS2022
37 | if($MSBuildFullPath -eq "")
38 | {
39 | $progFilesPaths = ${env:\ProgramFiles(x86)}, ${env:\ProgramFiles}
40 | foreach ($progFilesPath in $progFilesPaths)
41 | {
42 | $VS2022InstallPath = join-path $progFilesPath "Microsoft Visual Studio\2022"
43 | $versions = 'Preview', 'Community', 'Professional', 'Enterprise'
44 |
45 | foreach ($version in $versions)
46 | {
47 | $VS2022VersionPath = join-path $VS2022InstallPath $version
48 | $testPath = join-path $VS2022VersionPath "MSBuild\Current\Bin\MSBuild.exe"
49 |
50 | if (Test-Path $testPath)
51 | {
52 | $MSBuildFullPath = $testPath
53 | }
54 | }
55 | }
56 | }
57 |
58 | if (!(Test-Path $MSBuildFullPath))
59 | {
60 | throw "Unable to find MSBuild installed on this machine. Please install Visual Studio 2022 or if its installed at non-default location, provide the full path to msbuild using -MSBuildFullPath parameter."
61 | }
62 |
63 |
64 | Write-Output "Using msbuild from $msbuildFullPath"
65 |
66 | $msbuildArgs = @("buildall.proj", "/nr:false", "/nologo", "/t:$target", "/verbosity:$verbosity", "/property:RequestedVerbosity=$verbosity", "/property:Configuration=$configuration", $args)
67 | & $msbuildFullPath $msbuildArgs
--------------------------------------------------------------------------------
/buildAll.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | $(MSBuildThisFileDirectory)
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/code.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.7.34221.43
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ServiceFabric.AspNetCore", "src\Microsoft.ServiceFabric.AspNetCore\Microsoft.ServiceFabric.AspNetCore.csproj", "{A45918E1-6345-432E-AD6D-47DEEFB35661}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ServiceFabric.AspNetCore.HttpSys", "src\Microsoft.ServiceFabric.AspNetCore.HttpSys\Microsoft.ServiceFabric.AspNetCore.HttpSys.csproj", "{7BE05428-AD27-41CB-B01A-85821B69175F}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ServiceFabric.AspNetCore.Kestrel", "src\Microsoft.ServiceFabric.AspNetCore.Kestrel\Microsoft.ServiceFabric.AspNetCore.Kestrel.csproj", "{B80B46C9-759A-4C5B-8618-C7A45395D9A2}"
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{BC6C4F04-5CED-4AB6-930B-3348145E6316}"
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ServiceFabric.AspNetCore.Tests", "test\unittests\Microsoft.ServiceFabric.AspNetCore.Tests\Microsoft.ServiceFabric.AspNetCore.Tests.csproj", "{F9D9E1BB-212D-4785-8E1E-8427355AAF68}"
15 | EndProject
16 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0371241A-7255-4C77-AE01-00B80954DC23}"
17 | EndProject
18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionItems", "{BA7A4C8B-A2B3-4349-878D-4AB5681B9FA6}"
19 | ProjectSection(SolutionItems) = preProject
20 | .editorconfig = .editorconfig
21 | EndProjectSection
22 | EndProject
23 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.ServiceFabric.AspNetCore.Configuration", "src\Microsoft.ServiceFabric.AspNetCore.Configuration\Microsoft.ServiceFabric.AspNetCore.Configuration.csproj", "{99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}"
24 | EndProject
25 | Global
26 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
27 | Debug|Any CPU = Debug|Any CPU
28 | Debug|x64 = Debug|x64
29 | Release|Any CPU = Release|Any CPU
30 | Release|x64 = Release|x64
31 | EndGlobalSection
32 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
33 | {A45918E1-6345-432E-AD6D-47DEEFB35661}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
34 | {A45918E1-6345-432E-AD6D-47DEEFB35661}.Debug|Any CPU.Build.0 = Debug|Any CPU
35 | {A45918E1-6345-432E-AD6D-47DEEFB35661}.Debug|x64.ActiveCfg = Debug|x64
36 | {A45918E1-6345-432E-AD6D-47DEEFB35661}.Debug|x64.Build.0 = Debug|x64
37 | {A45918E1-6345-432E-AD6D-47DEEFB35661}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 | {A45918E1-6345-432E-AD6D-47DEEFB35661}.Release|Any CPU.Build.0 = Release|Any CPU
39 | {A45918E1-6345-432E-AD6D-47DEEFB35661}.Release|x64.ActiveCfg = Release|x64
40 | {A45918E1-6345-432E-AD6D-47DEEFB35661}.Release|x64.Build.0 = Release|x64
41 | {7BE05428-AD27-41CB-B01A-85821B69175F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
42 | {7BE05428-AD27-41CB-B01A-85821B69175F}.Debug|Any CPU.Build.0 = Debug|Any CPU
43 | {7BE05428-AD27-41CB-B01A-85821B69175F}.Debug|x64.ActiveCfg = Debug|x64
44 | {7BE05428-AD27-41CB-B01A-85821B69175F}.Debug|x64.Build.0 = Debug|x64
45 | {7BE05428-AD27-41CB-B01A-85821B69175F}.Release|Any CPU.ActiveCfg = Release|Any CPU
46 | {7BE05428-AD27-41CB-B01A-85821B69175F}.Release|Any CPU.Build.0 = Release|Any CPU
47 | {7BE05428-AD27-41CB-B01A-85821B69175F}.Release|x64.ActiveCfg = Release|x64
48 | {7BE05428-AD27-41CB-B01A-85821B69175F}.Release|x64.Build.0 = Release|x64
49 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
50 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
51 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2}.Debug|x64.ActiveCfg = Debug|x64
52 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2}.Debug|x64.Build.0 = Debug|x64
53 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
54 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2}.Release|Any CPU.Build.0 = Release|Any CPU
55 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2}.Release|x64.ActiveCfg = Release|x64
56 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2}.Release|x64.Build.0 = Release|x64
57 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
58 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68}.Debug|Any CPU.Build.0 = Debug|Any CPU
59 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68}.Debug|x64.ActiveCfg = Debug|x64
60 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68}.Debug|x64.Build.0 = Debug|x64
61 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68}.Release|Any CPU.ActiveCfg = Release|Any CPU
62 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68}.Release|Any CPU.Build.0 = Release|Any CPU
63 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68}.Release|x64.ActiveCfg = Release|x64
64 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68}.Release|x64.Build.0 = Release|x64
65 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
66 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}.Debug|Any CPU.Build.0 = Debug|Any CPU
67 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}.Debug|x64.ActiveCfg = Debug|x64
68 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}.Debug|x64.Build.0 = Debug|x64
69 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}.Release|Any CPU.ActiveCfg = Release|Any CPU
70 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}.Release|Any CPU.Build.0 = Release|Any CPU
71 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}.Release|x64.ActiveCfg = Release|x64
72 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780}.Release|x64.Build.0 = Release|x64
73 | EndGlobalSection
74 | GlobalSection(SolutionProperties) = preSolution
75 | HideSolutionNode = FALSE
76 | EndGlobalSection
77 | GlobalSection(NestedProjects) = preSolution
78 | {A45918E1-6345-432E-AD6D-47DEEFB35661} = {0371241A-7255-4C77-AE01-00B80954DC23}
79 | {7BE05428-AD27-41CB-B01A-85821B69175F} = {0371241A-7255-4C77-AE01-00B80954DC23}
80 | {B80B46C9-759A-4C5B-8618-C7A45395D9A2} = {0371241A-7255-4C77-AE01-00B80954DC23}
81 | {F9D9E1BB-212D-4785-8E1E-8427355AAF68} = {BC6C4F04-5CED-4AB6-930B-3348145E6316}
82 | {99AEA1AC-AA3B-426D-A0BE-2B2FAB68C780} = {0371241A-7255-4C77-AE01-00B80954DC23}
83 | EndGlobalSection
84 | GlobalSection(ExtensibilityGlobals) = postSolution
85 | SolutionGuid = {2CDABF99-A026-479B-B672-736D0A8C9A37}
86 | EndGlobalSection
87 | EndGlobal
88 |
--------------------------------------------------------------------------------
/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/nuget/NuGet.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/service-fabric-aspnetcore/c8221f6d5610d8dabb808a273bdcf31cfbb00af5/nuget/NuGet.exe
--------------------------------------------------------------------------------
/nuprojs/SF.AspNetCore.Internal/SF.AspNetCore.Internal.nuproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SF.AspNetCore.Internal
7 | SF.AspNetCore.Internal
8 | This package provides Service Fabric AspNetCore integration libraries for consumption by other Service Fabric repos.
9 | This package provides Service Fabric AspNetCore integration libraries for consumption by other Service Fabric repos.
10 | ServiceFabric Microsoft Azure Fabric
11 | v4.8.1
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | lib\netframework
20 |
21 |
22 | lib\net8.0
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/nuprojs/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/properties/Key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/service-fabric-aspnetcore/c8221f6d5610d8dabb808a273bdcf31cfbb00af5/properties/Key.snk
--------------------------------------------------------------------------------
/properties/service_fabric_common.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | $([System.String]::Copy('$(MSBuildThisFileDirectory)').Replace('properties\',''))
8 | minimal
9 |
10 |
11 | bin\$(Configuration)\
12 |
13 |
14 | $(RepoRoot)drop\$(Configuration)\
15 | $(RepoRoot)drop\$(Configuration)\net462\
16 | $(RepoRoot)drop\$(Configuration)\net8.0\
17 | $(DropFolder)\packages
18 |
19 |
20 | $(RepoRoot)\nuget\nuget.exe
21 |
22 |
23 |
24 | 9
25 | 0
26 | 0
27 | 0
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/properties/service_fabric_managed.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/properties/service_fabric_managed_common.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | AnyCPU
8 | true
9 | 4
10 |
11 |
12 | true
13 | AnyCPU
14 |
15 |
16 |
17 |
18 | true
19 |
20 |
21 |
22 |
23 | full
24 |
25 |
26 | pdbonly
27 |
28 |
29 |
30 |
31 | true
32 |
33 |
34 |
35 |
36 | false
37 |
38 |
39 |
40 |
41 | true
42 | true
43 | $(MSBuildThisFileDirectory)Key.snk
44 |
45 |
46 |
47 |
48 | 6.0.0.0
49 | $(MajorVersion).$(MinorVersion).$(BuildVersion).$(Revision)
50 | $(MajorVersion).$(MinorVersion).$(BuildVersion).$(Revision)
51 | $(MajorVersion).$(MinorVersion).$(BuildVersion).$(Revision)
52 |
53 |
54 |
55 | Microsoft Azure Service Fabric
56 | Copyright (c) Microsoft Corporation. All rights reserved.
57 | Microsoft
58 | Microsoft
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/properties/service_fabric_managed_stylecop.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildThisFileDirectory)stylecop\stylecop.json
5 | $(MSBuildThisFileDirectory)stylecop\StylecopSuppressions.cs
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/properties/service_fabric_nuget.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | $(MajorVersion).$(MinorVersion).$(BuildVersion)
8 |
9 |
10 |
11 | Microsoft
12 | Microsoft,ServiceFabric
13 | http://aka.ms/servicefabric
14 | http://www.microsoft.com/web/webpi/eula/net_library_eula_ENU.htm
15 | © Microsoft Corporation. All rights reserved.
16 | True
17 | true
18 | ServiceFabric Microsoft Azure Fabric
19 | http://go.microsoft.com/fwlink/?LinkID=288890
20 | en-US
21 | $(OutputRoot)\packages
22 |
23 |
24 | $(NuGetPackageVersion)
25 | False
26 |
27 |
28 |
29 |
30 | $(RepoRoot)\nuget\restored_packages\NuProj.0.11.30\tools
31 |
32 |
33 |
--------------------------------------------------------------------------------
/properties/service_fabric_nuget.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/properties/stylecop/StylecopSuppressions.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | using System.Diagnostics.CodeAnalysis;
7 |
8 | [assembly: SuppressMessage(
9 | "StyleCop.CSharp.MaintainabilityRules",
10 | "SA1119:StatementMustNotUseUnnecessaryParenthesis",
11 | Justification = "The code is more redable, especially when using parenthesis for the return statements.")]
12 |
13 | [assembly: SuppressMessage(
14 | "StyleCop.CSharp.ReadabilityRules",
15 | "SA1124:DoNotUseRegions",
16 | Justification = "In large files region allows creating logical sections in the file for better readability.")]
17 |
18 | [assembly: SuppressMessage(
19 | "Style",
20 | "IDE1006:Naming Styles",
21 | Justification = "Prefer SA1307-SA1307AccessibleFieldsMustBeginWithUpperCaseLetter over IDE:1006.")]
22 |
--------------------------------------------------------------------------------
/properties/stylecop/stylecop.json:
--------------------------------------------------------------------------------
1 | {
2 | // ACTION REQUIRED: This file was automatically added to your project, but it
3 | // will not take effect until additional steps are taken to enable it. See the
4 | // following page for additional information:
5 | //
6 | // https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/EnableConfiguration.md
7 |
8 | "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
9 | "settings": {
10 | "documentationRules": {
11 | "companyName": "Microsoft Corporation",
12 | "copyrightText": "------------------------------------------------------------\nCopyright (c) {companyName}. All rights reserved.\nLicensed under the {licenseName} License ({licenseName}). See {licenseFile} in the repo root for license information.\n------------------------------------------------------------",
13 | "variables": {
14 | "licenseName": "MIT",
15 | "licenseFile": "License.txt"
16 | },
17 | "xmlHeader": false,
18 | "documentInternalElements": false
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/refs/readme.txt:
--------------------------------------------------------------------------------
1 | Service Fabric pre-release nuget packages from other branches can be checked in here for develop branch until its officially released.
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Configuration/Microsoft.ServiceFabric.AspNetCore.Configuration.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Microsoft.ServiceFabric.AspNetCore.Configuration
7 | Microsoft.ServiceFabric.AspNetCore.Configuration
8 | $(OutputPath)\$(AssemblyName).xml
9 | net462;net8.0
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | True
23 | True
24 | SR.resx
25 |
26 |
27 |
28 |
29 | ResXFileCodeGenerator
30 | SR.Designer.cs
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Configuration/SR.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Microsoft.ServiceFabric.AspNetCore.Configuration {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class SR {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal SR() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.ServiceFabric.AspNetCore.Configuration.SR", typeof(SR).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Configuration/SR.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Configuration/ServiceFabricConfigurationExtensions.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.AspNetCore.Configuration
7 | {
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Fabric;
11 | using System.Text;
12 | using Microsoft.Extensions.Configuration;
13 |
14 | ///
15 | /// Configuration extentions to add service fabric configuration.
16 | ///
17 | public static class ServiceFabricConfigurationExtensions
18 | {
19 | ///
20 | /// Add configuration for all the configuration packages declared for current service.
21 | ///
22 | /// the configuration builder.
23 | /// the same configuration builder with service fabric configuration added.
24 | public static IConfigurationBuilder AddServiceFabricConfiguration(this IConfigurationBuilder builder)
25 | {
26 | if (builder == null)
27 | {
28 | throw new ArgumentNullException(nameof(builder));
29 | }
30 |
31 | ICodePackageActivationContext activationContext = FabricRuntime.GetActivationContext();
32 |
33 | // DO NOT dispose activation context as it will be saved to DI container and used later.
34 | // using (activationContext)
35 | {
36 | return builder.AddServiceFabricConfiguration(activationContext);
37 | }
38 | }
39 |
40 | ///
41 | /// Add configuration for all the configuration packages declared for current code package.
42 | ///
43 | /// the configuration builder.
44 | /// the activation context with information for configuration packages.
45 | /// the same configuration builder with service fabric configuration added.
46 | public static IConfigurationBuilder AddServiceFabricConfiguration(this IConfigurationBuilder builder, ICodePackageActivationContext context)
47 | {
48 | return builder.AddServiceFabricConfiguration(context, null);
49 | }
50 |
51 | ///
52 | /// Add configuration for given configuration package from packageName parameter as well as customize config action to populate the Data.
53 | ///
54 | /// the configuration builder.
55 | /// the activation context with information for configuration packages.
56 | /// the delegate to change the configuration options including configuration actions.
57 | /// the same configuration builder with service fabric configuration added.
58 | public static IConfigurationBuilder AddServiceFabricConfiguration(
59 | this IConfigurationBuilder builder,
60 | ICodePackageActivationContext context,
61 | Action optionsDelegate)
62 | {
63 | if (builder == null)
64 | {
65 | throw new ArgumentNullException(nameof(builder));
66 | }
67 |
68 | if (context == null)
69 | {
70 | throw new ArgumentNullException(nameof(context));
71 | }
72 |
73 | var packageNames = context.GetConfigurationPackageNames();
74 | foreach (var packageName in packageNames)
75 | {
76 | var options = new ServiceFabricConfigurationOptions(packageName);
77 |
78 | if (optionsDelegate != null)
79 | {
80 | optionsDelegate(options);
81 | }
82 |
83 | builder.Add(new ServiceFabricConfigurationSource(context, options));
84 | }
85 |
86 | return builder;
87 | }
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Configuration/ServiceFabricConfigurationOptions.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.AspNetCore.Configuration
7 | {
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Fabric;
11 | using System.Fabric.Description;
12 | using System.Runtime.InteropServices;
13 | using Microsoft.Extensions.Configuration;
14 | using FabricConfigurationSection = System.Fabric.Description.ConfigurationSection;
15 |
16 | ///
17 | /// The options used to configure the behavior of mapping configuration package to IConfiguration items.
18 | ///
19 | public class ServiceFabricConfigurationOptions
20 | {
21 | ///
22 | /// Initializes a new instance of the class.
23 | ///
24 | /// the name of the configuration package.
25 | public ServiceFabricConfigurationOptions(string packageName)
26 | {
27 | this.PackageName = packageName ?? throw new ArgumentNullException(packageName);
28 | this.IncludePackageName = true;
29 | this.DecryptValue = false; // secure by default.
30 |
31 | this.ConfigAction = this.DefaultConfigAction;
32 | this.ExtractKeyFunc = this.DefaultExtractKeyFunc;
33 | this.ExtractValueFunc = this.DefaultExtractValueFunc;
34 | }
35 |
36 | ///
37 | /// Gets the name of the configuration package this options is used for.
38 | ///
39 | public string PackageName { get; }
40 |
41 | ///
42 | /// Gets or sets the configuration used to transform the configuration package to IConfiguration items.
43 | ///
44 | ///
45 | /// This is for advanced usage scenario to take data from package and populate into the dictionary.
46 | /// For example, this could be used to populate json configuration files, adding logging for configuration updates, etc.
47 | /// The default value is a delegate which used PackageName, SectionName and ParamName as the key and value as the param value regardless of encrypted or not.
48 | ///
49 | public Action> ConfigAction { get; set; }
50 |
51 | ///
52 | /// Gets or sets the function to extract the IConfiguration key from the fabric configuration section and property.
53 | /// The return value of the fuction would be used as the key for IConfiguration in ConfigAction.
54 | ///
55 | ///
56 | /// The default value is a function which used PackageName, SectionName and ParamName as the key with default IncludePackageName as true.
57 | ///
58 | public Func ExtractKeyFunc { get; set; }
59 |
60 | ///
61 | /// Gets or sets the function to extract the IConfiguration value from the fabric configuration section and property.
62 | /// The return value of the fuction would be used as the value for IConfiguration in ConfigAction.
63 | ///
64 | ///
65 | /// The default value is a function which used the param value regardless of encrypted or not with default DecryptValue flag as true.
66 | ///
67 | public Func ExtractValueFunc { get; set; }
68 |
69 | ///
70 | /// Gets or sets a value indicating whether or not to include the configuration package name to the section name of IConfiguration item.
71 | /// The default is true, and will include the package name, section name and param namein configuraton package.
72 | /// You could set this to true for multiple config packages to avoid a setting with same section name and param name being override from other package.
73 | ///
74 | public bool IncludePackageName { get; set; }
75 |
76 | ///
77 | /// Gets or sets a value indicating whether or not to decypt the encrypted value to unsecure string.
78 | ///
79 | ///
80 | /// A typical safety guideline is to keep encrypted string encrypted in memory, and then decrypt (briefly) at time of use.
81 | /// With this reason, DecryptValue will default to false to treat encrypted value the same as plain text by default,
82 | /// user will need to handle encrypted string separately to compliant with security best practice.
83 | ///
84 | public bool DecryptValue { get; set; }
85 |
86 | internal void DefaultConfigAction(ConfigurationPackage config, IDictionary data)
87 | {
88 | foreach (var section in config.Settings.Sections)
89 | {
90 | foreach (var param in section.Parameters)
91 | {
92 | string key = this.ExtractKeyFunc(section, param);
93 | string value = this.ExtractValueFunc(section, param);
94 | data[key] = value;
95 | }
96 | }
97 | }
98 |
99 | internal string DefaultExtractKeyFunc(FabricConfigurationSection section, ConfigurationProperty property)
100 | {
101 | if (this.IncludePackageName)
102 | {
103 | return $"{this.PackageName}{ConfigurationPath.KeyDelimiter}{section.Name}{ConfigurationPath.KeyDelimiter}{property.Name}";
104 | }
105 | else
106 | {
107 | return $"{section.Name}{ConfigurationPath.KeyDelimiter}{property.Name}";
108 | }
109 | }
110 |
111 | internal string DefaultExtractValueFunc(FabricConfigurationSection section, ConfigurationProperty property)
112 | {
113 | // see https://github.com/Azure/service-fabric-aspnetcore/issues/9
114 | // A typical safety guideline is to keep encrypted string encrypted in memory, and then decrypt (briefly) at time of use.
115 | // With this reason, will treat encrypted value the same as plain text by default,
116 | // user will need to handle encrypted string separately to compliant with security best practice.
117 | if (property.IsEncrypted && this.DecryptValue)
118 | {
119 | IntPtr unmanagedString = IntPtr.Zero;
120 | var secureString = property.DecryptValue();
121 |
122 | try
123 | {
124 | unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
125 | return Marshal.PtrToStringUni(unmanagedString);
126 | }
127 | finally
128 | {
129 | Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString);
130 | }
131 | }
132 | else
133 | {
134 | return property.Value;
135 | }
136 | }
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Configuration/ServiceFabricConfigurationProvider.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.AspNetCore.Configuration
7 | {
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Fabric;
11 | using Microsoft.Extensions.Configuration;
12 |
13 | internal class ServiceFabricConfigurationProvider : ConfigurationProvider
14 | {
15 | private readonly ICodePackageActivationContext context;
16 | private readonly ServiceFabricConfigurationOptions options;
17 |
18 | public ServiceFabricConfigurationProvider(ICodePackageActivationContext activationContext, ServiceFabricConfigurationOptions options)
19 | {
20 | this.context = activationContext;
21 |
22 | this.options = options ?? throw new ArgumentNullException(nameof(options));
23 |
24 | this.context.ConfigurationPackageModifiedEvent += (sender, e) =>
25 | {
26 | this.HandleNewPackage(e.NewPackage);
27 | };
28 |
29 | this.context.ConfigurationPackageAddedEvent += (sender, e) =>
30 | {
31 | this.HandleNewPackage(e.Package);
32 | };
33 | }
34 |
35 | ///
36 | /// Load the configuration.
37 | ///
38 | public override void Load()
39 | {
40 | var config = this.context.GetConfigurationPackageObject(this.options.PackageName);
41 | this.LoadPackage(config);
42 | }
43 |
44 | ///
45 | /// Handle loading of a new package provided by a ConfigurationPackageModifiedEvent or a ConfigurationPackageAddedEvent.
46 | ///
47 | /// The new package to load from.
48 | private void HandleNewPackage(ConfigurationPackage package)
49 | {
50 | if (package.Description is null)
51 | {
52 | throw new ArgumentNullException($"{nameof(package)}.Description", $"A valid Description must be provided with {nameof(package)}.");
53 | }
54 |
55 | // Load configuration from new package only if it is the ConfigPackage mapped to this provider
56 | if (package.Description.Name == this.options.PackageName)
57 | {
58 | this.LoadPackage(package, reload: true);
59 | this.OnReload(); // Notify the change
60 | }
61 | }
62 |
63 | ///
64 | /// Load and populate data from .
65 | ///
66 | /// The package to load from.
67 | /// Whether or not to completely refresh .
68 | private void LoadPackage(ConfigurationPackage package, bool reload = false)
69 | {
70 | if (reload)
71 | {
72 | this.Data.Clear(); // Remove the old keys on re-load
73 | }
74 |
75 | // call the delegate action to populate the Data
76 | this.options.ConfigAction(package, this.Data);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Configuration/ServiceFabricConfigurationSource.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.AspNetCore.Configuration
7 | {
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Fabric;
11 | using Microsoft.Extensions.Configuration;
12 |
13 | internal class ServiceFabricConfigurationSource : IConfigurationSource
14 | {
15 | private readonly ServiceFabricConfigurationOptions options;
16 |
17 | ///
18 | /// Initializes a new instance of the class.
19 | ///
20 | /// the code package activation context.
21 | /// the configuration options.
22 | public ServiceFabricConfigurationSource(ICodePackageActivationContext activationContext, ServiceFabricConfigurationOptions options)
23 | {
24 | this.ActivationContext = activationContext;
25 | this.options = options;
26 | }
27 |
28 | public ICodePackageActivationContext ActivationContext { get; }
29 |
30 | public IConfigurationProvider Build(IConfigurationBuilder builder)
31 | {
32 | return new ServiceFabricConfigurationProvider(this.ActivationContext, this.options);
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.HttpSys/HttpSysCommunicationListener.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
6 | {
7 | using System;
8 | using System.Fabric;
9 | using System.Globalization;
10 | using Microsoft.AspNetCore.Hosting;
11 | using Microsoft.Extensions.Hosting;
12 |
13 | ///
14 | /// An AspNetCore HttpSys server based communication listener for Service Fabric stateless or stateful service.
15 | ///
16 | public class HttpSysCommunicationListener : AspNetCoreCommunicationListener
17 | {
18 | private readonly string endpointName;
19 |
20 | ///
21 | /// Initializes a new instance of the class.
22 | ///
23 | /// The context of the service for which this communication listener is being constructed.
24 | /// Name of endpoint resource defined in service manifest that should be used to create the address for listener.
25 | /// Delegate to build Microsoft.AspNetCore.Hosting.IWebHost, endpoint url generated by the listener is given as input to this delegate.
26 | /// This gives the flexibility to change the url before creating Microsoft.AspNetCore.Hosting.IWebHost if needed.
27 | public HttpSysCommunicationListener(ServiceContext serviceContext, string endpointName, Func build)
28 | : base(serviceContext, build)
29 | {
30 | if (string.IsNullOrEmpty(endpointName))
31 | {
32 | throw new ArgumentException(SR.EndpointNameNullOrEmptyExceptionMessage);
33 | }
34 |
35 | this.endpointName = endpointName;
36 | }
37 |
38 | ///
39 | /// Initializes a new instance of the class.
40 | ///
41 | /// The context of the service for which this communication listener is being constructed.
42 | /// Name of endpoint resource defined in service manifest that should be used to create the address for listener.
43 | /// Delegate to build Microsoft.Extensions.Hosting.IHost, endpoint url generated by the listener is given as input to this delegate.
44 | /// This gives the flexibility to change the url before creating Microsoft.Extensions.Hosting.IHost if needed.
45 | public HttpSysCommunicationListener(ServiceContext serviceContext, string endpointName, Func build)
46 | : base(serviceContext, build)
47 | {
48 | if (string.IsNullOrEmpty(endpointName))
49 | {
50 | throw new ArgumentException(SR.EndpointNameNullOrEmptyExceptionMessage);
51 | }
52 |
53 | this.endpointName = endpointName;
54 | }
55 |
56 | ///
57 | /// Gets url for the listener. Listener url is created using the endpointName passed in the constructor.
58 | ///
59 | /// url for the listener.
60 | protected override string GetListenerUrl()
61 | {
62 | var serviceEndpoint = this.GetEndpointResourceDescription(this.endpointName);
63 | var listenUrl = string.Format(
64 | CultureInfo.InvariantCulture,
65 | "{0}://+:{1}",
66 | serviceEndpoint.Protocol.ToString().ToLowerInvariant(),
67 | serviceEndpoint.Port);
68 |
69 | return listenUrl;
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.HttpSys/Microsoft.ServiceFabric.AspNetCore.HttpSys.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Microsoft.ServiceFabric.Services.Communication.AspNetCore
7 | Microsoft.ServiceFabric.AspNetCore.HttpSys
8 | $(OutputPath)\$(AssemblyName).xml
9 | net462;net8.0
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | True
26 | True
27 | SR.resx
28 |
29 |
30 |
31 |
32 | ResXFileCodeGenerator
33 | SR.Designer.cs
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.HttpSys/SR.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class SR {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal SR() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.ServiceFabric.Services.Communication.AspNetCore.SR", typeof(SR).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to endpointName cannot be null or empty string..
65 | ///
66 | internal static string EndpointNameNullOrEmptyExceptionMessage {
67 | get {
68 | return ResourceManager.GetString("EndpointNameNullOrEmptyExceptionMessage", resourceCulture);
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.HttpSys/SR.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | endpointName cannot be null or empty string.
122 |
123 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Kestrel/KestrelCommunicationListener.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
6 | {
7 | using System;
8 | using System.Fabric;
9 | using System.Globalization;
10 | using Microsoft.AspNetCore.Hosting;
11 | using Microsoft.Extensions.Hosting;
12 |
13 | ///
14 | /// An AspNetCore Kestrel based communication listener for Service Fabric stateless or stateful service.
15 | ///
16 | public class KestrelCommunicationListener : AspNetCoreCommunicationListener
17 | {
18 | private readonly string endpointName;
19 |
20 | ///
21 | /// Initializes a new instance of the class using a default address with http protocol and port 0.
22 | /// Kestrel will dynamically bind to an unspecified, available port when port 0 is specified in url.
23 | ///
24 | /// The context of the service for which this communication listener is being constructed.
25 | /// Delegate to build Microsoft.AspNetCore.Hosting.IWebHost, endpoint url generated by the listener is given as input to this delegate.
26 | /// This gives the flexibility to change the url before creating Microsoft.AspNetCore.Hosting.IWebHost if needed.
27 | public KestrelCommunicationListener(ServiceContext serviceContext, Func build)
28 | : this(serviceContext, null, build)
29 | {
30 | }
31 |
32 | ///
33 | /// Initializes a new instance of the class using a default address with http protocol and port 0.
34 | /// Kestrel will dynamically bind to an unspecified, available port when port 0 is specified in url.
35 | ///
36 | /// The context of the service for which this communication listener is being constructed.
37 | /// Delegate to build Microsoft.Extensions.Hosting.IHost, endpoint url generated by the listener is given as input to this delegate.
38 | /// This gives the flexibility to change the url before creating Microsoft.Extensions.Hosting.IHost if needed.
39 | public KestrelCommunicationListener(ServiceContext serviceContext, Func build)
40 | : this(serviceContext, null, build)
41 | {
42 | }
43 |
44 | ///
45 | /// Initializes a new instance of the class.
46 | ///
47 | /// The context of the service for which this communication listener is being constructed.
48 | /// Name of endpoint resource defined in service manifest that should be used to create the address for listener.
49 | /// Protocol and port specified in this endpoint is used to create the url.
50 | /// If the endpointName is null, a default address with http protocol and port 0 will be used.
51 | /// Kestrel will dynamically bind to an unspecified, available port when port 0 is specified in url.
52 | /// If the specified endpointName is not found in service manifest, an InvalidOperationException indicating this will be thrown.
53 | /// Delegate to build Microsoft.AspNetCore.Hosting.IWebHost, endpoint url generated by the listener is given as input to this delegate.
54 | /// This gives the flexibility to change the url before creating Microsoft.AspNetCore.Hosting.IWebHost if needed.
55 | public KestrelCommunicationListener(ServiceContext serviceContext, string endpointName, Func build)
56 | : base(serviceContext, build)
57 | {
58 | if (endpointName?.Length == 0)
59 | {
60 | throw new ArgumentException(SR.EndpointNameEmptyExceptionMessage);
61 | }
62 |
63 | this.endpointName = endpointName;
64 | }
65 |
66 | ///
67 | /// Initializes a new instance of the class.
68 | ///
69 | /// The context of the service for which this communication listener is being constructed.
70 | /// Name of endpoint resource defined in service manifest that should be used to create the address for listener.
71 | /// Protocol and port specified in this endpoint is used to create the url.
72 | /// If the endpointName is null, a default address with http protocol and port 0 will be used.
73 | /// Kestrel will dynamically bind to an unspecified, available port when port 0 is specified in url.
74 | /// If the specified endpointName is not found in service manifest, an InvalidOperationException indicating this will be thrown.
75 | /// Delegate to build Microsoft.Extensions.Hosting.IHost, endpoint url generated by the listener is given as input to this delegate.
76 | /// This gives the flexibility to change the url before creating Microsoft.Extensions.Hosting.IHost if needed.
77 | public KestrelCommunicationListener(ServiceContext serviceContext, string endpointName, Func build)
78 | : base(serviceContext, build)
79 | {
80 | if (endpointName?.Length == 0)
81 | {
82 | throw new ArgumentException(SR.EndpointNameEmptyExceptionMessage);
83 | }
84 |
85 | this.endpointName = endpointName;
86 | }
87 |
88 | ///
89 | /// Gets url for the listener. Listener url is created using the endpointName passed in the constructor.
90 | /// If the endpointName was null, a default url with http protocol and port zero is returned.
91 | ///
92 | /// url for the listener.
93 | protected override string GetListenerUrl()
94 | {
95 | // url with WebServer is always registered as http://+:port.
96 | var listenUrl = "http://+:0";
97 |
98 | // Get protocol and port from endpoint resource if specified.
99 | if (this.endpointName != null)
100 | {
101 | var serviceEndpoint = this.GetEndpointResourceDescription(this.endpointName);
102 | listenUrl = string.Format(
103 | CultureInfo.InvariantCulture,
104 | "{0}://+:{1}",
105 | serviceEndpoint.Protocol.ToString().ToLowerInvariant(),
106 | serviceEndpoint.Port);
107 | }
108 |
109 | return listenUrl;
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Kestrel/Microsoft.ServiceFabric.AspNetCore.Kestrel.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Microsoft.ServiceFabric.AspNetCore.Kestrel
7 | Microsoft.ServiceFabric.Services.Communication.AspNetCore
8 | $(OutputPath)\$(AssemblyName).xml
9 | net462;net8.0
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | True
26 | True
27 | SR.resx
28 |
29 |
30 |
31 |
32 | ResXFileCodeGenerator
33 | SR.Designer.cs
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Kestrel/SR.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class SR {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal SR() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.ServiceFabric.Services.Communication.AspNetCore.SR", typeof(SR).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to endpointResourceName cannot be empty string..
65 | ///
66 | internal static string EndpointNameEmptyExceptionMessage {
67 | get {
68 | return ResourceManager.GetString("EndpointNameEmptyExceptionMessage", resourceCulture);
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore.Kestrel/SR.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | endpointResourceName cannot be empty string.
122 |
123 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/ApplicationBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
7 | {
8 | using System;
9 | using Microsoft.AspNetCore.Builder;
10 |
11 | ///
12 | /// Class containing extension methods for IApplicationBuilder.
13 | ///
14 | public static class ApplicationBuilderExtensions
15 | {
16 | ///
17 | /// Extension method to use ServiceFabricMiddleware for Service Fabric stateful or stateless service
18 | /// using Kestrel or HttpSys as WebServer.
19 | ///
20 | /// Microsoft.AspNetCore.Builder.IApplicationBuilder.
21 | /// Url suffix to determine if the request is meant for current partition and replica.
22 | /// IApplicationBuilder instance.
23 | public static IApplicationBuilder UseServiceFabricMiddleware(this IApplicationBuilder builder, string urlSuffix)
24 | {
25 | if (builder == null)
26 | {
27 | throw new ArgumentNullException("builder");
28 | }
29 |
30 | if (urlSuffix == null)
31 | {
32 | throw new ArgumentNullException("urlSuffix");
33 | }
34 |
35 | return builder.UseMiddleware(urlSuffix);
36 | }
37 |
38 | ///
39 | /// Extension method to use ServiceFabricReverseProxyIntegrationMiddleware for Service Fabric stateful or stateless service
40 | /// using Kestrel or HttpSys as WebServer.
41 | ///
42 | /// Microsoft.AspNetCore.Builder.IApplicationBuilder.
43 | /// IApplicationBuilder instance.
44 | public static IApplicationBuilder UseServiceFabricReverseProxyIntegrationMiddleware(this IApplicationBuilder builder)
45 | {
46 | if (builder == null)
47 | {
48 | throw new ArgumentNullException(nameof(builder));
49 | }
50 |
51 | return builder.UseMiddleware();
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/AspNetCoreCommunicationListener.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
7 | {
8 | using System;
9 | using System.Fabric;
10 | using System.Fabric.Description;
11 | using System.Globalization;
12 | using System.Linq;
13 | using System.Threading;
14 | using System.Threading.Tasks;
15 | using Microsoft.AspNetCore.Hosting;
16 | using Microsoft.AspNetCore.Hosting.Server;
17 | using Microsoft.AspNetCore.Hosting.Server.Features;
18 | using Microsoft.Extensions.DependencyInjection;
19 | using Microsoft.Extensions.Hosting;
20 | using Microsoft.ServiceFabric.Services.Communication.Runtime;
21 |
22 | ///
23 | /// Base class for creating AspNetCore based communication listener for Service Fabric stateless or stateful service.
24 | ///
25 | public abstract class AspNetCoreCommunicationListener : ICommunicationListener
26 | {
27 | private readonly ServiceContext serviceContext;
28 | private readonly ICommunicationListener internalListener;
29 | private string urlSuffix = null;
30 | private bool configuredToUseUniqueServiceUrl = false;
31 |
32 | ///
33 | /// Initializes a new instance of the class.
34 | ///
35 | /// The context of the service for which this communication listener is being constructed.
36 | /// Delegate to build Microsoft.AspNetCore.Hosting.IWebHost, endpoint url generated by the listener is given as input to this delegate.
37 | /// This gives the flexibility to change the url before creating Microsoft.AspNetCore.Hosting.IWebHost if needed.
38 | public AspNetCoreCommunicationListener(ServiceContext serviceContext, Func build)
39 | {
40 | if (serviceContext == null)
41 | {
42 | throw new ArgumentNullException("serviceContext");
43 | }
44 |
45 | if (build == null)
46 | {
47 | throw new ArgumentNullException("build");
48 | }
49 |
50 | this.serviceContext = serviceContext;
51 | this.internalListener = new WebHostCommunicationListener(build, this);
52 | this.urlSuffix = string.Empty;
53 | }
54 |
55 | ///
56 | /// Initializes a new instance of the class.
57 | ///
58 | /// The context of the service for which this communication listener is being constructed.
59 | /// Delegate to build Microsoft.Extensions.Hosting.IHost, endpoint url generated by the listener is given as input to this delegate.
60 | /// This gives the flexibility to change the url before creating Microsoft.Extensions.Hosting.IHost if needed.
61 | public AspNetCoreCommunicationListener(ServiceContext serviceContext, Func build)
62 | {
63 | if (serviceContext == null)
64 | {
65 | throw new ArgumentNullException("serviceContext");
66 | }
67 |
68 | if (build == null)
69 | {
70 | throw new ArgumentNullException("build");
71 | }
72 |
73 | this.serviceContext = serviceContext;
74 | this.internalListener = new GenericHostCommunicationListener(build, this);
75 | this.urlSuffix = string.Empty;
76 | }
77 |
78 | ///
79 | /// Gets the context of the service for which this communication listener is being constructed.
80 | ///
81 | public ServiceContext ServiceContext
82 | {
83 | get { return this.serviceContext; }
84 | }
85 |
86 | ///
87 | /// Gets the url suffix to be used based on specified in
88 | /// .
89 | ///
90 | public string UrlSuffix
91 | {
92 | get
93 | {
94 | return this.urlSuffix;
95 | }
96 | }
97 |
98 | ///
99 | /// This method causes the communication listener to close. Close is a terminal state and
100 | /// this method causes the transition to close ungracefully. Any outstanding operations
101 | /// (including close) should be canceled when this method is called.
102 | ///
103 | public virtual void Abort()
104 | {
105 | this.internalListener.Abort();
106 | }
107 |
108 | ///
109 | /// This method causes the communication listener to close. Close is a terminal state and
110 | /// this method allows the communication listener to transition to this state in a graceful manner.
111 | ///
112 | /// Cancellation token.
113 | ///
114 | /// A Task that represents outstanding operation.
115 | ///
116 | public virtual Task CloseAsync(CancellationToken cancellationToken)
117 | {
118 | return this.internalListener.CloseAsync(cancellationToken);
119 | }
120 |
121 | ///
122 | /// This method causes the communication listener to be opened. Once the Open
123 | /// completes, the communication listener becomes usable - accepts and sends messages.
124 | ///
125 | /// Cancellation token.
126 | ///
127 | /// A Task that represents outstanding operation. The result of the Task is
128 | /// is endpoint string on which IWebHost/IHost is listening.
129 | ///
130 | public virtual Task OpenAsync(CancellationToken cancellationToken)
131 | {
132 | return this.internalListener.OpenAsync(cancellationToken);
133 | }
134 |
135 | ///
136 | /// Configures the listener to use UniqueServiceUrl by appending a urlSuffix PartitionId and ReplicaId.
137 | /// It helps in scenarios when ServiceA listening on a node on port X moves and another Service takes its place on the same node and starts using the same port X,
138 | /// The UniqueServiceUrl in conjunction with middleware rejects requests meant for serviceA arriving at ServiceB.
139 | /// Example:
140 | /// Service A is dynamically assigned port 30000 on node with IP 10.0.0.1, it listens on http://+:30000/ and reports to Naming service http://10.0.0.1:30000/serviceName-A/partitionId-A/replicaId-A
141 | /// Client resolves URL from NS: http://10.0.0.1:30000/serviceName-A/partitionId-A/replicaId-A and sends a request, Service A compares URL path segments to its own service name, partition ID, replica ID, finds they are equal, serves request.
142 | /// Now Service A moves to a different node and Service B comes up at the node with IP 10.0.0.1 and is dynamically assigned port 30000.
143 | /// Service B listens on: http://+:30000/ and reports to NS http://10.0.0.1:30000/serviceName-B/partitionId-B/replicaId-B, Client for Service a sends request to http://10.0.0.1:30000/serviceName-A/partitionId-A/replicaId-A
144 | /// Service B compares URL path segments to its own service name, partition ID, replica ID, finds they do not match, ends the request and responds with HTTP 410. Client receives 410 and re-resolves for service A.
145 | ///
146 | internal void ConfigureToUseUniqueServiceUrl()
147 | {
148 | if (!this.configuredToUseUniqueServiceUrl)
149 | {
150 | this.urlSuffix = string.Format(CultureInfo.InvariantCulture, "/{0}/{1}", this.serviceContext.PartitionId, this.serviceContext.ReplicaOrInstanceId);
151 |
152 | if (this.ServiceContext is StatefulServiceContext)
153 | {
154 | // For stateful service, also append a Guid, Guid makes the url unique in scenarios for stateful services when Listener is
155 | // created to support read on secondary and change role happens from Primary->Secondary for the replica.
156 | this.urlSuffix += "/" + Guid.NewGuid();
157 | }
158 |
159 | this.configuredToUseUniqueServiceUrl = true;
160 | }
161 | }
162 |
163 | ///
164 | /// Gets url for this listener to be used with Web Server.
165 | ///
166 | /// url for this listener to be used with Web Server.
167 | protected internal abstract string GetListenerUrl();
168 |
169 | ///
170 | /// Retrieves the endpoint resource with a given name from the service manifest.
171 | ///
172 | /// The name of the endpoint.
173 | /// The endpoint resource with the specified name.
174 | protected EndpointResourceDescription GetEndpointResourceDescription(string endpointName)
175 | {
176 | if (endpointName == null)
177 | {
178 | throw new ArgumentNullException("endpointName");
179 | }
180 |
181 | if (!this.serviceContext.CodePackageActivationContext.GetEndpoints().Contains(endpointName))
182 | {
183 | throw new InvalidOperationException(string.Format(SR.EndpointNameNotFoundExceptionMessage, endpointName));
184 | }
185 |
186 | return this.serviceContext.CodePackageActivationContext.GetEndpoint(endpointName);
187 | }
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/Friend.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | using System.Runtime.CompilerServices;
6 |
7 | [assembly: InternalsVisibleTo("Microsoft.ServiceFabric.AspNetCore.Tests,PublicKey=0024000004800000940000000602000000240000525341310004000001000100b5fc90e7027f67871e773a8fde8938c81dd402ba65b9201d60593e96c492651e889cc13f1415ebb53fac1131ae0bd333c5ee6021672d9718ea31a8aebd0da0072f25d87dba6fc90ffd598ed4da35e44c398c454307e8e33b8426143daec9f596836f97c8f74750e5975c64e2189f45def46b2a2b1247adc3652bf5c308055da9")]
8 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/GenericHostCommunicationListener.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Fabric;
10 | using System.Linq;
11 | using System.Text;
12 | using System.Threading;
13 | using System.Threading.Tasks;
14 | using Microsoft.AspNetCore.Hosting.Server;
15 | using Microsoft.AspNetCore.Hosting.Server.Features;
16 | using Microsoft.Extensions.DependencyInjection;
17 | using Microsoft.Extensions.Hosting;
18 | using Microsoft.ServiceFabric.Services.Communication.Runtime;
19 |
20 | internal class GenericHostCommunicationListener : ICommunicationListener
21 | {
22 | private readonly Func build;
23 | private readonly ServiceContext serviceContext;
24 | private readonly AspNetCoreCommunicationListener listener;
25 | private IHost host;
26 |
27 | public GenericHostCommunicationListener(Func build, AspNetCoreCommunicationListener listener)
28 | {
29 | this.serviceContext = listener.ServiceContext;
30 | this.build = build;
31 | this.listener = listener;
32 | }
33 |
34 | public void Abort()
35 | {
36 | if (this.host != null)
37 | {
38 | this.host.Dispose();
39 | }
40 | }
41 |
42 | public async Task CloseAsync(CancellationToken cancellationToken)
43 | {
44 | if (this.host != null)
45 | {
46 | await this.host.StopAsync(cancellationToken);
47 | this.host.Dispose();
48 | }
49 | }
50 |
51 | public async Task OpenAsync(CancellationToken cancellationToken)
52 | {
53 | this.host = this.build(this.listener.GetListenerUrl(), this.listener);
54 | if (this.host == null)
55 | {
56 | throw new InvalidOperationException(SR.HostNullExceptionMessage);
57 | }
58 |
59 | await this.host.StartAsync(cancellationToken);
60 |
61 | var server = this.host.Services.GetService();
62 | if (server == null)
63 | {
64 | throw new InvalidOperationException(SR.WebServerNotFound);
65 | }
66 |
67 | var url = server.Features.Get().Addresses.FirstOrDefault();
68 | if (url == null)
69 | {
70 | throw new InvalidOperationException(SR.ErrorNoUrlFromAspNetCore);
71 | }
72 |
73 | var publishAddress = this.serviceContext.PublishAddress;
74 |
75 | if (url.Contains("://+:"))
76 | {
77 | url = url.Replace("://+:", $"://{publishAddress}:");
78 | }
79 | else if (url.Contains("://[::]:"))
80 | {
81 | url = url.Replace("://[::]:", $"://{publishAddress}:");
82 | }
83 |
84 | // When returning url to naming service, add UrlSuffix to it.
85 | // This UrlSuffix will be used by middleware to:
86 | // - drop calls not intended for the service and return 410.
87 | // - modify Path and PathBase in Microsoft.AspNetCore.Http.HttpRequest to be sent correctly to the service code.
88 | url = url.TrimEnd(new[] { '/' }) + this.listener.UrlSuffix;
89 |
90 | return url;
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/Microsoft.ServiceFabric.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Microsoft.ServiceFabric.AspNetCore
7 | Microsoft.ServiceFabric.Services.Communication.AspNetCore
8 | $(OutputPath)\$(AssemblyName).xml
9 | net462;net8.0
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | True
23 | True
24 | SR.resx
25 |
26 |
27 |
28 |
29 | ResXFileCodeGenerator
30 | SR.Designer.cs
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/PathStringExtensions.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
7 | {
8 | using System;
9 | using System.Threading.Tasks;
10 | using Microsoft.AspNetCore.Builder;
11 | using Microsoft.AspNetCore.Http;
12 |
13 | ///
14 | /// PathString extension as aspnet core 1.0.0 binaries doesn't have StartsWithSegments() method with an out param for matched string.
15 | ///
16 | internal static class PathStringExtensions
17 | {
18 | internal static bool StartsWithSegments(
19 | this PathString pathString,
20 | PathString other,
21 | out PathString matched,
22 | out PathString remaining)
23 | {
24 | var value1 = pathString.Value ?? string.Empty;
25 | var value2 = other.Value ?? string.Empty;
26 |
27 | if (value1.StartsWith(value2, StringComparison.OrdinalIgnoreCase))
28 | {
29 | if (value1.Length == value2.Length || value1[value2.Length] == '/')
30 | {
31 | matched = new PathString(value1.Substring(0, value2.Length));
32 | remaining = new PathString(value1.Substring(value2.Length));
33 | return true;
34 | }
35 | }
36 |
37 | remaining = PathString.Empty;
38 | matched = PathString.Empty;
39 | return false;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/SR.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class SR {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal SR() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.ServiceFabric.Services.Communication.AspNetCore.SR", typeof(SR).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to {0} not found in Service Manifest..
65 | ///
66 | internal static string EndpointNameNotFoundExceptionMessage {
67 | get {
68 | return ResourceManager.GetString("EndpointNameNotFoundExceptionMessage", resourceCulture);
69 | }
70 | }
71 |
72 | ///
73 | /// Looks up a localized string similar to "No Url returned from AspNetCore IServerAddressesFeature..
74 | ///
75 | internal static string ErrorNoUrlFromAspNetCore {
76 | get {
77 | return ResourceManager.GetString("ErrorNoUrlFromAspNetCore", resourceCulture);
78 | }
79 | }
80 |
81 | ///
82 | /// Looks up a localized string similar to IHost returned from build delegate is null..
83 | ///
84 | internal static string HostNullExceptionMessage {
85 | get {
86 | return ResourceManager.GetString("HostNullExceptionMessage", resourceCulture);
87 | }
88 | }
89 |
90 | ///
91 | /// Looks up a localized string similar to IWebHost returned from build delegate is null..
92 | ///
93 | internal static string WebHostNullExceptionMessage {
94 | get {
95 | return ResourceManager.GetString("WebHostNullExceptionMessage", resourceCulture);
96 | }
97 | }
98 |
99 | ///
100 | /// Looks up a localized string similar to No web server found over IHost.
101 | ///
102 | internal static string WebServerNotFound {
103 | get {
104 | return ResourceManager.GetString("WebServerNotFound", resourceCulture);
105 | }
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/SR.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | {0} not found in Service Manifest.
122 |
123 |
124 | "No Url returned from AspNetCore IServerAddressesFeature.
125 |
126 |
127 | IHost returned from build delegate is null.
128 |
129 |
130 | IWebHost returned from build delegate is null.
131 |
132 |
133 | No web server found over IHost
134 |
135 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/ServiceFabricIntegrationOptions.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
6 | {
7 | using System;
8 |
9 | ///
10 | /// Integration options for method when used with Microsoft.AspNetCore.Hosting.IWebHostBuilder.
11 | ///
12 | [Flags]
13 | public enum ServiceFabricIntegrationOptions
14 | {
15 | ///
16 | /// This option will not configure the to add any suffix to url when providing the url to Service Fabric Runtime from its method.
17 | ///
18 | None = 0x00,
19 |
20 | ///
21 | /// This option will configure the to add a url suffix containing and
22 | /// to url when providing the url to Service Fabric Runtime from its method.
23 | ///
24 | UseUniqueServiceUrl = 0x01,
25 |
26 | ///
27 | /// This option will enable the Service Fabric Reverse Proxy integration middleware.
28 | ///
29 | UseReverseProxyIntegration = 0x02,
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/ServiceFabricMiddleware.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
7 | {
8 | using System;
9 | using System.Threading.Tasks;
10 | using Microsoft.AspNetCore.Http;
11 |
12 | ///
13 | /// A middleware to be used with Service Fabric stateful and stateless services hosted in Kestrel or HttpSys.
14 | /// This middleware examines the Microsoft.AspNetCore.Http.HttpRequest.Path in request to determine if the request is intended for this replica.
15 | ///
16 | ///
17 | /// This middleware when used with Kestrel and HttpSys based Service Fabric Communication Listeners allows handling of scenarios when
18 | /// the Replica1 listening on Node1 and por11 has moved and another Replica2 is opened on Node1 got Port1.
19 | /// A client which has resolved Replica1 before it moved, will send the request to Node1:Port1. Using this middleware
20 | /// Replica2 can reject calls which were meant for Replica1 by examining the Path in incoming request.
21 | ///
22 | public class ServiceFabricMiddleware
23 | {
24 | private readonly RequestDelegate next;
25 | private readonly string urlSuffix;
26 |
27 | ///
28 | /// Initializes a new instance of the class.
29 | ///
30 | /// Next request handler in pipeline.
31 | /// Url suffix to determine if the request is meant for current partition and replica.
32 | public ServiceFabricMiddleware(RequestDelegate next, string urlSuffix)
33 | {
34 | if (next == null)
35 | {
36 | throw new ArgumentNullException("next");
37 | }
38 |
39 | if (urlSuffix == null)
40 | {
41 | throw new ArgumentNullException("urlSuffix");
42 | }
43 |
44 | this.urlSuffix = urlSuffix;
45 | this.next = next;
46 | }
47 |
48 | ///
49 | /// Invoke.
50 | ///
51 | /// Context.
52 | /// Task for the execution by next middleware in pipeline.
53 | public async Task Invoke(HttpContext context)
54 | {
55 | if (context == null)
56 | {
57 | throw new ArgumentNullException("context");
58 | }
59 |
60 | if (this.urlSuffix.Length == 0)
61 | {
62 | // when urlSuffix is empty string, just call the next middleware in pipeline.
63 | await this.next(context);
64 | }
65 | else
66 | {
67 | // If this middleware is enabled by specifying UseServiceFabricIntegration(), CommunicationListnerBehavior is:
68 | // With ServiceFabricIntegrationOptions.UseUniqueServiceUrl (urlSuffix is /PartitionId/ReplicaOrInstanceId)
69 | // - Url given to WebServer is http://+:port
70 | // - Url given to Service Fabric Runtime is http://ip:port/PartitionId/ReplicaOrInstanceId
71 |
72 | // Since when registering with IWebHost, only http://+:port is provided:
73 | // - HttpRequest.Path contains everything in url after http://+:port, and it must start with urlSuffix
74 |
75 | // So short circuit and return StatusCode 410 if (message isn't intended for this replica,):
76 | // - HttpRequest.Path doesn't start with urlSuffix
77 | if (!context.Request.Path.StartsWithSegments(this.urlSuffix, out var matchedPath, out var remainingPath))
78 | {
79 | context.Response.StatusCode = StatusCodes.Status410Gone;
80 | return;
81 | }
82 |
83 | // All good, change Path, PathBase and call next middleware in the pipeline
84 | var originalPath = context.Request.Path;
85 | var originalPathBase = context.Request.PathBase;
86 | context.Request.Path = remainingPath;
87 | context.Request.PathBase = originalPathBase.Add(matchedPath);
88 |
89 | try
90 | {
91 | await this.next(context);
92 | }
93 | finally
94 | {
95 | context.Request.Path = originalPath;
96 | context.Request.PathBase = originalPathBase;
97 | }
98 | }
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/ServiceFabricReverseProxyIntegrationMiddleware.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
6 | {
7 | using System;
8 | using System.Threading.Tasks;
9 | using Microsoft.AspNetCore.Http;
10 |
11 | ///
12 | /// A middleware to be used with Service Fabric stateful and stateless services hosted in Kestrel or HttpSys.
13 | /// This middleware automatically adds X-ServiceFabric ResourceNotFound header, required by the Service Fabric Reverse Proxy, when 404 status code is returned.
14 | ///
15 | public class ServiceFabricReverseProxyIntegrationMiddleware
16 | {
17 | private const string XServiceFabricHeader = "X-ServiceFabric";
18 | private const string XServiceFabricResourceNotFoundValue = "ResourceNotFound";
19 |
20 | private readonly RequestDelegate next;
21 |
22 | ///
23 | /// Initializes a new instance of the class.
24 | ///
25 | /// Next request handler in pipeline.
26 | public ServiceFabricReverseProxyIntegrationMiddleware(RequestDelegate next)
27 | {
28 | if (next == null)
29 | {
30 | throw new ArgumentNullException(nameof(next));
31 | }
32 |
33 | this.next = next;
34 | }
35 |
36 | ///
37 | /// Invoke.
38 | ///
39 | /// Context.
40 | /// Task for the execution by next middleware in pipeline.
41 | public Task Invoke(HttpContext context)
42 | {
43 | if (context == null)
44 | {
45 | throw new ArgumentNullException(nameof(context));
46 | }
47 |
48 | context.Response.OnStarting(
49 | state =>
50 | {
51 | var response = (HttpResponse)state;
52 | if (response.StatusCode == StatusCodes.Status404NotFound)
53 | {
54 | response.Headers[XServiceFabricHeader] = XServiceFabricResourceNotFoundValue;
55 | }
56 |
57 | return Task.CompletedTask;
58 | },
59 | context.Response);
60 |
61 | return this.next(context);
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/ServiceFabricSetupFilter.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
6 | {
7 | using System;
8 | using Microsoft.AspNetCore.Builder;
9 | using Microsoft.AspNetCore.Hosting;
10 |
11 | internal class ServiceFabricSetupFilter : IStartupFilter
12 | {
13 | private readonly string urlSuffix;
14 | private readonly ServiceFabricIntegrationOptions options;
15 |
16 | internal ServiceFabricSetupFilter(string urlSuffix, ServiceFabricIntegrationOptions options)
17 | {
18 | this.urlSuffix = urlSuffix;
19 | this.options = options;
20 | }
21 |
22 | public Action Configure(Action next)
23 | {
24 | return app =>
25 | {
26 | if (!string.IsNullOrEmpty(this.urlSuffix))
27 | {
28 | app.UseServiceFabricMiddleware(this.urlSuffix);
29 | }
30 |
31 | if (this.options.HasFlag(ServiceFabricIntegrationOptions.UseReverseProxyIntegration))
32 | {
33 | app.UseServiceFabricReverseProxyIntegrationMiddleware();
34 | }
35 |
36 | next(app);
37 | };
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/WebHostBuilderServiceFabricExtension.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
6 | {
7 | using System;
8 | using Microsoft.AspNetCore.Hosting;
9 | using Microsoft.Extensions.DependencyInjection;
10 |
11 | ///
12 | /// Class containing Service Fabric related extension methods for Microsoft.AspNetCore.Hosting.IWebHostBuilder.
13 | ///
14 | public static class WebHostBuilderServiceFabricExtension
15 | {
16 | private static readonly string SettingName = "UseServiceFabricIntegration";
17 |
18 | ///
19 | /// Configures the Service to use ServiceFabricMiddleware and tells the listener that middleware is configured for the service so that it can
20 | /// suffix PartitionId and ReplicaOrInstanceId to url before providing it to Service Fabric Runtime.
21 | ///
22 | /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure.
23 | /// The to configure.
24 | /// Options to configure ServiceFabricMiddleware and AspNetCoreCommunicationListener.
25 | /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder.
26 | public static IWebHostBuilder UseServiceFabricIntegration(this IWebHostBuilder hostBuilder, AspNetCoreCommunicationListener listener, ServiceFabricIntegrationOptions options)
27 | {
28 | if (hostBuilder == null)
29 | {
30 | throw new ArgumentNullException("hostBuilder");
31 | }
32 |
33 | // Check if 'UseServiceFabricIntegration' has already been called.
34 | if (hostBuilder.GetSetting(SettingName) == true.ToString())
35 | {
36 | return hostBuilder;
37 | }
38 |
39 | // Set flag to prevent double service configuration
40 | hostBuilder.UseSetting(SettingName, true.ToString());
41 |
42 | // Configure listener to use PartitionId and ReplicaId as urlSuffix only when specified in options.
43 | if (options.HasFlag(ServiceFabricIntegrationOptions.UseUniqueServiceUrl))
44 | {
45 | // notify listener to use urlSuffix when giving url to Service Fabric Runtime from OpenAsync()
46 | listener.ConfigureToUseUniqueServiceUrl();
47 | }
48 |
49 | hostBuilder.ConfigureServices(services =>
50 | {
51 | // Configure MiddleWare
52 | services.AddSingleton(new ServiceFabricSetupFilter(listener.UrlSuffix, options));
53 | });
54 |
55 | return hostBuilder;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Microsoft.ServiceFabric.AspNetCore/WebHostCommunicationListener.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 | namespace Microsoft.ServiceFabric.Services.Communication.AspNetCore
6 | {
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Fabric;
10 | using System.Linq;
11 | using System.Text;
12 | using System.Threading;
13 | using System.Threading.Tasks;
14 | using Microsoft.AspNetCore.Hosting;
15 | using Microsoft.AspNetCore.Hosting.Server.Features;
16 | using Microsoft.ServiceFabric.Services.Communication.Runtime;
17 |
18 | internal class WebHostCommunicationListener : ICommunicationListener
19 | {
20 | private readonly Func build;
21 | private readonly ServiceContext serviceContext;
22 | private readonly AspNetCoreCommunicationListener listener;
23 | private IWebHost host;
24 |
25 | public WebHostCommunicationListener(Func build, AspNetCoreCommunicationListener listener)
26 | {
27 | this.serviceContext = listener.ServiceContext;
28 | this.build = build;
29 | this.listener = listener;
30 | }
31 |
32 | public void Abort()
33 | {
34 | if (this.host != null)
35 | {
36 | this.host.Dispose();
37 | }
38 | }
39 |
40 | public async Task CloseAsync(CancellationToken cancellationToken)
41 | {
42 | if (this.host != null)
43 | {
44 | await this.host.StopAsync(cancellationToken);
45 | this.host.Dispose();
46 | }
47 | }
48 |
49 | public async Task OpenAsync(CancellationToken cancellationToken)
50 | {
51 | this.host = this.build(this.listener.GetListenerUrl(), this.listener);
52 | if (this.host == null)
53 | {
54 | throw new InvalidOperationException(SR.WebHostNullExceptionMessage);
55 | }
56 |
57 | await this.host.StartAsync(cancellationToken);
58 |
59 | var url = this.host.ServerFeatures.Get().Addresses.FirstOrDefault();
60 |
61 | if (url == null)
62 | {
63 | throw new InvalidOperationException(SR.ErrorNoUrlFromAspNetCore);
64 | }
65 |
66 | var publishAddress = this.serviceContext.PublishAddress;
67 |
68 | if (url.Contains("://+:"))
69 | {
70 | url = url.Replace("://+:", $"://{publishAddress}:");
71 | }
72 | else if (url.Contains("://[::]:"))
73 | {
74 | url = url.Replace("://[::]:", $"://{publishAddress}:");
75 | }
76 |
77 | // When returning url to naming service, add UrlSuffix to it.
78 | // This UrlSuffix will be used by middleware to:
79 | // - drop calls not intended for the service and return 410.
80 | // - modify Path and PathBase in Microsoft.AspNetCore.Http.HttpRequest to be sent correctly to the service code.
81 | url = url.TrimEnd(new[] { '/' }) + this.listener.UrlSuffix;
82 |
83 | return url;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/test/unittests/Microsoft.ServiceFabric.AspNetCore.Tests/AspNetCoreCommunicationListenerTests.cs:
--------------------------------------------------------------------------------
1 | // ------------------------------------------------------------
2 | // Copyright (c) Microsoft Corporation. All rights reserved.
3 | // Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4 | // ------------------------------------------------------------
5 |
6 | namespace Microsoft.ServiceFabric.AspNetCore.Tests
7 | {
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Fabric.Description;
11 | using System.Threading;
12 | using FluentAssertions;
13 | using Microsoft.AspNetCore.Hosting;
14 | using Microsoft.AspNetCore.Hosting.Server;
15 | using Microsoft.AspNetCore.Hosting.Server.Features;
16 | using Microsoft.AspNetCore.Http.Features;
17 | using Microsoft.Extensions.DependencyInjection;
18 | using Microsoft.Extensions.Hosting;
19 | using Microsoft.ServiceFabric.Services.Communication.AspNetCore;
20 | using Moq;
21 |
22 | ///
23 | /// Test class for AspNetCoreCommunicationListener.
24 | ///
25 | public class AspNetCoreCommunicationListenerTests
26 | {
27 | ///
28 | /// Endpoint name used by tests.
29 | ///
30 | protected const string EndpointName = "MockEndpoint";
31 |
32 | private const EndpointProtocol ExpectedProtocolFromEndpoint = EndpointProtocol.Http;
33 | private const string DefaultExpectedProtocol = "http";
34 | private const string DefaultPathPrefix = "PathPrefix";
35 | private const int DefaultExpectedPort = 0;
36 | private string urlFromListenerToBuildFunc;
37 |
38 | ///
39 | /// Gets strings for the two Host Types - WebHost and GenericHost.
40 | ///
41 | public static IEnumerable