├── .gitattributes ├── .gitignore ├── LICENSE.md ├── NanoFabric.sln ├── README.md ├── Sample └── SampleService.IdentityServer │ ├── Controllers │ ├── AccountController.cs │ ├── ConsentController.cs │ └── GrantsController.cs │ ├── Extensions.cs │ ├── Filter │ └── SecurityHeadersAttribute.cs │ ├── SampleService.IdentityServer.csproj.user │ ├── ViewModel │ ├── AccountOptions.cs │ ├── ConsentInputModel.cs │ ├── ConsentOptions.cs │ ├── ConsentViewModel.cs │ ├── ErrorViewModel.cs │ ├── ExternalProvider.cs │ ├── GrantViewModel.cs │ ├── LoggedOutViewModel.cs │ ├── LoginInputModel.cs │ ├── LoginViewModel.cs │ ├── LogoutInputModel.cs │ ├── LogoutViewModel.cs │ ├── ProcessConsentResult.cs │ ├── RedirectViewModel.cs │ └── ScopeViewModel.cs │ └── Views │ ├── Account │ ├── LoggedOut.cshtml │ ├── Login.cshtml │ └── Logout.cshtml │ ├── Consent │ ├── Index.cshtml │ └── _ScopeListItem.cshtml │ ├── Grants │ └── Index.cshtml │ └── Shared │ ├── Redirect.cshtml │ └── _ValidationSummary.cshtml ├── sample ├── SampleService.Client │ ├── Program.cs │ ├── SampleService.Client.csproj │ ├── SampleService.Client.csproj.user │ └── appsettings.json ├── SampleService.IdentityServer │ ├── .bowerrc │ ├── Constans │ │ └── RoutePaths.cs │ ├── Controllers │ │ └── HomeController.cs │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── SampleService.IdentityServer.csproj │ ├── Startup.cs │ ├── Views │ │ ├── Home │ │ │ ├── About.cshtml │ │ │ ├── Contact.cshtml │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── Error.cshtml │ │ │ └── _Layout.cshtml │ │ ├── _ViewImports.cshtml │ │ └── _ViewStart.cshtml │ ├── appsettings.json │ ├── bower.json │ ├── bundleconfig.json │ ├── nanofabrictest.pfx │ ├── web.config │ └── wwwroot │ │ ├── _references.js │ │ ├── css │ │ ├── site.css │ │ └── site.min.css │ │ ├── favicon.ico │ │ ├── images │ │ ├── banner1.svg │ │ ├── banner2.svg │ │ ├── banner3.svg │ │ └── banner4.svg │ │ ├── js │ │ ├── site.js │ │ └── site.min.js │ │ └── lib │ │ ├── bootstrap │ │ ├── .bower.json │ │ ├── LICENSE │ │ └── dist │ │ │ ├── css │ │ │ ├── bootstrap-theme.css │ │ │ ├── bootstrap-theme.css.map │ │ │ ├── bootstrap-theme.min.css │ │ │ ├── bootstrap-theme.min.css.map │ │ │ ├── bootstrap.css │ │ │ ├── bootstrap.css.map │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ │ ├── fonts │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ ├── glyphicons-halflings-regular.svg │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ └── js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ └── npm.js │ │ ├── jquery-validation-unobtrusive │ │ ├── .bower.json │ │ ├── jquery.validate.unobtrusive.js │ │ └── jquery.validate.unobtrusive.min.js │ │ ├── jquery-validation │ │ ├── .bower.json │ │ ├── LICENSE.md │ │ └── dist │ │ │ ├── additional-methods.js │ │ │ ├── additional-methods.min.js │ │ │ ├── jquery.validate.js │ │ │ └── jquery.validate.min.js │ │ └── jquery │ │ ├── .bower.json │ │ ├── LICENSE.txt │ │ └── dist │ │ ├── jquery.js │ │ ├── jquery.min.js │ │ └── jquery.min.map ├── SampleService.Kestrel │ ├── ApiInfo.cs │ ├── Application │ │ └── CommandSide │ │ │ └── Commands │ │ │ ├── EchoCommand.cs │ │ │ └── EchoCommandHandler.cs │ ├── Controllers │ │ ├── EchoController.cs │ │ └── ValuesController.cs │ ├── HealthCheckOptions.cs │ ├── NLog.config │ ├── Program.cs │ ├── Properties │ │ ├── PublishProfiles │ │ │ ├── FileSystemProfile.pubxml │ │ │ └── FileSystemProfile.pubxml.user │ │ └── launchSettings.json │ ├── SampleService.Kestrel.csproj │ ├── SampleService.Kestrel.csproj.user │ ├── ServiceCollectionExtensions.cs │ ├── Startup.cs │ ├── SwaggerExtensions.cs │ ├── appsettings.json │ ├── web.config │ └── wwwroot │ │ └── lib │ │ └── swagger │ │ └── swagger_translator.js └── SampleService.MvcClient │ ├── .bowerrc │ ├── Controllers │ └── HomeController.cs │ ├── Program.cs │ ├── Properties │ ├── PublishProfiles │ │ ├── FolderProfile.pubxml │ │ └── FolderProfile.pubxml.user │ └── launchSettings.json │ ├── SampleService.MvcClient.csproj │ ├── SampleService.MvcClient.csproj.user │ ├── Startup.cs │ ├── Views │ ├── Home │ │ ├── About.cshtml │ │ ├── CallApi.cshtml │ │ ├── Contact.cshtml │ │ └── Index.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _Layout.cshtml │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── bower.json │ ├── bundleconfig.json │ ├── runtimeconfig.template.json │ ├── web.config │ └── wwwroot │ ├── css │ ├── site.css │ └── site.min.css │ ├── favicon.ico │ ├── images │ ├── banner1.svg │ ├── banner2.svg │ ├── banner3.svg │ └── banner4.svg │ ├── js │ ├── site.js │ └── site.min.js │ └── lib │ ├── bootstrap │ ├── .bower.json │ ├── LICENSE │ └── dist │ │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-theme.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ └── npm.js │ ├── jquery-validation-unobtrusive │ ├── .bower.json │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── .bower.json │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── .bower.json │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map ├── src ├── NanoFabric.AppMetrics │ ├── AppMetricsApplicationBuilderExtensions.cs │ ├── AppMetricsOptions.cs │ ├── AppMetricsServiceCollectionExtensions.cs │ └── NanoFabric.AppMetrics.csproj ├── NanoFabric.AspNetCore │ ├── ApiControllerBase.cs │ ├── ApiResult │ │ ├── ApiExceptionFilterAttribute.cs │ │ ├── ApiResult.cs │ │ ├── ApiResultFilterAttribute.cs │ │ ├── ApiResultOfT.cs │ │ ├── IApiResult.cs │ │ ├── IApiResultOfT.cs │ │ └── IMvcCoreBuilderApiResultExtensions.cs │ ├── ApplicationBuilderExtensions.cs │ ├── Cors │ │ └── WildcardCorsService.cs │ ├── Helper │ │ └── IPAddressHelper.cs │ ├── HttpContextUser.cs │ ├── Middleware │ │ └── AuthenticationMiddleware.cs │ ├── NanoFabric.AspNetCore.csproj │ ├── NanoStartupFilter.cs │ ├── ServiceCollectionExtensions.cs │ ├── StatusController.cs │ └── WebApiRegistryTenant.cs ├── NanoFabric.Autofac │ ├── NanoFabric.Autofac.csproj │ └── ServiceCollectionExtensions.cs ├── NanoFabric.Core │ ├── DnsHelper.cs │ ├── Exceptions │ │ ├── IStandardError.cs │ │ └── StandardException.cs │ ├── Extensions │ │ ├── StringExtensions.cs │ │ └── UriExtensions.cs │ ├── IApiInfo.cs │ ├── IUser.cs │ ├── Json │ │ ├── CamelCasePropertyNamesContractResolver.cs │ │ ├── ContractResolver.cs │ │ └── JsonExtensions.cs │ ├── MqMessages │ │ ├── IMqMessagePublisher.cs │ │ ├── MessageTrackers │ │ │ ├── DefaultInMemoryMessageTracker.cs │ │ │ └── IMessageTracker.cs │ │ └── NullMqMessagePublisher.cs │ ├── NanoFabric.Core.csproj │ ├── Registry │ │ ├── IManageHealthChecks.cs │ │ ├── IManageServiceInstances.cs │ │ ├── IRegistryHost.cs │ │ ├── IRegistryTenant.cs │ │ ├── IResolveServiceInstances.cs │ │ ├── RegistryInformation.cs │ │ └── ServiceRegistry.cs │ └── Threading │ │ └── AsyncHelper.cs ├── NanoFabric.Exceptionless │ ├── ApplicationBuilderExtensions.cs │ ├── Extensions │ │ └── ExceptionExtensions.cs │ ├── LessExceptionLog.cs │ ├── LessFeatureLog.cs │ ├── LessLinksLog.cs │ ├── LessLog.cs │ ├── Logging │ │ ├── ILessExceptionLog.cs │ │ ├── ILessFeatureLog.cs │ │ ├── ILessLinksLog.cs │ │ └── ILessLog.cs │ ├── Model │ │ ├── ExcDataParam.cs │ │ └── ExcUserParam.cs │ ├── NanoFabric.Exceptionless.csproj │ └── ServiceCollectionExtensions.cs ├── NanoFabric.Grpc.Hosting │ └── NanoFabric.Grpc.Hosting.csproj ├── NanoFabric.Grpc │ ├── Client │ │ ├── GRpcConnection.cs │ │ ├── GrpcChannelFactory.cs │ │ ├── IGRpcConnection.cs │ │ └── IGrpcChannelFactory.cs │ ├── Extensions │ │ ├── ApplicationBuilderExtensions.cs │ │ └── ServiceCollectionExtensions.cs │ └── NanoFabric.Grpc.csproj ├── NanoFabric.IdentityServer │ ├── IdentityOptions.cs │ ├── IdentityServerExtensions.cs │ ├── Interfaces │ │ ├── Repositories │ │ │ ├── IClientRepository.cs │ │ │ ├── IPersistedGrantRepository.cs │ │ │ ├── IScopeRepository.cs │ │ │ └── IUserRepository.cs │ │ └── Services │ │ │ ├── IPasswordService.cs │ │ │ └── IUserService.cs │ ├── Models │ │ ├── DomainEntity.cs │ │ └── User.cs │ ├── NanoFabric.IdentityServer.csproj │ ├── Repositories │ │ ├── ClientAggregate │ │ │ └── InMemory │ │ │ │ ├── ClientInMemoryRepository.cs │ │ │ │ └── InMemoryClients.cs │ │ ├── PersistedGrantAggregate │ │ │ └── PersistedGrantStore.cs │ │ ├── ResourceAggregate │ │ │ └── InMemory │ │ │ │ ├── InMemoryResources.cs │ │ │ │ └── ResourceInMemoryRepository.cs │ │ └── UserAggregate │ │ │ └── InMemory │ │ │ ├── InMemoryUsers.cs │ │ │ └── UserInMemoryRepository.cs │ ├── ServiceCollectionExtensions.cs │ ├── Services │ │ ├── PasswordService.cs │ │ ├── ProfileService.cs │ │ ├── ResourceOwnerPasswordValidator.cs │ │ └── UserService.cs │ ├── Utilities │ │ ├── ClaimsUtility.cs │ │ └── CryptographyUtility.cs │ └── obj │ │ ├── CFT.NanoFabric.IdentityServer.csproj.nuget.g.props │ │ └── CFT.NanoFabric.IdentityServer.csproj.nuget.g.targets ├── NanoFabric.Mediatr │ ├── Autofac │ │ └── MediatrModule.cs │ ├── CircularQueue.cs │ ├── Commands │ │ ├── ICommand.cs │ │ ├── IdentifiedCommand.cs │ │ └── IdentifiedCommandHandler.cs │ ├── Exceptions │ │ ├── HttpGlobalExceptionFilter.cs │ │ ├── MediatrPipelineException.cs │ │ └── ThrowMediatrPipelineException.cs │ ├── IRequestManager.cs │ ├── InMemoryRequestManager.cs │ ├── NanoFabric.Mediatr.csproj │ └── Validators │ │ └── ValidatorsBehavior.cs ├── NanoFabric.MqMessages │ ├── NanoFabric.MqMessages.csproj │ ├── RebusRabbitMqPublisher.cs │ └── ServiceCollectionExtensions.cs ├── NanoFabric.Ocelot │ ├── NanoFabric.Ocelot.csproj │ ├── NanoFabric.Ocelot.csproj.user │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── appsettings.json │ ├── nlog.config │ ├── ocelot.json │ ├── tempkey.rsa │ └── web.config ├── NanoFabric.RegistryHost.ConsulRegistry │ ├── ConsulRegistryHost.cs │ ├── ConsulRegistryHostConfiguration.cs │ ├── HealthCheckExtensions.cs │ ├── NanoFabric.RegistryHost.ConsulRegistry.csproj │ └── ServiceDiscoveryOption.cs ├── NanoFabric.Router │ ├── Cache │ │ ├── CacheServiceSubscriber.cs │ │ ├── CacheServiceSubscriberFactory.cs │ │ ├── ICacheServiceSubscriberFactory.cs │ │ └── Internal │ │ │ ├── CacheClient.cs │ │ │ └── ICacheClient.cs │ ├── Consul │ │ ├── ConsulClientExtensions.cs │ │ ├── ConsulConfiguration.cs │ │ ├── ConsulPreparedQueryServiceSubscriber.cs │ │ ├── ConsulPreparedQueryServiceSubscriberFactory.cs │ │ ├── ConsulServiceSubscriber.cs │ │ ├── ConsulServiceSubscriberFactory.cs │ │ ├── ConsulSubscriberOptions.cs │ │ ├── IConsulPreparedQueryServiceSubscriberFactory.cs │ │ └── IConsulServiceSubscriberFactory.cs │ ├── IPollingServiceSubscriber.cs │ ├── IServiceSubscriber.cs │ ├── IServiceSubscriberFactory.cs │ ├── LoadBalancer │ │ ├── ILoadBalancer.cs │ │ ├── RandomLoadBalancer.cs │ │ └── RoundRobinLoadBalancer.cs │ ├── NanoFabric.Router.csproj │ ├── NanoFabric.Router.csproj.user │ ├── ServiceCollectionExtensions.cs │ ├── ServiceSubscriberFactory.cs │ └── Throttle │ │ ├── ThrottleServiceSubscriber.cs │ │ └── ThrottleSubscriberOptions.cs └── NanoFabric.Swagger │ ├── AuthorizeCheckOperationFilter.cs │ ├── LowerCaseDocumentFilter.cs │ ├── NanoFabric.Swagger.csproj │ ├── OperationFilterContextExtensions.cs │ └── ServiceCollectionExtensions.cs ├── test ├── NanoFabric.AspNetCore.Tests │ ├── ApplicationBuilderExtensionsShould.cs │ ├── Base64Codec.cs │ ├── InMemoryRegistryHost.cs │ ├── NanoFabric.AspNetCore.Tests.csproj │ └── ServiceCollectionExtensionsShould.cs ├── NanoFabric.RegistryHost.ConsulRegistry.Test │ ├── ConsulRegistryHostShould.cs │ ├── HealthCheckExtensionsShould.cs │ └── NanoFabric.RegistryHost.ConsulRegistry.Tests.csproj └── NanoFabric.Router.Tests │ ├── CacheServiceSubscriberTests.cs │ ├── ConsulPreparedQueryServiceSubscriberFixture.cs │ ├── ConsulPreparedQueryServiceSubscriberTests.cs │ ├── ConsulServiceSubscriberFixture.cs │ ├── ConsulServiceSubscriberTests.cs │ ├── EndpointTests.cs │ ├── NanoFabric.Router.Tests.csproj │ └── RoundRobinAddressRouterShould.cs └── tools ├── Consul ├── consul.exe ├── consul_1.0.6_windows_amd64.zip └── readme.txt ├── ab └── ab.exe └── redis ├── RedisDesktopManager.rar ├── redis-64.3.0.503.zip └── redis-desktop-manager-0.9.3.817.exe /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2017 Geffzhang 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/Extensions.cs: -------------------------------------------------------------------------------- 1 | using IdentityServer4.Stores; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace SampleService.IdentityServer 8 | { 9 | public static class Extensions 10 | { 11 | /// 12 | /// Determines whether the client is configured to use PKCE. 13 | /// 14 | /// The store. 15 | /// The client identifier. 16 | /// 17 | public static async Task IsPkceClientAsync(this IClientStore store, string client_id) 18 | { 19 | if (!string.IsNullOrWhiteSpace(client_id)) 20 | { 21 | var client = await store.FindEnabledClientByIdAsync(client_id); 22 | return client?.RequirePkce == true; 23 | } 24 | 25 | return false; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/SampleService.IdentityServer.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ProjectDebugger 5 | 6 | 7 | SampleService.IdentityServer 8 | 9 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/AccountOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class AccountOptions 9 | { 10 | public static bool AllowLocalLogin = true; 11 | public static bool AllowRememberLogin = true; 12 | public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30); 13 | 14 | public static bool ShowLogoutPrompt = true; 15 | public static bool AutomaticRedirectAfterSignOut = false; 16 | 17 | // specify the Windows authentication scheme being used 18 | public static readonly string WindowsAuthenticationSchemeName = Microsoft.AspNetCore.Server.IISIntegration.IISDefaults.AuthenticationScheme; 19 | // if user uses windows auth, should we load the groups from windows 20 | public static bool IncludeWindowsGroups = false; 21 | 22 | public static string InvalidCredentialsErrorMessage = "Invalid username or password"; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/ConsentInputModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class ConsentInputModel 9 | { 10 | public string Button { get; set; } 11 | public IEnumerable ScopesConsented { get; set; } 12 | public bool RememberConsent { get; set; } 13 | public string ReturnUrl { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/ConsentOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class ConsentOptions 9 | { 10 | public static bool EnableOfflineAccess = true; 11 | public static string OfflineAccessDisplayName = "Offline Access"; 12 | public static string OfflineAccessDescription = "Access to your applications and resources, even when you are offline"; 13 | 14 | public static readonly string MustChooseOneErrorMessage = "You must pick at least one permission"; 15 | public static readonly string InvalidSelectionErrorMessage = "Invalid selection"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/ConsentViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class ConsentViewModel : ConsentInputModel 9 | { 10 | public string ClientName { get; set; } 11 | public string ClientUrl { get; set; } 12 | public string ClientLogoUrl { get; set; } 13 | public bool AllowRememberConsent { get; set; } 14 | 15 | public IEnumerable IdentityScopes { get; set; } 16 | public IEnumerable ResourceScopes { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using IdentityServer4.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace SampleService.IdentityServer.ViewModel 8 | { 9 | public class ErrorViewModel 10 | { 11 | public ErrorMessage Error { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/ExternalProvider.cs: -------------------------------------------------------------------------------- 1 | namespace SampleService.IdentityServer.ViewModel 2 | { 3 | public class ExternalProvider 4 | { 5 | public string DisplayName { get; set; } 6 | public string AuthenticationScheme { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/GrantViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class GrantsViewModel 9 | { 10 | public IEnumerable Grants { get; set; } 11 | } 12 | 13 | public class GrantViewModel 14 | { 15 | public string ClientId { get; set; } 16 | public string ClientName { get; set; } 17 | public string ClientUrl { get; set; } 18 | public string ClientLogoUrl { get; set; } 19 | public DateTime Created { get; set; } 20 | public DateTime? Expires { get; set; } 21 | public IEnumerable IdentityGrantNames { get; set; } 22 | public IEnumerable ApiGrantNames { get; set; } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/LoggedOutViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class LoggedOutViewModel 9 | { 10 | public string PostLogoutRedirectUri { get; set; } 11 | public string ClientName { get; set; } 12 | public string SignOutIframeUrl { get; set; } 13 | 14 | public bool AutomaticRedirectAfterSignOut { get; set; } = false; 15 | 16 | public string LogoutId { get; set; } 17 | public bool TriggerExternalSignout => ExternalAuthenticationScheme != null; 18 | public string ExternalAuthenticationScheme { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/LoginInputModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace SampleService.IdentityServer.ViewModel 8 | { 9 | public class LoginInputModel 10 | { 11 | [Required] 12 | public string Username { get; set; } 13 | [Required] 14 | public string Password { get; set; } 15 | public bool RememberLogin { get; set; } 16 | public string ReturnUrl { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/LoginViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class LoginViewModel : LoginInputModel 9 | { 10 | public bool AllowRememberLogin { get; set; } = true; 11 | public bool EnableLocalLogin { get; set; } = true; 12 | 13 | public IEnumerable ExternalProviders { get; set; } 14 | public IEnumerable VisibleExternalProviders => ExternalProviders.Where(x => !String.IsNullOrWhiteSpace(x.DisplayName)); 15 | 16 | public bool IsExternalLoginOnly => EnableLocalLogin == false && ExternalProviders?.Count() == 1; 17 | public string ExternalLoginScheme => IsExternalLoginOnly ? ExternalProviders?.SingleOrDefault()?.AuthenticationScheme : null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/LogoutInputModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class LogoutInputModel 9 | { 10 | public string LogoutId { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/LogoutViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class LogoutViewModel : LogoutInputModel 9 | { 10 | public bool ShowLogoutPrompt { get; set; } = true; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/ProcessConsentResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class ProcessConsentResult 9 | { 10 | public bool IsRedirect => RedirectUri != null; 11 | public string RedirectUri { get; set; } 12 | public string ClientId { get; set; } 13 | 14 | public bool ShowView => ViewModel != null; 15 | public ConsentViewModel ViewModel { get; set; } 16 | 17 | public bool HasValidationError => ValidationError != null; 18 | public string ValidationError { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/RedirectViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer.ViewModel 7 | { 8 | public class RedirectViewModel 9 | { 10 | public string RedirectUrl { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/ViewModel/ScopeViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace SampleService.IdentityServer.ViewModel 2 | { 3 | public class ScopeViewModel 4 | { 5 | public string Name { get; set; } 6 | public string DisplayName { get; set; } 7 | public string Description { get; set; } 8 | public bool Emphasize { get; set; } 9 | public bool Required { get; set; } 10 | public bool Checked { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/Views/Account/LoggedOut.cshtml: -------------------------------------------------------------------------------- 1 | @model LoggedOutViewModel 2 | 3 | @{ 4 | // set this so the layout rendering sees an anonymous user 5 | ViewData["signed-out"] = true; 6 | } 7 | 8 | 27 | 28 | @section scripts 29 | { 30 | @if (Model.AutomaticRedirectAfterSignOut) 31 | { 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/Views/Account/Logout.cshtml: -------------------------------------------------------------------------------- 1 | @model LogoutViewModel 2 | 3 |
4 | 7 | 8 |
9 |
10 |

Would you like to logout of IdentityServer?

11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 |
19 |
20 |
21 |
-------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/Views/Consent/_ScopeListItem.cshtml: -------------------------------------------------------------------------------- 1 | @model ScopeViewModel 2 | 3 |
  • 4 | 24 | @if (Model.Required) 25 | { 26 | (required) 27 | } 28 | @if (Model.Description != null) 29 | { 30 | 33 | } 34 |
  • -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/Views/Shared/Redirect.cshtml: -------------------------------------------------------------------------------- 1 | @model RedirectViewModel 2 | 3 |

    You are now being returned to the application.

    4 |

    Once complete, you may close this tab

    5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sample/SampleService.IdentityServer/Views/Shared/_ValidationSummary.cshtml: -------------------------------------------------------------------------------- 1 | @if (ViewContext.ModelState.IsValid == false) 2 | { 3 |
    4 | Error 5 |
    6 |
    7 | } -------------------------------------------------------------------------------- /sample/SampleService.Client/SampleService.Client.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | Exe 4 | netcoreapp2.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | PreserveNewest 12 | PreserveNewest 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /sample/SampleService.Client/SampleService.Client.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | false 5 | 6 | -------------------------------------------------------------------------------- /sample/SampleService.Client/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ServiceDiscovery": { 3 | "ServiceName": "SampleService.Client", 4 | "Version": "1.0.0-pre", 5 | "HealthCheckTemplate": "", 6 | "Endpoints": [], 7 | "Consul": { 8 | "HttpEndpoint": "http://127.0.0.1:8500", 9 | "DnsEndpoint": { 10 | "Address": "127.0.0.1", 11 | "Port": 8600 12 | } 13 | } 14 | }, 15 | "Logging": { 16 | "IncludeScopes": false, 17 | "LogLevel": { 18 | "Default": "Trace", 19 | "System": "Information", 20 | "Microsoft": "None" 21 | } 22 | }, 23 | "Butterfly": { 24 | "CollectorUrl": "http://127.0.0.1:9618" 25 | } 26 | } -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "wwwroot/lib" 3 | } 4 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/Constans/RoutePaths.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace SampleService.IdentityServer 7 | { 8 | public class RoutePaths 9 | { 10 | public const string SignInUrl = "signin"; 11 | public const string SignOutUrl = "signout"; 12 | public const string ConsentUrl = "consent"; 13 | public const string ErrorUrl = "error"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace SampleService.IdentityServer.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public IActionResult Index() 12 | { 13 | return View(); 14 | } 15 | 16 | public IActionResult About() 17 | { 18 | ViewData["Message"] = "Your application description page."; 19 | 20 | return View(); 21 | } 22 | 23 | public IActionResult Contact() 24 | { 25 | ViewData["Message"] = "Your contact page."; 26 | 27 | return View(); 28 | } 29 | 30 | public IActionResult Error() 31 | { 32 | return View(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Hosting; 7 | 8 | namespace SampleService.IdentityServer 9 | { 10 | public class Program 11 | { 12 | public static void Main(string[] args) 13 | { 14 | var host = new WebHostBuilder() 15 | .UseKestrel() 16 | .UseContentRoot(Directory.GetCurrentDirectory()) 17 | .UseIISIntegration() 18 | .UseStartup() 19 | .Build(); 20 | 21 | host.Run(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:59185/", 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.IdentityServer": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "launchUrl": "http://localhost:5000", 22 | "environmentVariables": { 23 | "ASPNETCORE_ENVIRONMENT": "Development" 24 | }, 25 | "applicationUrl": "http://localhost:5000" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/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.IdentityServer/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Contact"; 3 | } 4 |

    @ViewData["Title"].

    5 |

    @ViewData["Message"]

    6 | 7 |
    8 | One Microsoft Way
    9 | Redmond, WA 98052-6399
    10 | P: 11 | 425.555.0100 12 |
    13 | 14 |
    15 | Support: Support@example.com
    16 | Marketing: Marketing@example.com 17 |
    18 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/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.IdentityServer/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using SampleService.IdentityServer.ViewModel 2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 3 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | }, 10 | "ServiceDiscovery": { 11 | "ServiceName": "SampleService_Idserver", 12 | "Version": "1.0.0-pre", 13 | "HealthCheckTemplate": "", 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 | "Skywalking": { 24 | "CollectorUrl": "127.0.0.1:11800" 25 | }, 26 | "IdentityOptions": { 27 | "Redis": "127.0.0.1:6379,defaultDatabase=2" 28 | } 29 | } -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "asp.net", 3 | "private": true, 4 | "dependencies": { 5 | "bootstrap": "3.3.6", 6 | "jquery": "2.2.0", 7 | "jquery-validation": "1.14.0", 8 | "jquery-validation-unobtrusive": "3.2.6" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/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.IdentityServer/nanofabrictest.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.IdentityServer/nanofabrictest.pfx -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/wwwroot/_references.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/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 | { 29 | width: 100%; 30 | } 31 | 32 | /* Hide/rearrange for smaller screens */ 33 | @media screen and (max-width: 767px) { 34 | /* Hide captions */ 35 | .carousel-caption { 36 | display: none 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/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.IdentityServer/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.IdentityServer/wwwroot/favicon.ico -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Write your Javascript code. 2 | -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.IdentityServer/wwwroot/js/site.min.js -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/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 - 2" 33 | }, 34 | "version": "3.3.6", 35 | "_release": "3.3.6", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.6", 39 | "commit": "81df608a40bf0629a1dc08e584849bb1e43e0b7a" 40 | }, 41 | "_source": "git://github.com/twbs/bootstrap.git", 42 | "_target": "3.3.6", 43 | "_originalSource": "bootstrap" 44 | } -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2015 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.IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/geffzhang/NanoFabric/63872404c41a0e4a8d1e69f6bff38484d4ca72e2/sample/SampleService.IdentityServer/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /sample/SampleService.IdentityServer/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.IdentityServer/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.IdentityServer/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.IdentityServer/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.IdentityServer/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.IdentityServer/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 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/ApiInfo.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using NanoFabric.Core; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Threading.Tasks; 8 | 9 | namespace SampleService.Kestrel 10 | { 11 | public class ApiInfo : IApiInfo 12 | { 13 | private ApiInfo(IConfiguration config) 14 | { 15 | AuthenticationAuthority = config["Authority"]; 16 | } 17 | 18 | public string AuthenticationAuthority { get; } 19 | 20 | public string Title => "SampleService_Kestrel Api"; 21 | 22 | public string Version => "v1"; 23 | 24 | public Assembly ApplicationAssembly => GetType().Assembly; 25 | 26 | public IDictionary Scopes => new Dictionary 27 | { 28 | {"api1", Title} 29 | }; 30 | 31 | public SwaggerAuthInfo SwaggerAuthInfo => new SwaggerAuthInfo( 32 | "echoapiswaggerui", "", "" 33 | ); 34 | 35 | public static IApiInfo Instantiate(IConfiguration config) 36 | { 37 | Instance = new ApiInfo(config); 38 | return Instance; 39 | } 40 | 41 | public static IApiInfo Instance { get; private set; } 42 | 43 | public string ApiName => "api1"; 44 | 45 | public string ApiSecret => "secret"; 46 | 47 | public string BindAddress { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } 48 | 49 | public int BindPort { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/Application/CommandSide/Commands/EchoCommand.cs: -------------------------------------------------------------------------------- 1 | using NanoFabric.Mediatr.Commands; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace SampleService.Kestrel.Application.CommandSide.Commands 8 | { 9 | /// 10 | /// Echo Command 11 | /// 12 | public class EchoCommand : ICommand 13 | { 14 | /// 15 | /// 输入 16 | /// 17 | public string Input { get; } 18 | 19 | /// 20 | /// 构造函数 21 | /// 22 | /// 23 | public EchoCommand( 24 | string input 25 | ) 26 | { 27 | Input = input; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/Application/CommandSide/Commands/EchoCommandHandler.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | namespace SampleService.Kestrel.Application.CommandSide.Commands 9 | { 10 | /// 11 | /// EchoCommand 处理器 12 | /// 13 | public class EchoCommandHandler 14 | : IRequestHandler 15 | { 16 | public Task Handle( 17 | EchoCommand request, 18 | CancellationToken cancellationToken 19 | ) 20 | { 21 | return Task.FromResult(request.Input); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/Controllers/EchoController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Threading.Tasks; 6 | using MediatR; 7 | using Microsoft.AspNetCore.Mvc; 8 | using NanoFabric.Mediatr.Commands; 9 | using SampleService.Kestrel.Application.CommandSide.Commands; 10 | 11 | // For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860 12 | 13 | namespace SampleService.Kestrel.Controllers 14 | { 15 | [Route("api/[controller]")] 16 | public class EchoController : Controller 17 | { 18 | private readonly IMediator _mediator; 19 | 20 | public EchoController(IMediator mediator) 21 | { 22 | _mediator = mediator; 23 | } 24 | 25 | [HttpPut] 26 | [ProducesResponseType(typeof(string), (int)HttpStatusCode.OK)] 27 | [ProducesResponseType((int)HttpStatusCode.BadRequest)] 28 | public async Task GetEcho( 29 | [FromBody] EchoCommand command, 30 | [FromHeader(Name = "x-requestid")] string requestId 31 | ) 32 | { 33 | if (!Guid.TryParse(requestId, out var guid)) 34 | { 35 | return BadRequest(); 36 | } 37 | 38 | var identifiedCommand = new IdentifiedCommand( 39 | command, 40 | guid 41 | ); 42 | 43 | return Ok(await _mediator.Send(identifiedCommand)); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/Controllers/ValuesController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Microsoft.AspNetCore.Authorization; 3 | using Microsoft.AspNetCore.Mvc; 4 | 5 | namespace SampleService.Kestrel.Controllers 6 | { 7 | /// 8 | /// 测试API 9 | /// 10 | [Route("api/[controller]")] 11 | public class ValuesController : Controller 12 | { 13 | /// 14 | /// GET api/values 15 | /// 16 | /// 17 | [HttpGet] 18 | public IEnumerable Get() 19 | { 20 | return new[] { "value1", "value2" }; 21 | } 22 | 23 | /// 24 | /// GET api/values/5 25 | /// 26 | /// 27 | /// 28 | [HttpGet("{id}")] 29 | [Authorize()] 30 | public string Get(int id) 31 | { 32 | return $"{id}"; 33 | } 34 | 35 | /// 36 | /// POST api/values 37 | /// 38 | /// 39 | [HttpPost] 40 | public void Post([FromBody]string value) 41 | { 42 | } 43 | 44 | /// 45 | /// PUT api/values/5 46 | /// 47 | /// 48 | /// 49 | [HttpPut("{id}")] 50 | public void Put(int id, [FromBody]string value) 51 | { 52 | } 53 | 54 | /// 55 | /// DELETE api/values/5 56 | /// 57 | /// 58 | [HttpDelete("{id}")] 59 | public void Delete(int id) 60 | { 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/HealthCheckOptions.cs: -------------------------------------------------------------------------------- 1 | namespace SampleService.Kestrel 2 | { 3 | public class HealthCheckOptions 4 | { 5 | public string HealthCheckId { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/NLog.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using System.IO; 5 | 6 | namespace SampleService.Kestrel 7 | { 8 | public class Program 9 | { 10 | private const string defaultAddress = "http://localhost:9300"; 11 | private const string addressKey = "serveraddress"; 12 | 13 | public static void Main(string[] args) 14 | { 15 | IWebHost host = BuildWebHost(args); 16 | host.Run(); 17 | } 18 | 19 | private static IWebHost BuildWebHost(string[] args) 20 | { 21 | var configurationBuilder = new Microsoft.Extensions.Configuration.ConfigurationBuilder() 22 | .SetBasePath(Directory.GetCurrentDirectory()) 23 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 24 | .AddJsonFile("appsettings.Development.json", true, false) 25 | .AddJsonFile("appsettings.Production.json", true, false) 26 | .AddEnvironmentVariables() 27 | .AddCommandLine(args); 28 | 29 | if (args != null) 30 | { 31 | configurationBuilder.AddCommandLine(args); 32 | } 33 | var hostingconfig = configurationBuilder.Build(); 34 | var url = hostingconfig[addressKey] ?? defaultAddress; 35 | 36 | return WebHost.CreateDefaultBuilder(args) 37 | .ConfigureAppConfiguration(config => 38 | { 39 | config.AddJsonFile("appsettings.json", false, true); 40 | }) 41 | .UseConfiguration(hostingconfig) 42 | .UseKestrel() 43 | .UseContentRoot(Directory.GetCurrentDirectory()) 44 | .UseUrls(url) 45 | .UseStartup() 46 | .Build(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/Properties/PublishProfiles/FileSystemProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | FileSystem 10 | Release 11 | Any CPU 12 | 13 | True 14 | False 15 | 16 | bin\Release\PublishOutput 17 | False 18 | 19 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/Properties/PublishProfiles/FileSystemProfile.pubxml.user: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | <_NewBackgroundProfile>True 10 | <_PublishTargetUrl>F:\Workshop\Github\NanoFabric\sample\SampleService.Kestrel\bin\Release\PublishOutput 11 | 12 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:24070/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "launchUrl": "api/values", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "SampleService.Kestrel": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "api/values", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | }, 26 | "applicationUrl": "http://localhost:9300" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/SampleService.Kestrel.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ProjectDebugger 5 | 6 | 7 | SampleService.Kestrel 8 | false 9 | FileSystemProfile 10 | MvcControllerEmptyScaffolder 11 | root/Controller 12 | 600 13 | 14 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Configuration; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using NanoFabric.Mediatr; 4 | 5 | namespace SampleService.Kestrel 6 | { 7 | /// 8 | /// 应用扩展 9 | /// 10 | public static class ServiceCollectionExtensions 11 | { 12 | public static IServiceCollection AddApplication( 13 | this IServiceCollection services, IConfiguration configuration 14 | ) where TRequestManager : class, IRequestManager 15 | { 16 | return services 17 | .AddSingleton() 18 | .AddSingleton(ApiInfo.Instantiate(configuration)); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ServiceDiscovery": { 3 | "ServiceName": "SampleService_Kestrel", 4 | "Version": "1.0.0-pre", 5 | "HealthCheckTemplate": "", 6 | "Endpoints": [], 7 | "Consul": { 8 | "HttpEndpoint": "http://127.0.0.1:8500", 9 | "DnsEndpoint": { 10 | "Address": "127.0.0.1", 11 | "Port": 8600 12 | } 13 | } 14 | }, 15 | "Logging": { 16 | "IncludeScopes": false, 17 | "LogLevel": { 18 | "Default": "Trace", 19 | "System": "Information", 20 | "Microsoft": "None" 21 | } 22 | }, 23 | "Skywalking": { 24 | "CollectorUrl": "localhost:11800" 25 | }, 26 | "AppSettings": { 27 | "VirtualDirectory": "/Api", 28 | "IdentityServerAuthority": "http://127.0.0.1:5000" 29 | }, 30 | "ServerAddress": "http://127.0.0.1:9300", 31 | "Authority": "http://127.0.0.1:5000", 32 | "WhiteListIps": "127.0.0.1;139.199.141.46;10.165.19.29" 33 | } -------------------------------------------------------------------------------- /sample/SampleService.Kestrel/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /sample/SampleService.MvcClient/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "wwwroot/lib" 3 | } 4 | -------------------------------------------------------------------------------- /sample/SampleService.MvcClient/Program.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using Microsoft.AspNetCore.Hosting; 3 | using Microsoft.Extensions.Configuration; 4 | using Microsoft.Extensions.DependencyInjection; 5 | 6 | namespace SampleService.MvcClient 7 | { 8 | public class Program 9 | { 10 | private const string defaultAddress = "http://127.0.0.1:9000"; 11 | private const string addressKey = "serveraddress"; 12 | 13 | public static void Main(string[] args) 14 | { 15 | var configurationBuilder = new Microsoft.Extensions.Configuration.ConfigurationBuilder() 16 | .SetBasePath(Directory.GetCurrentDirectory()) 17 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 18 | .AddJsonFile("appsettings.Development.json", true, false) 19 | .AddJsonFile("appsettings.Production.json", true, false) 20 | .AddEnvironmentVariables() 21 | .AddCommandLine(args); 22 | 23 | if (args != null) 24 | { 25 | configurationBuilder.AddCommandLine(args); 26 | } 27 | var hostingconfig = configurationBuilder.Build(); 28 | var url = hostingconfig[addressKey] ?? defaultAddress; 29 | 30 | IWebHostBuilder builder = new WebHostBuilder(); 31 | builder.ConfigureServices(s => 32 | { 33 | s.AddSingleton(builder); 34 | }); 35 | builder.UseKestrel() 36 | .UseContentRoot(Directory.GetCurrentDirectory()) 37 | .UseConfiguration(hostingconfig) 38 | .UseIISIntegration() 39 | .UseUrls(url) 40 | .UseStartup(); 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 |
    8 | Call API 9 |
    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 --------------------------------------------------------------------------------