();
41 | var host = builder.Build();
42 | host.Run();
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Properties/PublishProfiles/FolderProfile.pubxml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 | FileSystem
9 | FileSystem
10 | Release
11 | Any CPU
12 |
13 | True
14 | False
15 | 457032d7-7127-4846-b25c-881394ec26db
16 | bin\Release\PublishOutput
17 | True
18 | netcoreapp2.1
19 | false
20 | <_IsPortable>true
21 |
22 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Properties/PublishProfiles/FolderProfile.pubxml.user:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 | <_PublishTargetUrl>F:\Workshop\Github\NanoFabric\sample\SampleService.MvcClient\bin\Release\PublishOutput
10 |
11 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:64290/",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "SampleService.MvcClient": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "http://localhost:5001"
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/SampleService.MvcClient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp2.1
4 |
5 |
6 | $(PackageTargetFallback);portable-net45+win8+wp8+wpa81;
7 | SampleService.MvcClient
8 | SampleService.MvcClient
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\system.identitymodel.tokens.jwt\5.1.4\lib\netstandard1.4\System.IdentityModel.Tokens.Jwt.dll
30 |
31 |
32 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/SampleService.MvcClient.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ProjectDebugger
5 |
6 |
7 | SampleService.MvcClient
8 | FolderProfile
9 |
10 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Views/Home/About.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "About";
3 | }
4 | @ViewData["Title"].
5 | @ViewData["Message"]
6 |
7 | Use this area to provide additional information.
8 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Views/Home/CallApi.cshtml:
--------------------------------------------------------------------------------
1 | API Response
2 |
3 | @ViewBag.Json
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Views/Home/Contact.cshtml:
--------------------------------------------------------------------------------
1 | @using Microsoft.AspNetCore.Authentication
2 | @{
3 | ViewData["Title"] = "Contact";
4 | }
5 | @ViewData["Title"].
6 | @ViewData["Message"]
7 |
10 | @{
11 | string it = await Context.GetTokenAsync("id_token");
12 | string at = await Context.GetTokenAsync("access_token");
13 | string rt = await Context.GetTokenAsync("refresh_token");
14 | }
15 |
16 |
17 |
18 | @if (it != null)
19 | {
20 | - id_token
21 | - @it
22 | }
23 | @if (at != null)
24 | {
25 | - access_token
26 | - @at
27 | }
28 | @if (rt != null)
29 | {
30 | - refresh_token
31 | - @rt
32 | }
33 | @foreach (var claim in User.Claims)
34 | {
35 | - @claim.Type
36 | - @claim.Value
37 | }
38 |
39 |
40 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Views/Home/Index.cshtml:
--------------------------------------------------------------------------------
1 |
2 | @{
3 | ViewData["Title"] = "Home Page";
4 | }
5 |
6 | @if (User.Identity.IsAuthenticated)
7 | {
8 | LoggedInAs: @User.Identity.Name
9 | }
10 | else
11 | {
12 | notLoggedIn
13 | }
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Views/Shared/Error.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | ViewData["Title"] = "Error";
3 | }
4 |
5 | Error.
6 | An error occurred while processing your request.
7 |
8 | Development Mode
9 |
10 | Swapping to Development environment will display more detailed information about the error that occurred.
11 |
12 |
13 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application.
14 |
15 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Views/Shared/_ValidationScriptsPartial.cshtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
12 |
18 |
19 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Views/_ViewImports.cshtml:
--------------------------------------------------------------------------------
1 | @using SampleService.MvcClient
2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
3 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/Views/_ViewStart.cshtml:
--------------------------------------------------------------------------------
1 | @{
2 | Layout = "_Layout";
3 | }
4 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Debug",
6 | "System": "Information",
7 | "Microsoft": "Information"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": false,
4 | "LogLevel": {
5 | "Default": "Warning"
6 | }
7 | },
8 | "ServiceDiscovery": {
9 | "ServiceName": "SampleService_MvcClient",
10 | "Version": "1.0.0-pre",
11 | "HealthCheckTemplate": "",
12 | "Endpoints": [],
13 | "Consul": {
14 | "HttpEndpoint": "http://127.0.0.1:8500",
15 | "DnsEndpoint": {
16 | "Address": "127.0.0.1",
17 | "Port": 8600
18 | }
19 | }
20 | },
21 | "Skywalking": {
22 | "CollectorUrl": "127.0.0.1:11800"
23 | },
24 | "ServerAddress": "http://127.0.0.1:9000",
25 | "Authority": "http://127.0.0.1:5000"
26 | }
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "asp.net",
3 | "private": true,
4 | "dependencies": {
5 | "bootstrap": "3.3.7",
6 | "jquery": "2.2.0",
7 | "jquery-validation": "1.14.0",
8 | "jquery-validation-unobtrusive": "3.2.6"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/bundleconfig.json:
--------------------------------------------------------------------------------
1 | // Configure bundling and minification for the project.
2 | // More info at https://go.microsoft.com/fwlink/?LinkId=808241
3 | [
4 | {
5 | "outputFileName": "wwwroot/css/site.min.css",
6 | // An array of relative input file paths. Globbing patterns supported
7 | "inputFiles": [
8 | "wwwroot/css/site.css"
9 | ]
10 | },
11 | {
12 | "outputFileName": "wwwroot/js/site.min.js",
13 | "inputFiles": [
14 | "wwwroot/js/site.js"
15 | ],
16 | // Optionally specify minification options
17 | "minify": {
18 | "enabled": true,
19 | "renameLocals": true
20 | },
21 | // Optionally generate .map file
22 | "sourceMap": false
23 | }
24 | ]
25 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/runtimeconfig.template.json:
--------------------------------------------------------------------------------
1 | {
2 | "configProperties": {
3 | "System.GC.Server": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/css/site.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding-top: 50px;
3 | padding-bottom: 20px;
4 | }
5 |
6 | /* Wrapping element */
7 | /* Set some basic padding to keep content from hitting the edges */
8 | .body-content {
9 | padding-left: 15px;
10 | padding-right: 15px;
11 | }
12 |
13 | /* Set widths on the form inputs since otherwise they're 100% wide */
14 | input,
15 | select,
16 | textarea {
17 | max-width: 280px;
18 | }
19 |
20 | /* Carousel */
21 | .carousel-caption p {
22 | font-size: 20px;
23 | line-height: 1.4;
24 | }
25 |
26 | /* Make .svg files in the carousel display properly in older browsers */
27 | .carousel-inner .item img[src$=".svg"] {
28 | width: 100%;
29 | }
30 |
31 | /* Hide/rearrange for smaller screens */
32 | @media screen and (max-width: 767px) {
33 | /* Hide captions */
34 | .carousel-caption {
35 | display: none;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/css/site.min.css:
--------------------------------------------------------------------------------
1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}input,select,textarea{max-width:280px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}@media screen and (max-width:767px){.carousel-caption{display:none}}
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.MvcClient/wwwroot/favicon.ico
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/js/site.js:
--------------------------------------------------------------------------------
1 | // Write your Javascript code.
2 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/js/site.min.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.MvcClient/wwwroot/js/site.min.js
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "bootstrap",
3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.",
4 | "keywords": [
5 | "css",
6 | "js",
7 | "less",
8 | "mobile-first",
9 | "responsive",
10 | "front-end",
11 | "framework",
12 | "web"
13 | ],
14 | "homepage": "http://getbootstrap.com",
15 | "license": "MIT",
16 | "moduleType": "globals",
17 | "main": [
18 | "less/bootstrap.less",
19 | "dist/js/bootstrap.js"
20 | ],
21 | "ignore": [
22 | "/.*",
23 | "_config.yml",
24 | "CNAME",
25 | "composer.json",
26 | "CONTRIBUTING.md",
27 | "docs",
28 | "js/tests",
29 | "test-infra"
30 | ],
31 | "dependencies": {
32 | "jquery": "1.9.1 - 3"
33 | },
34 | "version": "3.3.7",
35 | "_release": "3.3.7",
36 | "_resolution": {
37 | "type": "version",
38 | "tag": "v3.3.7",
39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86"
40 | },
41 | "_source": "https://github.com/twbs/bootstrap.git",
42 | "_target": "v3.3.7",
43 | "_originalSource": "bootstrap",
44 | "_direct": true
45 | }
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2011-2016 Twitter, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/bootstrap/dist/js/npm.js:
--------------------------------------------------------------------------------
1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
2 | require('../../js/transition.js')
3 | require('../../js/alert.js')
4 | require('../../js/button.js')
5 | require('../../js/carousel.js')
6 | require('../../js/collapse.js')
7 | require('../../js/dropdown.js')
8 | require('../../js/modal.js')
9 | require('../../js/tooltip.js')
10 | require('../../js/popover.js')
11 | require('../../js/scrollspy.js')
12 | require('../../js/tab.js')
13 | require('../../js/affix.js')
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/jquery-validation-unobtrusive/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-validation-unobtrusive",
3 | "version": "3.2.6",
4 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive",
5 | "description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.",
6 | "main": [
7 | "jquery.validate.unobtrusive.js"
8 | ],
9 | "ignore": [
10 | "**/.*",
11 | "*.json",
12 | "*.md",
13 | "*.txt",
14 | "gulpfile.js"
15 | ],
16 | "keywords": [
17 | "jquery",
18 | "asp.net",
19 | "mvc",
20 | "validation",
21 | "unobtrusive"
22 | ],
23 | "authors": [
24 | "Microsoft"
25 | ],
26 | "license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm",
27 | "repository": {
28 | "type": "git",
29 | "url": "git://github.com/aspnet/jquery-validation-unobtrusive.git"
30 | },
31 | "dependencies": {
32 | "jquery-validation": ">=1.8",
33 | "jquery": ">=1.8"
34 | },
35 | "_release": "3.2.6",
36 | "_resolution": {
37 | "type": "version",
38 | "tag": "v3.2.6",
39 | "commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7"
40 | },
41 | "_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git",
42 | "_target": "3.2.6",
43 | "_originalSource": "jquery-validation-unobtrusive"
44 | }
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/jquery-validation/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery-validation",
3 | "homepage": "http://jqueryvalidation.org/",
4 | "repository": {
5 | "type": "git",
6 | "url": "git://github.com/jzaefferer/jquery-validation.git"
7 | },
8 | "authors": [
9 | "Jörn Zaefferer "
10 | ],
11 | "description": "Form validation made easy",
12 | "main": "dist/jquery.validate.js",
13 | "keywords": [
14 | "forms",
15 | "validation",
16 | "validate"
17 | ],
18 | "license": "MIT",
19 | "ignore": [
20 | "**/.*",
21 | "node_modules",
22 | "bower_components",
23 | "test",
24 | "demo",
25 | "lib"
26 | ],
27 | "dependencies": {
28 | "jquery": ">= 1.7.2"
29 | },
30 | "version": "1.14.0",
31 | "_release": "1.14.0",
32 | "_resolution": {
33 | "type": "version",
34 | "tag": "1.14.0",
35 | "commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48"
36 | },
37 | "_source": "git://github.com/jzaefferer/jquery-validation.git",
38 | "_target": ">=1.8",
39 | "_originalSource": "jquery-validation"
40 | }
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/jquery-validation/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | =====================
3 |
4 | Copyright Jörn Zaefferer
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/jquery/.bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jquery",
3 | "main": "dist/jquery.js",
4 | "license": "MIT",
5 | "ignore": [
6 | "package.json"
7 | ],
8 | "keywords": [
9 | "jquery",
10 | "javascript",
11 | "browser",
12 | "library"
13 | ],
14 | "homepage": "https://github.com/jquery/jquery-dist",
15 | "version": "2.2.0",
16 | "_release": "2.2.0",
17 | "_resolution": {
18 | "type": "version",
19 | "tag": "2.2.0",
20 | "commit": "6fc01e29bdad0964f62ef56d01297039cdcadbe5"
21 | },
22 | "_source": "git://github.com/jquery/jquery-dist.git",
23 | "_target": "2.2.0",
24 | "_originalSource": "jquery"
25 | }
--------------------------------------------------------------------------------
/sample/SampleService.MvcClient/wwwroot/lib/jquery/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright jQuery Foundation and other contributors, https://jquery.org/
2 |
3 | This software consists of voluntary contributions made by many
4 | individuals. For exact contribution history, see the revision history
5 | available at https://github.com/jquery/jquery
6 |
7 | The following license applies to all parts of this software except as
8 | documented below:
9 |
10 | ====
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining
13 | a copy of this software and associated documentation files (the
14 | "Software"), to deal in the Software without restriction, including
15 | without limitation the rights to use, copy, modify, merge, publish,
16 | distribute, sublicense, and/or sell copies of the Software, and to
17 | permit persons to whom the Software is furnished to do so, subject to
18 | the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be
21 | included in all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 |
31 | ====
32 |
33 | All files located in the node_modules and external directories are
34 | externally maintained libraries used by this software which have their
35 | own licenses; we recommend you read them, as their terms may differ from
36 | the terms above.
37 |
--------------------------------------------------------------------------------
/src/NanoFabric.AppMetrics/AppMetricsApplicationBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace NanoFabric.AppMetrics
7 | {
8 | public static class AppMetricsApplicationBuilderExtensions
9 | {
10 | public static IApplicationBuilder UseAppMetrics(this IApplicationBuilder app)
11 | {
12 | app.UseMetricsAllMiddleware();
13 | // Or to cherry-pick the tracking of interest
14 | app.UseMetricsActiveRequestMiddleware();
15 | app.UseMetricsErrorTrackingMiddleware();
16 | app.UseMetricsPostAndPutSizeTrackingMiddleware();
17 | app.UseMetricsRequestTrackingMiddleware();
18 | app.UseMetricsOAuth2TrackingMiddleware();
19 | app.UseMetricsApdexTrackingMiddleware();
20 |
21 | app.UseMetricsAllEndpoints();
22 | // Or to cherry-pick endpoint of interest
23 | app.UseMetricsEndpoint();
24 | app.UseMetricsTextEndpoint();
25 | app.UseEnvInfoEndpoint();
26 |
27 | return app;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/NanoFabric.AppMetrics/AppMetricsOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.AppMetrics
6 | {
7 | public class AppMetricsOptions
8 | {
9 | public string DataBaseName { get; set; }
10 |
11 | public string ConnectionString { get; set; }
12 |
13 | public string UserName { get; set; }
14 |
15 | public string Password { get; set; }
16 |
17 | public string App { get; set; }
18 |
19 | public string Env { get; set; }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/NanoFabric.AppMetrics/NanoFabric.AppMetrics.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | NanoFabric.AppMetrics
6 | NanoFabric.AppMetrics
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/ApiControllerBase.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Mvc;
2 |
3 |
4 | namespace NanoFabric.WebApi
5 | {
6 | public class ApiControllerBase : Controller
7 | {
8 |
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/ApiResult/ApiResultFilterAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Microsoft.AspNetCore.Mvc;
3 | using Microsoft.AspNetCore.Mvc.Filters;
4 |
5 | namespace NanoFabric.WebApi.ApiWidgets
6 | {
7 | internal class ApiResultFilterAttribute : ResultFilterAttribute
8 | {
9 | public override void OnResultExecuting(ResultExecutingContext context) {
10 | if (context.Result is ObjectResult) {
11 | // this include OkObjectResult, NotFoundObjectResult, BadRequestObjectResult, CreatedResult (lose Location)
12 | var objectResult = context.Result as ObjectResult;
13 | if (objectResult.Value == null) {
14 | context.Result = new ObjectResult(ApiResult.Empty);
15 | }
16 | else if (!(objectResult.Value is IApiResult)) {
17 | var apiResult = Activator.CreateInstance(
18 | typeof(ApiResult<>).MakeGenericType(objectResult.DeclaredType), objectResult.Value, objectResult.StatusCode);
19 | context.Result = new ObjectResult(apiResult);
20 | }
21 | }
22 | else if (context.Result is EmptyResult) {
23 | // return void or Task
24 | context.Result = new ObjectResult(ApiResult.Empty);
25 | }
26 | else if (context.Result is ContentResult) {
27 | context.Result = new ObjectResult(ApiResult.Succeed((context.Result as ContentResult).Content));
28 | }
29 | else if (context.Result is StatusCodeResult) {
30 | // this include OKResult, NoContentResult, UnauthorizedResult, NotFoundResult, BadRequestResult
31 | context.Result = new ObjectResult(ApiResult.From((context.Result as StatusCodeResult).StatusCode));
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/ApiResult/ApiResultOfT.cs:
--------------------------------------------------------------------------------
1 | namespace NanoFabric.WebApi.ApiWidgets {
2 |
3 | public class ApiResult : ApiResult, IApiResult
4 | {
5 | ///
6 | /// Initializes a new instance of the class.
7 | ///
8 | public ApiResult() { }
9 |
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | /// The result.
14 | /// The status code.
15 | public ApiResult(TResult result, int? statusCode) {
16 | StatusCode = statusCode ?? 200;
17 | Result = result;
18 | }
19 |
20 | ///
21 | /// Gets or sets the result.
22 | ///
23 | /// The result.
24 | public TResult Result { get; set; }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/ApiResult/IApiResult.cs:
--------------------------------------------------------------------------------
1 | namespace NanoFabric.WebApi.ApiWidgets
2 | {
3 | public interface IApiResult
4 | {
5 | ///
6 | /// Gets or sets the status code.
7 | ///
8 | /// The status code.
9 | int StatusCode { get; set; }
10 |
11 | ///
12 | /// Gets or sets the message.
13 | ///
14 | /// The message.
15 | string Message { get; set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/ApiResult/IApiResultOfT.cs:
--------------------------------------------------------------------------------
1 | namespace NanoFabric.WebApi.ApiWidgets
2 | {
3 | public interface IApiResult : IApiResult {
4 |
5 | ///
6 | /// Gets or sets the result.
7 | ///
8 | /// The result.
9 | TResult Result { get; set; }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/ApiResult/IMvcCoreBuilderApiResultExtensions.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.WebApi.ApiWidgets;
2 | using System;
3 |
4 | namespace Microsoft.Extensions.DependencyInjection
5 | {
6 | public static class IMvcCoreBuilderApiResultExtensions
7 | {
8 | public static IMvcBuilder AddMvcApiResult(this IMvcBuilder builder)
9 | {
10 | if (builder == null) {
11 | throw new ArgumentNullException(nameof(builder));
12 | }
13 |
14 | return builder.AddMvcOptions(options => {
15 | options.Filters.Add(typeof(ApiResultFilterAttribute));
16 | options.Filters.Add(typeof(ApiExceptionFilterAttribute));
17 | });
18 | }
19 |
20 | public static IMvcCoreBuilder AddMvcApiResult(this IMvcCoreBuilder builder)
21 | {
22 | if (builder == null) {
23 | throw new ArgumentNullException(nameof(builder));
24 | }
25 |
26 | return builder.AddMvcOptions(options => {
27 | options.Filters.Add(typeof(ApiResultFilterAttribute));
28 | options.Filters.Add(typeof(ApiExceptionFilterAttribute));
29 | });
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/Cors/WildcardCorsService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Cors.Infrastructure;
2 | using Microsoft.AspNetCore.Http;
3 | using Microsoft.Extensions.Options;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace NanoFabric.AspNetCore.Cors
9 | {
10 | ///
11 | /// 一劳永逸:域名支持通配符,ASP.NET Core中配置CORS
12 | /// http://www.cnblogs.com/dudu/p/5895424.html
13 | ///
14 | public class WildcardCorsService : CorsService
15 | {
16 | public WildcardCorsService(IOptions options)
17 | : base(options)
18 | {
19 | }
20 |
21 | public override void EvaluateRequest(HttpContext context, CorsPolicy policy, CorsResult result)
22 | {
23 | var origin = context.Request.Headers[CorsConstants.Origin];
24 | EvaluateOriginForWildcard(policy.Origins, origin);
25 | base.EvaluateRequest(context, policy, result);
26 | }
27 |
28 | public override void EvaluatePreflightRequest(HttpContext context, CorsPolicy policy, CorsResult result)
29 | {
30 | var origin = context.Request.Headers[CorsConstants.Origin];
31 | EvaluateOriginForWildcard(policy.Origins, origin);
32 | base.EvaluatePreflightRequest(context, policy, result);
33 | }
34 |
35 | private void EvaluateOriginForWildcard(IList origins, string origin)
36 | {
37 | //...
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/HttpContextUser.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Security.Claims;
4 | using Microsoft.AspNetCore.Http;
5 | using NanoFabric.Core;
6 |
7 | namespace NanoFabric.AspNetCore
8 | {
9 | public class HttpContextUser : IUser
10 | {
11 | private readonly IHttpContextAccessor _httpContextAccessor;
12 |
13 | public HttpContextUser(IHttpContextAccessor httpContextAccessor)
14 | {
15 | _httpContextAccessor = httpContextAccessor;
16 | }
17 |
18 | public string Id => _httpContextAccessor.HttpContext.User.Claims.First(c => c.Type == "sub").Value;
19 |
20 | public string Name => _httpContextAccessor.HttpContext.User.Identity.Name;
21 |
22 | public IEnumerable Claims => _httpContextAccessor.HttpContext.User.Claims;
23 | }
24 | }
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/NanoFabric.AspNetCore.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.aspnetcore.authentication.jwtbearer\2.0.0\lib\netstandard2.0\Microsoft.AspNetCore.Authentication.JwtBearer.dll
20 |
21 |
22 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\system.identitymodel.tokens.jwt\5.1.4\lib\netstandard1.4\System.IdentityModel.Tokens.Jwt.dll
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/NanoStartupFilter.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.AspNetCore.Hosting;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace NanoFabric.AspNetCore
8 | {
9 | public class NanoStartupFilter : IStartupFilter
10 | {
11 | public Action Configure(Action next)
12 | {
13 | return app =>
14 | {
15 | app.Use(async (context, _next) =>
16 | {
17 | context.Response.Headers.Add("Server", "NanoFabric Server");
18 | await _next();
19 | });
20 | next(app);
21 | };
22 | }
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/StatusController.cs:
--------------------------------------------------------------------------------
1 |
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace NanoFabric.WebApi
5 | {
6 | public class StatusController : ApiControllerBase
7 | {
8 | [Route("/status")]
9 | [HttpGet]
10 | [ApiExplorerSettings(IgnoreApi = true)]
11 | public string GetStatus()
12 | {
13 | return "OK";
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NanoFabric.AspNetCore/WebApiRegistryTenant.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Core;
2 | using System;
3 |
4 | namespace NanoFabric.WebApi
5 | {
6 | public class WebApiRegistryTenant : IRegistryTenant
7 | {
8 | public Uri Uri { get; }
9 |
10 | public WebApiRegistryTenant(Uri uri)
11 | {
12 | Uri = uri;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/NanoFabric.Autofac/NanoFabric.Autofac.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.Autofac/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Autofac;
2 | using Autofac.Core;
3 | using Autofac.Extensions.DependencyInjection;
4 | using Microsoft.Extensions.DependencyInjection;
5 | using System;
6 |
7 | namespace NanoFabric.Autofac
8 | {
9 | public static class ServiceCollectionExtensions
10 | {
11 | public static IServiceProvider ConvertToAutofac(
12 | this IServiceCollection services,
13 | params IModule[] modules
14 | )
15 | {
16 | var container = new ContainerBuilder();
17 | foreach (var module in modules)
18 | {
19 | container.RegisterModule(module);
20 | }
21 | container.Populate(services);
22 | return new AutofacServiceProvider(container.Build());
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/DnsHelper.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 | using System.Net.Sockets;
3 | using System.Threading.Tasks;
4 | using System.Linq;
5 | using DnsClient;
6 |
7 | namespace NanoFabric.Core
8 | {
9 | public static class DnsHelper
10 | {
11 | ///
12 | /// 获取本地的IP地址
13 | ///
14 | /// 是否ipv4
15 | ///
16 | public static async Task GetIpAddressAsync(bool ipv4 = true)
17 | {
18 | var client = new LookupClient();
19 | var hostEntry = await client.GetHostEntryAsync(Dns.GetHostName());
20 | IPAddress ipaddress = null;
21 | if (ipv4)
22 | {
23 | ipaddress = (from ip in hostEntry.AddressList where
24 | (!IPAddress.IsLoopback(ip) && ip.AddressFamily == AddressFamily.InterNetwork)
25 | select ip)
26 | .FirstOrDefault() ;
27 | }
28 | else
29 | {
30 | ipaddress = (from ip in hostEntry.AddressList where
31 | (!IPAddress.IsLoopback(ip) && ip.AddressFamily == AddressFamily.InterNetworkV6)
32 | select ip)
33 | .FirstOrDefault();
34 | }
35 | if(ipaddress != null)
36 | {
37 | return ipaddress.ToString();
38 | }
39 |
40 | return string.Empty;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Extensions/StringExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace NanoFabric.Core
6 | {
7 | public static class StringExtensions
8 | {
9 | public static string TrimStart(this string source, string trim, StringComparison stringComparison = StringComparison.Ordinal)
10 | {
11 | if (source == null)
12 | {
13 | return null;
14 | }
15 |
16 | string s = source;
17 | while (s.StartsWith(trim, stringComparison))
18 | {
19 | s = s.Substring(trim.Length);
20 | }
21 |
22 | return s;
23 | }
24 |
25 | ///
26 | /// 分割逗号的字符串为List
27 | ///
28 | ///
29 | /// nullorwhitespace字符串是否返回空对象
30 | ///
31 | public static List SplitCsv(this string csvList, bool nullOrWhitespaceInputReturnsNull = false)
32 | {
33 | if (string.IsNullOrWhiteSpace(csvList))
34 | return nullOrWhitespaceInputReturnsNull ? null : new List();
35 |
36 | return csvList
37 | .TrimEnd(',')
38 | .Split(',')
39 | .AsEnumerable()
40 | .Select(s => s.Trim())
41 | .ToList();
42 | }
43 |
44 | public static bool IsNullOrWhitespace(this string s)
45 | {
46 | return String.IsNullOrWhiteSpace(s);
47 | }
48 |
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/IApiInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Reflection;
3 |
4 | namespace NanoFabric.Core
5 | {
6 | public interface IApiInfo
7 | {
8 | ///
9 | /// server-side-bound listener address
10 | ///
11 | string BindAddress { get; set; }
12 |
13 | ///
14 | /// service-side-bound listening ports
15 | ///
16 | int BindPort { get; set; }
17 |
18 | string AuthenticationAuthority { get; }
19 |
20 | string ApiName { get; }
21 |
22 | string ApiSecret { get; }
23 |
24 | string Title { get; }
25 |
26 | string Version { get; }
27 |
28 | Assembly ApplicationAssembly { get; }
29 |
30 | IDictionary Scopes { get; }
31 |
32 | SwaggerAuthInfo SwaggerAuthInfo { get; }
33 |
34 | }
35 |
36 | public class SwaggerAuthInfo
37 | {
38 | public string ClientId { get; }
39 | public string Secret { get; }
40 | public string Realm { get; }
41 |
42 | public SwaggerAuthInfo(
43 | string clientId,
44 | string secret,
45 | string realm
46 | )
47 | {
48 | ClientId = clientId;
49 | Secret = secret;
50 | Realm = realm;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/IUser.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Security.Claims;
3 |
4 | namespace NanoFabric.Core
5 | {
6 | public interface IUser
7 | {
8 | string Id { get; }
9 | string Name { get; }
10 | IEnumerable Claims { get; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Json/CamelCasePropertyNamesContractResolver.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Newtonsoft.Json.Serialization;
3 | using System;
4 | using System.Reflection;
5 |
6 | namespace NanoFabric.Core.Json
7 | {
8 | public class CamelCasePropertyNamesContractResolver : Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver
9 | {
10 | protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
11 | {
12 | JsonProperty property = base.CreateProperty(member, memberSerialization);
13 |
14 | ModifyProperty(member, property);
15 |
16 | return property;
17 | }
18 |
19 | protected virtual void ModifyProperty(MemberInfo member, JsonProperty property)
20 | {
21 | if (property.PropertyType != typeof(DateTime) && property.PropertyType != typeof(DateTime?))
22 | {
23 | return;
24 | }
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Json/ContractResolver.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using Newtonsoft.Json.Serialization;
3 | using System;
4 | using System.Reflection;
5 |
6 | namespace NanoFabric.Core.Json
7 | {
8 | public class ContractResolver : DefaultContractResolver
9 | {
10 | protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
11 | {
12 | JsonProperty property = base.CreateProperty(member, memberSerialization);
13 |
14 | ModifyProperty(member, property);
15 |
16 | return property;
17 | }
18 |
19 | protected virtual void ModifyProperty(MemberInfo member, JsonProperty property)
20 | {
21 | if (property.PropertyType != typeof(DateTime) && property.PropertyType != typeof(DateTime?))
22 | {
23 | return;
24 | }
25 |
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Core/MqMessages/IMqMessagePublisher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 |
6 | namespace NanoFabric.Core.MqMessages
7 | {
8 | ///
9 | /// 消息发布接口
10 | ///
11 | public interface IMqMessagePublisher
12 | {
13 | ///
14 | /// 发布
15 | ///
16 | ///
17 | void Publish(object mqMessages);
18 |
19 | ///
20 | /// 发布
21 | ///
22 | ///
23 | ///
24 | Task PublishAsync(object mqMessages);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/MqMessages/MessageTrackers/DefaultInMemoryMessageTracker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace NanoFabric.Core.MqMessages.MessageTrackers
9 | {
10 | public class DefaultInMemoryMessageTracker : IMessageTracker
11 | {
12 | private static readonly ConcurrentBag InMemoryStore;
13 |
14 | static DefaultInMemoryMessageTracker()
15 | {
16 | InMemoryStore = new ConcurrentBag();
17 | }
18 |
19 | public static DefaultInMemoryMessageTracker Instance { get; } = new DefaultInMemoryMessageTracker();
20 |
21 | public Task MarkAsProcessed(string processId)
22 | {
23 | InMemoryStore.Add(processId);
24 | return Task.FromResult(0);
25 | }
26 |
27 | public Task HasProcessed(string processId)
28 | {
29 | return Task.FromResult(InMemoryStore.Contains(processId));
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/MqMessages/MessageTrackers/IMessageTracker.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 |
6 | namespace NanoFabric.Core.MqMessages.MessageTrackers
7 | {
8 | public interface IMessageTracker
9 | {
10 | ///
11 | /// 查询是否已处理过
12 | ///
13 | /// 能唯一标记本次处理过程的Id,可采用msgId+HandlerName等组合
14 | ///
15 | Task HasProcessed(string processId);
16 |
17 | ///
18 | /// 标记为已处理过
19 | ///
20 | /// 能唯一标记本次处理过程的Id,可采用msgId+HandlerName等组合
21 | ///
22 | Task MarkAsProcessed(string processId);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/MqMessages/NullMqMessagePublisher.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 |
6 | namespace NanoFabric.Core.MqMessages
7 | {
8 | ///
9 | /// 空模式
10 | ///
11 | public class NullMqMessagePublisher : IMqMessagePublisher
12 | {
13 | ///
14 | /// 空模式实例
15 | ///
16 | public static NullMqMessagePublisher Instance { get; } = new NullMqMessagePublisher();
17 |
18 | ///
19 | ///
20 | ///
21 | ///
22 | ///
23 | public Task PublishAsync(object mqMessages)
24 | {
25 | //do nothing.
26 | return Task.FromResult(0);
27 | }
28 |
29 | ///
30 | ///
31 | ///
32 | ///
33 | public void Publish(object mqMessages)
34 | {
35 | //do nothing.
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/NanoFabric.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Registry/IManageHealthChecks.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 |
4 | namespace NanoFabric.Core
5 | {
6 | ///
7 | /// 服务健康检查
8 | ///
9 | public interface IManageHealthChecks
10 | {
11 | ///
12 | /// 注册服务的健康检查
13 | ///
14 | /// 服务名称
15 | /// 服务ID
16 | /// 健康检查服务
17 | /// 间隔时间
18 | ///
19 | ///
20 | Task RegisterHealthCheckAsync(string serviceName, string serviceId, Uri checkUri, TimeSpan? interval = null, string notes = null);
21 |
22 | ///
23 | /// 注销实例的健康检查服务
24 | ///
25 | /// 实例的健康检查标识Id
26 | ///
27 | Task DeregisterHealthCheckAsync(string checkId);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Registry/IManageServiceInstances.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | namespace NanoFabric.Core
6 | {
7 | public interface IManageServiceInstances
8 | {
9 | ///
10 | /// 注册服务实例
11 | ///
12 | /// 服务名称
13 | /// 版本号
14 | /// 服务地址
15 | /// 健康检查url
16 | /// 标签
17 | ///
18 | Task RegisterServiceAsync(string serviceName, string version, Uri uri, Uri healthCheckUri = null, IEnumerable tags = null);
19 |
20 | ///
21 | /// 注销服务实例
22 | ///
23 | ///
24 | ///
25 | Task DeregisterServiceAsync(string serviceId);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Registry/IRegistryHost.cs:
--------------------------------------------------------------------------------
1 | namespace NanoFabric.Core
2 | {
3 | public interface IRegistryHost : IManageServiceInstances,
4 | IManageHealthChecks,
5 | IResolveServiceInstances
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Registry/IRegistryTenant.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NanoFabric.Core
4 | {
5 | ///
6 | /// 注册Web API服务实例
7 | ///
8 | public interface IRegistryTenant
9 | {
10 | Uri Uri { get; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Registry/IResolveServiceInstances.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Threading.Tasks;
4 |
5 | namespace NanoFabric.Core
6 | {
7 | public interface IResolveServiceInstances
8 | {
9 | Task> FindServiceInstancesAsync();
10 | Task> FindServiceInstancesAsync(string name);
11 | Task> FindServiceInstancesWithVersionAsync(string name, string version);
12 | Task> FindServiceInstancesAsync(Predicate> nameTagsPredicate,
13 | Predicate registryInformationPredicate);
14 | Task> FindServiceInstancesAsync(Predicate> predicate);
15 | Task> FindServiceInstancesAsync(Predicate predicate);
16 | Task> FindAllServicesAsync();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Registry/RegistryInformation.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace NanoFabric.Core
5 | {
6 | public class RegistryInformation
7 | {
8 | public string Name { get; set; }
9 | public string Id { get; set; }
10 | public string Address { get; set; }
11 | public int Port { get; set; }
12 | public string Version { get; set; }
13 | public IEnumerable Tags { get; set; }
14 |
15 | public Uri ToUri(string scheme = "http", string path = "/")
16 | {
17 | var builder = new UriBuilder(scheme, Address, Port, path);
18 | return builder.Uri;
19 | }
20 |
21 | public override string ToString()
22 | {
23 | return $"{Address}:{Port}";
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/NanoFabric.Core/Threading/AsyncHelper.cs:
--------------------------------------------------------------------------------
1 | using Nito.AsyncEx;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Reflection;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace NanoFabric.Core.Threading
9 | {
10 | ///
11 | /// Provides some helper methods to work with async methods.
12 | ///
13 | public static class AsyncHelper
14 | {
15 | ///
16 | /// Checks if given method is an async method.
17 | ///
18 | /// A method to check
19 | public static bool IsAsync(this MethodInfo method)
20 | {
21 | return (
22 | method.ReturnType == typeof(Task) ||
23 | (method.ReturnType.GetTypeInfo().IsGenericType && method.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
24 | );
25 | }
26 |
27 | ///
28 | /// Checks if given method is an async method.
29 | ///
30 | /// A method to check
31 | [Obsolete("Use MethodInfo.IsAsync() extension method!")]
32 | public static bool IsAsyncMethod(MethodInfo method)
33 | {
34 | return method.IsAsync();
35 | }
36 |
37 | ///
38 | /// Runs a async method synchronously.
39 | ///
40 | /// A function that returns a result
41 | /// Result type
42 | /// Result of the async operation
43 | public static TResult RunSync(Func> func)
44 | {
45 | return AsyncContext.Run(func);
46 | }
47 |
48 | ///
49 | /// Runs a async method synchronously.
50 | ///
51 | /// An async action
52 | public static void RunSync(Func action)
53 | {
54 | AsyncContext.Run(action);
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/NanoFabric.Exceptionless/ApplicationBuilderExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.Exceptionless
6 | {
7 | public static class ApplicationBuilderExtensions
8 | {
9 |
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.Exceptionless/Model/ExcDataParam.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.Exceptionless.Model
6 | {
7 | ///
8 | /// 扩展数据
9 | ///
10 | public class ExcDataParam
11 | {
12 | ///
13 | /// 名称
14 | ///
15 | public string Name { get; set; }
16 |
17 | ///
18 | /// 数据内容
19 | ///
20 | public object Data { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/NanoFabric.Exceptionless/Model/ExcUserParam.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.Exceptionless.Model
6 | {
7 | ///
8 | /// 用户标识参数
9 | ///
10 | public class ExcUserParam
11 | {
12 | ///
13 | /// 用户标识
14 | ///
15 | public string Id { get; set; }
16 | ///
17 | /// 用户名称
18 | ///
19 | public string Name { get; set; }
20 | ///
21 | /// 邮件地址
22 | ///
23 | public string Email { get; set; }
24 | ///
25 | /// 描述信息
26 | ///
27 | public string Description { get; set; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/NanoFabric.Exceptionless/NanoFabric.Exceptionless.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/NanoFabric.Exceptionless/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 |
3 | namespace NanoFabric.Exceptionless
4 | {
5 | public static class ServiceCollectionExtensions
6 | {
7 | public static IServiceCollection AddNanoFabricExceptionless(this IServiceCollection services)
8 | {
9 | services.AddSingleton();
10 | services.AddSingleton();
11 | services.AddSingleton();
12 | services.AddSingleton();
13 |
14 | return services;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/NanoFabric.Grpc.Hosting/NanoFabric.Grpc.Hosting.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/NanoFabric.Grpc/Client/GRpcConnection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading.Tasks;
5 | using MagicOnion;
6 | using MagicOnion.Client;
7 | using NanoFabric.Router;
8 | using NanoFabric.Router.Consul;
9 |
10 | namespace NanoFabric.Grpc.Client
11 | {
12 | public class GRpcConnection : IGRpcConnection
13 | {
14 | private IServiceSubscriberFactory _subscriberFactory;
15 | private IGrpcChannelFactory _grpcChannelFactory;
16 |
17 |
18 | public GRpcConnection(IServiceSubscriberFactory subscriberFactory, IGrpcChannelFactory grpcChannelFactory)
19 | {
20 | this._subscriberFactory = subscriberFactory;
21 | this._grpcChannelFactory = grpcChannelFactory;
22 | }
23 |
24 | public async Task GetRemoteService(string serviceName) where TService : IService
25 | {
26 | var serviceSubscriber = _subscriberFactory.CreateSubscriber(serviceName, ConsulSubscriberOptions.Default, new NanoFabric.Router.Throttle.ThrottleSubscriberOptions()
27 | {
28 | MaxUpdatesPeriod = TimeSpan.FromSeconds(30),
29 | MaxUpdatesPerPeriod = 20
30 | });
31 | await serviceSubscriber.StartSubscription();
32 | serviceSubscriber.EndpointsChanged += async (sender, eventArgs) =>
33 | {
34 | var endpoints = await serviceSubscriber.Endpoints();
35 | var servicesInfo = string.Join(",", endpoints);
36 | };
37 | ILoadBalancer loadBalancer = new RoundRobinLoadBalancer(serviceSubscriber);
38 | var endPoint = await loadBalancer.Endpoint();
39 |
40 | var serviceChannel = _grpcChannelFactory.Get(endPoint.Address, endPoint.Port);
41 |
42 | return MagicOnionClient.Create(serviceChannel);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/NanoFabric.Grpc/Client/GrpcChannelFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using Grpc.Core;
5 |
6 | namespace NanoFabric.Grpc.Client
7 | {
8 | public class GrpcChannelFactory : IGrpcChannelFactory
9 | {
10 | private static readonly object _syncLock = new object();
11 | private Dictionary grpcServers;
12 |
13 | public GrpcChannelFactory()
14 | {
15 | grpcServers = new Dictionary();
16 | }
17 |
18 | public Channel Get(string address, int port)
19 | {
20 | Channel channel = null;
21 |
22 | string key = $"{address}:{port}";
23 | if (!grpcServers.ContainsKey(key))
24 | {
25 | lock (_syncLock)
26 | {
27 | channel = new Channel(address, port, ChannelCredentials.Insecure);
28 | grpcServers.Add(key, channel);
29 | }
30 | }
31 | else
32 | {
33 | channel = grpcServers[key];
34 | }
35 | return channel;
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/NanoFabric.Grpc/Client/IGRpcConnection.cs:
--------------------------------------------------------------------------------
1 | using MagicOnion;
2 | using System.Threading.Tasks;
3 |
4 | namespace NanoFabric.Grpc.Client
5 | {
6 | public interface IGRpcConnection
7 | {
8 | ///
9 | /// Get the specified remote service interface
10 | ///
11 | ///Remote Service Interface type
12 | /// Remote Service Name
13 | Task GetRemoteService(string serviceName) where TService : IService;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/NanoFabric.Grpc/Client/IGrpcChannelFactory.cs:
--------------------------------------------------------------------------------
1 | using Grpc.Core;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace NanoFabric.Grpc.Client
7 | {
8 | ///
9 | /// GRpc Channel Factory
10 | ///
11 | public interface IGrpcChannelFactory
12 | {
13 | ///
14 | /// Create a new object based on the GRPC server address provided
15 | ///
16 | /// GRpc server address
17 | /// GRpc server port
18 | ///
19 | Channel Get(string address, int port);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/NanoFabric.Grpc/Extensions/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using NanoFabric.Core;
3 | using NanoFabric.Grpc.Client;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace NanoFabric.Grpc.Extensions
9 | {
10 | public static class ServiceCollectionExtensions
11 | {
12 | public static IServiceCollection AddGrpcClient(this IServiceCollection services)
13 | {
14 | services.AddSingleton();
15 | services.AddSingleton();
16 | return services;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/NanoFabric.Grpc/NanoFabric.Grpc.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/IdentityOptions.cs:
--------------------------------------------------------------------------------
1 | namespace NanoFabric.IdentityServer
2 | {
3 | public class IdentityOptions
4 | {
5 | ///
6 | /// Redis连接字符串
7 | ///
8 | public string Redis { get; set; }
9 |
10 | }
11 | }
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Interfaces/Repositories/IClientRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using IdentityServer4.Stores;
4 |
5 | namespace NanoFabric.IdentityServer.Interfaces.Repositories
6 | {
7 | public interface IClientRepository : IClientStore
8 | {
9 | Task> GetAllAllowedCorsOriginsAsync();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Interfaces/Repositories/IPersistedGrantRepository.cs:
--------------------------------------------------------------------------------
1 | using IdentityServer4.Stores;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace NanoFabric.IdentityServer.Interfaces.Repositories
7 | {
8 | public interface IPersistedGrantRepository : IPersistedGrantStore
9 | {
10 |
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Interfaces/Repositories/IScopeRepository.cs:
--------------------------------------------------------------------------------
1 | using IdentityServer4.Stores;
2 |
3 | namespace NanoFabric.IdentityServer.Interfaces.Repositories
4 | {
5 | public interface IResourceRepository : IResourceStore
6 | {
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Interfaces/Repositories/IUserRepository.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.IdentityServer.Models;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace NanoFabric.IdentityServer.Interfaces.Repositories
8 | {
9 | public interface IUserRepository
10 | {
11 | Task GetAsync(string username);
12 | Task GetAsync(string username, string password);
13 | Task AddAsync(User entity, string password);
14 | Task DeleteAsync(int id);
15 | Task UpdateAsync(User entity);
16 | Task GetAsync(int id);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Interfaces/Services/IPasswordService.cs:
--------------------------------------------------------------------------------
1 | namespace NanoFabric.IdentityServer.Interfaces.Services
2 | {
3 | public interface IPasswordService
4 | {
5 | bool ValidatePassword(string password);
6 | string HashPassword(string password);
7 | bool VerifyHashedPassword(string hashedPassword, string password);
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Interfaces/Services/IUserService.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.IdentityServer.Interfaces.Repositories;
2 | using NanoFabric.IdentityServer.Models;
3 | using System.Collections.Generic;
4 | using System.Security.Claims;
5 | using System.Threading.Tasks;
6 |
7 | namespace NanoFabric.IdentityServer.Interfaces.Services
8 | {
9 | public interface IUserService
10 | {
11 | Task GetAsync(string username);
12 | Task GetAsync(string username, string password);
13 | Task AddAsync(User entity, string password);
14 | Task GetAsync(int id);
15 | Task AutoProvisionUserAsync(string provider, string userId, List claims);
16 | Task ValidateCredentialsAsync(string username, string password);
17 | Task FindByExternalProviderAsync(string provider, string userId);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Models/DomainEntity.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NanoFabric.Domain.Models
4 | {
5 | public abstract class DomainEntity
6 | {
7 | private TKey uniqueId;
8 |
9 | public TKey Id
10 | {
11 | get
12 | {
13 | return uniqueId;
14 | }
15 | }
16 |
17 | protected DomainEntity(TKey id)
18 | {
19 | if (id.Equals(default(TKey)))
20 | {
21 | throw new ArgumentOutOfRangeException(nameof(id), "The identifier cannot be equal to the default value of the type.");
22 | }
23 |
24 | uniqueId = id;
25 | }
26 |
27 | public override bool Equals(object obj)
28 | {
29 | var entity = obj as DomainEntity;
30 |
31 | if (entity == null)
32 | {
33 | return false;
34 | }
35 | else
36 | {
37 | return uniqueId.Equals(entity.Id);
38 | }
39 | }
40 |
41 | public static bool operator ==(DomainEntity x, DomainEntity y)
42 | {
43 | if ((object)x == null)
44 | {
45 | return (object)y == null;
46 | }
47 |
48 | if ((object)y == null)
49 | {
50 | return (object)x == null;
51 | }
52 |
53 | return x.Id.Equals(y.Id);
54 | }
55 |
56 | public static bool operator !=(DomainEntity x, DomainEntity y)
57 | {
58 | return !(x == y);
59 | }
60 |
61 | public override int GetHashCode()
62 | {
63 | return uniqueId.GetHashCode();
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Models/User.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Domain.Models;
2 | using NodaTime;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace NanoFabric.IdentityServer.Models
8 | {
9 | public class User : DomainEntity
10 | {
11 | public string Username { get; private set; }
12 | public Instant Created { get; private set; }
13 | public bool IsActive { get; private set; }
14 |
15 | public User(int id, string username)
16 | : this(id, username, SystemClock.Instance.GetCurrentInstant(), true)
17 | {
18 |
19 | }
20 |
21 | private User(int id, string username ,Instant created, bool isActive)
22 | : base(id)
23 | {
24 | if (string.IsNullOrEmpty(username) || string.IsNullOrWhiteSpace(username))
25 | {
26 | throw new ArgumentNullException($"The username [{nameof(username)}] is either null or empty.");
27 | }
28 | if (username.Length < 3)
29 | {
30 | throw new ArgumentException($"The username [{nameof(username)}] is too short.");
31 | }
32 | if (username.Length > 16)
33 | {
34 | throw new ArgumentException($"The username [{nameof(username)}] is too long.");
35 | }
36 |
37 |
38 | Username = username;
39 | Created = created;
40 | IsActive = isActive;
41 | }
42 |
43 | public static User Hydrate(int id, string username,Instant created, bool isActive)
44 | {
45 | return new User(id, username, created, isActive);
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/NanoFabric.IdentityServer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Repositories/ClientAggregate/InMemory/ClientInMemoryRepository.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Threading.Tasks;
4 | using IdentityServer4.Models;
5 | using NanoFabric.IdentityServer.Interfaces.Repositories;
6 |
7 | namespace NanoFabric.IdentityServer.Repositories.ClientAggregate.InMemory
8 | {
9 | #pragma warning disable 1998
10 | //TODO Remove when we async
11 | public class ClientInMemoryRepository : IClientRepository
12 | {
13 | public async Task FindClientByIdAsync(string clientId)
14 | {
15 | return InMemoryClients.Clients.SingleOrDefault(x => x.ClientId == clientId);
16 | }
17 |
18 | public async Task> GetAllAllowedCorsOriginsAsync()
19 | {
20 | var origins = InMemoryClients.Clients.SelectMany(x => x.AllowedCorsOrigins);
21 | return origins;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Repositories/ClientAggregate/InMemory/InMemoryClients.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using IdentityServer4;
3 | using IdentityServer4.Models;
4 | using static IdentityServer4.IdentityServerConstants;
5 |
6 | namespace NanoFabric.IdentityServer.Repositories.ClientAggregate.InMemory
7 | {
8 | public class InMemoryClients
9 | {
10 | public static IEnumerable Clients = new List
11 | {
12 | new Client
13 | {
14 | ClientId = "mvc.hybrid",
15 | ClientSecrets = { new Secret("secret".Sha256()) },
16 | AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
17 | RedirectUris = { "http://localhost:9000/signin-oidc" },
18 | AllowedScopes = {
19 | StandardScopes.OpenId,
20 | StandardScopes.Profile,
21 | StandardScopes.OfflineAccess,
22 | "api1"
23 | }
24 |
25 | }
26 | };
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Repositories/ResourceAggregate/InMemory/ResourceInMemoryRepository.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using IdentityServer4.Models;
6 | using NanoFabric.IdentityServer.Interfaces.Repositories;
7 |
8 | namespace NanoFabric.IdentityServer.Repositories.ResourceAggregate.InMemory
9 | {
10 | public class ResourceInMemoryRepository : IResourceRepository
11 | {
12 | public Task FindApiResourceAsync(string name)
13 | {
14 | var api = from a in InMemoryResources.ApiResources
15 | where a.Name == name
16 | select a;
17 |
18 | return Task.FromResult(api.FirstOrDefault());
19 | }
20 |
21 | public Task> FindApiResourcesByScopeAsync(IEnumerable scopeNames)
22 | {
23 | if (scopeNames == null) throw new ArgumentNullException(nameof(scopeNames));
24 |
25 | var api = from a in InMemoryResources.ApiResources
26 | from s in a.Scopes
27 | where scopeNames.Contains(s.Name)
28 | select a;
29 |
30 | return Task.FromResult(api);
31 | }
32 |
33 | public Task> FindIdentityResourcesByScopeAsync(IEnumerable scopeNames)
34 | {
35 | if (scopeNames == null)
36 | throw new ArgumentNullException(nameof(scopeNames));
37 |
38 | var identity = from i in InMemoryResources.IdentityResources
39 | where scopeNames.Contains(i.Name)
40 | select i;
41 |
42 | return Task.FromResult(identity);
43 | }
44 |
45 | public Task GetAllResourcesAsync()
46 | {
47 | var result = new Resources(InMemoryResources.IdentityResources,InMemoryResources.ApiResources);
48 | return Task.FromResult(result);
49 | }
50 | }
51 | }
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Repositories/UserAggregate/InMemory/InMemoryUsers.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using NodaTime;
4 | using NanoFabric.IdentityServer.Models;
5 |
6 | namespace NanoFabric.IdentityServer.Repositories.UserAggregate.InMemory
7 | {
8 | public static class InMemoryUsers
9 | {
10 | public static List Users = new List
11 | {
12 | User.Hydrate(1,"bob",Instant.FromUtc(2017,1,24,6,6), true),
13 | User.Hydrate(2,"alice", Instant.FromUtc(2017,1,24,6,6), true),
14 | };
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Repositories/UserAggregate/InMemory/UserInMemoryRepository.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.IdentityServer.Interfaces.Repositories;
2 | using NanoFabric.IdentityServer.Models;
3 | using System;
4 | using System.Linq;
5 | using System.Threading.Tasks;
6 |
7 |
8 | namespace NanoFabric.IdentityServer.Repositories.UserAggregate.InMemory
9 | {
10 | public class UserInMemoryRepository : IUserRepository
11 | {
12 | public Task AddAsync(User entity)
13 | {
14 | InMemoryUsers.Users.Add(entity);
15 | return Task.FromResult(0);
16 | }
17 |
18 | public Task AddAsync(User entity, string password)
19 | {
20 | InMemoryUsers.Users.Add(entity);
21 | return Task.FromResult(0);
22 | }
23 |
24 | public Task DeleteAsync(int id)
25 | {
26 | InMemoryUsers.Users.RemoveAll(x => x.Id == id);
27 | return Task.FromResult(0);
28 | }
29 |
30 | public Task GetAsync(int id)
31 | {
32 | return Task.FromResult(InMemoryUsers.Users.SingleOrDefault(x => x.Id == id));
33 | }
34 |
35 | public Task GetAsync(string username)
36 | {
37 | return Task.FromResult(InMemoryUsers.Users.SingleOrDefault(x => x.Username == username));
38 | }
39 |
40 | public Task GetAsync(string username, string password)
41 | {
42 | return GetAsync(username);
43 | }
44 |
45 | public Task UpdateAsync(User entity)
46 | {
47 | DeleteAsync(entity.Id);
48 | AddAsync(entity);
49 | return Task.FromResult(0);
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.IdentityServer.Interfaces.Repositories;
2 | using NanoFabric.IdentityServer.Interfaces.Services;
3 | using NanoFabric.IdentityServer.Repositories.ClientAggregate.InMemory;
4 | using NanoFabric.IdentityServer.Repositories.ResourceAggregate.InMemory;
5 | using NanoFabric.IdentityServer.Repositories.UserAggregate.InMemory;
6 | using NanoFabric.IdentityServer.Services;
7 | using IdentityServer4.Stores;
8 | using IdentityServer4.Validation;
9 | using Microsoft.Extensions.DependencyInjection;
10 | using System;
11 | using System.Collections.Generic;
12 | using System.Text;
13 | using Microsoft.Extensions.Configuration;
14 |
15 | namespace NanoFabric.IdentityServer
16 | {
17 | public static class ServiceCollectionExtensions
18 | {
19 | public static TConfig ConfigurePOCO(this IServiceCollection services, IConfiguration configuration, Func pocoProvider) where TConfig : class
20 | {
21 | if (services == null) throw new ArgumentNullException(nameof(services));
22 | if (configuration == null) throw new ArgumentNullException(nameof(configuration));
23 | if (pocoProvider == null) throw new ArgumentNullException(nameof(pocoProvider));
24 |
25 | var config = pocoProvider();
26 | configuration.Bind(config);
27 | services.AddSingleton(config);
28 | return config;
29 | }
30 |
31 | public static TConfig ConfigurePOCO(this IServiceCollection services, IConfiguration configuration, TConfig config) where TConfig : class
32 | {
33 | if (services == null) throw new ArgumentNullException(nameof(services));
34 | if (configuration == null) throw new ArgumentNullException(nameof(configuration));
35 | if (config == null) throw new ArgumentNullException(nameof(config));
36 |
37 | configuration.Bind(config);
38 | services.AddSingleton(config);
39 | return config;
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Services/ResourceOwnerPasswordValidator.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 | using IdentityServer4.Validation;
3 | using NanoFabric.IdentityServer.Interfaces.Services;
4 | using NanoFabric.IdentityServer.Utilities;
5 |
6 | namespace NanoFabric.IdentityServer.Services
7 | {
8 | public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
9 | {
10 | public IUserService UserService { get; private set; }
11 |
12 | public ResourceOwnerPasswordValidator(IUserService userService)
13 | {
14 | UserService = userService;
15 | }
16 | public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
17 | {
18 | var user = await UserService.GetAsync(context.UserName, context.Password);
19 |
20 | if (user != null)
21 | {
22 | var claims = ClaimsUtility.GetClaims(user);
23 | context.Result = new GrantValidationResult(user.Id.ToString(), "password",claims);
24 | }
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/Utilities/ClaimsUtility.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Security.Claims;
3 | using IdentityModel;
4 | using NanoFabric.IdentityServer.Models;
5 |
6 | namespace NanoFabric.IdentityServer.Utilities
7 | {
8 | public static class ClaimsUtility
9 | {
10 | public static IEnumerable GetClaims(User user)
11 | {
12 | var claims = new List
13 | {
14 | new Claim(JwtClaimTypes.Subject, user.Id.ToString()),
15 | new Claim(JwtClaimTypes.PreferredUserName, user.Username),
16 | };
17 |
18 | return claims;
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/obj/CFT.NanoFabric.IdentityServer.csproj.nuget.g.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | True
5 | NuGet
6 | D:\Workshop\Github\NanoFabric\src\CFT.NanoFabric.IdentityServer\obj\project.assets.json
7 | $(UserProfile)\.nuget\packages\
8 | C:\Users\geffz\.nuget\packages\
9 | PackageReference
10 | 4.0.0
11 |
12 |
13 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
14 |
15 |
--------------------------------------------------------------------------------
/src/NanoFabric.IdentityServer/obj/CFT.NanoFabric.IdentityServer.csproj.nuget.g.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath)
5 |
6 |
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/CircularQueue.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Concurrent;
2 | using System.Linq;
3 |
4 | namespace NanoFabric.Mediatr
5 | {
6 | public class CircularQueue
7 | {
8 | private readonly ConcurrentQueue _innerQueue = new ConcurrentQueue();
9 | private readonly object _lockObject = new object();
10 |
11 | public int Limit { get; }
12 |
13 | public CircularQueue(int limit = 1000)
14 | {
15 | Limit = limit;
16 | }
17 |
18 | public void Enqueue(T obj)
19 | {
20 | lock (_lockObject)
21 | {
22 | _innerQueue.Enqueue(obj);
23 | while (_innerQueue.Count > Limit && _innerQueue.TryDequeue(out T _)) ;
24 | }
25 | }
26 |
27 | public bool Contains(T value)
28 | {
29 | lock (_lockObject)
30 | {
31 | return _innerQueue.Contains(value);
32 | }
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/Commands/ICommand.cs:
--------------------------------------------------------------------------------
1 | using MediatR;
2 |
3 | namespace NanoFabric.Mediatr.Commands
4 | {
5 | public interface ICommand : IRequest
6 | {
7 | }
8 |
9 | public interface ICommand : ICommand
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/Commands/IdentifiedCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using MediatR;
3 |
4 | namespace NanoFabric.Mediatr.Commands
5 | {
6 | public class IdentifiedCommand :
7 | IRequest
8 | where TCommand : IRequest
9 | {
10 | public Guid Id { get; }
11 | public TCommand Command { get; }
12 |
13 | public IdentifiedCommand(TCommand command, Guid id)
14 | {
15 | Id = id;
16 | Command = command;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/Commands/IdentifiedCommandHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using MediatR;
5 |
6 | using NanoFabric.Mediatr;
7 | using NanoFabric.Mediatr.Exceptions;
8 |
9 | namespace NanoFabric.Mediatr.Commands
10 | {
11 | public class IdentifiedCommandHandler
12 | : IRequestHandler, TResult>
13 | where TCommand : IRequest
14 | {
15 | private readonly IMediator _mediator;
16 | private readonly IRequestManager _requestManager;
17 |
18 | public IdentifiedCommandHandler(IMediator mediator, IRequestManager requestManager)
19 | {
20 | _mediator = mediator;
21 | _requestManager = requestManager;
22 | }
23 |
24 | public async Task Handle(
25 | IdentifiedCommand message,
26 | CancellationToken cancellationToken = default(CancellationToken)
27 | )
28 | {
29 | if (message.Id == Guid.Empty)
30 | {
31 | ThrowMediatrPipelineException.IdentifiedCommandWithoutId();
32 | }
33 |
34 | if (message.Command == null)
35 | {
36 | ThrowMediatrPipelineException.IdentifiedCommandWithoutInnerCommand();
37 | }
38 |
39 | var alreadyRegistered = await _requestManager.IsRegistered(message.Id, cancellationToken);
40 | if (alreadyRegistered)
41 | {
42 | ThrowMediatrPipelineException.CommandWasAlreadyExecuted();
43 | }
44 |
45 | await _requestManager.Register(message.Id, cancellationToken);
46 | var result = await _mediator.Send(message.Command, cancellationToken);
47 | return result;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/Exceptions/MediatrPipelineException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NanoFabric.Mediatr.Validators
4 | {
5 | public class MediatrPipelineException : Exception
6 | {
7 | public MediatrPipelineException(string message, Exception innerException)
8 | : base(message, innerException)
9 | {
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/Exceptions/ThrowMediatrPipelineException.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using NanoFabric.Mediatr.Validators;
3 | using FluentValidation;
4 | using FluentValidation.Results;
5 |
6 | namespace NanoFabric.Mediatr.Exceptions
7 | {
8 | [DebuggerStepThrough]
9 | public static class ThrowMediatrPipelineException
10 | {
11 | public static void IdentifiedCommandWithoutId()
12 | {
13 | throw new MediatrPipelineException(
14 | "Invalid IdentifiedCommand",
15 | new ValidationException("Validation Exception",
16 | new[] { new ValidationFailure("Id", "You need to specify a valid id.") }
17 | )
18 | );
19 | }
20 |
21 | public static void IdentifiedCommandWithoutInnerCommand()
22 | {
23 | throw new MediatrPipelineException(
24 | "Invalid IdentifiedCommand",
25 | new ValidationException(
26 | "Validation Exception",
27 | new[] { new ValidationFailure("Command", "You need to specify a valid command to run.") }
28 | )
29 | );
30 | }
31 |
32 | public static void CommandWasAlreadyExecuted()
33 | {
34 | throw new MediatrPipelineException(
35 | "Invalid IdentifiedCommand",
36 | new ValidationException("Validation Exception",
37 | new[]
38 | {
39 | new ValidationFailure("Id", "This command was already executed.")
40 | }));
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/IRequestManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 |
5 | namespace NanoFabric.Mediatr
6 | {
7 | public interface IRequestManager
8 | {
9 | Task IsRegistered(
10 | Guid id,
11 | CancellationToken cancellationToken = default(CancellationToken));
12 |
13 | Task Register(Guid id,
14 | CancellationToken cancellationToken = default(CancellationToken));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/InMemoryRequestManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 |
5 | namespace NanoFabric.Mediatr
6 | {
7 | public class InMemoryRequestManager : IRequestManager
8 | {
9 | private readonly CircularQueue _queue = new CircularQueue();
10 |
11 | public Task IsRegistered(Guid id, CancellationToken cancellationToken = default(CancellationToken)) =>
12 | Task.FromResult(_queue.Contains(id));
13 |
14 | public Task Register(Guid id, CancellationToken cancellationToken = default(CancellationToken))
15 | {
16 | _queue.Enqueue(id);
17 | return Task.CompletedTask;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/NanoFabric.Mediatr.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/NanoFabric.Mediatr/Validators/ValidatorsBehavior.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using FluentValidation;
5 | using MediatR;
6 |
7 | namespace NanoFabric.Mediatr.Validators
8 | {
9 | public class ValidatorsBehavior
10 | : IPipelineBehavior
11 | {
12 | private readonly IValidator[] _validators;
13 |
14 | public ValidatorsBehavior(IValidator[] validators)
15 | {
16 | _validators = validators;
17 | }
18 |
19 | public async Task Handle(
20 | TRequest request,
21 | CancellationToken cancellationToken,
22 | RequestHandlerDelegate next)
23 | {
24 | var failures = _validators
25 | .Select(validator => validator.Validate(request))
26 | .SelectMany(result => result.Errors)
27 | .Where(error => error != null)
28 | .ToList();
29 |
30 | if (failures.Any())
31 | {
32 | throw new MediatrPipelineException(
33 | $"Command Validation Errors for type {typeof(TRequest).Name}",
34 | new ValidationException("Validation exception", failures)
35 | );
36 | }
37 |
38 | return await next();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/NanoFabric.MqMessages/NanoFabric.MqMessages.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.extensions.dependencyinjection.abstractions\2.0.0\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll
18 |
19 |
20 | C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.extensions.logging.abstractions\2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/NanoFabric.MqMessages/RebusRabbitMqPublisher.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Logging;
2 | using NanoFabric.Core.Json;
3 | using NanoFabric.Core.MqMessages;
4 | using NanoFabric.Core.Threading;
5 | using Rebus.Bus;
6 | using System.Threading.Tasks;
7 |
8 | namespace NanoFabric.MqMessages.RebusCore
9 | {
10 | public class RebusRabbitMqPublisher : IMqMessagePublisher
11 | {
12 | private readonly IBus _bus;
13 |
14 | public ILogger Logger { get; set; }
15 |
16 | public RebusRabbitMqPublisher(IBus bus, ILoggerFactory factory)
17 | {
18 | _bus = bus;
19 | Logger = factory.CreateLogger();
20 | }
21 |
22 | public void Publish(object mqMessages)
23 | {
24 | Logger.LogDebug(mqMessages.GetType().FullName + ":" + mqMessages.ToJsonString());
25 |
26 | AsyncHelper.RunSync(() => _bus.Publish(mqMessages));
27 | }
28 |
29 | public async Task PublishAsync(object mqMessages)
30 | {
31 | Logger.LogDebug(mqMessages.GetType().FullName + ":" + mqMessages.ToJsonString());
32 |
33 | await _bus.Publish(mqMessages);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/NanoFabric.MqMessages/ServiceCollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.DependencyInjection;
2 | using NanoFabric.Core.MqMessages;
3 | using NanoFabric.MqMessages.RebusCore;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Text;
7 |
8 | namespace NanoFabric.MqMessages
9 | {
10 | public static class ServiceCollectionExtensions
11 | {
12 | public static IServiceCollection AddMqMessages(this IServiceCollection services
13 | )
14 | {
15 | services.AddSingleton();
16 | return services;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/NanoFabric.Ocelot/NanoFabric.Ocelot.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netcoreapp2.1
4 | NanoFabric.Ocelot
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | PreserveNewest
32 |
33 |
34 | PreserveNewest
35 |
36 |
37 | PreserveNewest
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/NanoFabric.Ocelot/NanoFabric.Ocelot.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ProjectDebugger
5 |
6 |
7 | NanoFabric.Ocelot
8 | FolderProfile
9 | false
10 |
11 |
--------------------------------------------------------------------------------
/src/NanoFabric.Ocelot/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:4321/",
7 | "sslPort": 0
8 | }
9 | },
10 | "profiles": {
11 | "IIS Express": {
12 | "commandName": "IISExpress",
13 | "launchBrowser": true,
14 | "environmentVariables": {
15 | "ASPNETCORE_ENVIRONMENT": "Development"
16 | }
17 | },
18 | "NanoFabric.Ocelot": {
19 | "commandName": "Project",
20 | "launchBrowser": true,
21 | "environmentVariables": {
22 | "ASPNETCORE_ENVIRONMENT": "Development"
23 | },
24 | "applicationUrl": "http://localhost:4322"
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/NanoFabric.Ocelot/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "IncludeScopes": true,
4 | "LogLevel": {
5 | "Default": "Information",
6 | "System": "Error",
7 | "Microsoft": "Error"
8 | }
9 | },
10 | "ServiceDiscovery": {
11 | "ServiceName": "NanoFabric_Ocelot",
12 | "Version": "1.0.0-pre",
13 | "HealthCheckTemplate": "/administration/status",
14 | "Endpoints": [],
15 | "Consul": {
16 | "HttpEndpoint": "http://127.0.0.1:8500",
17 | "DnsEndpoint": {
18 | "Address": "127.0.0.1",
19 | "Port": 8600
20 | }
21 | }
22 | },
23 | "MetricsWebTrackingOptions": {
24 | "ApdexTrackingEnabled": true,
25 | "ApdexTSeconds": 0.1,
26 | "IgnoredHttpStatusCodes": [ 404 ],
27 | "IgnoredRoutesRegexPatterns": [],
28 | "OAuth2TrackingEnabled": true
29 | },
30 | "MetricEndpointsOptions": {
31 | "MetricsEndpointEnabled": true,
32 | "MetricsTextEndpointEnabled": true,
33 | "EnvironmentInfoEndpointEnabled": true
34 | },
35 | "AppMetrics": {
36 | "DataBaseName": "AppMetricsDemo",
37 | "ConnectionString": "http://127.0.0.1:8086",
38 | "UserName": "admin",
39 | "Password": "123456",
40 | "App": "NanoFabric_Ocelot",
41 | "Env": "develop"
42 | },
43 | "Skywalking": {
44 | "CollectorUrl": "127.0.0.1:11800"
45 | },
46 | "Exceptionless": {
47 | "ApiKey": "QE99T0zncQPOAvgIRPuBTn6OmE2eewdGW9sKGH2k"
48 | },
49 | "ServerAddress": "http://127.0.0.1:8000",
50 | "Authority": "http://127.0.0.1:5000"
51 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Ocelot/nlog.config:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/NanoFabric.Ocelot/tempkey.rsa:
--------------------------------------------------------------------------------
1 | {"KeyId":"f8d4aed4a83544b2eccf517c078fa32a","Parameters":{"D":"Z6S8MNzAWg/rkNsMt8IHlxH218ardDkmSF3WgM069tiARZxyReixJJtObPGRISe4VRxDUjAVm75WGpYzScZGVzzmpit7N02uRHwvdag/gS3uWhJLPDLSfTxkyFC0KoNcjlf8DJfdmRML9c9G7OE5iBNa5GpLlowTLlJnSrlC7rgCdQKxbmxnSV9mmXAWT4qX0wY91oygkphGeL6Y6bTBlhf/oFD9wY2CmX/bQJ2SDV7//S6gngnkmluvqh+WnIEy/k/6Mh76JvYpBRiuqVu17YOeUi0PhFYFtn5XfsQC8PJOF925vlIYmLsxcmCa1zamzKF54yeIULddO0j/bQdBrQ==","DP":"SAhLtF/yz0HL9GGZ3ZixHw3FoYzULxwihIlAyCbevvS6ddWZEUdQE9XhRHJ5lbnjmdp6M4HRiwFHgRI0xysnUP/dYawm9+DvvzKUPluRbB1bZ70Eo2/BcZcdRzmlQj+VfJBW5c8qiftvpaqPQkbTHxqN50rWhwRlvFE8P5FBk50=","DQ":"VL80x09pv8Jo0f0L0QOCT5RHzztbmROR2WZGqe+MkDJCDvf+gjo7By2O3bn/BCrK5GKlgWHCcTtMhUtclh0LY9T3JkjyO+cjUFK4Lk4gLXj0QNLF58hfexYVVp2sYJf8H6+n6xi/C9/sK4Uuhf1+F1JtLdoOvYBbsFiOI7axt6k=","Exponent":"AQAB","InverseQ":"QZbwNSE1R879+S27kV7O6kISaElTz5B/pDHhMnb8JQziZneMu2LJXGE6x6xqEoBSxFD3704NjkzKmCv1wXJTC3qnCOhbu20cJeFEyypUo21oMv4QzjvktDqwVKIcKp1oLuaH1VyW4uGAIr628454DHLI02WyZTSoT2vh8hl02mI=","Modulus":"0ZYaqfqfWIrgw/LOI8XTiX69SmGkUKNfOBeP0qhLjAmxa9Xho46oNmFrS22JXLOy+aFTVJ4jHiZzieVdCue2G8hn2WgEgjcBak0L+0o0cfJ1FGBxGjOaGlOahMtrfeo1BBqXXbCZsO+J5nrmKdmtVsMdK1n2UorU1bqcnYLgYUiGDlAgKRLyWxhd1UikAHQdqaNDtr93vjawxgwW4uc9fK6Raj80JOuvuiY4h8LvZS62Vn+ORST47+1Vk0OBXTVZBS+Zk/ObJTbl5g5ZWPCHzNEzoT1+C+n9EhgNWoQGnbGwKgwTjYUQyS9nG4iwGhq33eKlyBDztQ8PtkpSJ/HAtQ==","P":"7K2s1w2Rj3k53GQWedv+w71sL/tZtqQmgzfzSTrlnBabb1QaroE8mCQ1N3fTIfQoZnJ8XhqbXHitjf+3ODBxt4z7EMggStm45dJNLIipGvZ4dFa3O7zPHgO7ssXdf8RXVDFuovmqBcZ4ZzgMR9l2b/CPXHHXT/IzF1H4J86GNdc=","Q":"4rI71hSogzL0jVTdVLaZbFyya/M9cc007HuMpT4NHwrD3lV884LAMT3hGvemCTbI3NLsBZfNCkzMIzDhC21lR9nUZiZ1Ka9TYJHfflTUccfCvungbdJZ5boJvunWb87QTrMMsWOJ2XQRVuhoGt/8NIBG44dsykhnKOEDbhlilFM="}}
--------------------------------------------------------------------------------
/src/NanoFabric.Ocelot/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/NanoFabric.RegistryHost.ConsulRegistry/ConsulRegistryHostConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 |
4 | namespace NanoFabric.RegistryHost.ConsulRegistry
5 | {
6 | public class ConsulRegistryHostConfiguration
7 | {
8 | public string HttpEndpoint { get; set; }
9 |
10 | public DnsEndpoint DnsEndpoint { get; set; }
11 |
12 | public string Datacenter { get; set; }
13 |
14 | public string AclToken { get; set; }
15 |
16 | public TimeSpan? LongPollMaxWait { get; set; }
17 |
18 | public TimeSpan? RetryDelay { get; set; } = Defaults.ErrorRetryInterval;
19 | }
20 |
21 | public class DnsEndpoint
22 | {
23 | public string Address { get; set; }
24 |
25 | public int Port { get; set; }
26 |
27 | public IPEndPoint ToIPEndPoint()
28 | {
29 | return new IPEndPoint(IPAddress.Parse(Address), Port);
30 | }
31 | }
32 |
33 | public static class Defaults
34 | {
35 | public static TimeSpan ErrorRetryInterval => TimeSpan.FromSeconds(15);
36 |
37 | public static TimeSpan UpdateMaxInterval => TimeSpan.FromSeconds(15);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/NanoFabric.RegistryHost.ConsulRegistry/HealthCheckExtensions.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using System;
3 |
4 | namespace NanoFabric.RegistryHost.ConsulRegistry
5 | {
6 | public static class HealthCheckExtensions
7 | {
8 | public static bool NeedsStatusCheck(this HealthCheck healthCheck)
9 | {
10 | if (healthCheck == null)
11 | {
12 | return false;
13 | }
14 |
15 | string serviceName = string.IsNullOrWhiteSpace(healthCheck.ServiceName) ? "" : $" {healthCheck.ServiceName}";
16 |
17 | // don't check consul
18 | if (healthCheck.ServiceName == "consul")
19 | {
20 | return false;
21 | }
22 |
23 | // don't check services without service ID
24 | if (healthCheck.ServiceID == "")
25 | {
26 | return false;
27 | }
28 |
29 | // don't check serfHealth
30 | if (healthCheck.CheckID.Equals("serfHealth", StringComparison.OrdinalIgnoreCase))
31 | {
32 | return false;
33 | }
34 |
35 | // don't check nodes in maintenance
36 | if (healthCheck.CheckID.Equals("_node_maintenance", StringComparison.OrdinalIgnoreCase))
37 | {
38 | return false;
39 | }
40 |
41 | // don't check services in maintenance
42 | if (healthCheck.CheckID.StartsWith("_service_maintenance:", StringComparison.OrdinalIgnoreCase))
43 | {
44 | return false;
45 | }
46 |
47 | return true;
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/NanoFabric.RegistryHost.ConsulRegistry/NanoFabric.RegistryHost.ConsulRegistry.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.RegistryHost.ConsulRegistry/ServiceDiscoveryOption.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.RegistryHost.ConsulRegistry;
2 |
3 | namespace NanoFabric.RegistryHost.ConsulRegistry
4 | {
5 | public class ConsulServiceDiscoveryOption
6 | {
7 | public string ServiceName { get; set; }
8 |
9 | public string Version { get; set; }
10 |
11 | public ConsulRegistryHostConfiguration Consul { get; set; }
12 |
13 | public string HealthCheckTemplate { get; set; }
14 |
15 | public string[] Endpoints { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Cache/CacheServiceSubscriberFactory.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Router.Cache.Internal;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace NanoFabric.Router.Cache
7 | {
8 | public class CacheServiceSubscriberFactory : ICacheServiceSubscriberFactory
9 | {
10 | private readonly ICacheClient _cacheClient;
11 |
12 | public CacheServiceSubscriberFactory(ICacheClient cacheClient)
13 | {
14 | _cacheClient = cacheClient;
15 | }
16 |
17 | public IPollingServiceSubscriber CreateSubscriber(IServiceSubscriber serviceSubscriber)
18 | {
19 | return new CacheServiceSubscriber(serviceSubscriber, _cacheClient);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Cache/ICacheServiceSubscriberFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.Router.Cache
6 | {
7 | public interface ICacheServiceSubscriberFactory
8 | {
9 | IPollingServiceSubscriber CreateSubscriber(IServiceSubscriber serviceSubscriber);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Cache/Internal/CacheClient.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Extensions.Caching.Memory;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace NanoFabric.Router.Cache.Internal
7 | {
8 | public class CacheClient : ICacheClient
9 | {
10 | private readonly IMemoryCache _cache;
11 |
12 | public CacheClient(IMemoryCache cache)
13 | {
14 | _cache = cache;
15 | }
16 |
17 | public T Get(object key)
18 | {
19 | return _cache.Get(key);
20 | }
21 |
22 | public T Set(object key, T value)
23 | {
24 | return _cache.Set(key, value);
25 | }
26 |
27 | public void Remove(object key)
28 | {
29 | _cache.Remove(key);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Cache/Internal/ICacheClient.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.Router.Cache.Internal
6 | {
7 | public interface ICacheClient
8 | {
9 | T Get(object key);
10 | T Set(object key, T value);
11 | void Remove(object key);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Consul/ConsulClientExtensions.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using NanoFabric.Core;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 |
8 | namespace NanoFabric.Router.Consul
9 | {
10 | public static class ConsulClientExtensions
11 | {
12 | private const string VERSION_PREFIX = "version-";
13 |
14 | public static RegistryInformation ToEndpoint(this ServiceEntry serviceEntry)
15 | {
16 | var host = !string.IsNullOrWhiteSpace(serviceEntry.Service.Address)
17 | ? serviceEntry.Service.Address
18 | : serviceEntry.Node.Address;
19 | return new RegistryInformation
20 | {
21 | Name = serviceEntry.Service.Service,
22 | Address = host,
23 | Port = serviceEntry.Service.Port,
24 | Version = GetVersionFromStrings(serviceEntry.Service.Tags),
25 | Tags = serviceEntry.Service.Tags ?? Enumerable.Empty(),
26 | Id = serviceEntry.Service.ID
27 | };
28 | }
29 |
30 | private static string GetVersionFromStrings(IEnumerable strings)
31 | {
32 | return strings
33 | ?.FirstOrDefault(x => x.StartsWith(VERSION_PREFIX, StringComparison.Ordinal))
34 | .TrimStart(VERSION_PREFIX);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Consul/ConsulConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.Router.Consul
6 | {
7 | public class ConsulConfiguration
8 | {
9 | public string HostName { get; set; }
10 |
11 | public int? Port { get; set; }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Consul/ConsulPreparedQueryServiceSubscriber.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using NanoFabric.Core;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace NanoFabric.Router.Consul
9 | {
10 | public class ConsulPreparedQueryServiceSubscriber : IServiceSubscriber
11 | {
12 | private readonly IConsulClient _client;
13 | private readonly string _queryName;
14 |
15 | public ConsulPreparedQueryServiceSubscriber(IConsulClient client, string queryName)
16 | {
17 | _client = client;
18 | _queryName = queryName;
19 | }
20 |
21 | public async Task> Endpoints(CancellationToken ct = default(CancellationToken))
22 | {
23 | var servicesQuery = await
24 | _client.PreparedQuery.Execute(_queryName, ct)
25 | .ConfigureAwait(false);
26 |
27 | return servicesQuery.Response.Nodes.Select(service => service.ToEndpoint()).ToList();
28 | }
29 |
30 | public void Dispose() { }
31 | }
32 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Consul/ConsulPreparedQueryServiceSubscriberFactory.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace NanoFabric.Router.Consul
7 | {
8 | public class ConsulPreparedQueryServiceSubscriberFactory : IConsulPreparedQueryServiceSubscriberFactory
9 | {
10 | private readonly IConsulClient _consulClient;
11 |
12 | public ConsulPreparedQueryServiceSubscriberFactory(IConsulClient consulClient)
13 | {
14 | _consulClient = consulClient;
15 | }
16 |
17 | public IServiceSubscriber CreateSubscriber(string queryName)
18 | {
19 | return new ConsulPreparedQueryServiceSubscriber(_consulClient, queryName);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Consul/ConsulServiceSubscriberFactory.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 |
6 | namespace NanoFabric.Router.Consul
7 | {
8 | public class ConsulServiceSubscriberFactory : IConsulServiceSubscriberFactory
9 | {
10 | private readonly IConsulClient _consulClient;
11 |
12 | public ConsulServiceSubscriberFactory(IConsulClient consulClient)
13 | {
14 | _consulClient = consulClient;
15 | }
16 |
17 | public IServiceSubscriber CreateSubscriber(string serviceName, ConsulSubscriberOptions consulOptions, bool watch = false)
18 | {
19 | return new ConsulServiceSubscriber(_consulClient, serviceName, consulOptions, watch);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Consul/ConsulSubscriberOptions.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace NanoFabric.Router.Consul
4 | {
5 | public class ConsulSubscriberOptions
6 | {
7 | public static readonly ConsulSubscriberOptions Default = new ConsulSubscriberOptions();
8 |
9 | public List Tags { get; set; }
10 |
11 | public bool PassingOnly { get; set; } = true;
12 | }
13 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Consul/IConsulPreparedQueryServiceSubscriberFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.Router.Consul
6 | {
7 | public interface IConsulPreparedQueryServiceSubscriberFactory
8 | {
9 | IServiceSubscriber CreateSubscriber(string queryName);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Consul/IConsulServiceSubscriberFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace NanoFabric.Router.Consul
6 | {
7 | public interface IConsulServiceSubscriberFactory
8 | {
9 | IServiceSubscriber CreateSubscriber(string serviceName, ConsulSubscriberOptions consulOptions, bool watch);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/IPollingServiceSubscriber.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 |
7 | namespace NanoFabric.Router
8 | {
9 | public interface IPollingServiceSubscriber : IServiceSubscriber
10 | {
11 | Task StartSubscription(CancellationToken ct = default(CancellationToken));
12 |
13 | event EventHandler EndpointsChanged;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/IServiceSubscriber.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Core;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace NanoFabric.Router
9 | {
10 | public interface IServiceSubscriber : IDisposable
11 | {
12 | Task> Endpoints(CancellationToken ct = default(CancellationToken));
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/IServiceSubscriberFactory.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Router.Consul;
2 | using NanoFabric.Router.Throttle;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace NanoFabric.Router
8 | {
9 | public interface IServiceSubscriberFactory
10 | {
11 | IPollingServiceSubscriber CreateSubscriber(string serviceName);
12 |
13 | IPollingServiceSubscriber CreateSubscriber(string serviceName, ConsulSubscriberOptions consulOptions,
14 | ThrottleSubscriberOptions throttleOptions);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/LoadBalancer/ILoadBalancer.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Core;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace NanoFabric.Router
9 | {
10 | public interface ILoadBalancer
11 | {
12 | Task Endpoint(CancellationToken ct = default(CancellationToken));
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/LoadBalancer/RandomLoadBalancer.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Core;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace NanoFabric.Router.LoadBalancer
9 | {
10 | public class RandomLoadBalancer : ILoadBalancer
11 | {
12 | private readonly Random _random;
13 | private readonly IServiceSubscriber _subscriber;
14 |
15 | public RandomLoadBalancer(IServiceSubscriber subscriber, int? seed = null)
16 | {
17 | _subscriber = subscriber;
18 | _random = seed.HasValue ? new Random(seed.Value) : new Random();
19 | }
20 |
21 | public async Task Endpoint(CancellationToken ct = default(CancellationToken))
22 | {
23 | var endpoints = await _subscriber.Endpoints(ct).ConfigureAwait(false);
24 | return endpoints.Count == 0 ? null : endpoints[_random.Next(endpoints.Count)];
25 | }
26 |
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/LoadBalancer/RoundRobinLoadBalancer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 | using System.Linq;
5 | using NanoFabric.Core;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace NanoFabric.Router
10 | {
11 | ///
12 | /// 主机地址的轮播负载均衡
13 | ///
14 | public class RoundRobinLoadBalancer : ILoadBalancer
15 | {
16 | private readonly IServiceSubscriber _subscriber;
17 | private readonly SemaphoreSlim _lock = new SemaphoreSlim(1, 1);
18 | private int _index;
19 |
20 | public RoundRobinLoadBalancer(IServiceSubscriber subscriber)
21 | {
22 | _subscriber = subscriber;
23 | }
24 |
25 | public async Task Endpoint(CancellationToken ct = default(CancellationToken))
26 | {
27 | var endpoints = await _subscriber.Endpoints(ct).ConfigureAwait(false);
28 | if (endpoints.Count == 0)
29 | {
30 | return null;
31 | }
32 |
33 | await _lock.WaitAsync(ct).ConfigureAwait(false);
34 | try
35 | {
36 | if (_index >= endpoints.Count)
37 | {
38 | _index = 0;
39 | }
40 | var uri = endpoints[_index];
41 | _index++;
42 |
43 | return uri;
44 | }
45 | finally
46 | {
47 | _lock.Release();
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/NanoFabric.Router.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/NanoFabric.Router.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/ServiceSubscriberFactory.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Router.Cache;
2 | using NanoFabric.Router.Consul;
3 | using NanoFabric.Router.Throttle;
4 |
5 | namespace NanoFabric.Router
6 | {
7 | public class ServiceSubscriberFactory : IServiceSubscriberFactory
8 | {
9 | private readonly IConsulServiceSubscriberFactory _consulServiceSubscriberFactory;
10 | private readonly ICacheServiceSubscriberFactory _cacheServiceSubscriberFactory;
11 |
12 | public ServiceSubscriberFactory(IConsulServiceSubscriberFactory consulServiceSubscriberFactory, ICacheServiceSubscriberFactory cacheServiceSubscriberFactory)
13 | {
14 | _consulServiceSubscriberFactory = consulServiceSubscriberFactory;
15 | _cacheServiceSubscriberFactory = cacheServiceSubscriberFactory;
16 | }
17 |
18 | public IPollingServiceSubscriber CreateSubscriber(string servicName)
19 | {
20 | return CreateSubscriber(servicName, ConsulSubscriberOptions.Default, ThrottleSubscriberOptions.Default);
21 | }
22 |
23 | public IPollingServiceSubscriber CreateSubscriber(string serviceName, ConsulSubscriberOptions consulOptions, ThrottleSubscriberOptions throttleOptions)
24 | {
25 | var consulSubscriber = _consulServiceSubscriberFactory.CreateSubscriber(serviceName, consulOptions, true);
26 | var throttleSubscriber = new ThrottleServiceSubscriber(consulSubscriber, throttleOptions.MaxUpdatesPerPeriod, throttleOptions.MaxUpdatesPeriod);
27 | return _cacheServiceSubscriberFactory.CreateSubscriber(throttleSubscriber);
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/NanoFabric.Router/Throttle/ThrottleSubscriberOptions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace NanoFabric.Router.Throttle
4 | {
5 | public class ThrottleSubscriberOptions
6 | {
7 | public static readonly ThrottleSubscriberOptions Default = new ThrottleSubscriberOptions();
8 |
9 | public int MaxUpdatesPerPeriod { get; set; } = 5;
10 |
11 | public TimeSpan MaxUpdatesPeriod { get; set; } = TimeSpan.FromSeconds(10);
12 | }
13 | }
--------------------------------------------------------------------------------
/src/NanoFabric.Swagger/AuthorizeCheckOperationFilter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using NanoFabric.Core;
4 | using Swashbuckle.AspNetCore.Swagger;
5 | using Swashbuckle.AspNetCore.SwaggerGen;
6 |
7 | namespace NanoFabric.Swagger
8 | {
9 | public class AuthorizeCheckOperationFilter : IOperationFilter
10 | {
11 | private readonly IApiInfo _apiInfo;
12 |
13 | public AuthorizeCheckOperationFilter(IApiInfo apiInfo)
14 | {
15 | _apiInfo = apiInfo;
16 | }
17 |
18 | public void Apply(
19 | Operation operation,
20 | OperationFilterContext context
21 | )
22 | {
23 | if (!context.HasAuthorize()) return;
24 |
25 | operation.Responses.Add("401", new Response { Description = "Unauthorized" });
26 | operation.Responses.Add("403", new Response { Description = "Forbidden" });
27 |
28 | operation.Security = new List>>
29 | {
30 | new Dictionary>
31 | {
32 | {"oauth2", _apiInfo.Scopes.Keys.ToArray() }
33 | }
34 | };
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/NanoFabric.Swagger/LowerCaseDocumentFilter.cs:
--------------------------------------------------------------------------------
1 | using Swashbuckle.AspNetCore.Swagger;
2 | using Swashbuckle.AspNetCore.SwaggerGen;
3 | using System.Linq;
4 |
5 | namespace NanoFabric.Swagger
6 | {
7 | ///
8 | /// Converts Swagger document paths to lower case.
9 | ///
10 | public sealed class LowerCaseDocumentFilter : IDocumentFilter
11 | {
12 | public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
13 | {
14 | swaggerDoc.Paths = swaggerDoc.Paths.ToDictionary(x => x.Key.ToLower(), x => x.Value);
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/NanoFabric.Swagger/NanoFabric.Swagger.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/NanoFabric.Swagger/OperationFilterContextExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using Microsoft.AspNetCore.Authorization;
3 | using Swashbuckle.AspNetCore.SwaggerGen;
4 |
5 | namespace NanoFabric.Swagger
6 | {
7 | internal static class OperationFilterContextExtensions
8 | {
9 | internal static bool HasAuthorize(this OperationFilterContext context)
10 | {
11 | var apiDescription = context.ApiDescription;
12 |
13 | return
14 | apiDescription.ControllerAttributes().OfType().Any() ||
15 | apiDescription.ActionAttributes().OfType().Any();
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/test/NanoFabric.AspNetCore.Tests/ApplicationBuilderExtensionsShould.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Core;
2 | using Microsoft.AspNetCore.Hosting;
3 | using Microsoft.AspNetCore.TestHost;
4 | using System;
5 | using Xunit;
6 | using Microsoft.Extensions.DependencyInjection;
7 |
8 | namespace NanoFabric.AspNetCore.Tests
9 | {
10 | public class ApplicationBuilderExtensionsShould
11 | {
12 | [Fact]
13 | public void AddTenant()
14 | {
15 | var registryHost = new InMemoryRegistryHost();
16 | var hostBuilder = new WebHostBuilder()
17 | .ConfigureServices(services =>
18 | {
19 | services.AddNanoFabric(() => registryHost);
20 | })
21 | .Configure(app =>
22 | {
23 | app.AddTenant(nameof(ApplicationBuilderExtensionsShould), "1.0.0", new Uri("http://localhost:1234"));
24 |
25 | var serviceRegistry = app.ApplicationServices.GetService();
26 | Assert.NotNull(serviceRegistry);
27 |
28 | var instances = serviceRegistry.FindAllServicesAsync().Result;
29 | Assert.Equal(1, instances.Count);
30 | });
31 |
32 | using (new TestServer(hostBuilder))
33 | {
34 | // ConfigureServices
35 | // Configure
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/test/NanoFabric.AspNetCore.Tests/Base64Codec.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace NanoFabric.AspNetCore.Tests
5 | {
6 | public class Base64Codec
7 | {
8 | private readonly Encoding _encoding;
9 |
10 | public Base64Codec(Encoding encoding)
11 | {
12 | _encoding = encoding;
13 | }
14 |
15 | public Base64Codec()
16 | : this(Encoding.UTF8)
17 | { }
18 |
19 | public string Encode(string s)
20 | {
21 | var bytes = _encoding.GetBytes(s);
22 | return Convert.ToBase64String(bytes);
23 | }
24 |
25 | public byte[] EncodeToBytes(string s)
26 | {
27 | return _encoding.GetBytes(Encode(s));
28 | }
29 |
30 | public string Decode(string s)
31 | {
32 | var bytes = Convert.FromBase64String(s);
33 | return _encoding.GetString(bytes);
34 | }
35 |
36 | public string DecodeFromBytes(byte[] bytes)
37 | {
38 | return Decode(_encoding.GetString(bytes));
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test/NanoFabric.AspNetCore.Tests/NanoFabric.AspNetCore.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | netcoreapp2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test/NanoFabric.RegistryHost.ConsulRegistry.Test/ConsulRegistryHostShould.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 | using Xunit;
6 | using NanoFabric.Core;
7 | using NanoFabric.RegistryHost.ConsulRegistry;
8 |
9 | namespace NanoFabric.RegistryHost.ConsulRegistry.Tests
10 | {
11 | public class ConsulRegistryHostShould
12 | {
13 | private readonly IRegistryHost _registryHost;
14 |
15 | public ConsulRegistryHostShould()
16 | {
17 | var configuration = new ConsulRegistryHostConfiguration() { HttpEndpoint = "http://127.0.0.1:8500" , DnsEndpoint = new DnsEndpoint() { Address = "127.0.0.1", Port = 8600 } } ;
18 | _registryHost = new ConsulRegistryHost(configuration);
19 | }
20 |
21 | [Fact]
22 | public async Task FindServicesAsync()
23 | {
24 | var services = await _registryHost.FindServiceInstancesAsync("consul");
25 |
26 | Assert.NotNull(services);
27 | Assert.True(services.Any());
28 | }
29 |
30 | [Fact]
31 | public async Task RegisterServiceAsync()
32 | {
33 | var serviceName = nameof(ConsulRegistryHostShould);
34 | _registryHost.RegisterServiceAsync(serviceName, serviceName, new Uri("http://localhost:1234"))
35 | .Wait();
36 |
37 | Func> findTenant = async s => (await ((ConsulRegistryHost)_registryHost).FindAllServicesAsync())
38 | .FirstOrDefault(x => x.Name == s);
39 |
40 | var tenant = findTenant(serviceName).Result;
41 | Assert.NotNull(tenant);
42 | await _registryHost.DeregisterServiceAsync(tenant.Id);
43 | Assert.Null(findTenant(serviceName).Result);
44 | }
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/test/NanoFabric.RegistryHost.ConsulRegistry.Test/HealthCheckExtensionsShould.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using Xunit;
3 |
4 | namespace NanoFabric.RegistryHost.ConsulRegistry.Tests
5 | {
6 | public class HealthCheckExtensionsShould
7 | {
8 | [Fact]
9 | public void IgnoreServicesWithoutServiceId()
10 | {
11 | var healthCheck = new HealthCheck { ServiceID = "" };
12 | Assert.False(healthCheck.NeedsStatusCheck());
13 | }
14 |
15 | [Fact]
16 | public void IgnoreSystemHealthChecks()
17 | {
18 | var healthCheck = new HealthCheck { CheckID = "serfHealth" };
19 | Assert.False(healthCheck.NeedsStatusCheck());
20 | }
21 |
22 | [Fact]
23 | public void IgnoreServicesInNodeMaintenance()
24 | {
25 | var healthCheck = new HealthCheck { CheckID = "_node_maintenance" };
26 | Assert.False(healthCheck.NeedsStatusCheck());
27 | }
28 |
29 | [Fact]
30 | public void IgnoreServicesInMaintenance()
31 | {
32 | var healthCheck = new HealthCheck { CheckID = "_service_maintenance:" };
33 | Assert.False(healthCheck.NeedsStatusCheck());
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/test/NanoFabric.RegistryHost.ConsulRegistry.Test/NanoFabric.RegistryHost.ConsulRegistry.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | netcoreapp2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/test/NanoFabric.Router.Tests/ConsulPreparedQueryServiceSubscriberFixture.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using NanoFabric.Router.Consul;
3 | using NSubstitute;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 |
7 | namespace NanoFabric.Router.Tests
8 | {
9 | public class ConsulPreparedQueryServiceSubscriberFixture
10 | {
11 | public string ServiceName { get; set; }
12 |
13 | public IConsulClient Client { get; set; }
14 |
15 | public QueryResult ClientQueryResult { get; set; }
16 | public IPreparedQueryEndpoint PreparedQueryEndpoint { get; set; }
17 |
18 | public ConsulPreparedQueryServiceSubscriberFixture()
19 | {
20 | Client = Substitute.For();
21 | PreparedQueryEndpoint = Substitute.For();
22 | }
23 |
24 | public void SetPreparedQueryEndpoint()
25 | {
26 | PreparedQueryEndpoint.Execute(Arg.Any(), Arg.Any())
27 | .Returns(Task.FromResult(ClientQueryResult));
28 |
29 | Client.PreparedQuery.Returns(PreparedQueryEndpoint);
30 | }
31 |
32 | public ConsulPreparedQueryServiceSubscriber CreateSut()
33 | {
34 | return new ConsulPreparedQueryServiceSubscriber(Client, ServiceName);
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/test/NanoFabric.Router.Tests/ConsulServiceSubscriberFixture.cs:
--------------------------------------------------------------------------------
1 | using Consul;
2 | using NanoFabric.Router.Consul;
3 | using NSubstitute;
4 | using System.Collections.Generic;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 |
8 | namespace NanoFabric.Router.Tests
9 | {
10 | public class ConsulServiceSubscriberFixture
11 | {
12 | public string ServiceName { get; set; }
13 | public List Tags { get; set; }
14 | public bool PassingOnly { get; set; }
15 | public bool Watch { get; set; }
16 |
17 | public IConsulClient Client { get; set; }
18 | public IServiceSubscriber ServiceSubscriber { get; set; }
19 |
20 | public QueryResult ClientQueryResult { get; set; }
21 | public IHealthEndpoint HealthEndpoint { get; set; }
22 |
23 | public ConsulServiceSubscriberFixture()
24 | {
25 | Client = Substitute.For();
26 | HealthEndpoint = Substitute.For();
27 | ServiceSubscriber = Substitute.For();
28 | }
29 |
30 | public void SetHealthEndpoint()
31 | {
32 | HealthEndpoint.Service(Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any(), Arg.Any())
33 | .Returns(Task.FromResult(ClientQueryResult));
34 |
35 | Client.Health.Returns(HealthEndpoint);
36 | }
37 |
38 | public ConsulServiceSubscriber CreateSut()
39 | {
40 | return new ConsulServiceSubscriber(Client, ServiceName, Tags, PassingOnly, Watch);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test/NanoFabric.Router.Tests/EndpointTests.cs:
--------------------------------------------------------------------------------
1 | using NanoFabric.Core;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Text;
5 | using Xunit;
6 |
7 | namespace NanoFabric.Router.Tests
8 | {
9 | public class EndpointTests
10 | {
11 | [Fact]
12 | public void ToUri_WithNullScheme_ReturnsUriWithHttpScheme()
13 | {
14 | var endpoint = new RegistryInformation
15 | {
16 | Address = Guid.NewGuid().ToString(),
17 | Port = 123
18 | };
19 |
20 | var actual = endpoint.ToUri();
21 |
22 | Assert.Equal("http", actual.Scheme);
23 | }
24 |
25 | [Fact]
26 | public void ToString_WithHostAndPort_ReturnsHostAndPortString()
27 | {
28 | var endpoint = new RegistryInformation
29 | {
30 | Address = Guid.NewGuid().ToString(),
31 | Port = 123
32 | };
33 |
34 | var actual = endpoint.ToString();
35 | Assert.Equal($"{endpoint.Address}:{endpoint.Port}", actual);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/test/NanoFabric.Router.Tests/NanoFabric.Router.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | netcoreapp2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tools/Consul/consul.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/tools/Consul/consul.exe
--------------------------------------------------------------------------------
/tools/Consul/consul_1.0.6_windows_amd64.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/tools/Consul/consul_1.0.6_windows_amd64.zip
--------------------------------------------------------------------------------
/tools/Consul/readme.txt:
--------------------------------------------------------------------------------
1 | consul.exe agent -data-dir=/data/consul/data -ui -dev -bind 0.0.0.0 -client 0.0.0.0
--------------------------------------------------------------------------------
/tools/ab/ab.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/tools/ab/ab.exe
--------------------------------------------------------------------------------
/tools/redis/RedisDesktopManager.rar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/tools/redis/RedisDesktopManager.rar
--------------------------------------------------------------------------------
/tools/redis/redis-64.3.0.503.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/tools/redis/redis-64.3.0.503.zip
--------------------------------------------------------------------------------
/tools/redis/redis-desktop-manager-0.9.3.817.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/tools/redis/redis-desktop-manager-0.9.3.817.exe
--------------------------------------------------------------------------------