[
  {
    "path": ".dockerignore",
    "content": "**/.classpath\n**/.dockerignore\n**/.env\n**/.git\n**/.gitignore\n**/.project\n**/.settings\n**/.toolstarget\n**/.vs\n**/.vscode\n**/*.*proj.user\n**/*.dbmdl\n**/*.jfm\n**/azds.yaml\n**/bin\n**/charts\n**/docker-compose*\n**/Dockerfile*\n**/node_modules\n**/npm-debug.log\n**/obj\n**/secrets.dev.yaml\n**/values.dev.yaml\nLICENSE\nREADME.md"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# Logs\nlogs/\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n#屏蔽本地配置文件\nappsettings.Development.json\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\nbld/\n[Bb]in/\n[Oo]bj/\n[Ll]og/\nnode_modules/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# TODO: Comment the next line if you want to checkin your web deploy settings\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# JetBrains Rider\n.idea/\n*.sln.iml\n\n# Gateway\nsrc/Pterosaur.Gateway.Web/Logs/*\nsrc/Pterosaur.Gateway.Web.Host/Logs/*\nsrc/Pterosaur.Gateway.IdentityServer/Logs/*\nsrc/Pterosaur.Gateway.HttpApi.Host/Logs/*\nsrc/Pterosaur.Gateway.HttpApi.Host/Logs/*\nsrc/Pterosaur.Gateway.DbMigrator/Logs/*\nsrc/Pterosaur.Gateway.Blazor.Server/Logs/*\nsrc/Pterosaur.Gateway.Blazor.Server.Tiered/Logs/*"
  },
  {
    "path": "Kite.Gateway.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.1.32328.378\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Kite.Gateway.EntityFrameworkCore\", \"src\\Kite.Gateway.EntityFrameworkCore\\Kite.Gateway.EntityFrameworkCore.csproj\", \"{22772D7B-C655-491D-8CED-3DD6961D59F8}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Kite.Gateway.Application\", \"src\\Kite.Gateway.Application\\Kite.Gateway.Application.csproj\", \"{FCECED16-7C02-47CC-A325-5D710C9C57D7}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Kite.Gateway.Domain\", \"src\\Kite.Gateway.Domain\\Kite.Gateway.Domain.csproj\", \"{28CE009E-4E3D-4F06-9811-9A083637A5DC}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Kite.Gateway.Domain.Shared\", \"src\\Kite.Gateway.Domain.Shared\\Kite.Gateway.Domain.Shared.csproj\", \"{C8BF159F-19BC-4E05-BA6C-BD3BB1D4A397}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"src\", \"src\", \"{CD55B1DC-925D-4B8D-8B43-47AE9A9661BD}\"\nEndProject\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"admin\", \"admin\", \"{5DCEB584-F097-4769-8172-4FFBA9E1898D}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Kite.Gateway.Application.Contracts\", \"src\\Kite.Gateway.Application.Contracts\\Kite.Gateway.Application.Contracts.csproj\", \"{E50AB14E-6DB5-4DE3-95EA-BECF1ED6AB75}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"Kite.Gateway.Admin\", \"admin\\Kite.Gateway.Admin\\Kite.Gateway.Admin.csproj\", \"{45989E3A-AFC8-46B2-A4B7-E38D22E8D93A}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Kite.Gateway.Web\", \"src\\Kite.Gateway.Web\\Kite.Gateway.Web.csproj\", \"{BA1CBE4F-E321-453F-94D7-F6CE7117851D}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{22772D7B-C655-491D-8CED-3DD6961D59F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{22772D7B-C655-491D-8CED-3DD6961D59F8}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{22772D7B-C655-491D-8CED-3DD6961D59F8}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{22772D7B-C655-491D-8CED-3DD6961D59F8}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{FCECED16-7C02-47CC-A325-5D710C9C57D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{FCECED16-7C02-47CC-A325-5D710C9C57D7}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{FCECED16-7C02-47CC-A325-5D710C9C57D7}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{FCECED16-7C02-47CC-A325-5D710C9C57D7}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{28CE009E-4E3D-4F06-9811-9A083637A5DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{28CE009E-4E3D-4F06-9811-9A083637A5DC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{28CE009E-4E3D-4F06-9811-9A083637A5DC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{28CE009E-4E3D-4F06-9811-9A083637A5DC}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C8BF159F-19BC-4E05-BA6C-BD3BB1D4A397}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C8BF159F-19BC-4E05-BA6C-BD3BB1D4A397}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C8BF159F-19BC-4E05-BA6C-BD3BB1D4A397}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C8BF159F-19BC-4E05-BA6C-BD3BB1D4A397}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{E50AB14E-6DB5-4DE3-95EA-BECF1ED6AB75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{E50AB14E-6DB5-4DE3-95EA-BECF1ED6AB75}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{E50AB14E-6DB5-4DE3-95EA-BECF1ED6AB75}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{E50AB14E-6DB5-4DE3-95EA-BECF1ED6AB75}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{45989E3A-AFC8-46B2-A4B7-E38D22E8D93A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{45989E3A-AFC8-46B2-A4B7-E38D22E8D93A}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{45989E3A-AFC8-46B2-A4B7-E38D22E8D93A}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{45989E3A-AFC8-46B2-A4B7-E38D22E8D93A}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{BA1CBE4F-E321-453F-94D7-F6CE7117851D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{BA1CBE4F-E321-453F-94D7-F6CE7117851D}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{BA1CBE4F-E321-453F-94D7-F6CE7117851D}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{BA1CBE4F-E321-453F-94D7-F6CE7117851D}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(NestedProjects) = preSolution\n\t\t{22772D7B-C655-491D-8CED-3DD6961D59F8} = {CD55B1DC-925D-4B8D-8B43-47AE9A9661BD}\n\t\t{FCECED16-7C02-47CC-A325-5D710C9C57D7} = {CD55B1DC-925D-4B8D-8B43-47AE9A9661BD}\n\t\t{28CE009E-4E3D-4F06-9811-9A083637A5DC} = {CD55B1DC-925D-4B8D-8B43-47AE9A9661BD}\n\t\t{C8BF159F-19BC-4E05-BA6C-BD3BB1D4A397} = {CD55B1DC-925D-4B8D-8B43-47AE9A9661BD}\n\t\t{E50AB14E-6DB5-4DE3-95EA-BECF1ED6AB75} = {CD55B1DC-925D-4B8D-8B43-47AE9A9661BD}\n\t\t{45989E3A-AFC8-46B2-A4B7-E38D22E8D93A} = {5DCEB584-F097-4769-8172-4FFBA9E1898D}\n\t\t{BA1CBE4F-E321-453F-94D7-F6CE7117851D} = {CD55B1DC-925D-4B8D-8B43-47AE9A9661BD}\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {43E3871F-1034-4291-B5C2-FA50167CC09D}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "README.en.md",
    "content": "# 基于Yarp的API网关\n\n#### Description\n基于Yarp的API网关\n\n#### Software Architecture\nSoftware architecture description\n\n#### Installation\n\n1.  xxxx\n2.  xxxx\n3.  xxxx\n\n#### Instructions\n\n1.  xxxx\n2.  xxxx\n3.  xxxx\n\n#### Contribution\n\n1.  Fork the repository\n2.  Create Feat_xxx branch\n3.  Commit your code\n4.  Create Pull Request\n\n\n#### Gitee Feature\n\n1.  You can use Readme\\_XXX.md to support different languages, such as Readme\\_en.md, Readme\\_zh.md\n2.  Gitee blog [blog.gitee.com](https://blog.gitee.com)\n3.  Explore open source project [https://gitee.com/explore](https://gitee.com/explore)\n4.  The most valuable open source project [GVP](https://gitee.com/gvp)\n5.  The manual of Gitee [https://gitee.com/help](https://gitee.com/help)\n6.  The most popular members  [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)\n"
  },
  {
    "path": "README.md",
    "content": "# Kite Api网关\n\n#### 介绍\n基于微软反向代理组件Yarp开发的Api网关\n\n\n#### 软件架构\n\n开发框架 .Net 7 + Abp Vnext 7.0.1 + Blazor(UI框架:BootstrapBlazor)\n\nadmin 目录为网关管理后台\nsimples 目录为服务案例\nsrc 目录为项目源代码目录\n\n\n#### 使用说明\nSupervision\n#### 参与贡献\n\n1.  Fork 本仓库\n2.  新建 dev_xxx 分支\n3.  提交代码\n4.  新建 Pull Request\n\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/.config/dotnet-tools.json",
    "content": "{\n  \"version\": 1,\n  \"isRoot\": true,\n  \"tools\": {\n    \"dotnet-ef\": {\n      \"version\": \"6.0.8\",\n      \"commands\": [\n        \"dotnet-ef\"\n      ]\n    }\n  }\n}"
  },
  {
    "path": "admin/Kite.Gateway.Admin/App.razor",
    "content": "﻿<BootstrapBlazorRoot>\n    <Router AppAssembly=\"@typeof(App).Assembly\">\n        <Found Context=\"routeData\">\n            <PageTitle>Kite Gateway System Manager</PageTitle>\n            <RouteView RouteData=\"@routeData\" DefaultLayout=\"@typeof(MainLayout)\" />\n            <FocusOnNavigate RouteData=\"@routeData\" Selector=\"h1\" />\n        </Found>\n        <NotFound>\n            <PageTitle>Not found</PageTitle>\n            <LayoutView Layout=\"@typeof(MainLayout)\">\n                <p>正在玩命开发中 ...</p>\n            </LayoutView>\n        </NotFound>\n    </Router>\n</BootstrapBlazorRoot>"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Controllers/RefreshController.cs",
    "content": "﻿using Kite.Gateway.Application;\nusing Kite.Gateway.Application.Contracts;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing System.Linq;\nusing Kite.Gateway.Application.Contracts.Dtos;\nusing Kite.Gateway.Application.Contracts.Dtos.Node;\n\nnamespace Kite.Gateway.Admin.Controllers\n{\n    [Route(\"api/[controller]\")]\n    [ApiController]\n    public class RefreshController : ControllerBase\n    {\n        private readonly IConfigureAppService _configureAppService;\n        public RefreshController(IConfigureAppService configureAppService)\n        {\n            _configureAppService = configureAppService;\n        }\n        [HttpGet(\"/api/kite/refresh/configure\")]\n        public async Task<KiteResult<RefreshConfigureDto>> GetConfigureAsync()\n        {\n            var result= await _configureAppService.GetConfigureAsync(new ReloadConfigureDto() \n            {\n                IsReloadAuthentication = true,\n                IsReloadMiddleware = true,\n                IsReloadWhitelist = true,\n                IsReloadYarp = true,\n            });\n            return result;\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Core/AuthorizationServerStorage.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos.Administrator;\nusing Microsoft.AspNetCore.Components;\nusing Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;\nusing System;\nusing System.Linq;\nusing Microsoft.Extensions.Caching.Memory;\nnamespace Kite.Gateway.Admin.Core\n{\n    public class AuthorizationServerStorage\n    {\n        private readonly IMemoryCache _memoryCache;\n        public AuthorizationServerStorage(IMemoryCache memoryCache)\n        {\n            _memoryCache = memoryCache;\n        }\n        /// <summary>\n        /// 判断是否已经登录\n        /// </summary>\n        /// <returns></returns>\n        public bool IsLogin()\n        {\n            if (_memoryCache.TryGetValue(\"administrator\", out AdministratorDto administrator))\n            {\n                return true;\n            }\n            else\n            {\n                return false;\n            }\n        }\n        /// <summary>\n        /// 删除登录会话信息\n        /// </summary>\n        /// <returns></returns>\n        public void DeleteServerStorage()\n        {\n            if (_memoryCache.TryGetValue(\"administrator\", out AdministratorDto administrator))\n            {\n                _memoryCache.Remove(\"administrator\");\n            }\n        }\n        /// <summary>\n        /// 设置登录会话信息\n        /// </summary>\n        /// <param name=\"value\"></param>\n        /// <returns></returns>\n        public void SetServerStorage(AdministratorDto value)\n        {\n            if (_memoryCache.TryGetValue(\"administrator\", out AdministratorDto administrator))\n            {\n                _memoryCache.Remove(\"administrator\");\n            }\n            _memoryCache.Set(\"administrator\", value, DateTimeOffset.Now.AddMinutes(120));\n        }\n        /// <summary>\n        /// 获取登录会话\n        /// </summary>\n        /// <returns></returns>\n        public AdministratorDto GetServerStorage()\n        {\n            if (_memoryCache.TryGetValue(\"administrator\", out AdministratorDto administrator))\n            {\n                return administrator;\n            }\n            else\n            {\n                return new AdministratorDto();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Dockerfile",
    "content": "#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.\n\nFROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base\nWORKDIR /app\nEXPOSE 80\n\nFROM mcr.microsoft.com/dotnet/sdk:6.0 AS build\nWORKDIR /src\nCOPY [\"admin/Kite.Gateway.Admin/Kite.Gateway.Admin.csproj\", \"admin/Kite.Gateway.Admin/\"]\nCOPY [\"src/Kite.Gateway.EntityFrameworkCore/Kite.Gateway.EntityFrameworkCore.csproj\", \"src/Kite.Gateway.EntityFrameworkCore/\"]\nCOPY [\"src/Kite.Gateway.Domain/Kite.Gateway.Domain.csproj\", \"src/Kite.Gateway.Domain/\"]\nCOPY [\"src/Kite.Gateway.Domain.Shared/Kite.Gateway.Domain.Shared.csproj\", \"src/Kite.Gateway.Domain.Shared/\"]\nCOPY [\"src/Kite.Gateway.Application/Kite.Gateway.Application.csproj\", \"src/Kite.Gateway.Application/\"]\nCOPY [\"src/Kite.Gateway.Application.Contracts/Kite.Gateway.Application.Contracts.csproj\", \"src/Kite.Gateway.Application.Contracts/\"]\nRUN dotnet restore \"admin/Kite.Gateway.Admin/Kite.Gateway.Admin.csproj\"\nCOPY . .\nWORKDIR \"/src/admin/Kite.Gateway.Admin\"\nRUN dotnet build \"Kite.Gateway.Admin.csproj\" -c Release -o /app/build\n\nFROM build AS publish\nRUN dotnet publish \"Kite.Gateway.Admin.csproj\" -c Release -o /app/publish\n\nFROM base AS final\nWORKDIR /app\nCOPY --from=publish /app/publish .\nENTRYPOINT [\"dotnet\", \"Kite.Gateway.Admin.dll\"]"
  },
  {
    "path": "admin/Kite.Gateway.Admin/GatewayAdminModule.cs",
    "content": "﻿using Microsoft.AspNetCore.Builder;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing Kite.Gateway.Application;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Volo.Abp;\nusing Volo.Abp.Autofac;\nusing Volo.Abp.Modularity;\nusing Microsoft.AspNetCore.Http;\nusing System.Security.Cryptography.X509Certificates;\nusing System.Text;\nusing Microsoft.AspNetCore.Mvc;\nusing Newtonsoft.Json;\nusing Volo.Abp.Json;\nusing Kite.Gateway.Admin.Core;\nusing Volo.Abp.AspNetCore;\nusing Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.EntityFrameworkCore;\nusing BootstrapBlazor.Components;\nusing Microsoft.Extensions.Options;\n\nnamespace Kite.Gateway.Admin\n{\n    [DependsOn(\n        typeof(AbpAspNetCoreModule),\n         typeof(AbpAutofacModule),\n         typeof(ApplicationModule),\n         typeof(EntityFrameworkCoreModule)\n     )]\n    public class GatewayAdminModule:AbpModule\n    {\n        #region 中间件注入\n        public override void ConfigureServices(ServiceConfigurationContext context)\n        {\n            context.Services.AddMemoryCache();\n            context.Services.AddHttpClient();\n            ConfigureBlazor(context);\n            ConfigureMvc(context);\n        }\n        private void ConfigureMvc(ServiceConfigurationContext context)\n        {\n            context.Services.AddControllers();\n        }\n        /// <summary>\n        /// Blazor\n        /// </summary>\n        /// <param name=\"context\"></param>\n        private void ConfigureBlazor(ServiceConfigurationContext context)\n        {\n            context.Services.AddRazorPages();\n            context.Services.AddServerSideBlazor();\n            context.Services.AddBootstrapBlazor(options =>\n            {\n                // 统一设置 Toast 组件自动消失时间\n                options.ToastDelay = 4000;\n                options.ToastPlacement = Placement.TopEnd;\n                options.SupportedCultures = new List<string> { \"zh\" };\n\n                options.FallbackCulture = \"zh\";\n                options.DefaultCultureInfo = \"zh\";\n            });\n            // 增加多语言支持配置信息\n            context.Services.AddRequestLocalization<IOptionsMonitor<BootstrapBlazorOptions>>((localizerOption, blazorOption) =>\n            {\n                blazorOption.OnChange(op => Invoke(op));\n                Invoke(blazorOption.CurrentValue);\n\n                void Invoke(BootstrapBlazorOptions option)\n                {\n                    var supportedCultures = option.GetSupportedCultures();\n                    localizerOption.SupportedCultures = supportedCultures;\n                    localizerOption.SupportedUICultures = supportedCultures;\n                }\n            });\n        }\n        \n        #endregion\n        public override void OnApplicationInitialization(ApplicationInitializationContext context)\n        {\n            var app = context.GetApplicationBuilder();\n            var env = context.GetEnvironment();\n\n            var option = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>();\n            if (option != null)\n            {\n                app.UseRequestLocalization(option.Value);\n            }\n            app.UseStaticFiles();\n            app.UseRouting();\n\n            app.UseExceptionHandler(\"/Error\");\n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapControllers();\n                endpoints.MapBlazorHub();\n                endpoints.MapFallbackToPage(\"/_Host\");\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Kite.Gateway.Admin.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>net7.0</TargetFramework>\n    <Nullable>enable</Nullable>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>\n    <DockerfileContext>..\\..</DockerfileContext>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <NoWarn>1701;1702;8601;8602;8618;8625;</NoWarn>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\n    <NoWarn>1701;1702;8601;8602;8618;8625;</NoWarn>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Remove=\"Models\\**\" />\n    <Content Remove=\"Models\\**\" />\n    <EmbeddedResource Remove=\"Models\\**\" />\n    <None Remove=\"Models\\**\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"BootstrapBlazor\" Version=\"7.2.4\" />\n    <PackageReference Include=\"BootstrapBlazor.FontAwesome\" Version=\"7.0.2\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Design\" Version=\"7.0.2\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Tools\" Version=\"7.0.2\">\n      <PrivateAssets>all</PrivateAssets>\n      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n    </PackageReference>\n    <PackageReference Include=\"Volo.Abp.AspNetCore\" Version=\"7.0.1\" />\n    <PackageReference Include=\"Volo.Abp.Autofac\" Version=\"7.0.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\src\\Kite.Gateway.Application\\Kite.Gateway.Application.csproj\" />\n    <ProjectReference Include=\"..\\..\\src\\Kite.Gateway.EntityFrameworkCore\\Kite.Gateway.EntityFrameworkCore.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Folder Include=\"wwwroot\\upload\\\" />\n    <Folder Include=\"data\\\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Administrator/Administrator.razor",
    "content": "﻿@page \"/Administrator\"\n\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Administrator\n@using Mapster\n@using Kite.Gateway.Domain.Shared.Enums\n@inject ToastService ToastService\n@inject IAdministratorAppService AdministratorAppService\n\n<div class=\"row\">\n    <div class=\"col=12\">\n        <Button OnClick=\"@OnAddAsync\" Color=\"Color.Primary\">添加管理员</Button>\n    </div>\n</div>\n<div class=\"row\" style=\"margin-top:10px;\">\n    <table class=\"table\">\n      <thead class=\"table-light\">\n        <tr>\n            <th>管理员名</th>\n            <th>昵称</th>\n            <th>创建时间</th>\n            <th>更新时间</th>\n            <th>操作</th>\n        </tr>\n      </thead>\n      <tbody>\n          @if(Administrators!=null&&Administrators.Any())\n          {\n              foreach(var item in Administrators)\n              {\n                <tr>\n                    <td>@item.AdminName</td>\n                    <td>@item.NickName</td>\n                    <td>@item.Created</td>\n                    <td>@item.Updated</td>\n                    <td>\n                        <div class=\"btn-group\" role=\"group\">\n                            <Button Color=\"Color.Info\" Size=\"Size.ExtraSmall\" OnClick=\"@(e=>OnUpdateAsync(item.Id))\">编辑</Button>\n                            <PopConfirmButton  Size=\"Size.ExtraSmall\" Placement=\"Placement.Bottom\" Color=\"Color.Danger\" ConfirmIcon=\"fa fa-exclamation-triangle text-danger\"\n                  ConfirmButtonColor=\"Color.Danger\" Text=\"删除\" Content=\"确定删除数据吗？\" Icon=\"fa fa-fa fa-fw\" IsAsync=\"true\"\n                  OnConfirm=\"@(()=>OnDeleteAsync(item.Id))\" />\n                        </div>\n                    </td>\n                </tr>\n              }\n            }\n        </tbody>\n    </table>\n    \n</div>\n<div class=\"row col-12\"  style=\"margin-top:15px;\">\n    <Pagination PageItems=\"@PageSize\" PageItemsSource=\"@(new int[] { 10,20 })\" TotalCount=\"@TotalCount\" OnPageClick=\"@OnPageClick\" OnPageItemsChanged=\"@OnPageItemsChanged\"></Pagination>\n</div>\n\n<Modal @ref=\"Modal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"添加管理员\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n          <NewAdministrator OnClickCallback=\"OnAddCallbackAsync\"></NewAdministrator>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n<Modal @ref=\"UpdateModal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"管理员编辑\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n           <UpdateAdministrator Model=\"@UpdateModel\" OnClickCallback=\"OnUpdateCallbackAsync\"></UpdateAdministrator>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n@code {\n    private Modal Modal;\n\n    private Modal UpdateModal;\n\n    public UpdateAdministratorDto UpdateModel { get; set; }\n    //分页数据\n\n    private List<AdministratorDto>? Administrators { get; set; }\n\n    private int TotalCount { get; set; } = 0;\n    private int PageSize { get; set; } = 10;\n    private int PageIndex { get; set; } = 1;\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        OnQueryAsync();\n        base.OnInitialized();\n    }\n    #region 管理员编辑更新\n    private async void OnUpdateAsync(Guid id)\n    {\n        UpdateModel= await GetAsync(id);\n        await UpdateModal.Toggle();\n    }\n    private async Task<UpdateAdministratorDto> GetAsync(Guid id)\n    {\n        var result = await AdministratorAppService.GetAsync(id);\n        if (result.Code != 0 || result.Data == null)\n        {\n            await ToastService.Warning(\"系统警告\", \"数据不存在\");\n        }\n        var model= TypeAdapter.Adapt<UpdateAdministratorDto>(result.Data);\n        return model;\n    }\n    private async void OnUpdateCallbackAsync()\n    {\n        await UpdateModal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    #region 新增管理员\n    private async void OnAddAsync()\n    {\n        await Modal.Toggle();\n    }\n    private async void OnAddCallbackAsync()\n    {\n        await Modal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    private async Task OnDeleteAsync(Guid id)\n    {\n        var result= await AdministratorAppService.DeleteAsync(id);\n        if (result.Code == 0)\n        {\n            OnQueryAsync();\n            await ToastService.Success(\"系统通知\",\"数据删除成功!\");\n            return;\n        }\n        await ToastService.Warning(\"系统警告\",\"数据删除失败\");\n    }\n\n    private Task OnPageClick(int pageIndex, int pageItems)\n    {\n        PageIndex = pageIndex;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n    private Task OnPageItemsChanged(int pageItems)\n    {\n        PageIndex=1;\n        PageSize = pageItems;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n\n    private async void OnQueryAsync()\n    {\n        var result = await AdministratorAppService.GetListAsync(PageIndex, PageSize);\n\n        if (result.Code == 0)\n        {\n            Administrators = result.Data;\n            TotalCount = result.Count;\n            StateHasChanged();\n        }\n        else\n        {\n            await ToastService.Warning(\"系统警告\", \"数据加载失败\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Administrator/Login.razor",
    "content": "﻿@page \"/Login\"\n@layout SimpleLayout\n\n@using Kite.Gateway.Admin.Core\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Administrator\n@using Mapster\n@using Kite.Gateway.Domain.Shared.Enums\n@inject ToastService ToastService\n@inject NavigationManager NavigationManager\n@inject IAdministratorAppService AdministratorAppService\n@inject AuthorizationServerStorage AuthorizationServerStorage\n\n\n<main class=\"form-signin text-center\">\n  <ValidateForm Model=\"@LoginAdministrator\"  OnValidSubmit=\"@OnLoginAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n    <img class=\"mb-4\" src=\"/images/kitelogo.png\" alt=\"\" width=\"72\" height=\"57\">\n    <h1 class=\"h3 mb-3 fw-normal\">Kite Gateway</h1>\n\n    <div class=\"form-floating\">\n      <input type=\"text\" class=\"form-control\" @bind-value=\"LoginAdministrator.AdminName\" id=\"floatingInput\" placeholder=\"请输入管理员账号名\">\n            <label for=\"floatingInput\" style=\"text-align:left;\">账号名:<em style=\"color:red\">*</em></label>\n    </div>\n    <div class=\"form-floating\">\n      <input type=\"password\" class=\"form-control\" @bind-value=\"LoginAdministrator.Password\" id=\"floatingPassword\" placeholder=\"请输入管理员密码\">\n      <label for=\"floatingPassword\" style=\"text-align:left;\">登录密码:<em style=\"color:red\">*</em></label>\n    </div>\n    <Button ButtonType=\"ButtonType.Submit\"  class=\"w-100 btn btn-lg btn-primary\" IsAsync=\"true\" Color=\"Color.Primary\">登 录</Button>\n@*    <button class=\"w-100 btn btn-lg btn-primary\" type=\"submit\">登录</button>*@\n  </ValidateForm>\n</main>\n\n@code {\n    //表单数据\n    private LoginAdministratorDto LoginAdministrator { get; set; }= new LoginAdministratorDto();\n    private EditContext? editContext;\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        editContext = new(LoginAdministrator);\n        base.OnInitialized();\n    }\n    private Task OnInvalidSubmitAsync(EditContext editContext)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnLoginAsync(EditContext editContext)\n    {\n        try\n        {\n            if (string.IsNullOrEmpty(LoginAdministrator.AdminName) || LoginAdministrator.AdminName.Trim() == \"\")\n            {\n                await ToastService.Warning(\"系统警告\",\"管理员账号名不能为空\");\n                return;\n            }\n            if (string.IsNullOrEmpty(LoginAdministrator.Password) || LoginAdministrator.Password.Trim() == \"\")\n            {\n                await ToastService.Warning(\"系统警告\",\"管理员密码不能为空\");\n                return;\n            }\n            var result = await AdministratorAppService.LoginAsync(LoginAdministrator);\n            if (result.Code != 0)\n            {\n                await ToastService.Warning(\"系统警告\",result.Message);\n            }\n            else\n            {\n                AuthorizationServerStorage.SetServerStorage(result.Data);\n                NavigationManager.NavigateTo(\"/\");\n            }\n            await Task.CompletedTask;    \n        }\n        catch (Exception ex)\n        {\n            await ToastService.Warning(\"系统警告\", ex.Message);\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Administrator/Login.razor.css",
    "content": "﻿html,\nbody {\n    height: 100%;\n}\n\nbody {\n    display: flex;\n    align-items: center;\n    padding-top: 40px;\n    padding-bottom: 40px;\n    background-color: #f5f5f5;\n}\n\n.form-signin {\n    width: 100%;\n    max-width: 330px;\n    padding: 15px;\n    margin: auto;\n    margin-top:260px;\n}\n\n    .form-signin .checkbox {\n        font-weight: 400;\n    }\n\n    .form-signin .form-floating:focus-within {\n        z-index: 2;\n    }\n\n    .form-signin input[type=\"email\"] {\n        margin-bottom: -1px;\n        border-bottom-right-radius: 0;\n        border-bottom-left-radius: 0;\n    }\n\n    .form-signin input[type=\"password\"] {\n        margin-bottom: 10px;\n        border-top-left-radius: 0;\n        border-top-right-radius: 0;\n    }\n\n.bd-placeholder-img {\n    font-size: 1.125rem;\n    text-anchor: middle;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    user-select: none;\n}\n\n@media (min-width: 768px) {\n    .bd-placeholder-img-lg {\n        font-size: 3.5rem;\n    }\n}"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Administrator/Logout.razor",
    "content": "﻿@page \"/Logout\"\n@using System\n@layout SimpleLayout\n@using Kite.Gateway.Admin.Core\n@using Mapster\n@using Kite.Gateway.Domain.Shared.Enums\n@inject ToastService ToastService\n@inject NavigationManager NavigationManager\n@inject AuthorizationServerStorage AuthorizationServerStorage\n\n\n<main class=\"form-signin text-center\">\n  <form>\n    <img class=\"mb-4\" src=\"/images/kitelogo.png\" alt=\"\" width=\"72\" height=\"57\">\n    <h1 class=\"h3 mb-3 fw-normal\">正在退出登录...</h1>\n    <Spinner Color=\"Color.Primary\"></Spinner>\n  </form>\n</main>\n\n@code {\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n        //如果没有登录则跳转到登录页面\n        if (!AuthorizationServerStorage.IsLogin())\n        {\n            NavigationManager.NavigateTo(\"/Login\");\n        }\n        else\n        {\n            //清理服务器登录存储信息\n            AuthorizationServerStorage.DeleteServerStorage();\n            //跳转到登录页面\n            NavigationManager.NavigateTo(\"/Login\");\n           \n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Administrator/Logout.razor.css",
    "content": "﻿html,\nbody {\n    height: 100%;\n}\n\nbody {\n    display: flex;\n    align-items: center;\n    padding-top: 40px;\n    padding-bottom: 40px;\n    background-color: #f5f5f5;\n}\n\n.form-signin {\n    width: 100%;\n    max-width: 330px;\n    padding: 15px;\n    margin: auto;\n    margin-top: 260px;\n}\n\n    .form-signin .checkbox {\n        font-weight: 400;\n    }\n\n    .form-signin .form-floating:focus-within {\n        z-index: 2;\n    }\n\n    .form-signin input[type=\"email\"] {\n        margin-bottom: -1px;\n        border-bottom-right-radius: 0;\n        border-bottom-left-radius: 0;\n    }\n\n    .form-signin input[type=\"password\"] {\n        margin-bottom: 10px;\n        border-top-left-radius: 0;\n        border-top-right-radius: 0;\n    }\n\n.bd-placeholder-img {\n    font-size: 1.125rem;\n    text-anchor: middle;\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    user-select: none;\n}\n\n@media (min-width: 768px) {\n    .bd-placeholder-img-lg {\n        font-size: 3.5rem;\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Administrator/NewAdministrator.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Administrator\n@inject ToastService ToastService\n@inject IAdministratorAppService AdministratorAppService\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                   <BootstrapInput @bind-Value=\"Model.AdminName\" DisplayText=\"管理员账号名\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.Password\" DisplayText=\"登录密码\" type=\"password\" IsTrim=\"true\" />\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                 <BootstrapInput @bind-Value=\"Model.NickName\" DisplayText=\"昵称\" IsTrim=\"true\" />\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n    </ValidateForm>\n</div>\n\n\n@code {\n    \n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    private CreateAdministratorDto Model { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n        Model = new CreateAdministratorDto();\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await AdministratorAppService.CreateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n            Model = new CreateAdministratorDto();\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Administrator/UpdateAdministrator.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Administrator\n@inject ToastService ToastService\n@inject IAdministratorAppService AdministratorAppService\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                   <BootstrapInput @bind-Value=\"Model.AdminName\" DisplayText=\"管理员账号名\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.Password\" DisplayText=\"登录密码(不修改则留空)\" type=\"password\" IsTrim=\"true\" />\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                 <BootstrapInput @bind-Value=\"Model.NickName\" DisplayText=\"昵称\" IsTrim=\"true\" />\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n     </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    [Parameter]\n    public UpdateAdministratorDto Model { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await AdministratorAppService.UpdateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Authorization/Authentication.razor",
    "content": "﻿@page \"/Authentication\"\n@using System.IO;\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Authorization\n@inject ToastService ToastService\n@inject IAuthorizationAppService AuthorizationAppService\n@inject IWebHostEnvironment WebHostEnvironment;\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-5\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.UseState\" DisplayText=\"状态\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-5\">\n                   <BootstrapInput @bind-Value=\"Model.Issuer\" DisplayText=\"颁发者\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-5\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.Audience\" DisplayText=\"观察者\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-5\"  style=\"margin-top:5px;\" >\n                 \n                 <BootstrapInputNumber @bind-Value=\"Model.ClockSkew\" DisplayText=\"时间偏移(秒)\" IsTrim=\"true\" />\n             </div>\n            <div class=\"col-5\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.ValidateIssuerSigningKey\" DisplayText=\"是否验证签名\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-5\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.ValidateIssuer\" DisplayText=\"是否验证颁发者\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-5\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.ValidateAudience\" DisplayText=\"是否验证观察者\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-5\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.ValidateLifetime\" DisplayText=\"是否验证失效时间\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-5\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.RequireExpirationTime\" DisplayText=\"是否需要过期时间\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            \n             <div class=\"col-5\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.UseSSL\" OnValueChanged=\"@OnUseSSLSwitch\" DisplayText=\"是否启用SSL证书\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-5\" style=\"margin-top:5px;\">\n                  <InputUpload Accept=\"\" @bind-Value=\"@Model.CertificateFileName\"  OnChange=\"@OnFileChange\" DisplayText=\"证书文件(.pfx Or .cer)\" />  \n             </div>\n             \n            <div class=\"col-5\" style=\"margin-top:5px;\">\n                 <BootstrapInput @bind-Value=\"Model.CertificatePassword\" DisplayText=\"证书密码\" IsDisabled=\"@(IsDisabledUseSSL)\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-5\" style=\"margin-top:5px;\">\n                   <BootstrapInput @bind-Value=\"Model.SecurityKeyStr\" DisplayText=\"自定义秘钥\" IsDisabled=\"@IsDisabledSecurityKey\" IsTrim=\"true\" />\n             </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-5\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    private SaveAuthenticationDto Model { get; set; }\n\n    private bool IsDisabledUseSSL { get; set; }\n    private bool IsDisabledSecurityKey { get; set; }\n\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override async void OnInitialized()\n    {\n        base.OnInitialized();\n        var result = await AuthorizationAppService.GetAuthenticationAsync();\n        if (result.Code == 0)\n        {\n            Model = result.Data;\n            IsDisabledUseSSL = Model.UseSSL ? false : true;\n            IsDisabledSecurityKey = Model.UseSSL;\n        }\n    }\n    private Task OnUseSSLSwitch(bool val)\n    {\n        IsDisabledSecurityKey = val;\n        IsDisabledUseSSL = val ? false : true;\n        return Task.FromResult(true);\n    }\n    private async Task OnFileChange(UploadFile file)\n    {\n        if (file.File != null)\n        {\n            //保存证书文件\n            var filePath = Path.Combine(WebHostEnvironment.WebRootPath, $\"upload/{file.File.Name}\");\n            await file.SaveToFile(filePath);\n            //读取文件并且转换为BASE64字符串存储\n            using var fs = new FileStream(filePath, FileMode.Open);\n            fs.Seek(0, SeekOrigin.Begin);\n            var buffer = new byte[fs.Length];\n            fs.Read(buffer, 0, buffer.Length);\n            Model.CertificateFileName = file.File.Name;\n            Model.CertificateFile = Convert.ToBase64String(buffer);\n        }\n        else\n        {\n            Model.CertificateFileName = \"\";\n            Model.CertificateFile = \"\";\n        }\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await AuthorizationAppService.SaveAuthenticationAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Error.cshtml",
    "content": "﻿@page\n@model Kite.Gateway.Admin.Pages.ErrorModel\n\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\" />\n    <title>Error</title>\n    <link href=\"~/css/bootstrap/bootstrap.min.css\" rel=\"stylesheet\" />\n    <link href=\"~/css/site.css\" rel=\"stylesheet\" asp-append-version=\"true\" />\n</head>\n\n<body>\n    <div class=\"main\">\n        <div class=\"content px-4\">\n            <h1 class=\"text-danger\">Error.</h1>\n            <h2 class=\"text-danger\">An error occurred while processing your request.</h2>\n\n            @if (Model.ShowRequestId)\n            {\n                <p>\n                    <strong>Request ID:</strong> <code>@Model.RequestId</code>\n                </p>\n            }\n\n            <h3>Development Mode</h3>\n            <p>\n                Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.\n            </p>\n            <p>\n                <strong>The Development environment shouldn't be enabled for deployed applications.</strong>\n                It can result in displaying sensitive information from exceptions to end users.\n                For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>\n                and restarting the app.\n            </p>\n        </div>\n    </div>\n</body>\n\n</html>\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Error.cshtml.cs",
    "content": "﻿using Microsoft.AspNetCore.Mvc;\nusing Microsoft.AspNetCore.Mvc.RazorPages;\nusing System.Diagnostics;\n\nnamespace Kite.Gateway.Admin.Pages\n{\n    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]\n    [IgnoreAntiforgeryToken]\n    public class ErrorModel : PageModel\n    {\n        public string? RequestId { get; set; }\n\n        public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);\n\n        private readonly ILogger<ErrorModel> _logger;\n\n        public ErrorModel(ILogger<ErrorModel> logger)\n        {\n            _logger = logger;\n        }\n\n        public void OnGet()\n        {\n            RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;\n        }\n    }\n}"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Home.razor",
    "content": "﻿@page \"/\"\n\n<div role=\"alert\" class=\"alert fade show alert-info is-bar\">\n    <div class=\"alert-content\">\n        <h4><i class=\"fa fa-lightbulb-o\"></i>有言</h4><!--!-->\n        <p>\n            .Net版本: .Net 7  <br/>\n            数据库:   Sqlite <br/>\n            后台管理: Blazor (<a href=\"https://www.blazor.zone\">Bootstrap Blazor UI</a>)  <br/>\n            开发框架: Abp Vnext 7.X <br/>\n            反向代理组件: Yarp 2.X\n        </p>\n        <p>\n            开源地址:<a href=\"https://github.com/yupingyong/kite.gateway\">https://github.com/yupingyong/kite.gateway</a>\n        </p>\n        <p>\n            怕什么真理无穷，进一寸有一寸的欢喜--胡适\n        </p>\n    </div>\n</div>\n\n<Timeline Items=\"AlternateTimelineItems\" />\n\n@code {\n    private List<TimelineItem> AlternateTimelineItems { get; set; }\n\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n        AlternateTimelineItems = new List<TimelineItem>()\n        {\n            new TimelineItem()\n            {\n                Description=\"2022-09-21\",\n                Content=\"升级到.NET 7\"\n            }\n            ,\n            new TimelineItem()\n            {\n                Description=\"2022-07-28\",\n                Content=\"第一个小迭代版本(数据库更换成Sqlite、调整配置数据热更新功能)\"\n            }\n            ,\n            new TimelineItem()\n            {\n                Description=\"2022-07-21\",\n                Content=\"完成第一个版本的更替,并且分享源代码到github上\"\n            }\n        };\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Middleware/Middleware.razor",
    "content": "﻿@page \"/Middleware\"\n\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Middleware\n@using Mapster\n@using Kite.Gateway.Domain.Shared.Enums\n@inject ToastService ToastService\n@inject IMiddlewareAppService MiddlewareAppService\n\n<div class=\"row\">\n    <div class=\"col-4\">\n        <BootstrapInputGroup>\n            <BootstrapInput @bind-Value=\"@SearchKw\" PlaceHolder=\"中间件名称/服务端地址\" />\n            <Button Icon=\"fa fa-search\" IsAsync=\"true\" @onclick=\"OnSearchAsync\"></Button>\n        </BootstrapInputGroup>\n    </div>\n    <div class=\"col-2\">\n          <Button OnClick=\"@OnAddAsync\" Color=\"Color.Primary\">添加中间件</Button>\n    </div>\n</div>\n<div class=\"row\" style=\"margin-top:10px;\">\n    <table class=\"table\">\n      <thead class=\"table-light\">\n        <tr>\n            <th>中间件名称</th>\n            <th>服务端</th>\n            <th>通信类型</th>\n            <th>执行权重</th>\n            <th>状态</th>\n            <th>描述</th>\n            <th>创建时间</th>\n            <th>更新时间</th>\n            <th>操作</th>\n        </tr>\n      </thead>\n      <tbody>\n          @if(Middlewares!=null&&Middlewares.Any())\n          {\n              foreach(var item in Middlewares)\n              {\n                <tr>\n                    <td>@item.Name</td>\n                    <td>@item.Server</td>\n                    <td>\n                        @switch(item.SignalType)\n                        {\n                            case SignalTypeEnum.Http:\n                                <div>http</div>\n                            break;\n                            default:\n                                <div>grpc</div>\n                            break;\n                        }\n                    </td>\n                    <td>@item.ExecWeight</td>\n                    <td>\n                        <Switch OnValueChanged=\"@(async (val)=>{ OnUpdateStateAsync(item.Id,val);await Task.CompletedTask; })\" OnColor=\"Color.Success\" @bind-Value=\"item.UseState\" ShowLabel=\"false\" style=\"max-height:18px;\"  ></Switch>\n                    </td>\n                    <td>@item.Description</td>\n                    <td>@item.Created</td>\n                    <td>@item.Updated</td>\n                    <td>\n                        <div class=\"btn-group\" role=\"group\">\n                            <Button Color=\"Color.Info\" Size=\"Size.ExtraSmall\" OnClick=\"@(e=>OnUpdateAsync(item.Id))\">编辑</Button>\n                            <PopConfirmButton  Size=\"Size.ExtraSmall\" Placement=\"Placement.Bottom\" Color=\"Color.Danger\" ConfirmIcon=\"fa fa-exclamation-triangle text-danger\"\n                  ConfirmButtonColor=\"Color.Danger\" Text=\"删除\" Content=\"确定删除数据吗？\" Icon=\"fa fa-fa fa-fw\" IsAsync=\"true\"\n                  OnConfirm=\"@(()=>OnDeleteAsync(item.Id))\" />\n                        </div>\n                    </td>\n                </tr>\n              }\n            }\n        </tbody>\n    </table>\n    \n</div>\n<div class=\"row col-12\"  style=\"margin-top:15px;\">\n    <Pagination PageItems=\"@PageSize\" PageItemsSource=\"@(new int[] { 10,20 })\" TotalCount=\"@TotalCount\" OnPageClick=\"@OnPageClick\" OnPageItemsChanged=\"@OnPageItemsChanged\"></Pagination>\n</div>\n<Modal @ref=\"Modal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"添加中间件\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n          <NewMiddleware OnClickCallback=\"OnAddCallbackAsync\"></NewMiddleware>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n<Modal @ref=\"UpdateModal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"中间件信息编辑\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n           <UpdateMiddleware Model=\"@UpdateModel\" OnClickCallback=\"OnUpdateCallbackAsync\"></UpdateMiddleware>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n@code {\n    private Modal Modal;\n\n    private Modal UpdateModal;\n\n    public UpdateMiddlewareDto UpdateModel { get; set; }\n    //分页数据\n\n    private List<MiddlewareListDto>? Middlewares { get; set; }\n\n    private int TotalCount { get; set; } = 0;\n    private int PageSize { get; set; } = 10;\n    private int PageIndex { get; set; } = 1;\n    private string SearchKw { get; set; } = \"\";\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        OnQueryAsync();\n        base.OnInitialized();\n    }\n    #region 中间件编辑更新\n    private async void OnUpdateStateAsync(Guid id,bool val)\n    {\n        var result = await MiddlewareAppService.UpdateUseStateAsync(id, val);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(\"系统警告\",result.Message);\n        }\n        else\n        {\n            await ToastService.Success(\"系统通知\",\"保存成功\");\n        }\n    }\n    private async void OnUpdateAsync(Guid id)\n    {\n        UpdateModel= await GetAsync(id);\n        await UpdateModal.Toggle();\n    }\n    private async Task<UpdateMiddlewareDto> GetAsync(Guid id)\n    {\n        var result = await MiddlewareAppService.GetAsync(id);\n        if (result.Code != 0 || result.Data == null)\n        {\n            await ToastService.Warning(\"系统警告\", \"数据不存在\");\n        }\n        var model= TypeAdapter.Adapt<UpdateMiddlewareDto>(result.Data);\n        return model;\n    }\n    private async void OnUpdateCallbackAsync()\n    {\n        await UpdateModal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    #region 新增中间件\n    private async void OnAddAsync()\n    {\n        await Modal.Toggle();\n    }\n    private async void OnAddCallbackAsync()\n    {\n        await Modal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    private async Task OnDeleteAsync(Guid id)\n    {\n        var result= await MiddlewareAppService.DeleteAsync(id);\n        if (result.Code == 0)\n        {\n            OnQueryAsync();\n            await ToastService.Success(\"系统通知\",\"数据删除成功!\");\n            return;\n        }\n        await ToastService.Warning(\"系统警告\",\"数据删除失败\");\n    }\n\n    private Task OnPageClick(int pageIndex, int pageItems)\n    {\n        PageIndex = pageIndex;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n    private Task OnPageItemsChanged(int pageItems)\n    {\n        PageIndex=1;\n        PageSize = pageItems;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n\n     private void OnSearchAsync()\n    {\n        PageIndex=1;\n        OnQueryAsync();\n    }\n    private async void OnQueryAsync()\n    {\n        var result = await MiddlewareAppService.GetListAsync(SearchKw, PageIndex, PageSize);\n\n        if (result.Code == 0)\n        {\n            Middlewares = result.Data;\n            TotalCount = result.Count;\n            StateHasChanged();\n        }\n        else\n        {\n            await ToastService.Warning(\"系统警告\", \"数据加载失败\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Middleware/NewMiddleware.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Middleware\n@inject ToastService ToastService\n@inject IMiddlewareAppService MiddlewareAppService\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                   <BootstrapInput @bind-Value=\"Model.Name\" DisplayText=\"中间件名称\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.Server\" DisplayText=\"服务端地址\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <Select @bind-Value=\"Model.SignalType\" DisplayText=\"通信类型\">\n                   </Select>\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInputNumber  @bind-Value=\"Model.ExecWeight\" DisplayText=\"执行权重\" IsTrim=\"true\" />\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.UseState\" DisplayText=\"状态\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                 <Textarea  @bind-Value=\"Model.Description\" DisplayText=\"描述\" IsTrim=\"true\"/>\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n    \n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    private CreateMiddlewareDto Model { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n        Model = new CreateMiddlewareDto()\n        {\n            UseState=true\n        };\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await MiddlewareAppService.CreateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n            Model = new CreateMiddlewareDto()\n            {\n                UseState=true\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Middleware/UpdateMiddleware.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Middleware\n@inject ToastService ToastService\n@inject IMiddlewareAppService MiddlewareAppService\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                   <BootstrapInput @bind-Value=\"Model.Name\" DisplayText=\"中间件名称\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.Server\" DisplayText=\"服务端地址\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <Select @bind-Value=\"Model.SignalType\" DisplayText=\"通信类型\">\n                   </Select>\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInputNumber  @bind-Value=\"Model.ExecWeight\" DisplayText=\"执行权重\" IsTrim=\"true\" />\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.UseState\" DisplayText=\"状态\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                 <Textarea  @bind-Value=\"Model.Description\" DisplayText=\"描述\" IsTrim=\"true\"/>\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    [Parameter]\n    public UpdateMiddlewareDto Model { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await MiddlewareAppService.UpdateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Node/NewNode.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Node\n@inject ToastService ToastService\n@inject INodeAppService NodeAppService\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                   <BootstrapInput @bind-Value=\"Model.NodeName\" DisplayText=\"节点名称\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.Server\" DisplayText=\"服务端地址(结尾勿带 / )\" IsTrim=\"true\" />\n             </div>\n              <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.AccessToken\" DisplayText=\"访问Token\" IsTrim=\"true\" />\n             </div>\n\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                 <Textarea  @bind-Value=\"Model.Description\" DisplayText=\"描述\" IsTrim=\"true\"/>\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n    \n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    private CreateNodeDto Model { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n        Model = new CreateNodeDto();\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await NodeAppService.CreateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n            Model = new CreateNodeDto();\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Node/Node.razor",
    "content": "﻿@page \"/Node\"\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Node\n@using Mapster\n@using Kite.Gateway.Domain.Shared.Enums\n@inject ToastService ToastService\n@inject INodeAppService NodeAppService\n\n<div class=\"row\">\n    <div class=\"col=12\">\n        <Button OnClick=\"@OnAddAsync\" Color=\"Color.Primary\">添加节点</Button>\n        <Button OnClick=\"@OnRefreshAsync\" Color=\"Color.Success\">刷新节点配置数据</Button>\n    </div>\n</div>\n<div class=\"row\" style=\"margin-top:10px;\">\n    <table class=\"table\">\n      <thead class=\"table-light\">\n        <tr>\n            <th>节点名称</th>\n            <th>节点服务端地址</th>\n            <th>授权访问Token</th>\n            <th>描述</th>\n            <th>创建时间</th>\n            <th>更新时间</th>\n            <th>操作</th>\n        </tr>\n      </thead>\n      <tbody>\n          @if(Nodes!=null&&Nodes.Any())\n          {\n              foreach(var item in Nodes)\n              {\n                <tr>\n                    <td>@item.NodeName</td>\n                    <td>@item.Server</td>\n                    <td>@item.AccessToken</td>\n                    <td>@item.Description</td>\n                    <td>@item.Created</td>\n                    <td>@item.Updated</td>\n                    <td>\n                        <div class=\"btn-group\" role=\"group\">\n                            <Button Color=\"Color.Info\" Size=\"Size.ExtraSmall\" OnClick=\"@(e=>OnUpdateAsync(item.Id))\">编辑</Button>\n                            <PopConfirmButton  Size=\"Size.ExtraSmall\" Placement=\"Placement.Bottom\" Color=\"Color.Danger\" ConfirmIcon=\"fa fa-exclamation-triangle text-danger\"\n                  ConfirmButtonColor=\"Color.Danger\" Text=\"删除\" Content=\"确定删除数据吗？\" Icon=\"fa fa-fa fa-fw\" IsAsync=\"true\"\n                  OnConfirm=\"@(()=>OnDeleteAsync(item.Id))\" />\n                        </div>\n                    </td>\n                </tr>\n              }\n            }\n        </tbody>\n    </table>\n    \n</div>\n<div class=\"row col-12\"  style=\"margin-top:15px;\">\n    <Pagination PageItems=\"@PageSize\" PageItemsSource=\"@(new int[] { 10,20 })\" TotalCount=\"@TotalCount\" OnPageClick=\"@OnPageClick\" OnPageItemsChanged=\"@OnPageItemsChanged\"></Pagination>\n</div>\n<Modal @ref=\"Modal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"添加节点\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n          <NewNode OnClickCallback=\"OnAddCallbackAsync\"></NewNode>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n<Modal @ref=\"UpdateModal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"节点信息编辑\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n           <UpdateNode Model=\"@UpdateModel\" OnClickCallback=\"OnUpdateCallbackAsync\"></UpdateNode>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n<Modal @ref=\"RefreshModal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"刷新节点配置数据\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n           <RefreshConfigure OnClickCallback=\"OnRefreshCallbackAsync\"></RefreshConfigure>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n@code {\n    private Modal Modal;\n\n    private Modal UpdateModal;\n    private Modal RefreshModal;\n\n    public UpdateNodeDto UpdateModel { get; set; }\n    //分页数据\n\n    private List<NodeDto>? Nodes { get; set; }\n\n    private int TotalCount { get; set; } = 0;\n    private int PageSize { get; set; } = 10;\n    private int PageIndex { get; set; } = 1;\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        OnQueryAsync();\n        base.OnInitialized();\n    }\n    #region 刷新节点配置数据\n    private async void OnRefreshAsync()\n    {\n        await RefreshModal.Toggle();\n    }\n    private async void OnRefreshCallbackAsync()\n    {\n        await Modal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    #region 节点编辑更新\n    private async void OnUpdateAsync(Guid id)\n    {\n        UpdateModel= await GetAsync(id);\n        await UpdateModal.Toggle();\n    }\n    private async Task<UpdateNodeDto> GetAsync(Guid id)\n    {\n        var result = await NodeAppService.GetAsync(id);\n        if (result.Code != 0 || result.Data == null)\n        {\n            await ToastService.Warning(\"系统警告\", \"数据不存在\");\n        }\n        var model= TypeAdapter.Adapt<UpdateNodeDto>(result.Data);\n        return model;\n    }\n    private async void OnUpdateCallbackAsync()\n    {\n        await UpdateModal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    #region 新增节点\n    private async void OnAddAsync()\n    {\n        await Modal.Toggle();\n    }\n    private async void OnAddCallbackAsync()\n    {\n        await Modal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    private async Task OnDeleteAsync(Guid id)\n    {\n        var result= await NodeAppService.DeleteAsync(id);\n        if (result.Code == 0)\n        {\n            OnQueryAsync();\n            await ToastService.Success(\"系统通知\",\"数据删除成功!\");\n            return;\n        }\n        await ToastService.Warning(\"系统警告\",\"数据删除失败\");\n    }\n\n    private Task OnPageClick(int pageIndex, int pageItems)\n    {\n        PageIndex = pageIndex;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n    private Task OnPageItemsChanged(int pageItems)\n    {\n        PageIndex=1;\n        PageSize = pageItems;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n    private async void OnQueryAsync()\n    {\n        var result = await NodeAppService.GetListAsync(PageIndex, PageSize);\n\n        if (result.Code == 0)\n        {\n            Nodes = result.Data;\n            TotalCount = result.Count;\n            StateHasChanged();\n        }\n        else\n        {\n            await ToastService.Warning(\"系统警告\", \"数据加载失败\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Node/RefreshConfigure.razor",
    "content": "﻿@using Kite.Gateway.Application\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Node\n@using Kite.Gateway.Application.Contracts.Dtos\n@using System.Linq\n@inject ToastService ToastService\n@inject IHttpClientFactory HttpClientFactory\n@inject INodeAppService NodeAppService\n@inject IConfigureAppService ConfigureAppService;\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.IsReloadAuthentication\" DisplayText=\"是否重新加载身份认证数据\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.IsReloadMiddleware\" DisplayText=\"是否重新加载中间件数据\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                 <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.IsReloadWhitelist\" DisplayText=\"是否重新加载白名单数据\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                 <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.IsReloadYarp\" DisplayText=\"是否重新加载Yarp相关数据\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    private ReloadConfigureDto Model { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n        Model = new ReloadConfigureDto()\n        {\n            IsReloadAuthentication=false,\n            IsReloadMiddleware=false,\n            IsReloadWhitelist=false,\n            IsReloadYarp=false\n        };\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        try\n        {\n            var nodeResult = await NodeAppService.GetAllAsync();\n            if (nodeResult.Code == 0 && nodeResult.Data.Any())\n            {\n                var configureResult = await ConfigureAppService.GetConfigureAsync(Model);\n                foreach (var node in nodeResult.Data)\n                {\n                    var httpClient = HttpClientFactory.CreateClient();\n                    httpClient.DefaultRequestHeaders.Add(\"AccessToken\", node.AccessToken);\n                    var response = await httpClient.PostAsJsonAsync($\"{node.Server}/api/kite/refresh/configure\", configureResult.Data);\n\n                    if (response.IsSuccessStatusCode)\n                    {\n                        var jsonResult = await response.Content.ReadFromJsonAsync<KiteResult>();\n                        await ToastService.Success(\"系统提示\", $\"节点[{node.NodeName}]配置数据刷新成功-{jsonResult.Message}\");\n                    }\n                    else\n                    {\n                        var responseContent =await response.Content.ReadAsStringAsync();\n                        await ToastService.Warning(\"系统警告\", $\"节点[{node.NodeName}]配置数据刷新失败-{responseContent}\");\n                    }\n                }\n            }\n        }\n        catch (Exception ex)\n        {\n            await ToastService.Error(\"系统警告\", $\"节点配置数据刷新失败:{ex.Message}\");\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Node/UpdateNode.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Node\n@inject ToastService ToastService\n@inject INodeAppService NodeAppService\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n           <div class=\"col-12\">\n                   <BootstrapInput @bind-Value=\"Model.NodeName\" DisplayText=\"节点名称\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.Server\" DisplayText=\"服务端地址(结尾勿带 / )\" IsTrim=\"true\" />\n             </div>\n              <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.AccessToken\" DisplayText=\"访问Token\" IsTrim=\"true\" />\n             </div>\n\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                 <Textarea  @bind-Value=\"Model.Description\" DisplayText=\"描述\" IsTrim=\"true\"/>\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    [Parameter]\n    public UpdateNodeDto Model { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await NodeAppService.UpdateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/PaginationComponent.razor",
    "content": "﻿\n<nav aria-label=\"Page navigation example\">\n  <ul class=\"pagination\">\n    <li class=\"page-item disabled\">\n      <span class=\"page-link\">\n          总记录条数:&nbsp;@(TotalCount)&nbsp;&nbsp;@(PageIndex)/@(PageCount) 页\n      </span>\n    </li>\n    <li class=\"page-item\"><a class=\"page-link\" @onclick=\"@(e=>OnClickAsync(1))\">首页</a></li>\n    <li class=\"page-item\"><a class=\"page-link\" @onclick=\"@(e=>OnClickAsync(PreviousPage))\">上一页</a></li>\n    <li class=\"page-item\"><a class=\"page-link\" @onclick=\"@(e=>OnClickAsync(NextPage))\">下一页</a></li>\n    <li class=\"page-item\"><a class=\"page-link\" @onclick=\"@(e=>OnClickAsync(PageCount))\">最后一页</a></li>\n  </ul>\n</nav>\n\n@code {\n    /// <summary>\n    /// 当前页码\n    /// </summary>\n    [Parameter]\n    public int PageIndex { get; set; }\n    /// <summary>\n    /// 每页记录数\n    /// </summary>\n\n    [Parameter]\n    public int PageSize { get; set; }\n    /// <summary>\n    /// 总记录数\n    /// </summary>\n    [Parameter]\n    public int TotalCount { get; set; }\n    /// <summary>\n    /// 点击分页页码时回调事件\n    /// </summary>\n    [Parameter]\n    public EventCallback<int> OnClickCallback { get; set; }\n\n    private int PageCount { get; set; }\n    private int PreviousPage { get; set; }\n    private int NextPage { get; set; }\n\n    protected override void OnInitialized()\n    {\n        HandlePagination();\n        base.OnInitialized();\n    }\n    private async void OnClickAsync(int page)\n    {\n        PageIndex = page;\n        await OnClickCallback.InvokeAsync(page);\n        HandlePagination();\n    }\n    /// <summary>\n    /// 处理页码信息\n    /// </summary>\n    private void HandlePagination()\n    {\n        if (TotalCount % PageSize == 0)\n        {\n            PageCount = TotalCount / PageSize;\n        }\n        else\n        {\n            PageCount = TotalCount / PageSize + 1;\n        }\n        PreviousPage = 1;\n        if (PageIndex >1)\n        {\n\n            PreviousPage = PageIndex - 1;\n        }\n        NextPage = PageCount;\n        if (PageCount < PageIndex )\n        {\n            NextPage = PageIndex + 1;\n        }\n        StateHasChanged();\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/ServiceGovernance/ServiceGovernance.razor",
    "content": "﻿@page \"/ServiceGovernance\"\n\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.ServiceGovernance\n@inject ToastService ToastService\n@inject IServiceGovernanceAppService ServiceGovernanceAppService\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-5\">\n                   <BootstrapInput @bind-Value=\"Model.ConsulServer\" DisplayText=\"Consul服务端地址\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-5\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.ConsulDatacenter\" DisplayText=\"Consul数据中心\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-5\"  style=\"margin-top:5px;\" >\n                   <BootstrapInput @bind-Value=\"Model.ConsulToken\" DisplayText=\"Consul访问令牌\" IsTrim=\"true\" />\n             </div>\n            <div class=\"col-5\">\n                   <BootstrapInput @bind-Value=\"Model.NacosServer\" DisplayText=\"Nacos服务端地址\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-5\">\n                   <BootstrapInput @bind-Value=\"Model.NacosNamespaceId\" DisplayText=\"Nacos命名空间ID\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-5\">\n                   <BootstrapInput @bind-Value=\"Model.NacosGroupName\" DisplayText=\"Nacos服务端地址\" IsTrim=\"true\" />\n             </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-5\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n    //表单数据\n    private ServiceGovernanceConfigureDto Model { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override async void OnInitialized()\n    {\n        base.OnInitialized();\n        var result = await ServiceGovernanceAppService.GetServiceGovernanceConfigureAsync();\n        if (result.Code == 0)\n        {\n            Model = result.Data;\n        }\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await ServiceGovernanceAppService.SaveServiceGovernanceConfigureAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n        }\n    }\n}\n\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Whitelist/NewWhitelist.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Whitelist\n@inject ToastService ToastService\n@inject IWhitelistAppService WhitelistAppService\n@inject IRouteAppService RouteAppService\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                   <BootstrapInput @bind-Value=\"Model.Name\" DisplayText=\"白名单名称\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <Select @bind-Value=\"Model.RouteId\" Items=\"@Routes\" DisplayText=\"所属作用域\">\n                         \n                   </Select>\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                    <BootstrapInput @bind-Value=\"Model.FilterText\" DisplayText=\"过滤文本(根据类型保存的值为路径或者正则表达式)\" IsTrim=\"true\"/>\n            </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\">\n                   <CheckboxList @bind-Value=\"@Model.RequestMethod\" Items=\"@RequestMethods\" DisplayText=\"请求方式\"></CheckboxList>\n            </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.UseState\" DisplayText=\"状态\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n\n\n    //表单数据\n    private CreateWhitelistDto Model { get; set; }\n\n    private List<SelectedItem> RequestMethods{ get; set; }\n    private List<SelectedItem> Routes { get; set; }\n\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override async void OnInitialized()\n    {\n        base.OnInitialized();\n        Model = new CreateWhitelistDto()\n        {\n            UseState=true\n        };\n        //初始化请求方式数据\n        var requestMethods = new string[] { \"POST\", \"GET\", \"PUT\", \"DELETE\", \"OPTIONS\", \"PATCH\", \"HEAD\" };\n        RequestMethods = new List<SelectedItem>();\n        foreach (var m in requestMethods)\n        {\n            RequestMethods.Add(new SelectedItem()\n            {\n                Text=m,\n                Value=m\n            });\n        }\n        //初始化路由数据\n        Routes = new List<SelectedItem>()\n        {\n            new SelectedItem()\n            {\n                Text=\"全局\",\n                Value=\"00000000-0000-0000-0000-000000000000\"\n            }\n        };\n        var routeResult =await RouteAppService.GetListAsync();\n        if (routeResult.Code == 0)\n        {\n            foreach (var item in routeResult.Data)\n            {\n                Routes.Add(new SelectedItem()\n                    {\n                        Text = item.RouteName,\n                        Value = item.Id.ToString()\n                    });\n            }\n        }\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await WhitelistAppService.CreateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n            Model = new CreateWhitelistDto()\n            {\n                UseState=true\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Whitelist/UpdateWhitelist.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Whitelist\n@inject ToastService ToastService\n@inject IWhitelistAppService WhitelistAppService\n@inject IRouteAppService RouteAppService\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                   <BootstrapInput @bind-Value=\"Model.Name\" DisplayText=\"白名单名称\" IsTrim=\"true\" />\n             </div>\n             <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                   <Select @bind-Value=\"Model.RouteId\" Items=\"@Routes\" DisplayText=\"所属作用域\">\n                         \n                   </Select>\n             </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\" >\n                    <BootstrapInput @bind-Value=\"Model.FilterText\" DisplayText=\"过滤文本(根据类型保存的值为路径或者正则表达式)\" IsTrim=\"true\"/>\n            </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\">\n                   <CheckboxList @bind-Value=\"@Model.RequestMethod\" Items=\"@RequestMethods\" DisplayText=\"请求方式\"></CheckboxList>\n            </div>\n            <div class=\"col-12\"  style=\"margin-top:5px;\">\n                   <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.UseState\" DisplayText=\"状态\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n            </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n\n\n    //表单数据\n    [Parameter]\n    public UpdateWhitelistDto Model { get; set; }\n\n    private List<SelectedItem> RequestMethods{ get; set; }\n    private List<SelectedItem> Routes { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override async void OnInitialized()\n    {\n        base.OnInitialized();\n        //初始化请求方式数据\n        var requestMethods = new string[] { \"POST\", \"GET\", \"PUT\", \"DELETE\", \"OPTIONS\", \"PATCH\", \"HEAD\" };\n        RequestMethods = new List<SelectedItem>();\n        foreach (var m in requestMethods)\n        {\n            RequestMethods.Add(new SelectedItem()\n            {\n                Text=m,\n                Value=m\n            });\n        }\n        //初始化路由数据\n        Routes = new List<SelectedItem>()\n        {\n            new SelectedItem()\n            {\n                Text=\"全局\",\n                Value=\"00000000-0000-0000-0000-000000000000\"\n            }\n        };\n        var routeResult =await RouteAppService.GetListAsync();\n        if (routeResult.Code == 0)\n        {\n            foreach (var item in routeResult.Data)\n            {\n                Routes.Add(new SelectedItem()\n                    {\n                        Text = item.RouteName,\n                        Value = item.Id.ToString()\n                    });\n            }\n        }\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await WhitelistAppService.UpdateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Whitelist/WhiteList.razor",
    "content": "﻿@page \"/Whitelist\"\n\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.Whitelist\n@using Mapster\n@using Kite.Gateway.Domain.Shared.Enums\n@inject ToastService ToastService\n@inject IWhitelistAppService WhitelistAppService\n@inject NavigationManager NavigationManager\n\n<div class=\"row\">\n    <div class=\"col-4\">\n        <BootstrapInputGroup>\n            <BootstrapInput @bind-Value=\"@SearchKw\" PlaceHolder=\"白名单名称/过滤文本值\" />\n            <Button Icon=\"fa fa-search\" IsAsync=\"true\" @onclick=\"OnSearchAsync\"></Button>\n        </BootstrapInputGroup>\n    </div>\n    <div class=\"col-2\">\n        <Button OnClick=\"@OnAddAsync\" Color=\"Color.Primary\">添加白名单</Button>\n    </div>\n</div>\n<div class=\"row\" style=\"margin-top:10px;\">\n    <table class=\"table\">\n      <thead class=\"table-light\">\n        <tr>\n            <th>白名单名称</th>\n            <th>作用域</th>\n            <th>过滤文本</th>\n            <th>请求方式</th>\n            <th>状态</th>\n            <th>创建时间</th>\n            <th>操作</th>\n        </tr>\n      </thead>\n      <tbody>\n          @if(Whitelists!=null&&Whitelists.Any())\n          {\n              foreach(var item in Whitelists)\n              {\n                <tr>\n                    <td>@item.Name</td>\n                    <td>@item.RouteName</td>\n                    <td>@item.FilterText</td>\n                    <td>@item.RequestMethod</td>\n                    <td>\n                        <Switch OnValueChanged=\"@(async (val)=>{ OnUpdateStateAsync(item.Id,val);await Task.CompletedTask; })\" OnColor=\"Color.Success\" @bind-Value=\"item.UseState\" ShowLabel=\"false\" style=\"max-height:18px;\"  ></Switch>\n                    </td>\n                    \n                    <td>@item.Created</td>\n                    \n                    <td>\n                        <div class=\"btn-group\" role=\"group\">\n                            <Button Color=\"Color.Info\" Size=\"Size.ExtraSmall\" OnClick=\"@(e=>OnUpdateAsync(item.Id))\">编辑</Button>\n                            <PopConfirmButton  Size=\"Size.ExtraSmall\" Placement=\"Placement.Bottom\" Color=\"Color.Danger\" ConfirmIcon=\"fa fa-exclamation-triangle text-danger\"\n                  ConfirmButtonColor=\"Color.Danger\" Text=\"删除\" Content=\"确定删除数据吗？\" Icon=\"fa fa-fa fa-fw\" IsAsync=\"true\"\n                  OnConfirm=\"@(()=>OnDeleteAsync(item.Id))\" />\n                        </div>\n                    </td>\n                </tr>\n              }\n            }\n        </tbody>\n    </table>\n    \n</div>\n<div class=\"row col-12\"  style=\"margin-top:15px;\">\n     <Pagination PageItems=\"@PageSize\" PageItemsSource=\"@(new int[] { 10,20 })\" TotalCount=\"@TotalCount\" OnPageClick=\"@OnPageClick\" OnPageItemsChanged=\"@OnPageItemsChanged\"></Pagination>\n</div>\n<Modal @ref=\"Modal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"新增白名单\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n           <NewWhitelist OnClickCallback=\"OnAddCallbackAsync\"></NewWhitelist>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n<Modal @ref=\"UpdateModal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"白名单编辑\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n           <UpdateWhitelist Model=\"@UpdateModel\" OnClickCallback=\"OnUpdateCallbackAsync\"></UpdateWhitelist>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n@code {\n    private Modal Modal;\n\n    private Modal UpdateModal;\n\n    public UpdateWhitelistDto UpdateModel { get; set; }\n    //分页数据\n\n    private List<WhitelistDto> Whitelists { get; set; }\n\n    private int TotalCount { get; set; } = 0;\n    private int PageSize { get; set; } = 10;\n    private int PageIndex { get; set; } = 1;\n    private string SearchKw { get; set; } = \"\";\n\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        OnQueryAsync();\n        base.OnInitialized();\n    }\n    #region 白名单编辑更新\n    private async void OnUpdateStateAsync(Guid id,bool val)\n    {\n        var result = await WhitelistAppService.UpdateUseStateAsync(id, val);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(\"系统警告\",result.Message);\n        }\n        else\n        {\n            await ToastService.Success(\"系统通知\",\"保存成功\");\n        }\n    }\n    private async void OnUpdateAsync(Guid id)\n    {\n        UpdateModel= await GetAsync(id);\n        await UpdateModal.Toggle();\n    }\n    private async Task<UpdateWhitelistDto> GetAsync(Guid id)\n    {\n        var result = await WhitelistAppService.GetAsync(id);\n        if (result.Code != 0 || result.Data == null)\n        {\n            await ToastService.Warning(\"系统警告\", \"数据不存在\");\n        }\n        var model= TypeAdapter.Adapt<UpdateWhitelistDto>(result.Data);\n        return model;\n    }\n    private async void OnUpdateCallbackAsync()\n    {\n        await UpdateModal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    #region 新增白名单\n    private async void OnAddAsync()\n    {\n        await Modal.Toggle();\n    }\n    private async void OnAddCallbackAsync()\n    {\n        await Modal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    private async Task OnDeleteAsync(Guid routeId)\n    {\n        var result= await WhitelistAppService.DeleteAsync(routeId);\n        if (result.Code == 0)\n        {\n            OnQueryAsync();\n            await ToastService.Success(\"系统通知\",\"数据删除成功!\");\n            return;\n        }\n        await ToastService.Warning(\"系统警告\",\"数据删除失败\");\n    }\n\n    private Task OnPageClick(int pageIndex, int pageItems)\n    {\n        PageIndex = pageIndex;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n    private Task OnPageItemsChanged(int pageItems)\n    {\n        PageIndex=1;\n        PageSize = pageItems;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n    private void OnSearchAsync()\n    {\n        PageIndex = 1;\n        OnQueryAsync();\n    }\n    private async void OnQueryAsync()\n    {\n        var result = await WhitelistAppService.GetListAsync(SearchKw, PageIndex, PageSize);\n\n        if (result.Code == 0)\n        {\n            Whitelists = result.Data;\n            TotalCount = result.Count;\n            StateHasChanged();\n        }\n        else\n        {\n            await ToastService.Warning(\"系统警告\", \"数据加载失败\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Yarp/NewRoute.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n@inject ToastService ToastService\n@inject IRouteAppService RouteAppService\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" class=\"form-inline\"  OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                    <GroupBox Title=\"路由基础信息\"  class=\"col-12\">\n                        <BootstrapInput @bind-Value=\"Model.RouteName\" DisplayText=\"路由名称\" IsTrim=\"true\" />\n                        <BootstrapInput @bind-Value=\"Model.RouteMatchPath\" DisplayText=\"路由规则\" IsTrim=\"true\"  style=\"margin-top:5px;\" />\n                        <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.UseState\" DisplayText=\"开启状态\" OnText=\"开启\" OffText=\"关闭\"  style=\"margin-top:5px;\"></Switch>\n                    </GroupBox>\n                    \n                </div>\n             <div class=\"col-12\">\n                    <GroupBox Title=\"路由转换\"  class=\"col-12\">\n                       <BootstrapInput @bind-Value=\"Model.PathRemovePrefix\" DisplayText=\"移除路径前缀\" IsTrim=\"true\" />\n                       <BootstrapInput @bind-Value=\"Model.PathPrefix\" DisplayText=\"添加加路径前缀\" IsTrim=\"true\"  style=\"margin-top:5px;\" />\n                    </GroupBox>\n             </div>\n            <div class=\"col-12\">\n                    <GroupBox Title=\"集群配置\"  class=\"col-12\">\n                        <Select @bind-Value=\"Model.LoadBalancingPolicy\" DisplayText=\"集群策略\">\n                            <Options>\n                                <SelectOption Text=\"默认\" Value=\"PowerOfTwoChoices\"/>\n                                <SelectOption Text=\"第一可用\" Value=\"FirstAlphabetical\" />\n                                <SelectOption Text=\"随机\" Value=\"Random\" />\n                                <SelectOption Text=\"顺序循环\" Value=\"RoundRobin\" />\n                                 <SelectOption Text=\"请求最少\" Value=\"LeastRequests\" />\n                            </Options>\n                        </Select>\n                        <Select @bind-Value=\"Model.ServiceGovernanceType\" DisplayText=\"服务治理类型\"  style=\"margin-top:5px;\" >\n                        </Select>\n                       <BootstrapInput @bind-Value=\"Model.ClusterDestinationValue\" ShowLabel=\"true\" DisplayText=\"集群目的地\" IsTrim=\"true\"   style=\"margin-top:5px;\" />\n                       <Tag Icon=\"fa fa-fw fa-question-circle\" Color=\"Color.Info\">如果治理类型为默认时多个目的地用,(逗号,半角)分隔,否则为服务治理名称</Tag>\n                    </GroupBox>\n                </div>\n            <div class=\"col-12\">\n                    <GroupBox Title=\"集群健康检查配置\"  class=\"col-12\">\n                       <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.ClusterHealthCheck.Enabled\" DisplayText=\"是否开启\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n                       <BootstrapInputNumber @bind-Value=\"Model.ClusterHealthCheck.Interval\" DisplayText=\"间隔时间(秒)\" IsSelectAllTextOnFocus=\"true\" style=\"margin-top:5px;\" />\n                       <BootstrapInputNumber @bind-Value=\"Model.ClusterHealthCheck.Timeout\" DisplayText=\"超时时间(秒)\" IsSelectAllTextOnFocus=\"true\"  style=\"margin-top:5px;\" />\n                       <BootstrapInput @bind-Value=\"Model.ClusterHealthCheck.Path\" DisplayText=\"路径\" IsTrim=\"true\" style=\"margin-top:5px;\" />\n                    </GroupBox>\n                </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n\n\n    //表单数据\n    private CreateRouteDto Model { get; set; }\n\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n        Model = new CreateRouteDto()\n        {\n            UseState=true,\n            ClusterHealthCheck=new ClusterHealthCheckDto()\n            {\n                Enabled = false\n            }\n        };\n    }\n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await RouteAppService.CreateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n            Model = new CreateRouteDto()\n            {\n                UseState=true,\n                ClusterHealthCheck=new ClusterHealthCheckDto()\n                {\n                    Enabled = false\n                }\n            };  \n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Yarp/Route.razor",
    "content": "﻿@page \"/Route\"\n\n@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n@using Mapster\n@using Kite.Gateway.Domain.Shared.Enums\n@inject ToastService ToastService\n@inject IRouteAppService RouteAppService\n@inject NavigationManager NavigationManager\n@inject DialogService? DialogService\n\n<div class=\"row\">\n    <div class=\"col-4\">\n        <BootstrapInputGroup>\n            <BootstrapInput @bind-Value=\"@SearchKw\" PlaceHolder=\"路由名称\" />\n            <Button Icon=\"fa fa-search\" IsAsync=\"true\" @onclick=\"OnSearchAsync\"></Button>\n        </BootstrapInputGroup>\n    </div>\n    <div class=\"col-2\">\n         <Button OnClick=\"@OnAddAsync\" Color=\"Color.Primary\">添加路由</Button>\n    </div>\n</div>\n<div class=\"row\" style=\"margin-top:10px;\">\n    <table class=\"table\">\n      <thead class=\"table-light\">\n        <tr>\n            <th>路由名称</th>\n            <th>路由路径</th>\n            <th>负载均衡策略</th>\n            <th>服务治理类型</th>\n            <th>服务治理名称</th>\n            <th>状态</th>\n            <th>创建时间</th>\n            <th>描述</th>\n            <th>操作</th>\n        </tr>\n      </thead>\n      <tbody>\n          @if(Routes!=null&&Routes.Any())\n          {\n              foreach(var item in Routes)\n              {\n                <tr>\n                    <td>@item.RouteName</td>\n                    <td>@item.RouteMatchPath</td>\n                    <td>\n                        @switch(item.LoadBalancingPolicy)\n                        {\n                            case \"FirstAlphabetical\" :\n                                <div>第一个可用</div>\n                            break;\n                            case \"Random\":\n                                <div>随机</div>\n                            break;\n                            case \"RoundRobin\":\n                                <div>顺序循环</div>\n                            break;\n                            case \"LeastRequests\":\n                                <div>请求最少</div>\n                            break;\n                            default:\n                                <div>默认</div>\n                            break;\n                        }\n                    </td>\n                    <td>\n                        @switch(item.ServiceGovernanceType)\n                            {\n                                case ServiceGovernanceType.Consul:\n                                    <div>Consul</div>\n                                    break;\n                                default:\n                                    <div>默认</div>\n                                    break;\n                            }\n                        </td>\n                    <td>@item.ServiceGovernanceName</td>\n                    <td>\n                        <Switch  OnValueChanged=\"@(async (val)=>{ OnUpdateStateAsync(item.Id,val);await Task.CompletedTask; })\" OnColor=\"Color.Success\" @bind-Value=\"item.UseState\" ShowLabel=\"false\" style=\"max-height:18px;\" ></Switch>\n                    </td>\n                    <td>@item.Created</td>\n                    <td>@item.Description</td>\n                    <td>\n                        <div class=\"btn-group\" role=\"group\">\n                            <Button Color=\"Color.Info\" Size=\"Size.ExtraSmall\" OnClick=\"@(e=>OnUpdateAsync(item.Id))\">编辑</Button>\n                            <PopConfirmButton  Size=\"Size.ExtraSmall\" Placement=\"Placement.Bottom\" Color=\"Color.Danger\" ConfirmIcon=\"fa fa-exclamation-triangle text-danger\"\n                  ConfirmButtonColor=\"Color.Danger\" Text=\"删除\" Content=\"确定删除数据吗？\" Icon=\"fa fa-fa fa-fw\" IsAsync=\"true\"\n                  OnConfirm=\"@(()=>OnDeleteAsync(item.Id))\" />\n                        </div>\n                    </td>\n                </tr>\n              }\n            }\n        </tbody>\n    </table>\n    \n</div>\n<div class=\"row col-12\"  style=\"margin-top:15px;\">\n    <Pagination PageItems=\"@PageSize\" PageItemsSource=\"@(new int[] { 10,20 })\" TotalCount=\"@TotalCount\" OnPageClick=\"@OnPageClick\" OnPageItemsChanged=\"@OnPageItemsChanged\"></Pagination>\n</div>\n\n\n<Modal @ref=\"Modal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"新增路由\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n           <NewRoute OnClickCallback=\"OnAddCallbackAsync\"></NewRoute>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n<Modal @ref=\"UpdateModal\">\n    <ModalDialog  IsScrolling=\"true\" Title=\"编辑路由\" IsCentered=\"true\" Size=\"Size.Large\" ShowCloseButton=\"false\">\n        <BodyTemplate >\n           <UpdateRoute Model=\"@UpdateModel\" OnClickCallback=\"OnUpdateCallbackAsync\"></UpdateRoute>\n        </BodyTemplate>\n    </ModalDialog>\n</Modal>\n\n@code {\n    private Modal Modal;\n\n    private Modal UpdateModal;\n\n    public UpdateRouteDto UpdateModel { get; set; }\n    //分页数据\n\n    private List<RoutePageDto> Routes { get; set; }\n\n    private int TotalCount { get; set; } = 0;\n    private int PageSize { get; set; } = 10;\n    private int PageIndex { get; set; } = 1;\n    private string SearchKw { get; set; } = \"\";\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        OnQueryAsync();\n        base.OnInitialized();\n    }\n    #region 路由编辑更新\n    private async void OnUpdateStateAsync(Guid id,bool val)\n    {\n        var result = await RouteAppService.UpdateStateAsync(id, val);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(\"系统警告\",result.Message);\n        }\n        else\n        {\n            await ToastService.Success(\"系统通知\",\"保存成功\");\n        }\n    }\n    private async void OnUpdateAsync(Guid id)\n    {\n        UpdateModel= await GetUpdateRouteDataAsync(id);\n        await UpdateModal.Toggle();\n    }\n    private async Task<UpdateRouteDto> GetUpdateRouteDataAsync(Guid id)\n    {\n        var result =await RouteAppService.GetAsync(id);\n        if (result.Code != 0 || result.Data == null)\n        {\n            await ToastService.Warning(\"系统警告\",\"信息获取失败\");\n        }\n        var data = result.Data;\n        var updateDataModel = new UpdateRouteDto()\n            {\n                ClusterHealthCheck = TypeAdapter.Adapt<ClusterHealthCheckDto>(data.Cluster.HealthCheck),\n                Description = \"\",\n                UseState = data.UseState,\n                LoadBalancingPolicy = data.Cluster.LoadBalancingPolicy,\n                PathPrefix = data.RouteTransforms.Where(x => x.TransformsName == \"PathPrefix\").Select(x => x.TransformsValue).FirstOrDefault(),\n                PathRemovePrefix = data.RouteTransforms.Where(x => x.TransformsName == \"PathRemovePrefix\").Select(x => x.TransformsValue).FirstOrDefault(),\n                RouteId = data.Id,\n                RouteMatchPath = data.RouteMatchPath,\n                RouteName = data.RouteName,\n                ServiceGovernanceType = data.Cluster.ServiceGovernanceType\n            };\n        if (data.Cluster.ServiceGovernanceType == ServiceGovernanceType.Default)\n        {\n            updateDataModel.ClusterDestinationValue = string.Join(',', data.Cluster.ClusterDestinations.Select(x => x.DestinationAddress).ToList());\n        }\n        else\n        {\n            updateDataModel.ClusterDestinationValue = data.Cluster.ServiceGovernanceName;\n        }\n        return updateDataModel;\n    }\n    private async void OnUpdateCallbackAsync()\n    {\n        await UpdateModal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    #region 新增路由\n    private async void OnAddAsync()\n    {\n        await Modal.Toggle();\n    }\n    private async void OnAddCallbackAsync()\n    {\n        await Modal.Close();\n        OnQueryAsync();\n    }\n    #endregion\n    private async Task OnDeleteAsync(Guid routeId)\n    {\n        var result= await RouteAppService.DeleteAsync(routeId);\n        if (result.Code == 0)\n        {\n            OnQueryAsync();\n            await ToastService.Success(\"系统通知\",\"数据删除成功!\");\n            return;\n        }\n        await ToastService.Warning(\"系统警告\",\"数据删除失败\");\n    }\n\n    private Task OnPageClick(int pageIndex, int pageItems)\n    {\n        PageIndex = pageIndex;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n    private Task OnPageItemsChanged(int pageItems)\n    {\n        PageIndex=1;\n        PageSize = pageItems;\n        OnQueryAsync();\n        return Task.CompletedTask;\n    }\n\n    private void OnSearchAsync()\n    {\n        PageIndex = 1;\n        OnQueryAsync();\n    }\n    private async void OnQueryAsync()\n    {\n        var result = await RouteAppService.GetListAsync(SearchKw, PageIndex, PageSize);\n\n        if (result.Code == 0)\n        {\n            Routes = result.Data;\n            TotalCount = result.Count;\n            StateHasChanged();\n        }\n        else\n        {\n            await ToastService.Warning(\"系统警告\", \"路由数据加载失败\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/Yarp/UpdateRoute.razor",
    "content": "﻿@using Kite.Gateway.Application.Contracts\n@using Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n@using Mapster;\n@inject ToastService ToastService\n@inject IRouteAppService RouteAppService\n\n<div class=\"row\">\n    <ValidateForm Model=\"@Model\" class=\"form-inline\"  OnValidSubmit=\"@OnSaveAsync\" OnInvalidSubmit=\"@OnInvalidSubmitAsync\">\n            <div class=\"col-12\">\n                    <GroupBox Title=\"路由基础信息\"  class=\"col-12\">\n                        <BootstrapInput @bind-Value=\"Model.RouteName\" DisplayText=\"路由名称\" IsTrim=\"true\" />\n                        <BootstrapInput @bind-Value=\"Model.RouteMatchPath\" DisplayText=\"路由规则\" IsTrim=\"true\"  style=\"margin-top:5px;\" />\n                        <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.UseState\" DisplayText=\"开启状态\" OnText=\"开启\" OffText=\"关闭\"  style=\"margin-top:5px;\"></Switch>\n                    </GroupBox>\n                    \n                </div>\n             <div class=\"col-12\">\n                    <GroupBox Title=\"路由转换\"  class=\"col-12\">\n                       <BootstrapInput @bind-Value=\"Model.PathRemovePrefix\" DisplayText=\"移除路径前缀\" IsTrim=\"true\" />\n                       <BootstrapInput @bind-Value=\"Model.PathPrefix\" DisplayText=\"添加加路径前缀\" IsTrim=\"true\"  style=\"margin-top:5px;\" />\n                    </GroupBox>\n             </div>\n            <div class=\"col-12\">\n                    <GroupBox Title=\"集群配置\"  class=\"col-12\">\n                        <Select @bind-Value=\"Model.LoadBalancingPolicy\" DisplayText=\"集群策略\">\n                            <Options>\n                                <SelectOption Text=\"默认\" Value=\"PowerOfTwoChoices\"/>\n                                <SelectOption Text=\"第一可用\" Value=\"FirstAlphabetical\" />\n                                <SelectOption Text=\"随机\" Value=\"Random\" />\n                                <SelectOption Text=\"顺序循环\" Value=\"RoundRobin\" />\n                                 <SelectOption Text=\"请求最少\" Value=\"LeastRequests\" />\n                            </Options>\n                        </Select>\n                       <Select @bind-Value=\"Model.ServiceGovernanceType\" DisplayText=\"服务治理类型\"  style=\"margin-top:5px;\" >\n                        </Select>\n                       <BootstrapInput @bind-Value=\"Model.ClusterDestinationValue\" ShowLabel=\"true\" DisplayText=\"集群目的地\" IsTrim=\"true\"   style=\"margin-top:5px;\" />\n                       <Tag Icon=\"fa fa-fw fa-question-circle\" Color=\"Color.Info\">如果治理类型为默认时多个目的地用,(逗号,半角)分隔,否则为服务治理名称</Tag>\n                    </GroupBox>\n                </div>\n            <div class=\"col-12\">\n                    <GroupBox Title=\"集群健康检查配置\"  class=\"col-12\">\n                       <Switch OnColor=\"Color.Success\" @bind-Value=\"Model.ClusterHealthCheck.Enabled\" DisplayText=\"是否开启\" OnText=\"开启\" OffText=\"关闭\"></Switch>\n                       <BootstrapInputNumber @bind-Value=\"Model.ClusterHealthCheck.Interval\" DisplayText=\"间隔时间(秒)\" IsSelectAllTextOnFocus=\"true\" style=\"margin-top:5px;\" />\n                       <BootstrapInputNumber @bind-Value=\"Model.ClusterHealthCheck.Timeout\" DisplayText=\"超时时间(秒)\" IsSelectAllTextOnFocus=\"true\"  style=\"margin-top:5px;\" />\n                       <BootstrapInput @bind-Value=\"Model.ClusterHealthCheck.Path\" DisplayText=\"路径\" IsTrim=\"true\" style=\"margin-top:5px;\" />\n                    </GroupBox>\n                </div>\n            <div class=\"row\" style=\"margin-top:10px;\">\n                <div class=\"col-12\">\n                    <Button ButtonType=\"ButtonType.Submit\"  IsAsync=\"true\" Color=\"Color.Primary\">保 存</Button>\n                </div>\n            </div>\n           </ValidateForm>\n</div>\n\n\n@code {\n\n\n    [Parameter]\n    public EventCallback OnClickCallback { get; set; }\n\n    //表单数据\n    [Parameter]\n    public UpdateRouteDto Model { get; set; }\n\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n    }\n    \n    private Task OnInvalidSubmitAsync(EditContext context)\n    {\n        return Task.CompletedTask;\n    }\n    private async Task OnSaveAsync(EditContext context)\n    {\n        var result= await RouteAppService.UpdateAsync(Model);\n        if (result.Code != 0)\n        {\n            await ToastService.Warning(result.Message);\n        }\n        else\n        {\n            await OnClickCallback.InvokeAsync();\n            await ToastService.Success(\"保存成功\");\n        }\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/_Host.cshtml",
    "content": "﻿@page \"/\"\n@namespace Kite.Gateway.Admin.Pages\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n@{\n\n    Layout = \"_Layout\";\n}\n<component type=\"typeof(App)\" render-mode=\"ServerPrerendered\" />\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Pages/_Layout.cshtml",
    "content": "﻿@using Microsoft.AspNetCore.Components.Web\n@namespace Kite.Gateway.Admin.Pages\n@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <base href=\"~/\" />\n    <link href=\"_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css\" rel=\"stylesheet\">\n    <link href=\"_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css\" rel=\"stylesheet\">\n    <link href=\"css/site.css\" rel=\"stylesheet\" />\n    <link href=\"Kite.Gateway.Admin.styles.css\" rel=\"stylesheet\" />\n    <component type=\"typeof(HeadOutlet)\" render-mode=\"ServerPrerendered\" />\n</head>\n<body>\n    @RenderBody()\n\n   @* <div id=\"blazor-error-ui\">\n        <environment include=\"Staging,Production\">\n            An error has occurred. This application may no longer respond until reloaded.\n        </environment>\n        <environment include=\"Development\">\n            An unhandled exception has occurred. See browser dev tools for details.\n        </environment>\n        <a href=\"\" class=\"reload\">Reload</a>\n        <a class=\"dismiss\">🗙</a>\n    </div>*@\n    <script src=\"_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js\"></script>\n    <script src=\"_framework/blazor.server.js\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Program.cs",
    "content": "\nusing Kite.Gateway.Admin;\nusing Kite.Gateway.Admin.Core;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.Components;\nusing Microsoft.AspNetCore.Components.Web;\nusing Microsoft.AspNetCore.Http.Features;\nusing Serilog;\nusing Serilog.Events;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n//־\nbuilder.Logging.ClearProviders();\nLog.Logger = new LoggerConfiguration()\n          .Enrich.FromLogContext()\n          .WriteTo.Console()// ־̨\n          .WriteTo.File($\"data/logs/log-.txt\", restrictedToMinimumLevel: LogEventLevel.Warning, rollingInterval: RollingInterval.Day)\n          .MinimumLevel.Information()\n          .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Information)\n          .CreateLogger();\nbuilder.Host\n     .UseSerilog(dispose:true)\n     .UseAutofac();\n//ļ\nbuilder.Services.ReplaceConfiguration(builder.Configuration);//ô\n//ע\nbuilder.Services.AddApplication<GatewayAdminModule>();\nbuilder.Services.AddHttpClient();\nbuilder.Services.AddSingleton<AuthorizationServerStorage>();\n\nvar app = builder.Build();\nawait app.InitializeApplicationAsync();\nawait app.RunAsync();\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:29547\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"Kite.Gateway.Admin\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:55661\",\n      \"dotnetRunMessages\": true\n    },\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"Docker\": {\n      \"commandName\": \"Docker\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"{Scheme}://{ServiceHost}:{ServicePort}\",\n      \"publishAllPorts\": true\n    }\n  }\n}"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Shared/MainLayout.razor",
    "content": "﻿@inherits LayoutComponentBase\n@inject SwalService swalService\n@inject NavigationManager navigationManager\n\n<Layout SideWidth=\"0\" IsPage=\"true\" ShowGotoTop=\"true\" ShowCollapseBar=\"true\"\n        IsFullSide=\"@IsFullSide\" IsFixedHeader=\"@IsFixedHeader\" IsFixedFooter=\"@IsFixedFooter\" ShowFooter=\"@ShowFooter\"\n        TabDefaultUrl=\"/\"\n        Menus=\"@Menus\"  UseTabSet=\"@UseTabSet\" AdditionalAssemblies=\"new[] { GetType().Assembly }\" class=\"@Theme\">\n    <Header>\n        <span class=\"ms-3 flex-sm-fill d-none d-sm-block\">Kite Gateway</span>\n        <div class=\"flex-fill d-sm-none\">\n        </div>\n        <Logout ImageUrl=\"images/kitelogo.png\" DisplayName=\"@(Administrator.NickName)\" UserName=\"@(Administrator.AdminName)\">\n            <LinkTemplate>\n                <LogoutLink Url=\"/Logout\" />\n            </LinkTemplate>\n        </Logout>\n    </Header>\n    <Side>\n        <div class=\"layout-banner\">\n            <div class=\"layout-title\">\n                <span>后台管理</span>\n            </div>\n        </div>\n    </Side>\n    <Main>\n        <CascadingValue Value=\"this\" IsFixed=\"true\">\n            @Body\n        </CascadingValue>\n    </Main>\n    <Footer>\n        <div class=\"text-center flex-fill\">\n            \n        </div>\n    </Footer>\n    <NotFound>\n        <p>Sorry, there's nothing at this address.</p>\n    </NotFound>\n</Layout>\n@code {\n    protected override async Task OnAfterRenderAsync(bool firstRender)\n    {\n        if (Administrator.Id == Guid.Empty)\n        {\n\n            var op = new SwalOption()\n                {\n                    Category = SwalCategory.Warning,\n                    Title = \"你还未登录,请先登录\",\n                    ShowClose = false\n                };\n            op.ButtonTemplate = new RenderFragment(builder =>\n            {\n                builder.OpenComponent<Button>(0);\n                builder.AddAttribute(1, nameof(Button.Text), \"前往登录\");\n                builder.AddAttribute(2, nameof(Button.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, () =>\n                {\n                    navigationManager.NavigateTo(\"/Login\");\n                    op.Close();\n                }));\n                builder.CloseComponent();\n            });\n            await swalService.Show(op);\n        }\n        await base.OnAfterRenderAsync(firstRender);\n\t}\n \n}"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Shared/MainLayout.razor.cs",
    "content": "﻿using BootstrapBlazor.Components;\nusing Microsoft.AspNetCore.Components.Routing;\n\nusing Kite.Gateway.Admin.Core;\nusing Kite.Gateway.Application.Contracts.Dtos.Administrator;\nusing Microsoft.AspNetCore.Components;\n\n\nnamespace Kite.Gateway.Admin.Shared;\n\n/// <summary>\n/// \n/// </summary>\npublic sealed partial class MainLayout\n{\n    private bool UseTabSet { get; set; } = true;\n\n    private string Theme { get; set; } = \"\";\n\n    private bool IsFixedHeader { get; set; } = true;\n\n    private bool IsFixedFooter { get; set; } = true;\n\n    private bool IsFullSide { get; set; } = true;\n\n    private bool ShowFooter { get; set; } = false;\n\n    private List<MenuItem>? Menus { get; set; }\n\n    [Inject]\n    private AuthorizationServerStorage ServerStorage { get; set; }\n\n    [Inject]\n    private NavigationManager NavigationManager { get; set; }\n\n    private AdministratorDto Administrator { get; set; }\n    /// <summary>\n    /// OnInitialized 方法\n    /// </summary>\n    protected override void OnInitialized()\n    {\n        base.OnInitialized();\n        //如果没有登录则跳转到登录页面\n        if (ServerStorage.IsLogin())\n        {\n            Administrator = ServerStorage.GetServerStorage();\n        }\n        else\n        {\n            //\n            Administrator = new AdministratorDto() \n            {\n                AdminName=\"未登录\",\n                NickName=\"未登录\",\n                Id=Guid.Empty\n            };\n        }\n        Menus = GetIconSideMenuItems();\n    }\n\n    private static List<MenuItem> GetIconSideMenuItems()\n    {\n        var menus = new List<MenuItem>\n            {\n               new MenuItem()\n                        {\n                            Text = \"首页\",\n                            Icon = \"fa fa-home\",\n                            Url = \"/\",\n                            IsActive = true\n                        },\n               new MenuItem()\n               {\n                   Text =\"系统设置\",\n                   Icon =\"fa fa-gear\",\n                   Url = \"\",\n                   Id = \"1\",\n                   Items = new List<MenuItem>()\n                   {\n                       \n                       new MenuItem()\n                        {\n                            Text = \"账号管理\",\n                            Icon = \"fa fa-user\",\n                            Url = \"/Administrator\"\n                        },\n                        new MenuItem()\n                        {\n                            Text = \"节点管理\",\n                            Icon = \"fa fa-chain\",\n                            Url = \"/Node\"\n                        }\n                   }\n               },         \n               new MenuItem()\n               {\n                   Text=\"网关配置\",\n                   Icon = \"fa fa-fw fa-database\",\n                   Items=new List<MenuItem>()\n                   {\n                       new MenuItem() { Text = \"服务治理配置\", Icon = \"fa fa-cogs\", Url = \"/ServiceGovernance\" },\n                       new MenuItem() { Text = \"身份认证配置(Jwt)\", Icon = \"fas fa-user-secret\", Url = \"/Authentication\" },\n                       new MenuItem() { Text = \"白名单管理\", Icon = \"fas fa-paper-plane\", Url = \"/WhiteList\" },\n                       new MenuItem() { Text = \"路由管理\", Icon = \"fa fa-external-link\", Url = \"/Route\" },\n                       new MenuItem(){ Text=\"中间件管理\", Icon=\"fa fa-plug\",Url=\"/Middleware\"}\n                   }\n               } \n            };\n\n        return menus;\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Shared/MainLayout.razor.css",
    "content": ".page {\n    position: relative;\n    display: flex;\n    flex-direction: column;\n}\n\nmain {\n    flex: 1;\n}\n\n.sidebar {\n    background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);\n}\n\n.top-row {\n    background-color: #f7f7f7;\n    border-bottom: 1px solid #d6d5d5;\n    justify-content: flex-end;\n    height: 3.5rem;\n    display: flex;\n    align-items: center;\n}\n\n    .top-row ::deep a, .top-row .btn-link {\n        white-space: nowrap;\n        margin-left: 1.5rem;\n    }\n\n    .top-row a:first-child {\n        overflow: hidden;\n        text-overflow: ellipsis;\n    }\n\n@media (max-width: 640.98px) {\n    .top-row:not(.auth) {\n        display: none;\n    }\n\n    .top-row.auth {\n        justify-content: space-between;\n    }\n\n    .top-row a, .top-row .btn-link {\n        margin-left: 0;\n    }\n}\n\n@media (min-width: 641px) {\n    .page {\n        flex-direction: row;\n    }\n\n    .sidebar {\n        width: 250px;\n        height: 100vh;\n        position: sticky;\n        top: 0;\n    }\n\n    .top-row {\n        position: sticky;\n        top: 0;\n        z-index: 1;\n    }\n\n    .top-row, article {\n        padding-left: 2rem !important;\n        padding-right: 1.5rem !important;\n    }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/Shared/SimpleLayout.razor",
    "content": "﻿@inherits LayoutComponentBase\n\n\n @Body\n\n@code {\n\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/_Imports.razor",
    "content": "﻿@using System.Net.Http\n@using Microsoft.AspNetCore.Authorization\n@using Microsoft.AspNetCore.Components.Authorization\n@using Microsoft.AspNetCore.Components.Forms\n@using Microsoft.AspNetCore.Components.Routing\n@using Microsoft.AspNetCore.Components.Web\n@using Microsoft.AspNetCore.Components.Web.Virtualization\n@using Microsoft.JSInterop\n@using Kite.Gateway.Admin\n@using Kite.Gateway.Admin.Shared\n@using BootstrapBlazor.Components"
  },
  {
    "path": "admin/Kite.Gateway.Admin/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\",\n  \"ConnectionStrings\": {\n    \"Default\": \"DataSource=./data/KiteGateway.db\"\n  }\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/wwwroot/css/open-iconic/FONT-LICENSE",
    "content": "SIL OPEN FONT LICENSE Version 1.1\n\nCopyright (c) 2014 Waybury\n\nPREAMBLE\nThe goals of the Open Font License (OFL) are to stimulate worldwide\ndevelopment of collaborative font projects, to support the font creation\nefforts of academic and linguistic communities, and to provide a free and\nopen framework in which fonts may be shared and improved in partnership\nwith others.\n\nThe OFL allows the licensed fonts to be used, studied, modified and\nredistributed freely as long as they are not sold by themselves. The\nfonts, including any derivative works, can be bundled, embedded,\nredistributed and/or sold with any software provided that any reserved\nnames are not used by derivative works. The fonts and derivatives,\nhowever, cannot be released under any other type of license. The\nrequirement for fonts to remain under this license does not apply\nto any document created using the fonts or their derivatives.\n\nDEFINITIONS\n\"Font Software\" refers to the set of files released by the Copyright\nHolder(s) under this license and clearly marked as such. This may\ninclude source files, build scripts and documentation.\n\n\"Reserved Font Name\" refers to any names specified as such after the\ncopyright statement(s).\n\n\"Original Version\" refers to the collection of Font Software components as\ndistributed by the Copyright Holder(s).\n\n\"Modified Version\" refers to any derivative made by adding to, deleting,\nor substituting -- in part or in whole -- any of the components of the\nOriginal Version, by changing formats or by porting the Font Software to a\nnew environment.\n\n\"Author\" refers to any designer, engineer, programmer, technical\nwriter or other person who contributed to the Font Software.\n\nPERMISSION & CONDITIONS\nPermission is hereby granted, free of charge, to any person obtaining\na copy of the Font Software, to use, study, copy, merge, embed, modify,\nredistribute, and sell modified and unmodified copies of the Font\nSoftware, subject to the following conditions:\n\n1) Neither the Font Software nor any of its individual components,\nin Original or Modified Versions, may be sold by itself.\n\n2) Original or Modified Versions of the Font Software may be bundled,\nredistributed and/or sold with any software, provided that each copy\ncontains the above copyright notice and this license. These can be\nincluded either as stand-alone text files, human-readable headers or\nin the appropriate machine-readable metadata fields within text or\nbinary files as long as those fields can be easily viewed by the user.\n\n3) No Modified Version of the Font Software may use the Reserved Font\nName(s) unless explicit written permission is granted by the corresponding\nCopyright Holder. This restriction only applies to the primary font name as\npresented to the users.\n\n4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\nSoftware shall not be used to promote, endorse or advertise any\nModified Version, except to acknowledge the contribution(s) of the\nCopyright Holder(s) and the Author(s) or with their explicit written\npermission.\n\n5) The Font Software, modified or unmodified, in part or in whole,\nmust be distributed entirely under this license, and must not be\ndistributed under any other license. The requirement for fonts to\nremain under this license does not apply to any document created\nusing the Font Software.\n\nTERMINATION\nThis license becomes null and void if any of the above conditions are\nnot met.\n\nDISCLAIMER\nTHE FONT SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\nOF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\nCOPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nINCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\nDAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\nOTHER DEALINGS IN THE FONT SOFTWARE.\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/wwwroot/css/open-iconic/ICON-LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Waybury\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "admin/Kite.Gateway.Admin/wwwroot/css/open-iconic/README.md",
    "content": "[Open Iconic v1.1.1](http://useiconic.com/open)\n===========\n\n### Open Iconic is the open source sibling of [Iconic](http://useiconic.com). It is a hyper-legible collection of 223 icons with a tiny footprint&mdash;ready to use with Bootstrap and Foundation. [View the collection](http://useiconic.com/open#icons)\n\n\n\n## What's in Open Iconic?\n\n* 223 icons designed to be legible down to 8 pixels\n* Super-light SVG files - 61.8 for the entire set \n* SVG sprite&mdash;the modern replacement for icon fonts\n* Webfont (EOT, OTF, SVG, TTF, WOFF), PNG and WebP formats\n* Webfont stylesheets (including versions for Bootstrap and Foundation) in CSS, LESS, SCSS and Stylus formats\n* PNG and WebP raster images in 8px, 16px, 24px, 32px, 48px and 64px.\n\n\n## Getting Started\n\n#### For code samples and everything else you need to get started with Open Iconic, check out our [Icons](http://useiconic.com/open#icons) and [Reference](http://useiconic.com/open#reference) sections.\n\n### General Usage\n\n#### Using Open Iconic's SVGs\n\nWe like SVGs and we think they're the way to display icons on the web. Since Open Iconic are just basic SVGs, we suggest you display them like you would any other image (don't forget the `alt` attribute).\n\n```\n<img src=\"/open-iconic/svg/icon-name.svg\" alt=\"icon name\">\n```\n\n#### Using Open Iconic's SVG Sprite\n\nOpen Iconic also comes in a SVG sprite which allows you to display all the icons in the set with a single request. It's like an icon font, without being a hack.\n\nAdding an icon from an SVG sprite is a little different than what you're used to, but it's still a piece of cake. *Tip: To make your icons easily style able, we suggest adding a general class to the* `<svg>` *tag and a unique class name for each different icon in the* `<use>` *tag.*  \n\n```\n<svg class=\"icon\">\n  <use xlink:href=\"open-iconic.svg#account-login\" class=\"icon-account-login\"></use>\n</svg>\n```\n\nSizing icons only needs basic CSS. All the icons are in a square format, so just set the `<svg>` tag with equal width and height dimensions.\n\n```\n.icon {\n  width: 16px;\n  height: 16px;\n}\n```\n\nColoring icons is even easier. All you need to do is set the `fill` rule on the `<use>` tag.\n\n```\n.icon-account-login {\n  fill: #f00;\n}\n```\n\nTo learn more about SVG Sprites, read [Chris Coyier's guide](http://css-tricks.com/svg-sprites-use-better-icon-fonts/).\n\n#### Using Open Iconic's Icon Font...\n\n\n##### …with Bootstrap\n\nYou can find our Bootstrap stylesheets in `font/css/open-iconic-bootstrap.{css, less, scss, styl}`\n\n\n```\n<link href=\"/open-iconic/font/css/open-iconic-bootstrap.css\" rel=\"stylesheet\">\n```\n\n\n```\n<span class=\"oi oi-icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n##### …with Foundation\n\nYou can find our Foundation stylesheets in `font/css/open-iconic-foundation.{css, less, scss, styl}`\n\n```\n<link href=\"/open-iconic/font/css/open-iconic-foundation.css\" rel=\"stylesheet\">\n```\n\n\n```\n<span class=\"fi-icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n##### …on its own\n\nYou can find our default stylesheets in `font/css/open-iconic.{css, less, scss, styl}`\n\n```\n<link href=\"/open-iconic/font/css/open-iconic.css\" rel=\"stylesheet\">\n```\n\n```\n<span class=\"oi\" data-glyph=\"icon-name\" title=\"icon name\" aria-hidden=\"true\"></span>\n```\n\n\n## License\n\n### Icons\n\nAll code (including SVG markup) is under the [MIT License](http://opensource.org/licenses/MIT).\n\n### Fonts\n\nAll fonts are under the [SIL Licensed](http://scripts.sil.org/cms/scripts/page.php?item_id=OFL_web).\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/wwwroot/css/signin.css",
    "content": "html,\nbody {\n  height: 100%;\n}\n\nbody {\n  display: flex;\n  align-items: center;\n  padding-top: 40px;\n  padding-bottom: 40px;\n  background-color: #f5f5f5;\n}\n\n.form-signin {\n  width: 100%;\n  max-width: 330px;\n  padding: 15px;\n  margin: auto;\n}\n\n.form-signin .checkbox {\n  font-weight: 400;\n}\n\n.form-signin .form-floating:focus-within {\n  z-index: 2;\n}\n\n.form-signin input[type=\"email\"] {\n  margin-bottom: -1px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.form-signin input[type=\"password\"] {\n  margin-bottom: 10px;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n"
  },
  {
    "path": "admin/Kite.Gateway.Admin/wwwroot/css/site.css",
    "content": "@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');\n\nhtml, body {\n    font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n}\n\nh1:focus {\n    outline: none;\n}\n\na, .btn-link {\n    color: #0071c1;\n}\n\n.btn-primary {\n    color: #fff;\n    background-color: #1b6ec2;\n    border-color: #1861ac;\n}\n\n.content {\n    padding-top: 1.1rem;\n}\n\n.valid.modified:not([type=checkbox]) {\n    outline: 1px solid #26b050;\n}\n\n.invalid {\n    outline: 1px solid red;\n}\n\n.validation-message {\n    color: red;\n}\n\n#blazor-error-ui {\n    background: lightyellow;\n    bottom: 0;\n    box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);\n    display: none;\n    left: 0;\n    padding: 0.6rem 1.25rem 0.7rem 1.25rem;\n    position: fixed;\n    width: 100%;\n    z-index: 1000;\n}\n\n    #blazor-error-ui .dismiss {\n        cursor: pointer;\n        position: absolute;\n        right: 0.75rem;\n        top: 0.5rem;\n    }\n\n.blazor-error-boundary {\n    background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;\n    padding: 1rem 1rem 1rem 3.7rem;\n    color: white;\n}\n\n    .blazor-error-boundary::after {\n        content: \"An error has occurred.\"\n    }\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Authorization/ClaimModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Simple.Account.Authorization\n{\n    public class ClaimModel\n    {\n        /// <summary>\n        /// 声明名\n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        /// 声明值\n        /// </summary>\n        public string Value { get; set; }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Authorization/IJwtTokenManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Simple.Account.Authorization\n{\n    public interface IJwtTokenManager\n    {\n        /// <summary>\n        /// 生成token\n        /// </summary>\n        /// <param name=\"claims\"></param>\n        /// <returns></returns>\n        JwtTokenResult GenerateToken(List<Claim> claims);\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Authorization/JwtTokenAuthenticateResult.cs",
    "content": "﻿using Microsoft.IdentityModel.Tokens;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Simple.Account.Authorization\n{\n    public class JwtTokenAuthenticateResult\n    {\n        /// <summary>\n        /// 验证是否成功\n        /// </summary>\n        public bool Successed { get; set; }\n        /// <summary>\n        /// 消息\n        /// </summary>\n        public string Message { get; set; }\n        /// <summary>\n        /// 声明信息(验证成功时返回)\n        /// </summary>\n        public List<ClaimModel> Claims { get; set; }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Authorization/JwtTokenManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Authentication.JwtBearer;\nusing Microsoft.IdentityModel.Tokens;\nusing Microsoft.Extensions.Options;\nusing System.Security.Cryptography.X509Certificates;\nusing Microsoft.AspNetCore.Hosting;\nusing System.IO;\n\nnamespace Kite.Simple.Account.Authorization\n{\n    public class JwtTokenManager: IJwtTokenManager\n    {\n        private readonly JwtTokenOptions _options;\n        private readonly IWebHostEnvironment _env;\n        public JwtTokenManager(IOptions<JwtTokenOptions> options, IWebHostEnvironment env)\n        {\n            _options = options?.Value;\n            _env = env;\n        }\n        /// <summary>\n        /// 生成Token\n        /// </summary>\n        /// <param name=\"claims\">声明对象集合</param>\n        /// <returns></returns>\n        public JwtTokenResult GenerateToken(List<Claim> claims)\n        {\n\n            var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_options.SecurityKeyStr));\n            var credentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);\n            var token = new JwtSecurityToken(\n                _options.Issuer,\n                _options.Audience,\n                claims,\n                DateTime.Now,\n                DateTime.Now.AddSeconds(_options.ExpiresTime),\n                credentials\n            );\n            var jwtToken = new JwtSecurityTokenHandler().WriteToken(token);\n            return new JwtTokenResult()\n            {\n                AccessToken = jwtToken,\n                EffectiveTime = _options.ExpiresTime,\n                IssueTime = DateTime.Now,\n                ExpiresTime = DateTime.Now.AddSeconds(_options.ExpiresTime)\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Authorization/JwtTokenOptions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Simple.Account.Authorization\n{\n    public class JwtTokenOptions\n    {\n        /// <summary>\n        /// 颁发者\n        /// </summary>\n        public string Issuer { get; set; }\n        /// <summary>\n        /// 观察者\n        /// </summary>\n        public string Audience { get; set; }\n        /// <summary>\n        /// token生成与验证密钥\n        /// </summary>\n        public string SecurityKeyStr { get; set; }\n        /// <summary>\n        /// 过期时间(单位:秒)\n        /// </summary>\n        public int ExpiresTime { get; set; }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Authorization/JwtTokenResult.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Simple.Account.Authorization\n{\n    public class JwtTokenResult\n    {\n        /// <summary>\n        /// token\n        /// </summary>\n        public string AccessToken {  get; set; }\n        /// <summary>\n        /// 有效时长(单位:分钟)\n        /// </summary>\n        public int EffectiveTime { get; set; }\n        /// <summary>\n        /// 颁发时间\n        /// </summary>\n        public DateTime IssueTime { get; set; }\n        /// <summary>\n        /// 过期时间\n        /// </summary>\n        public DateTime ExpiresTime { get; set; }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Controllers/AccountController.cs",
    "content": "﻿using Kite.Simple.Account.Models;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Kite.Simple.Account.Controllers\n{\n    [Route(\"api/[controller]\")]\n    [ApiController]\n    public class AccountController : ControllerBase\n    {\n        /// <summary>\n        /// 创建账号\n        /// </summary>\n        /// <param name=\"createAccount\"></param>\n        /// <returns></returns>\n        [HttpPost]\n        public IActionResult CreateAsync(CreateAccountDto createAccount)\n        {\n            return Ok(createAccount);\n        }\n        /// <summary>\n        /// 获取账号信息\n        /// </summary>\n        /// <param name=\"accountName\">账号名</param>\n        /// <returns></returns>\n        [HttpGet]\n        public IActionResult GetAsync(string accountName)\n        {\n            return Ok(new \n            {\n                AccountName= accountName,\n                Password=\"123456\",\n                NickName=\"法外狂徒张三\"\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Controllers/LoginController.cs",
    "content": "﻿using Kite.Simple.Account.Authorization;\nusing Kite.Simple.Account.Models;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing System.Security.Claims;\nnamespace Kite.Simple.Account.Controllers\n{\n    [Route(\"api/[controller]\")]\n    [ApiController]\n    public class LoginController : ControllerBase\n    {\n        private readonly IJwtTokenManager _jwtTokenManager;\n\n        public LoginController(IJwtTokenManager jwtTokenManager)\n        {\n            _jwtTokenManager = jwtTokenManager;\n        }\n\n        /// <summary>\n        /// 登录(测试账号:test/123456)\n        /// </summary>\n        /// <param name=\"accountLogin\"></param>\n        /// <returns></returns>\n        [HttpPost]\n        public IActionResult PostAsync(AccountLoginDto accountLogin)\n        {\n            if (accountLogin.AccountName != \"test\" && accountLogin.Password != \"123456\")\n            {\n                throw new Exception(\"账号密码错误\");\n            }\n            var result = new AccountLoginResultDto();\n            result.AccountName = accountLogin.AccountName;\n            result.NickName = \"法外狂徒张三\";\n            //\n            var claims = new List<Claim>();\n            claims.Add(new Claim(\"AccountName\", accountLogin.AccountName));\n            claims.Add(new Claim(\"NickName\", result.NickName));\n            result.JwtToken = _jwtTokenManager.GenerateToken(claims);\n            return Ok(result);\n        }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Controllers/MiddlewareController.cs",
    "content": "﻿using Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing System.Text.Json;\nnamespace Kite.Simple.Account.Controllers\n{\n    [Route(\"api/[controller]\")]\n    [ApiController]\n    public class MiddlewareController : ControllerBase\n    {\n        /// <summary>\n        /// 中间件判断\n        /// </summary>\n        /// <returns></returns>\n        [HttpPost]\n        public IActionResult PostAsync()\n        {\n            foreach (var item in Request.Headers)\n            {\n                Console.WriteLine(JsonSerializer.Serialize(item));\n            }\n            return Ok();\n        }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Controllers/WeatherForecastController.cs",
    "content": "using Microsoft.AspNetCore.Mvc;\n\nnamespace Kite.Simple.Account.Controllers\n{\n    [ApiController]\n    [Route(\"[controller]\")]\n    public class WeatherForecastController : ControllerBase\n    {\n        private static readonly string[] Summaries = new[]\n        {\n        \"Freezing\", \"Bracing\", \"Chilly\", \"Cool\", \"Mild\", \"Warm\", \"Balmy\", \"Hot\", \"Sweltering\", \"Scorching\"\n    };\n\n        private readonly ILogger<WeatherForecastController> _logger;\n\n        public WeatherForecastController(ILogger<WeatherForecastController> logger)\n        {\n            _logger = logger;\n        }\n\n        [HttpGet(Name = \"GetWeatherForecast\")]\n        public IEnumerable<WeatherForecast> Get()\n        {\n            return Enumerable.Range(1, 5).Select(index => new WeatherForecast\n            {\n                Date = DateTime.Now.AddDays(index),\n                TemperatureC = Random.Shared.Next(-20, 55),\n                Summary = Summaries[Random.Shared.Next(Summaries.Length)]\n            })\n            .ToArray();\n        }\n    }\n}"
  },
  {
    "path": "simples/Kite.Simple.Account/Kite.Simple.Account.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>net6.0</TargetFramework>\n    <Nullable>enable</Nullable>\n    <ImplicitUsings>enable</ImplicitUsings>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.JwtBearer\" Version=\"6.0.6\" />\n    <PackageReference Include=\"Swashbuckle.AspNetCore\" Version=\"6.2.3\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Models/AccountLoginDto.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace Kite.Simple.Account.Models\n{\n    public class AccountLoginDto\n    {\n        /// <summary>\n        /// 账号名\n        /// </summary>\n        [Required]\n        public string AccountName { get; set; }\n        /// <summary>\n        /// 密码\n        /// </summary>\n        [Required]\n        public string Password { get; set; }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Models/AccountLoginResultDto.cs",
    "content": "﻿using Kite.Simple.Account.Authorization;\n\nnamespace Kite.Simple.Account.Models\n{\n    public class AccountLoginResultDto\n    {\n        /// <summary>\n        /// 账号名\n        /// </summary>\n        public string AccountName { get; set; }\n        /// <summary>\n        /// 昵称\n        /// </summary>\n        public string NickName { get; set; }\n        /// <summary>\n        /// 授权token\n        /// </summary>\n        public JwtTokenResult JwtToken { get; set; }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Models/CreateAccountDto.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\nnamespace Kite.Simple.Account.Models\n{\n    public class CreateAccountDto\n    {\n        /// <summary>\n        /// 账号名\n        /// </summary>\n        [Required]\n        public string AccountName { get; set; }\n        /// <summary>\n        /// 密码\n        /// </summary>\n        [Required]\n        public string Password { get; set; }\n        /// <summary>\n        /// 昵称\n        /// </summary>\n        [Required]\n        public string NickName { get; set; }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Program.cs",
    "content": "using Kite.Simple.Account.Authorization;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\n\nbuilder.Services.AddControllers();\n// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle\nbuilder.Services.AddEndpointsApiExplorer();\nbuilder.Services.AddSwaggerGen();\n\nbuilder.Services.Configure<JwtTokenOptions>(builder.Configuration.GetSection(\"Authorization\"));\nbuilder.Services.AddSingleton<IJwtTokenManager, JwtTokenManager>();\nvar app = builder.Build();\n\n// Configure the HTTP request pipeline.\nif (app.Environment.IsDevelopment())\n{\n    app.UseSwagger();\n    app.UseSwaggerUI();\n}\n\napp.UseAuthorization();\n\napp.MapControllers();\n\napp.Run();\n"
  },
  {
    "path": "simples/Kite.Simple.Account/Properties/launchSettings.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/launchsettings.json\",\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:24268\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"Kite.Simple.Account\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"swagger\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:55667\",\n      \"dotnetRunMessages\": true\n    },\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"swagger\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "simples/Kite.Simple.Account/WeatherForecast.cs",
    "content": "namespace Kite.Simple.Account\n{\n    public class WeatherForecast\n    {\n        public DateTime Date { get; set; }\n\n        public int TemperatureC { get; set; }\n\n        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);\n\n        public string? Summary { get; set; }\n    }\n}"
  },
  {
    "path": "simples/Kite.Simple.Account/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\",\n  \"Authorization\": {\n    \"Issuer\": \"kite.top\", //颁发者\n    \"Audience\": \"kite.top\", //观察者\n    \"SecurityKeyStr\": \"SFYHDzdXrFRZIPhbpkJdWbpgBfQ3yNUa\", //密钥字符串\n    \"ExpiresTime\": 7200\n  }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Order/Controllers/OrderController.cs",
    "content": "﻿using Kite.Simple.Order.Models;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Kite.Simple.Order.Controllers\n{\n    [Route(\"api/[controller]\")]\n    [ApiController]\n    public class OrderController : ControllerBase\n    {\n        /// <summary>\n        /// 创建订单\n        /// </summary>\n        /// <returns></returns>\n        [HttpPost]\n        public IActionResult CreateAsync(CreateOrderDto createOrder)\n        {\n            var result = new\n            {\n                AccountId = createOrder.AccountId,\n                ProductId = createOrder.ProductId,\n                Price = createOrder.Price,\n                BuyCount = createOrder.BuyCount,\n                OrderNo = \"T202207090001\",\n                TotalAmount= createOrder.Price* createOrder.BuyCount\n            };\n            return Ok(result);\n        }\n        /// <summary>\n        /// 获取订单信息\n        /// </summary>\n        /// <param name=\"orderNo\">订单号</param>\n        /// <returns></returns>\n        [HttpGet]\n        public IActionResult GetAsync(string orderNo)\n        {\n            var result = new\n            {\n                AccountId = 1,\n                ProductId = 1,\n                Price = 9.9,\n                BuyCount = 10,\n                OrderNo = orderNo,\n                TotalAmount = 99\n            };\n            return Ok(result);\n        }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Order/Controllers/WeatherForecastController.cs",
    "content": "using Microsoft.AspNetCore.Mvc;\n\nnamespace Kite.Simple.Order.Controllers\n{\n    [ApiController]\n    [Route(\"[controller]\")]\n    public class WeatherForecastController : ControllerBase\n    {\n        private static readonly string[] Summaries = new[]\n        {\n        \"Freezing\", \"Bracing\", \"Chilly\", \"Cool\", \"Mild\", \"Warm\", \"Balmy\", \"Hot\", \"Sweltering\", \"Scorching\"\n    };\n\n        private readonly ILogger<WeatherForecastController> _logger;\n\n        public WeatherForecastController(ILogger<WeatherForecastController> logger)\n        {\n            _logger = logger;\n        }\n\n        [HttpGet(Name = \"GetWeatherForecast\")]\n        public IEnumerable<WeatherForecast> Get()\n        {\n            return Enumerable.Range(1, 5).Select(index => new WeatherForecast\n            {\n                Date = DateTime.Now.AddDays(index),\n                TemperatureC = Random.Shared.Next(-20, 55),\n                Summary = Summaries[Random.Shared.Next(Summaries.Length)]\n            })\n            .ToArray();\n        }\n    }\n}"
  },
  {
    "path": "simples/Kite.Simple.Order/Kite.Simple.Order.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>net6.0</TargetFramework>\n    <Nullable>enable</Nullable>\n    <ImplicitUsings>enable</ImplicitUsings>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Swashbuckle.AspNetCore\" Version=\"6.2.3\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "simples/Kite.Simple.Order/Models/CreateOrderDto.cs",
    "content": "﻿namespace Kite.Simple.Order.Models\n{\n    public class CreateOrderDto\n    {\n        /// <summary>\n        /// 下单账号ID\n        /// </summary>\n        public int AccountId { get; set; }\n        /// <summary>\n        /// 产品ID\n        /// </summary>\n        public int ProductId { get; set; }\n        /// <summary>\n        /// 单价\n        /// </summary>\n        public decimal Price { get; set; }\n        /// <summary>\n        /// 购买数量\n        /// </summary>\n        public int BuyCount { get; set; }\n    }\n}\n"
  },
  {
    "path": "simples/Kite.Simple.Order/Program.cs",
    "content": "var builder = WebApplication.CreateBuilder(args);\n\n// Add services to the container.\n\nbuilder.Services.AddControllers();\n// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle\nbuilder.Services.AddEndpointsApiExplorer();\nbuilder.Services.AddSwaggerGen();\n\nvar app = builder.Build();\n\n// Configure the HTTP request pipeline.\nif (app.Environment.IsDevelopment())\n{\n    app.UseSwagger();\n    app.UseSwaggerUI();\n}\n\napp.UseAuthorization();\n\napp.MapControllers();\n\napp.Run();\n"
  },
  {
    "path": "simples/Kite.Simple.Order/Properties/launchSettings.json",
    "content": "{\n  \"$schema\": \"https://json.schemastore.org/launchsettings.json\",\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:31561\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"Kite.Simple.Order\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"swagger\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"applicationUrl\": \"http://localhost:55665\",\n      \"dotnetRunMessages\": true\n    },\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"swagger\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    }\n  }\n}"
  },
  {
    "path": "simples/Kite.Simple.Order/WeatherForecast.cs",
    "content": "namespace Kite.Simple.Order\n{\n    public class WeatherForecast\n    {\n        public DateTime Date { get; set; }\n\n        public int TemperatureC { get; set; }\n\n        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);\n\n        public string? Summary { get; set; }\n    }\n}"
  },
  {
    "path": "simples/Kite.Simple.Order/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\"\n}\n"
  },
  {
    "path": "simples/Kite.SimpleServices.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.2.32616.157\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Kite.Simple.Account\", \"Kite.Simple.Account\\Kite.Simple.Account.csproj\", \"{C8CABF49-AC3C-4409-9052-DCD4DB05D95B}\"\nEndProject\nProject(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"Kite.Simple.Order\", \"Kite.Simple.Order\\Kite.Simple.Order.csproj\", \"{5B542B99-706E-4233-8DC8-FC6323DCFDCC}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{C8CABF49-AC3C-4409-9052-DCD4DB05D95B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C8CABF49-AC3C-4409-9052-DCD4DB05D95B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C8CABF49-AC3C-4409-9052-DCD4DB05D95B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C8CABF49-AC3C-4409-9052-DCD4DB05D95B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{5B542B99-706E-4233-8DC8-FC6323DCFDCC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{5B542B99-706E-4233-8DC8-FC6323DCFDCC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{5B542B99-706E-4233-8DC8-FC6323DCFDCC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{5B542B99-706E-4233-8DC8-FC6323DCFDCC}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {A0942BEF-2D59-4E9C-AC1A-95B5603A89D3}\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "src/Kite.Gateway.Application/AdministratorAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Application.Contracts.Dtos.Administrator;\nusing Kite.Gateway.Domain.Administrator;\nusing Kite.Gateway.Domain.Entities;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\nusing Mapster;\nusing Kite.Gateway.Domain.Shared;\n\nnamespace Kite.Gateway.Application\n{\n    public class AdministratorAppService : BaseApplicationService, IAdministratorAppService\n    {\n        private readonly IRepository<Administrator> _repository;\n        private readonly IAdministratorManager _administratorManager;\n\n        public AdministratorAppService(IAdministratorManager administratorManager, IRepository<Administrator> repository)\n        {\n            _administratorManager = administratorManager;\n            _repository = repository;\n        }\n        public async Task<KiteResult<AdministratorDto>> LoginAsync(LoginAdministratorDto loginAdministrator)\n        {\n            //如果账号未初始化则默认初始化一个账号\n            if (await _repository.CountAsync() <= 0)\n            {\n                await _repository.InsertAsync(new Administrator(GuidGenerator.Create())\n                {\n                    AdminName = \"admin\",\n                    Password = TextHelper.MD5Encrypt(\"admin\"),\n                    Created = DateTime.Now,\n                    NickName = \"默认管理员\",\n                    Updated = DateTime.Now\n                });\n                await CurrentUnitOfWork.SaveChangesAsync();\n            }\n            var administrator =await _administratorManager.LoginAsync(loginAdministrator.AdminName, TextHelper.MD5Encrypt(loginAdministrator.Password));\n            var result = TypeAdapter.Adapt<AdministratorDto>(administrator);\n            return Ok(result);\n        }\n\n        public async Task<KiteResult> CreateAsync(CreateAdministratorDto createAdministrator)\n        {\n            var model =await _administratorManager.CreateAsync(createAdministrator.AdminName);\n            model.AdminName = createAdministrator.AdminName;\n            model.NickName = createAdministrator.NickName;\n            model.Password = TextHelper.MD5Encrypt(createAdministrator.Password);\n            await _repository.InsertAsync(model);\n            return Ok();\n        }\n\n        public async Task<KiteResult> DeleteAsync(Guid id)\n        {\n            await _repository.DeleteAsync(x => x.Id == id);\n            return Ok();\n        }\n\n        public async Task<KiteResult<AdministratorDto>> GetAsync(Guid id)\n        {\n            var result = (await _repository.GetQueryableAsync())\n                .Where(x => x.Id == id)\n                .ProjectToType<AdministratorDto>()\n                .FirstOrDefault();\n            return Ok(result);\n        }\n\n        public async Task<KitePageResult<List<AdministratorDto>>> GetListAsync(int page = 1, int pageSize = 10)\n        {\n            var query = (await _repository.GetQueryableAsync());\n            var result = query.OrderByDescending(x => x.Created)\n                .PageBy((page - 1) * pageSize, pageSize)\n                .ProjectToType<AdministratorDto>()\n                .ToList();\n            return Ok(result, query.Count());\n        }\n\n        \n\n        public async Task<KiteResult> UpdateAsync(UpdateAdministratorDto updateAdministrator)\n        {\n            var model = await _administratorManager.UpdateAsync(updateAdministrator.Id, updateAdministrator.AdminName);\n            model.AdminName = updateAdministrator.AdminName;\n            model.NickName = updateAdministrator.NickName;\n            model.Updated = DateTime.Now;\n            if (!string.IsNullOrEmpty(updateAdministrator.Password) && updateAdministrator.Password != \"\")\n            {\n                model.Password = TextHelper.MD5Encrypt(updateAdministrator.Password);\n            }\n            await _repository.UpdateAsync(model);\n            return Ok();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/ApplicationModule.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Domain;\nusing Microsoft.Extensions.DependencyInjection;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp;\nusing Volo.Abp.Modularity;\n\nnamespace Kite.Gateway.Application\n{\n    [DependsOn(\n        typeof(DomainModule),\n        typeof(ApplicationContractsModule)\n        )]\n    public class ApplicationModule:AbpModule\n    {\n        public override void ConfigureServices(ServiceConfigurationContext context)\n        {\n            //在此处注入依赖项\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/AuthorizationAppService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Application.Contracts.Dtos.Authorization;\nusing Kite.Gateway.Domain.Entities;\nusing Volo.Abp.Domain.Repositories;\nusing Mapster;\nnamespace Kite.Gateway.Application\n{\n    public class AuthorizationAppService : BaseApplicationService, IAuthorizationAppService\n    {\n        private readonly IRepository<AuthenticationConfigure> _authenticationRepository;\n\n        public AuthorizationAppService(IRepository<AuthenticationConfigure> authenticationRepository)\n        {\n            _authenticationRepository = authenticationRepository;\n\n        }\n\n        public async Task<KiteResult<SaveAuthenticationDto>> GetAuthenticationAsync()\n        {\n            var result= (await _authenticationRepository.GetQueryableAsync())\n                .ProjectToType<SaveAuthenticationDto>()\n                .FirstOrDefault();\n            if (result == null)\n            {\n                result = new SaveAuthenticationDto() \n                {\n                    UseState = true\n                };\n            }\n            return Ok(result);\n        }\n\n        public async Task<KiteResult> SaveAuthenticationAsync(SaveAuthenticationDto authenticationDto)\n        {\n            var model =await _authenticationRepository.FirstOrDefaultAsync();\n            if (model == null)\n            {\n                model = new AuthenticationConfigure(GuidGenerator.Create());\n                TypeAdapter.Adapt(authenticationDto, model);\n                await _authenticationRepository.InsertAsync(model);\n            }\n            else\n            {\n                TypeAdapter.Adapt(authenticationDto, model);\n                \n                await _authenticationRepository.UpdateAsync(model);\n            }\n            return Ok();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/BaseApplicationService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp;\nusing Volo.Abp.Application.Services;\n\nnamespace Kite.Gateway.Application\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public class BaseApplicationService : ApplicationService\n    {\n        /// <summary>\n        /// 抛出异常\n        /// </summary>\n        /// <param name=\"msg\">消息</param>\n        /// <exception cref=\"Exception\"></exception>\n        [RemoteService(IsEnabled = false)]\n        public static void ThrownFailed(string msg)\n        {\n            throw new SimpleHttpException(msg);\n        }\n        /// <summary>\n        /// 成功返回\n        /// </summary>\n        /// <returns></returns>\n        [RemoteService(IsEnabled = false)]\n        public static KiteResult Ok()\n        {\n            return new KiteResult()\n            {\n                Code = 0,\n                Message = \"success\"\n            };\n        }\n        /// <summary>\n        /// 成功返回\n        /// </summary>\n        /// <param name=\"data\">数据</param>\n        /// <returns></returns>\n        [RemoteService(IsEnabled = false)]\n        public static KiteResult<TResult> Ok<TResult>(TResult data)\n        {\n            return new KiteResult<TResult>()\n            {\n                Code = 0,\n                Message = \"success\",\n                Data = data\n            };\n        }\n        /// <summary>\n        /// 成功返回\n        /// </summary>\n        /// <param name=\"data\">数据</param>\n        /// <param name=\"totalCount\">总记录数</param>\n        /// <returns></returns>\n        [RemoteService(IsEnabled = false)]\n        public static KitePageResult<TResult> Ok<TResult>(TResult data, int totalCount)\n        {\n            return new KitePageResult<TResult>()\n            {\n                Code = 0,\n                Message = \"success\",\n                Data = data,\n                Count = totalCount\n            };\n        }\n        /// <summary>\n        /// 返回自定义状态码 \n        /// </summary>\n        /// <param name=\"code\">状态码</param>\n        /// <param name=\"message\"></param>\n        /// <returns></returns>\n        [RemoteService(IsEnabled = false)]\n        public static KiteResult Customize(int code, string message = \"\")\n        {\n            return new KiteResult()\n            {\n                Code = code,\n                Message = message\n            };\n        }\n        /// <summary>\n        /// 返回自定义状态码 \n        /// </summary>\n        /// <param name=\"code\">状态码</param>\n        /// <param name=\"message\"></param>\n        /// <param name=\"data\"></param>\n        /// <returns></returns>\n        [RemoteService(IsEnabled = false)]\n        public static KiteResult<TResult> Customize<TResult>(int code, string message, TResult data)\n        {\n            return new KiteResult<TResult>()\n            {\n                Code = code,\n                Message = message,\n                Data = data\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/ConfigureAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Application.Contracts.Dtos;\nusing Kite.Gateway.Application.Contracts.Dtos.Node;\nusing Kite.Gateway.Domain;\nusing Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.ReverseProxy;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Mapster;\nusing Microsoft.Extensions.DependencyInjection;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\n\nnamespace Kite.Gateway.Application\n{\n    public class ConfigureAppService: BaseApplicationService,IConfigureAppService\n    {\n        private readonly IServiceProvider _serviceProvider;\n        public ConfigureAppService(IServiceProvider serviceProvider)\n        {\n            _serviceProvider = serviceProvider;\n        }\n        public async Task<KiteResult<RefreshConfigureDto>> GetConfigureAsync(ReloadConfigureDto reloadConfigure)\n        {\n            var result = new RefreshConfigureDto();\n            if (reloadConfigure.IsReloadAuthentication)\n            {\n                var repository = _serviceProvider.GetService<IRepository<AuthenticationConfigure>>();\n                result.Authentication = (await repository.GetQueryableAsync())\n                    .ProjectToType<AuthenticationOption>()\n                    .FirstOrDefault();\n            }\n            if (reloadConfigure.IsReloadMiddleware)\n            {\n                var repository = _serviceProvider.GetService<IRepository<Middleware>>();\n                result.Middlewares = (await repository.GetQueryableAsync())\n                    .Where(x => x.UseState)\n                    .OrderByDescending(x => x.ExecWeight)\n                    .ProjectToType<MiddlewareOption>()\n                    .ToList();\n            }\n            if (reloadConfigure.IsReloadWhitelist)\n            {\n                var repository = _serviceProvider.GetService<IRepository<Whitelist>>();\n                result.Whitelists = (await repository.GetQueryableAsync())\n                    .Where(x => x.UseState)\n                    .Select(x => new WhitelistOption()\n                    {\n                        FilterText = x.FilterText,\n                        Id = x.Id,\n                        Name = x.Name,\n                        RequestMethod = x.RequestMethod,\n                        RouteId = x.RouteId.HasValue ? x.RouteId.ToString().ToLower() : \"00000000-0000-0000-0000-000000000000\"\n                    })\n                    .ToList();\n            }\n            if (reloadConfigure.IsReloadYarp)\n            {\n                var yarpManager = _serviceProvider.GetService<IYarpManager>();\n                result.Yarp = await yarpManager.GetConfigureAsync();\n            }\n            return Ok(result);\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/Kite.Gateway.Application.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net7.0</TargetFramework>\n    <BaseOutputPath></BaseOutputPath>\n    <GenerateDocumentationFile>False</GenerateDocumentationFile>\n    <DocumentationFile>Kite.Gateway.Application.xml</DocumentationFile>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <NoWarn>1701;1702;8602;1591</NoWarn>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\n    <NoWarn>1701;1702;8602;1591</NoWarn>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Volo.Abp.Ddd.Application\" Version=\"7.0.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Kite.Gateway.Application.Contracts\\Kite.Gateway.Application.Contracts.csproj\" />\n    <ProjectReference Include=\"..\\Kite.Gateway.Domain\\Kite.Gateway.Domain.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Kite.Gateway.Application/MiddlewareAppService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Application.Contracts.Dtos.Middleware;\nusing Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.Middlewares;\nusing Mapster;\nusing Volo.Abp.Domain.Repositories;\n\nnamespace Kite.Gateway.Application\n{\n    /// <summary>\n    /// 中间件管理服务\n    /// </summary>\n    public class MiddlewareAppService : BaseApplicationService, IMiddlewareAppService\n    {\n        private readonly IMiddlewareManager _middlewareManager;\n        private readonly IRepository<Middleware> _repository;\n        public MiddlewareAppService(IMiddlewareManager middlewareManager, IRepository<Middleware> repository)\n        {\n            _middlewareManager = middlewareManager;\n            _repository = repository;\n        }\n\n        public async Task<KiteResult> CreateAsync(CreateMiddlewareDto middlewareDto)\n        {\n            var model =await _middlewareManager.CreateAsync(middlewareDto.Name, middlewareDto.Server);\n            TypeAdapter.Adapt(middlewareDto, model);\n            await _repository.InsertAsync(model);\n            return Ok();\n        }\n\n        public async Task<KiteResult> DeleteAsync(Guid id)\n        {\n            await _repository.DeleteAsync(x => x.Id == id);\n            return Ok();\n        }\n\n        public async Task<KiteResult<MiddlewareDto>> GetAsync(Guid id)\n        {\n            var result = (await _repository.GetQueryableAsync())\n                .Where(x => x.Id == id)\n                .ProjectToType<MiddlewareDto>()\n                .FirstOrDefault();\n            return Ok(result);\n        }\n\n        public async Task<KitePageResult<List<MiddlewareListDto>>> GetListAsync(string kw = \"\", int page = 1, int pageSize = 10)\n        {\n            var query = (await _repository.GetQueryableAsync())\n                .WhereIf(!string.IsNullOrEmpty(kw) && kw != \"\", x => x.Name.Contains(kw) || x.Server.Contains(kw));\n            var totalCount = query.Count();\n            var result = query\n                .OrderByDescending(x => x.Created)\n                .PageBy((page - 1) * pageSize, pageSize)\n                .ProjectToType<MiddlewareListDto>()\n                .ToList();\n            return Ok(result, totalCount);\n        }\n\n        public async Task<KiteResult> UpdateAsync(UpdateMiddlewareDto middlewareDto)\n        {\n            var model =await _middlewareManager.UpdateAsync(middlewareDto.Id, middlewareDto.Name, middlewareDto.Server);\n            TypeAdapter.Adapt(middlewareDto, model);\n            model.Updated = DateTime.Now;\n            await _repository.UpdateAsync(model);\n            return Ok();\n        }\n\n        public async Task<KiteResult> UpdateUseStateAsync(Guid id, bool useState)\n        {\n            var model = await _repository.FirstOrDefaultAsync(x=>x.Id==id);\n            model.UseState = useState;\n            model.Updated = DateTime.Now;\n            await _repository.UpdateAsync(model);\n            return Ok();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/NodeAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Application.Contracts.Dtos.Node;\nusing Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.Node;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\nusing Mapster;\nnamespace Kite.Gateway.Application\n{\n    public class NodeAppService : BaseApplicationService, INodeAppService\n    {\n        private readonly IRepository<Node> _repository;\n        private readonly INodeManager _nodeManager;\n\n        public NodeAppService(IRepository<Node> repository, INodeManager nodeManager)\n        {\n            _repository = repository;\n            _nodeManager = nodeManager;\n        }\n\n        public async Task<KiteResult> CreateAsync(CreateNodeDto createNode)\n        {\n            createNode.Server = createNode.Server.TrimEnd('/');\n            var model =await _nodeManager.CreateAsync(createNode.NodeName, createNode.Server);\n            TypeAdapter.Adapt(createNode, model);\n            await _repository.InsertAsync(model);\n            return Ok();\n        }\n\n        public async Task<KiteResult> DeleteAsync(Guid id)\n        {\n            await _repository.DeleteAsync(x=>x.Id==id);\n            return Ok();\n        }\n\n        public async Task<KiteResult<List<NodeDto>>> GetAllAsync()\n        {\n            var result = (await _repository.GetQueryableAsync())\n                .OrderByDescending(x => x.Created)\n                .ProjectToType<NodeDto>()\n                .ToList();\n            return Ok(result);\n        }\n\n        public async Task<KiteResult<NodeDto>> GetAsync(Guid id)\n        {\n            var result= (await _repository.GetQueryableAsync())\n                .Where(x => x.Id == id)\n                .ProjectToType<NodeDto>()\n                .FirstOrDefault();\n            return Ok(result);\n        }\n\n        public async Task<KitePageResult<List<NodeDto>>> GetListAsync(int page = 1, int pageSize = 10)\n        {\n            var query = await _repository.GetQueryableAsync();\n            var result = query\n                .OrderByDescending(x => x.Created)\n                .PageBy((page - 1) * pageSize, pageSize)\n                .ProjectToType<NodeDto>()\n                .ToList();\n            return Ok(result, query.Count());\n        }\n\n        public async Task<KiteResult> UpdateAsync(UpdateNodeDto updateNode)\n        {\n            updateNode.Server = updateNode.Server.TrimEnd('/');\n            var model =await _nodeManager.UpdateAsync(updateNode.Id, updateNode.NodeName, updateNode.Server);\n            TypeAdapter.Adapt(updateNode, model);\n            model.Updated = DateTime.Now;\n            await _repository.UpdateAsync(model);\n            return Ok();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/RefreshAppService.cs",
    "content": "﻿using Microsoft.Extensions.DependencyInjection;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\nusing Volo.Abp.DependencyInjection;\nusing Kite.Gateway.Domain.ReverseProxy;\nusing Volo.Abp;\nusing Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Domain;\nusing Kite.Gateway.Application.Contracts.Dtos.Node;\nusing Kite.Gateway.Application.Contracts.Dtos;\nusing Mapster;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Kite.Gateway.Domain.Entities;\n\nnamespace Kite.Gateway.Application\n{\n    public class RefreshAppService : BaseApplicationService, IRefreshAppService\n    {\n        private readonly IRefreshManager _refreshManager;\n        private readonly IConfigureManager _configureManager;\n        public RefreshAppService( IConfigureManager configureManager, IRefreshManager refreshManager)\n        {\n            _configureManager = configureManager;\n            _refreshManager = refreshManager;\n        }\n        public async Task<KiteResult> RefreshConfigureAsync(RefreshConfigureDto refreshConfigure)\n        {\n            //加载基础配置\n            if (refreshConfigure.Authentication != null)\n            {\n                _configureManager.ReloadAuthentication(refreshConfigure.Authentication);\n            }\n            if (refreshConfigure.Whitelists!=null)\n            {\n                _configureManager.ReloadWhitelist(refreshConfigure.Whitelists);\n            }\n            if (refreshConfigure.Middlewares != null)\n            {\n                _configureManager.ReloadMiddleware(refreshConfigure.Middlewares);\n            }\n            //加载路由等数据\n            if (refreshConfigure.Yarp != null)\n            {\n                _configureManager.ReloadYayp(refreshConfigure.Yarp);\n                await _refreshManager.ReloadConfigAsync();\n            }\n            return Ok();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/RouteAppService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\nusing Volo.Abp.Domain.Services;\nusing Mapster;\nusing Volo.Abp.Application.Services;\nusing Kite.Gateway.Domain;\nusing Microsoft.AspNetCore.Mvc;\nusing Kite.Gateway.Domain.ReverseProxy;\nusing Volo.Abp;\nusing Kite.Gateway.Application.Contracts.Dtos.ReverseProxy;\nusing Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.Shared.Enums;\n\nnamespace Kite.Gateway.Application\n{\n    /// <summary>\n    /// 路由相关接口\n    /// </summary>\n    public class RouteAppService: BaseApplicationService,IRouteAppService\n    {\n        private readonly IClusterManager _clusterManager;\n        private readonly IRouteManager _routeManager;\n\n        private readonly IRepository<Route> _routeRepository;\n        private readonly IRepository<RouteTransform> _routeTransformRepository;\n        private readonly IRepository<Cluster> _clusterRepository;\n        private readonly IRepository<ClusterDestination> _clusterDestinationRepository;\n        private readonly IRepository<ClusterHealthCheck> _clusterHealthCheckRepository;\n        public RouteAppService(IRepository<Route> routeRepository\n            , IRepository<Cluster> clusterRepository\n            , IRepository<ClusterDestination> clusterDestinationRepository\n            , IRepository<RouteTransform> routeTransformRepository\n            , IClusterManager clusterManager, IRouteManager routeManager, IRepository<ClusterHealthCheck> clusterHealthCheckRepository)\n        {\n            _clusterManager = clusterManager;\n            _routeManager = routeManager;\n\n            _routeRepository = routeRepository;\n            _clusterRepository = clusterRepository;\n            _clusterDestinationRepository = clusterDestinationRepository;\n            _routeTransformRepository = routeTransformRepository;\n            _clusterHealthCheckRepository = clusterHealthCheckRepository;\n        }\n        /// <summary>\n        /// 创建路由\n        /// </summary>\n        /// <param name=\"createRouteDto\"></param>\n        /// <returns></returns>\n        public async Task<KiteResult> CreateAsync(CreateRouteDto createRouteDto)\n        {\n            var route = await _routeManager.CreateAsync(createRouteDto.RouteName, createRouteDto.RouteMatchPath, createRouteDto.UseState, createRouteDto.Description);\n            //插入路由信息\n            await _routeRepository.InsertAsync(route);\n            await CurrentUnitOfWork.SaveChangesAsync();\n            //路由转换配置\n            if (!string.IsNullOrEmpty(createRouteDto.PathRemovePrefix)&&createRouteDto.PathRemovePrefix!=\"\")\n            {\n                await _routeTransformRepository.InsertAsync(await _routeManager.CreateRouteTransformAsync(route.Id, \"PathRemovePrefix\", createRouteDto.PathRemovePrefix));\n            }\n            if (!string.IsNullOrEmpty(createRouteDto.PathPrefix) && createRouteDto.PathPrefix != \"\")\n            {\n                await _routeTransformRepository.InsertAsync(await _routeManager.CreateRouteTransformAsync(route.Id, \"PathPrefix\", createRouteDto.PathPrefix));\n            }\n            //插入集群信息\n            var cluster = await _clusterManager.CreateAsync(route.Id, route.RouteName\n                , createRouteDto.ServiceGovernanceType\n                , createRouteDto.ServiceGovernanceType != ServiceGovernanceType.Default ? createRouteDto.ClusterDestinationValue : \"\"\n                , createRouteDto.LoadBalancingPolicy);\n\n            await _clusterRepository.InsertAsync(cluster);\n            await CurrentUnitOfWork.SaveChangesAsync();\n            //集群目的地信息\n            if (createRouteDto.ServiceGovernanceType == ServiceGovernanceType.Default)\n            {\n                var clusterDestinations = new List<ClusterDestination>();\n\n                var destinations = createRouteDto.ClusterDestinationValue.Split(',');\n                foreach (var destination in destinations)\n                {\n                    clusterDestinations.Add(await _clusterManager.CreateClusterDestinationAsync(cluster.Id, GuidGenerator.Create().ToString().Replace(\"-\", \"\"), destination));\n                }\n                await _clusterDestinationRepository.InsertManyAsync(clusterDestinations);\n            }\n            //集群健康检查信息\n            if (createRouteDto.ClusterHealthCheck != null)\n            {\n                createRouteDto.ClusterHealthCheck.ClusterId = cluster.Id;\n                var healthCheck =await _clusterManager.CreateHealthCheckAsync(createRouteDto.ClusterHealthCheck);\n                await _clusterHealthCheckRepository.InsertAsync(healthCheck);\n            }\n            await CurrentUnitOfWork.SaveChangesAsync();\n            return Ok();\n        }\n        /// <summary>\n        /// 删除路由\n        /// </summary>\n        /// <param name=\"routeId\">路由ID</param>\n        /// <returns></returns>\n        public async Task<KiteResult> DeleteAsync(Guid routeId)\n        {\n            await _routeRepository.DeleteAsync(x=>x.Id==routeId);\n            return Ok();\n        }\n        /// <summary>\n        /// 获取路由列表\n        /// </summary>\n        /// <param name=\"kw\">关键字</param>\n        /// <param name=\"page\">当前页码</param>\n        /// <param name=\"pageSize\">每页记录数</param>\n        /// <returns></returns>\n        public async Task<KitePageResult<List<RoutePageDto>>> GetListAsync(string kw = \"\", int page = 1, int pageSize = 10)\n        {\n            var query =(await _routeRepository.GetQueryableAsync()).WhereIf(!string.IsNullOrEmpty(kw) && kw != \"\", x => x.RouteName.Contains(kw));\n            var totalCount = query.Count();\n            var result = query\n                .Join((await _clusterRepository.GetQueryableAsync()), x => x.Id, y => y.RouteId, (x, y) =>new RoutePageDto()\n                {\n                    Created = x.Created,\n                    Description=x.Description,\n                    Id = x.Id,\n                    LoadBalancingPolicy=y.LoadBalancingPolicy,\n                    RouteMatchPath=x.RouteMatchPath,\n                    RouteName=x.RouteName,\n                    ServiceGovernanceName=y.ServiceGovernanceName,\n                    ServiceGovernanceType=y.ServiceGovernanceType,\n                    UseState =x.UseState,\n                    ClusterId=y.Id\n                })\n                .OrderByDescending(x => x.Created)\n                .PageBy((page - 1) * pageSize, pageSize)\n                .ToList();\n            //获取集群目的地\n            var clusters = await _clusterDestinationRepository.GetListAsync();\n            foreach (var item in result)\n            {\n                if (item.ServiceGovernanceType == ServiceGovernanceType.Default)\n                {\n                    item.ServiceGovernanceName = string.Join(',', clusters.Where(x => x.ClusterId == item.ClusterId).Select(x => x.DestinationAddress).ToList());\n                }\n            }\n            return Ok(result, totalCount);\n        }\n        /// <summary>\n        /// 根据路由ID获取路由信息\n        /// </summary>\n        /// <param name=\"routeId\">路由ID</param>\n        /// <returns></returns>\n        public async Task<KiteResult<RouteDto>> GetAsync(Guid routeId)\n        {\n            var query = await _routeRepository.GetQueryableAsync();\n            //查询基本信息\n            var route = query.ProjectToType<RouteDto>().Where(x => x.Id == routeId).FirstOrDefault();\n            if (route == null)\n            {\n                ThrownFailed(\"路由数据不存在\");\n            }\n            route.RouteTransforms = (await _routeTransformRepository.GetQueryableAsync()).ProjectToType<RouteTransformDto>().Where(x => x.RouteId == route.Id).ToList();\n\n            //查询集群信息\n            route.Cluster = (await _clusterRepository.GetQueryableAsync()).ProjectToType<ClusterDto>().Where(x => x.RouteId == route.Id).First();\n            route.Cluster.ClusterDestinations = (await _clusterDestinationRepository.GetQueryableAsync()).ProjectToType<ClusterDestinationDto>().Where(x => x.ClusterId == route.Cluster.Id).ToList();\n            route.Cluster.HealthCheck = (await _clusterHealthCheckRepository.GetQueryableAsync())\n                .Where(x => x.ClusterId == route.Cluster.Id)\n                .ProjectToType<ClusterHealthCheckDto>()\n                .FirstOrDefault();\n            return Ok(route);\n        }\n        /// <summary>\n        /// 更新路由信息\n        /// </summary>\n        /// <param name=\"updateRouteDto\"></param>\n        /// <returns></returns>\n        public async Task<KiteResult> UpdateAsync(UpdateRouteDto updateRouteDto)\n        {\n            //更新路由信息\n            var model = await _routeRepository.FirstOrDefaultAsync(x => x.Id == updateRouteDto.RouteId);\n            model.Updated = DateTime.Now;\n            TypeAdapter.Adapt(updateRouteDto, model);\n            await _routeRepository.UpdateAsync(model);\n            //路由转换配置\n            await _routeTransformRepository.DeleteAsync(x => x.RouteId == model.Id);\n            if (!string.IsNullOrEmpty(updateRouteDto.PathRemovePrefix) && updateRouteDto.PathRemovePrefix != \"\")\n            {\n                await _routeTransformRepository.InsertAsync(await _routeManager.CreateRouteTransformAsync(model.Id, \"PathRemovePrefix\", updateRouteDto.PathRemovePrefix));\n            }\n            if (!string.IsNullOrEmpty(updateRouteDto.PathPrefix) && updateRouteDto.PathPrefix != \"\")\n            {\n                await _routeTransformRepository.InsertAsync(await _routeManager.CreateRouteTransformAsync(model.Id, \"PathPrefix\", updateRouteDto.PathPrefix));\n            }\n            //更新集群信息\n            var cluster = await _clusterRepository.FirstOrDefaultAsync(x => x.RouteId == updateRouteDto.RouteId);\n            TypeAdapter.Adapt(updateRouteDto, cluster);\n            if (updateRouteDto.ServiceGovernanceType != ServiceGovernanceType.Default)\n            {\n                cluster.ServiceGovernanceName = updateRouteDto.ClusterDestinationValue;\n            }\n            else\n            {\n                cluster.ServiceGovernanceName = \"\";\n            }\n            await _clusterRepository.UpdateAsync(cluster);\n\n            var clusterDestinations = await _clusterDestinationRepository.GetListAsync(x=>x.ClusterId==cluster.Id);\n            //移除原有集群下的目的地数据\n            await _clusterDestinationRepository.DeleteManyAsync(clusterDestinations);\n            //新增集群下目的地地址\n            //集群目的地信息\n            if (updateRouteDto.ServiceGovernanceType == ServiceGovernanceType.Default)\n            {\n                var newDestinations = new List<ClusterDestination>();\n\n                var destinations = updateRouteDto.ClusterDestinationValue.Split(',');\n                foreach (var destination in destinations)\n                {\n                    newDestinations.Add(await _clusterManager.CreateClusterDestinationAsync(cluster.Id, GuidGenerator.Create().ToString().Replace(\"-\", \"\"), destination));\n                }\n                await _clusterDestinationRepository.InsertManyAsync(newDestinations);\n            }\n            //集群健康检查信息\n            if (updateRouteDto.ClusterHealthCheck != null)\n            {\n                var healthCheck = await _clusterHealthCheckRepository.FirstOrDefaultAsync(x=>x.ClusterId==cluster.Id);\n                await _clusterHealthCheckRepository.UpdateAsync(healthCheck);\n            }\n            \n            return Ok();\n        }\n        /// <summary>\n        /// 更新路由状态\n        /// </summary>\n        /// <param name=\"routeId\">路由ID</param>\n        /// <param name=\"useState\">路由状态(1.开启 0.关闭)</param>\n        /// <returns></returns>\n        public async Task<KiteResult> UpdateStateAsync(Guid routeId, bool useState)\n        {\n            var model = await _routeRepository.FindAsync(x => x.Id == routeId);\n            model.UseState = useState;\n            model.Updated = DateTime.Now;\n            await _routeRepository.UpdateAsync(model);\n\n            return Ok();\n        }\n\n        public async Task<KiteResult<List<RouteMainDto>>> GetListAsync()\n        {\n            var result = (await _routeRepository.GetQueryableAsync())\n                .OrderByDescending(x => x.Created)\n                .ProjectToType<RouteMainDto>()\n                .ToList();\n            return Ok(result);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/ServiceGovernanceAppService.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Application.Contracts.Dtos.ServiceGovernance;\nusing Volo.Abp.Domain.Repositories;\nusing Kite.Gateway.Domain.Entities;\nusing Mapster;\n\nnamespace Kite.Gateway.Application\n{\n    public class ServiceGovernanceAppService : BaseApplicationService, IServiceGovernanceAppService\n    {\n        private readonly IRepository<ServiceGovernanceConfigure> _repository;\n\n        public ServiceGovernanceAppService(IRepository<ServiceGovernanceConfigure> repository)\n        {\n            _repository = repository;\n        }\n\n        public async Task<KiteResult<ServiceGovernanceConfigureDto>> GetServiceGovernanceConfigureAsync()\n        {\n            var result = (await _repository.GetQueryableAsync())\n                .ProjectToType<ServiceGovernanceConfigureDto>()\n                .FirstOrDefault();\n            if (result == null)\n            {\n                result = new ServiceGovernanceConfigureDto();\n            }\n            return Ok(result);\n        }\n\n        public async Task<KiteResult> SaveServiceGovernanceConfigureAsync(ServiceGovernanceConfigureDto configure)\n        {\n            var model = await _repository.FirstOrDefaultAsync();\n            if (model == null)\n            {\n                model = new ServiceGovernanceConfigure(GuidGenerator.Create());\n                TypeAdapter.Adapt(configure, model);\n                await _repository.InsertAsync(model);\n            }\n            else\n            {\n                TypeAdapter.Adapt(configure, model);\n                await _repository.UpdateAsync(model);\n            }\n            return Ok();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application/WhitelistAppService.cs",
    "content": "﻿using Mapster;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Application.Services;\nusing Volo.Abp.Domain.Repositories;\nusing Volo.Abp;\nusing Kite.Gateway.Application.Contracts;\nusing Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.Whitelist;\nusing Kite.Gateway.Application.Contracts.Dtos.Whitelist;\n\nnamespace Kite.Gateway.Application\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public class WhitelistAppService: BaseApplicationService, IWhitelistAppService\n    {\n        private readonly IWhiteListManager _whiteListManager;\n        private readonly IRepository<Whitelist> _whiteListRepository;\n        private readonly IRepository<Route> _routeRepository;\n        public WhitelistAppService(\n             IRepository<Whitelist> whiteListRepository, IWhiteListManager whiteListManager, IRepository<Route> routeListRepository)\n        {\n            _whiteListRepository = whiteListRepository;\n            _whiteListManager = whiteListManager;\n            _routeRepository = routeListRepository;\n        }\n\n        public async Task<KitePageResult<List<WhitelistDto>>> GetListAsync(string kw = \"\", int page = 1, int pageSize = 10)\n        {\n            var query = (await _whiteListRepository.GetQueryableAsync()).WhereIf(!string.IsNullOrEmpty(kw) && kw != \"\", x => x.Name.Contains(kw) || x.FilterText.Contains(kw));\n            var totalCount = query.Count();\n            var result = query\n                .ProjectToType<WhitelistDto>()\n                .OrderByDescending(x => x.Created)\n                .PageBy((page - 1) * pageSize, pageSize).ToList();\n            //获取对应路由信息\n            var routes = await _routeRepository.GetListAsync();\n            foreach (var item in result)\n            {\n                if (item.RouteId != default(Guid))\n                {\n                    item.RouteName = routes.Where(x => x.Id == item.RouteId).Select(x => x.RouteName).FirstOrDefault();\n                }\n                else\n                {\n                    item.RouteName = \"全局\";\n                }\n            }\n            return Ok(result, totalCount);\n        }\n\n        public async Task<KiteResult> DeleteAsync(Guid id)\n        {\n            var model = await _whiteListRepository.FirstOrDefaultAsync(x => x.Id == id);\n            if (model != null)\n            {\n                await _whiteListRepository.DeleteAsync(model);\n            }\n            return Ok();\n        }\n\n        public async Task<KiteResult> CreateAsync(CreateWhitelistDto createWhiteList)\n        {\n            var model = await _whiteListManager.CreateAsync(createWhiteList);\n            await _whiteListRepository.InsertAsync(model);\n            return Ok();\n        }\n\n        public async Task<KiteResult> UpdateAsync(UpdateWhitelistDto updateWhiteList)\n        {\n            var model =await _whiteListRepository.FirstOrDefaultAsync(x => x.Id == updateWhiteList.Id);\n            if (model==null)\n            {\n                ThrownFailed(\"白名单信息不存在\");\n            }\n            TypeAdapter.Adapt(updateWhiteList, model);\n            await _whiteListRepository.UpdateAsync(model);\n            return Ok();\n        }\n\n        public async Task<KiteResult<WhitelistDto>> GetAsync(Guid id)\n        {\n            var result = (await _whiteListRepository.GetQueryableAsync())\n                .Where(x => x.Id == id)\n                .ProjectToType<WhitelistDto>()\n                .FirstOrDefault();\n            return Ok(result);\n        }\n\n        public async Task<KiteResult> UpdateUseStateAsync(Guid id, bool useState)\n        {\n            var model = await _whiteListRepository.FirstOrDefaultAsync(x => x.Id == id);\n            if (model == null)\n            {\n                ThrownFailed(\"白名单信息不存在\");\n            }\n            model.UseState = useState;\n            await _whiteListRepository.UpdateAsync(model);\n            return Ok();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/ApplicationContractsModule.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Modularity;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    public class ApplicationContractsModule:AbpModule\n    {\n        public override void ConfigureServices(ServiceConfigurationContext context)\n        {\n            //在此处注入依赖项\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Administrator/AdministratorDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Administrator\n{\n    public class AdministratorDto\n    {\n        /// <summary>\n        /// 账号ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 管理员名\n        /// </summary>\n        public string AdminName { get; set; }\n        /// <summary>\n        /// 昵称\n        /// </summary>\n        public string NickName { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 最后更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Administrator/CreateAdministratorDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Administrator\n{\n    public class CreateAdministratorDto\n    {\n        /// <summary>\n        /// 管理员名\n        /// </summary>\n        [Required]\n        public string AdminName { get; set; }\n        /// <summary>\n        /// 登录密码\n        /// </summary>\n        [Required]\n        public string Password { get; set; }\n        /// <summary>\n        /// 昵称\n        /// </summary>\n        [Required]\n        public string NickName { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Administrator/LoginAdministratorDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Administrator\n{\n    public class LoginAdministratorDto\n    {\n        /// <summary>\n        /// 管理员名\n        /// </summary>\n        [Required]\n        public string AdminName { get; set; }\n        /// <summary>\n        /// 登录密码\n        /// </summary>\n        [Required]\n        public string Password { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Administrator/UpdateAdministratorDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Administrator\n{\n    public class UpdateAdministratorDto\n    {\n        /// <summary>\n        /// 账号ID\n        /// </summary>\n        [Required]\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 管理员名\n        /// </summary>\n        [Required]\n        public string AdminName { get; set; }\n        /// <summary>\n        /// 登录密码\n        /// </summary>\n        public string Password { get; set; }\n        /// <summary>\n        /// 昵称\n        /// </summary>\n        [Required]\n        public string NickName { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Authorization/SaveAuthenticationDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Authorization\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public class SaveAuthenticationDto\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        [Required]\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 是否开启\n        /// </summary>\n        [Required]\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 颁发者\n        /// </summary>\n        [Required]\n        public string Issuer { get; set; }\n        /// <summary>\n        /// 观察者\n        /// </summary>\n        [Required]\n        public string Audience { get; set; }\n        /// <summary>\n        /// 时间偏移(秒)\n        /// </summary>\n        [Required]\n        public int ClockSkew { get; set; }\n        /// <summary>\n        /// 是否验证签名\n        /// </summary>\n        [Required]\n        public bool ValidateIssuerSigningKey { get; set; }\n        /// <summary>\n        /// 是否验证颁发者\n        /// </summary>\n        public bool ValidateIssuer { get; set; }\n        /// <summary>\n        /// 是否验证观察者\n        /// </summary>\n        [Required]\n        public bool ValidateAudience { get; set; }\n        /// <summary>\n        /// 是否验证失效时间\n        /// </summary>\n        [Required]\n        public bool ValidateLifetime { get; set; }\n        /// <summary>\n        /// 是否需要过期时间\n        /// </summary>\n        [Required]\n        public bool RequireExpirationTime { get; set; }\n        /// <summary>\n        /// 是否启用SSL证书\n        /// </summary>\n        [Required]\n        public bool UseSSL { get; set; }\n        /// <summary>\n        /// 秘钥字符串\n        /// </summary>\n        public string SecurityKeyStr { get; set; }\n        /// <summary>\n        /// 证书文件(BASE64:文件后缀名.pfx或者.cer 文件内容)\n        /// </summary>\n        public string CertificateFile { get; set; }\n        /// <summary>\n        /// 证书文件名(文件后缀名.pfx或者.cer 文件内容)\n        /// </summary>\n        public string CertificateFileName { get; set; }\n        /// <summary>\n        /// 证书密码\n        /// </summary>\n        public string CertificatePassword { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Middleware/CreateMiddlewareDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Middleware\n{\n    /// <summary>\n    /// 创建中间件DTO\n    /// </summary>\n    public class CreateMiddlewareDto\n    {\n        /// <summary>\n        /// 中间件名称\n        /// </summary>\n        [Required]\n        public string Name { get; set; }\n        /// <summary>\n        /// 服务端地址\n        /// </summary>\n        [Required]\n        public string Server { get; set; }\n        /// <summary>\n        /// 通信类型\n        /// </summary>\n        [Required]\n        public SignalTypeEnum SignalType { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        [Required]\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 执行权重(数字越大越靠前)\n        /// </summary>\n        [Required]\n        public int ExecWeight { get; set; }\n        /// <summary>\n        /// 中间件描述\n        /// </summary>\n        [StringLength(1024)]\n        public string Description { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Middleware/MiddlewareDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Middleware\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public class MiddlewareDto\n    {\n        /// <summary>\n        /// 中间件ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 中间件名称\n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        /// 服务端地址\n        /// </summary>\n        public string Server { get; set; }\n        /// <summary>\n        /// 通信类型\n        /// </summary>\n        public SignalTypeEnum SignalType { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 执行权重(数字越大越靠前)\n        /// </summary>\n        public int ExecWeight { get; set; }\n        /// <summary>\n        /// 中间件描述\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Middleware/MiddlewareListDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Middleware\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public class MiddlewareListDto\n    {\n        /// <summary>\n        /// 中间件ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 中间件名称\n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        /// 服务端地址\n        /// </summary>\n        public string Server { get; set; }\n        /// <summary>\n        /// 通信类型\n        /// </summary>\n        public SignalTypeEnum SignalType { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 执行权重(数字越大越靠前)\n        /// </summary>\n        public int ExecWeight { get; set; }\n        /// <summary>\n        /// 中间件描述\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Middleware/UpdateMiddlewareDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Middleware\n{\n    public class UpdateMiddlewareDto\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        [Required]\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 中间件名称\n        /// </summary>\n        [Required]\n        public string Name { get; set; }\n        /// <summary>\n        /// 服务端地址\n        /// </summary>\n        [Required]\n        public string Server { get; set; }\n        /// <summary>\n        /// 通信类型\n        /// </summary>\n        [Required]\n        public SignalTypeEnum SignalType { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        [Required]\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 执行权重(数字越大越靠前)\n        /// </summary>\n        [Required]\n        public int ExecWeight { get; set; }\n        /// <summary>\n        /// 中间件描述\n        /// </summary>\n        [StringLength(1024)]\n        public string Description { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Node/CreateNodeDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Node\n{\n    public class CreateNodeDto\n    {\n        /// <summary>\n        /// 节点名称\n        /// </summary>\n        [Required]\n        public string NodeName { get; set; }\n        /// <summary>\n        /// 节点描述\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        /// 节点服务端地址\n        /// </summary>\n        [Required]\n        public string Server { get; set; }\n        /// <summary>\n        /// 访问Token\n        /// </summary>\n        [Required]\n        public string AccessToken { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Node/NodeDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Node\n{\n    public class NodeDto\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 节点名称\n        /// </summary>\n        public string NodeName { get; set; }\n        /// <summary>\n        /// 节点描述\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        /// 节点服务端地址\n        /// </summary>\n        public string Server { get; set; }\n        /// <summary>\n        /// 访问Token\n        /// </summary>\n        public string AccessToken { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 最后更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Node/ReloadConfigureDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.ComponentModel.DataAnnotations;\nusing Kite.Gateway.Domain.Shared.Options;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Node\n{\n    public class ReloadConfigureDto\n    {\n        /// <summary>\n        /// 是否重新加载身份认证数据\n        /// </summary>\n        [Required]\n        public bool IsReloadAuthentication { get; set; }\n        \n        /// <summary>\n        /// 是否重新加载白名单数据\n        /// </summary>\n        [Required]\n        public bool IsReloadWhitelist { get; set; }\n        \n        \n        /// <summary>\n        /// 是否重新加载中间件数据\n        /// </summary>\n        [Required]\n        public bool IsReloadMiddleware { get; set; }\n        \n        /// <summary>\n        /// 是否重新加载Yarp相关数据\n        /// </summary>\n        [Required]\n        public bool IsReloadYarp { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Node/UpdateNodeDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.ComponentModel.DataAnnotations;\nnamespace Kite.Gateway.Application.Contracts.Dtos.Node\n{\n    public class UpdateNodeDto\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        [Required]\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 节点名称\n        /// </summary>\n        [Required]\n        public string NodeName { get; set; }\n        /// <summary>\n        /// 节点描述\n        /// </summary>\n        [Required]\n        public string Description { get; set; }\n        /// <summary>\n        /// 节点服务端地址\n        /// </summary>\n        [Required]\n        public string Server { get; set; }\n        /// <summary>\n        /// 访问Token\n        /// </summary>\n        [Required]\n        public string AccessToken { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/RefreshConfigureDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Options;\nusing Microsoft.AspNetCore.Mvc.ModelBinding.Validation;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos\n{\n    public class RefreshConfigureDto\n    {\n        /// <summary>\n        /// 身份认证数据\n        /// </summary>\n        [ValidateNever]\n        public AuthenticationOption Authentication { get; set; }\n        /// <summary>\n        /// 中间件数据\n        /// </summary>\n        [ValidateNever]\n        public List<WhitelistOption> Whitelists { get; set; }\n        /// <summary>\n        /// 中间件数据\n        /// </summary>\n        [ValidateNever]\n        public List<MiddlewareOption> Middlewares { get; set; }\n        /// <summary>\n        /// Yarp反向代理配置数据\n        /// </summary>\n        [ValidateNever]\n        public YarpOption Yarp { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/ClusterDestinationDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class ClusterDestinationDto\n    {\n        /// <summary>\n        /// 集群目的地ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 集群ID\n        /// </summary>\n        public Guid ClusterId { get; set; }\n        /// <summary>\n        /// 目的地名称\n        /// </summary>\n        public string DestinationName { get; set; }\n        /// <summary>\n        /// 目的地地址\n        /// </summary>\n        public string DestinationAddress { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/ClusterDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class ClusterDto\n    {\n        /// <summary>\n        /// 集群ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 关联服务ID\n        /// </summary>\n        public Guid RouteId { get; set; }\n        /// <summary>\n        /// 集群名称\n        /// </summary>\n        public string ClusterName { get; set; }\n        /// <summary>\n        /// 负载均衡策略\n        /// FirstAlphabetical: 在不考虑负载的情况下选择按字母顺序排列的第一个可用目的地。这对于双目的地故障转移系统很有用。\n        /// Random: 随机选择一个目的地。\n        /// PowerOfTwoChoices (默认): 选择两个随机目标，然后选择分配请求最少的目标。这避免了它选择繁忙目的地的开销LeastRequests和最坏情况。Random\n        /// RoundRobin: 通过按顺序循环选择目的地。\n        /// LeastRequests: 选择分配的请求最少的目标。这需要检查所有目的地。\n        /// </summary>\n        public string LoadBalancingPolicy { get; set; }\n        /// <summary>\n        /// 服务治理类型(Default、Nacos、Consul)\n        /// </summary>\n        public ServiceGovernanceType ServiceGovernanceType { get; set; }\n        /// <summary>\n        /// 服务治理名称\n        /// </summary>\n        public string ServiceGovernanceName { get; set; }\n        /// <summary>\n        /// 集群目的地\n        /// </summary>\n        public List<ClusterDestinationDto> ClusterDestinations { get; set; }\n        /// <summary>\n        /// 健康检查\n        /// </summary>\n        public ClusterHealthCheckDto HealthCheck { get; set; }\n\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/ClusterHealthCheckDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class ClusterHealthCheckDto\n    {\n        /// <summary>\n        /// 关联集群ID\n        /// </summary>\n        public Guid ClusterId { get; set; }\n        /// <summary>\n        /// 是否开启健康检查\n        /// </summary>\n        [Required]\n        public bool Enabled { get; set; }\n        /// <summary>\n        /// 检查间隔时间(秒)\n        /// </summary>\n        [Required]\n        public int Interval { get; set; }\n        /// <summary>\n        /// 超时时间(秒)\n        /// </summary>\n        [Required]\n        public int Timeout { get; set; }\n        /// <summary>\n        /// 健康检查地址\n        /// </summary>\n        [Required]\n        public string Path { get; set; } = \"/api/health\";\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/CreateRouteDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.ComponentModel.DataAnnotations;\nusing Kite.Gateway.Domain.Shared.Enums;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class CreateRouteDto\n    {\n        /// <summary>\n        /// 路由名称\n        /// </summary>\n        [Required]\n        public string RouteName { get; set; }\n\n        /// <summary>\n        /// 状态(0.关闭 1.开启)\n        /// </summary>\n        [Required]\n        public bool UseState { get; set; }\n\n        /// <summary>\n        /// 路由路径规则\n        /// </summary>\n        [Required]\n        public string RouteMatchPath { get; set; }\n        /// <summary>\n        /// 描述信息\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        /// 路由转换(移除路由路径前缀)\n        /// </summary>\n        public string PathRemovePrefix { get; set; }\n        /// <summary>\n        /// 路由转换(增加路由路径前缀)\n        /// </summary>\n        public string PathPrefix { get; set; }\n        /// <summary>\n        /// 负载均衡策略\n        /// FirstAlphabetical: 在不考虑负载的情况下选择按字母顺序排列的第一个可用目的地。这对于双目的地故障转移系统很有用。\n        /// Random: 随机选择一个目的地。\n        /// PowerOfTwoChoices (默认): 选择两个随机目标，然后选择分配请求最少的目标。这避免了它选择繁忙目的地的开销LeastRequests和最坏情况。\n        /// RoundRobin: 通过按顺序循环选择目的地。\n        /// LeastRequests: 选择分配的请求最少的目标。这需要检查所有目的地。\n        /// </summary>\n        [Required]\n        public string LoadBalancingPolicy { get; set; }\n        /// <summary>\n        /// 服务治理类型(0.Default  1.Consul  2.Nacos)\n        /// </summary>\n        [Required]\n        public ServiceGovernanceType ServiceGovernanceType { get; set; }\n        /// <summary>\n        /// 集群目的地信息(ServiceGovernanceType!=Default 时为服务治理名称)\n        /// </summary>\n        [Required]\n        public string ClusterDestinationValue { get; set; }\n        /// <summary>\n        /// 健康检查设置\n        /// </summary>\n        public ClusterHealthCheckDto ClusterHealthCheck { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/RouteDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class RouteDto\n    {\n        /// <summary>\n        /// 路由ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 路由名称\n        /// </summary>\n        public string RouteName { get; set; }\n        /// <summary>\n        /// 服务状态(0.关闭 1.开启)\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 描述\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        /// 路由路径规则\n        /// </summary>\n        public string RouteMatchPath { get; set; }\n\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n        /// <summary>\n        /// 集群\n        /// </summary>\n        public ClusterDto Cluster { get; set; }\n        /// <summary>\n        /// 路由交换配置项\n        /// </summary>\n        public List<RouteTransformDto> RouteTransforms { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/RouteMainDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class RouteMainDto\n    {\n        /// <summary>\n        /// 路由ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 路由名称\n        /// </summary>\n        public string RouteName { get; set; }\n        /// <summary>\n        /// 服务状态(0.关闭 1.开启)\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 描述\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        /// 路由路径规则\n        /// </summary>\n        public string RouteMatchPath { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/RoutePageDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class RoutePageDto\n    {\n        /// <summary>\n        /// 路由ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 路由名称\n        /// </summary>\n        public string RouteName { get; set; }\n        /// <summary>\n        /// 服务状态(0.关闭 1.开启)\n        /// </summary>\n        public bool UseState { get; set; }\n\n        /// <summary>\n        /// 路由路径规则\n        /// </summary>\n        public string RouteMatchPath { get; set; }\n        /// <summary>\n        /// 备注信息\n        /// </summary>\n        public string Description { get; set; }\n\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 集群ID\n        /// </summary>\n        public Guid ClusterId { get; set; }\n        /// <summary>\n        /// 服务治理类型(0.Default  1.Consul  2.Nacos)\n        /// </summary>\n        public ServiceGovernanceType ServiceGovernanceType { get; set; }\n        /// <summary>\n        /// 服务治理名称\n        /// </summary>\n        public string ServiceGovernanceName { get; set; }\n        /// <summary>\n        /// 负载均衡策略\n        /// FirstAlphabetical: 在不考虑负载的情况下选择按字母顺序排列的第一个可用目的地。这对于双目的地故障转移系统很有用。\n        /// Random: 随机选择一个目的地。\n        /// PowerOfTwoChoices (默认): 选择两个随机目标，然后选择分配请求最少的目标。这避免了它选择繁忙目的地的开销LeastRequests和最坏情况。\n        /// RoundRobin: 通过按顺序循环选择目的地。\n        /// LeastRequests: 选择分配的请求最少的目标。这需要检查所有目的地。\n        /// </summary>\n        public string LoadBalancingPolicy { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/RouteTransformDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class RouteTransformDto\n    {\n        /// <summary>\n        /// 交换配置ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 关联服务ID\n        /// </summary>\n        public Guid RouteId { get; set; }\n        /// <summary>\n        /// 交换配置项名称\n        /// </summary>\n        public string TransformsName { get; set; }\n        /// <summary>\n        /// 交换配置项值\n        /// </summary>\n        public string TransformsValue { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ReverseProxy/UpdateRouteDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ReverseProxy\n{\n    public class UpdateRouteDto\n    {\n        /// <summary>\n        /// 路由ID\n        /// </summary>\n        [Required]\n        public Guid RouteId { get; set; }\n        /// <summary>\n        /// 路由名称\n        /// </summary>\n        [Required]\n        public string RouteName { get; set; }\n\n        /// <summary>\n        /// 状态(0.关闭 1.开启)\n        /// </summary>\n        [Required]\n        public bool UseState { get; set; }\n\n        /// <summary>\n        /// 路由路径规则\n        /// </summary>\n        [Required]\n        public string RouteMatchPath { get; set; }\n        /// <summary>\n        /// 描述信息\n        /// </summary>\n        public string Description { get; set; }\n        /// <summary>\n        /// 路由转换(移除路由路径前缀)\n        /// </summary>\n        public string PathRemovePrefix { get; set; }\n        /// <summary>\n        /// 路由转换(增加路由路径前缀)\n        /// </summary>\n        public string PathPrefix { get; set; }\n        /// <summary>\n        /// 负载均衡策略\n        /// FirstAlphabetical: 在不考虑负载的情况下选择按字母顺序排列的第一个可用目的地。这对于双目的地故障转移系统很有用。\n        /// Random: 随机选择一个目的地。\n        /// PowerOfTwoChoices (默认): 选择两个随机目标，然后选择分配请求最少的目标。这避免了它选择繁忙目的地的开销LeastRequests和最坏情况。\n        /// RoundRobin: 通过按顺序循环选择目的地。\n        /// LeastRequests: 选择分配的请求最少的目标。这需要检查所有目的地。\n        /// </summary>\n        [Required]\n        public string LoadBalancingPolicy { get; set; }\n        /// <summary>\n        /// 服务治理类型(0.Default  1.Consul  2.Nacos)\n        /// </summary>\n        [Required]\n        public ServiceGovernanceType ServiceGovernanceType { get; set; }\n        /// <summary>\n        /// 集群目的地信息(ServiceGovernanceType!=Default 时为服务治理名称)\n        /// </summary>\n        [Required]\n        public string ClusterDestinationValue { get; set; }\n        /// <summary>\n        /// 健康检查设置\n        /// </summary>\n        public ClusterHealthCheckDto ClusterHealthCheck { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ServiceGovernance/ServiceGovernanceConfigureDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.ServiceGovernance\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public class ServiceGovernanceConfigureDto\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// Consul服务端地址\n        /// </summary>\n        public string ConsulServer { get; set; }\n        /// <summary>\n        /// Consul数据中心\n        /// </summary>\n        public string ConsulDatacenter { get; set; }\n        /// <summary>\n        /// Consul访问令牌\n        /// </summary>\n        public string ConsulToken { get; set; }\n        /// <summary>\n        /// Nacos服务器地址\n        /// </summary>\n        public string NacosServer { get; set; }\n        /// <summary>\n        /// Nacos群组名\n        /// </summary>\n        public string NacosGroupName { get; set; }\n        /// <summary>\n        /// Nacos命名空间ID\n        /// </summary>\n        public string NacosNamespaceId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/ValidateTokenDto.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos\n{\n    public class ValidateTokenDto\n    {\n        /// <summary>\n        /// 请求token\n        /// </summary>\n        [Required]\n        public string AccessToken { get; set; }\n        /// <summary>\n        /// 请求路径\n        /// </summary>\n        [Required]\n        public string ReuqestPath { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Whitelist/CreateWhitelistDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Whitelist\n{\n    public class CreateWhitelistDto\n    {\n        /// <summary>\n        /// 所属路由(为空则全局)\n        /// </summary>\n        [Required]\n        public Guid? RouteId { get; set; }\n        /// <summary>\n        /// 白名单名称\n        /// </summary>\n        [Required]\n        public string Name { get; set; }\n        /// <summary>\n        /// 过滤文本(根据类型保存的值为路径或者正则表达式)\n        /// </summary>\n        [Required]\n        public string FilterText { get; set; }\n        /// <summary>\n        /// 请求方式(多请求方式使用,分隔)\n        /// </summary>\n        [Required]\n        public string RequestMethod { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        public bool UseState { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Whitelist/UpdateWhitelistDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Whitelist\n{\n    public class UpdateWhitelistDto\n    {\n        /// <summary>\n        /// \n        /// </summary>\n        [Required]\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 所属路由(为空则全局)\n        /// </summary>\n        [Required]\n        public Guid? RouteId { get; set; }\n        /// <summary>\n        /// 白名单名称\n        /// </summary>\n        [Required]\n        public string Name { get; set; }\n        /// <summary>\n        /// 过滤文本(根据类型保存的值为路径或者正则表达式)\n        /// </summary>\n        [Required]\n        public string FilterText { get; set; }\n        /// <summary>\n        /// 请求方式(多请求方式使用,分隔)\n        /// </summary>\n        [Required]\n        public string RequestMethod { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        public bool UseState { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Dtos/Whitelist/WhitelistDto.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts.Dtos.Whitelist\n{\n    public class WhitelistDto\n    {\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 所属路由(为空则全局)\n        /// </summary>\n        public Guid? RouteId { get; set; }\n        /// <summary>\n        /// 白名单名称\n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        /// 过滤文本(根据类型保存的值为路径或者正则表达式)\n        /// </summary>\n        public string FilterText { get; set; }\n        /// <summary>\n        /// 请求方式(多请求方式使用,分隔)\n        /// </summary>\n        public string RequestMethod { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 关联路由名称\n        /// </summary>\n        public string RouteName { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Http/SimpleHttpException.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application\n{\n    /// <summary>\n    /// 简易Http响应异常\n    /// </summary>\n    public class SimpleHttpException:Exception\n    {\n        /// <summary>\n        /// 简易Http响应异常\n        /// </summary>\n        /// <param name=\"message\">异常消息</param>\n        public SimpleHttpException(string message) : base(message)\n        {\n\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/IAdministratorAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos.Administrator;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    public interface IAdministratorAppService\n    {\n        /// <summary>\n        /// 管理员登录\n        /// </summary>\n        /// <param name=\"loginAdministrator\"></param>\n        /// <returns></returns>\n        Task<KiteResult<AdministratorDto>> LoginAsync(LoginAdministratorDto loginAdministrator);\n        /// <summary>\n        /// 获取管理员账号详情信息\n        /// </summary>\n        /// <param name=\"id\">节点ID</param>\n        /// <returns></returns>\n        Task<KiteResult<AdministratorDto>> GetAsync(Guid id);\n        /// <summary>\n        /// 更新管理员账号数据\n        /// </summary>\n        /// <param name=\"updateAdministrator\"></param>\n        /// <returns></returns>\n        Task<KiteResult> UpdateAsync(UpdateAdministratorDto updateAdministrator);\n        /// <summary>\n        /// 获取管理员账号列表\n        /// </summary>\n        /// <param name=\"page\"></param>\n        /// <param name=\"pageSize\"></param>\n        /// <returns></returns>\n        Task<KitePageResult<List<AdministratorDto>>> GetListAsync(int page = 1, int pageSize = 10);\n        /// <summary>\n        /// 删除管理员账号\n        /// </summary>\n        /// <param name=\"id\">管理员ID</param>\n        /// <returns></returns>\n        Task<KiteResult> DeleteAsync(Guid id);\n        /// <summary>\n        /// 创建管理员账号\n        /// </summary>\n        /// <param name=\"createAdministrator\"></param>\n        /// <returns></returns>\n        Task<KiteResult> CreateAsync(CreateAdministratorDto createAdministrator);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/IAuthorizationAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos.Authorization;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Application.Services;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    /// <summary>\n    /// 授权相关接口\n    /// </summary>\n    public interface IAuthorizationAppService:IApplicationService\n    {\n        /// <summary>\n        /// 获取身份认证配置信息\n        /// </summary>\n        /// <returns></returns>\n        Task<KiteResult<SaveAuthenticationDto>> GetAuthenticationAsync();\n        \n        /// <summary>\n        /// 保存身份认证配置信息\n        /// </summary>\n        /// <param name=\"authenticationDto\"></param>\n        /// <returns></returns>\n        Task<KiteResult> SaveAuthenticationAsync(SaveAuthenticationDto authenticationDto);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/IConfigureAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos;\nusing Kite.Gateway.Application.Contracts.Dtos.Node;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Application.Services;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    public interface IConfigureAppService : IApplicationService\n    {\n        /// <summary>\n        /// 根据推送配置获取配置项数据\n        /// </summary>\n        /// <param name=\"reloadConfigure\"></param>\n        /// <returns></returns>\n        Task<KiteResult<RefreshConfigureDto>> GetConfigureAsync(ReloadConfigureDto reloadConfigure);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/IMiddlewareAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos.Middleware;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Application.Services;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public interface IMiddlewareAppService:IApplicationService\n    {\n        /// <summary>\n        /// 获取中间件列表\n        /// </summary>\n        /// <param name=\"kw\">关键字</param>\n        /// <param name=\"page\">当前页码</param>\n        /// <param name=\"pageSize\">每页记录数</param>\n        /// <returns></returns>\n        Task<KitePageResult<List<MiddlewareListDto>>> GetListAsync(string kw = \"\", int page = 1, int pageSize = 10);\n        /// <summary>\n        /// 根据ID获取中间件信息\n        /// </summary>\n        /// <param name=\"id\">中间件ID</param>\n        /// <returns></returns>\n        Task<KiteResult<MiddlewareDto>> GetAsync(Guid id);\n        /// <summary>\n        /// 更新中间件信息\n        /// </summary>\n        /// <param name=\"middlewareDto\"></param>\n        /// <returns></returns>\n        Task<KiteResult> UpdateAsync(UpdateMiddlewareDto middlewareDto);\n        /// <summary>\n        /// 更新中间件状态\n        /// </summary>\n        /// <param name=\"id\">中间件ID</param>\n        /// <param name=\"useState\">状态</param>\n        /// <returns></returns>\n        Task<KiteResult> UpdateUseStateAsync(Guid id,bool useState);\n        /// <summary>\n        /// 创建中间件信息\n        /// </summary>\n        /// <param name=\"middlewareDto\"></param>\n        /// <returns></returns>\n        Task<KiteResult> CreateAsync(CreateMiddlewareDto middlewareDto);\n        /// <summary>\n        /// 根据ID删除中间件信息\n        /// </summary>\n        /// <param name=\"id\">中间件ID</param>\n        /// <returns></returns>\n        Task<KiteResult> DeleteAsync(Guid id);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/INodeAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos.Node;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Application.Services;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    public interface INodeAppService:IApplicationService\n    {\n        /// <summary>\n        /// 获取所有节点数据\n        /// </summary>\n        /// <returns></returns>\n        Task<KiteResult<List<NodeDto>>> GetAllAsync();\n        /// <summary>\n        /// 获取节点详情信息\n        /// </summary>\n        /// <param name=\"id\">节点ID</param>\n        /// <returns></returns>\n        Task<KiteResult<NodeDto>> GetAsync(Guid id);\n        /// <summary>\n        /// 更新节点数据\n        /// </summary>\n        /// <param name=\"updateNode\"></param>\n        /// <returns></returns>\n        Task<KiteResult> UpdateAsync(UpdateNodeDto updateNode);\n        /// <summary>\n        /// 获取节点列表\n        /// </summary>\n        /// <param name=\"page\"></param>\n        /// <param name=\"pageSize\"></param>\n        /// <returns></returns>\n        Task<KitePageResult<List<NodeDto>>> GetListAsync(int page = 1, int pageSize = 10);\n        /// <summary>\n        /// 删除节点\n        /// </summary>\n        /// <param name=\"id\">节点ID</param>\n        /// <returns></returns>\n        Task<KiteResult> DeleteAsync(Guid id);\n        /// <summary>\n        /// 创建节点\n        /// </summary>\n        /// <param name=\"createNode\"></param>\n        /// <returns></returns>\n        Task<KiteResult> CreateAsync(CreateNodeDto createNode);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/IRefreshAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos;\nusing Kite.Gateway.Application.Contracts.Dtos.Node;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Application.Services;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    public interface IRefreshAppService: IApplicationService\n    {\n        \n        /// <summary>\n        /// 刷新配置数据\n        /// </summary>\n        /// <param name=\"refreshConfigure\"></param>\n        /// <returns></returns>\n        Task<KiteResult> RefreshConfigureAsync(RefreshConfigureDto refreshConfigure);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/IRouteAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos.ReverseProxy;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Application.Services;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    /// <summary>\n    /// \n    /// </summary>\n    public interface IRouteAppService:IApplicationService\n    {\n        /// <summary>\n        /// 获取全部路由数据\n        /// </summary>\n        /// <returns></returns>\n        Task<KiteResult<List<RouteMainDto>>> GetListAsync();\n        /// <summary>\n        /// 获取路由列表\n        /// </summary>\n        /// <param name=\"kw\">关键字</param>\n        /// <param name=\"page\">当前页码</param>\n        /// <param name=\"pageSize\">每页记录数</param>\n        /// <returns></returns>\n        Task<KitePageResult<List<RoutePageDto>>> GetListAsync(string kw = \"\", int page = 1, int pageSize = 10);\n        /// <summary>\n        /// 根据路由ID获取路由信息\n        /// </summary>\n        /// <param name=\"routeId\">路由ID</param>\n        /// <returns></returns>\n        Task<KiteResult<RouteDto>> GetAsync(Guid routeId);\n        /// <summary>\n        /// 创建路由\n        /// </summary>\n        /// <param name=\"createRouteDto\"></param>\n        /// <returns></returns>\n        Task<KiteResult> CreateAsync(CreateRouteDto createRouteDto);\n        /// <summary>\n        /// 删除路由\n        /// </summary>\n        /// <param name=\"routeId\"></param>\n        /// <returns></returns>\n        Task<KiteResult> DeleteAsync(Guid routeId);\n        /// <summary>\n        /// 更新路由信息\n        /// </summary>\n        /// <param name=\"updateRouteDto\"></param>\n        /// <returns></returns>\n        Task<KiteResult> UpdateAsync(UpdateRouteDto updateRouteDto);\n        /// <summary>\n        /// 更新路由状态\n        /// </summary>\n        /// <param name=\"routeId\">路由ID</param>\n        /// <param name=\"useState\">路由状态</param>\n        /// <returns></returns>\n        Task<KiteResult> UpdateStateAsync(Guid routeId, bool useState);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/IServiceGovernanceAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos.ServiceGovernance;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    /// <summary>\n    /// 服务治理相关配置\n    /// </summary>\n    public interface IServiceGovernanceAppService\n    {\n        /// <summary>\n        /// 获取服务治理配置信息\n        /// </summary>\n        /// <returns></returns>\n        Task<KiteResult<ServiceGovernanceConfigureDto>> GetServiceGovernanceConfigureAsync();\n        /// <summary>\n        /// 保存服务治理相关配置信息\n        /// </summary>\n        /// <param name=\"configure\"></param>\n        /// <returns></returns>\n        Task<KiteResult> SaveServiceGovernanceConfigureAsync(ServiceGovernanceConfigureDto configure);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/IWhitelistAppService.cs",
    "content": "﻿using Kite.Gateway.Application.Contracts.Dtos.Whitelist;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Application.Services;\n\nnamespace Kite.Gateway.Application.Contracts\n{\n    /// <summary>\n    /// 白名单\n    /// </summary>\n    public interface IWhitelistAppService : IApplicationService\n    {\n        /// <summary>\n        /// 获取白名单详情信息\n        /// </summary>\n        /// <param name=\"id\">白名单ID</param>\n        /// <returns></returns>\n        Task<KiteResult<WhitelistDto>> GetAsync(Guid id);\n        /// <summary>\n        /// 更新启用状态\n        /// </summary>\n        /// <param name=\"id\">白名单ID</param>\n        /// <param name=\"useState\">状态</param>\n        /// <returns></returns>\n        Task<KiteResult> UpdateUseStateAsync(Guid id,bool useState);\n        /// <summary>\n        /// 更新白名单数据\n        /// </summary>\n        /// <param name=\"updateWhiteList\"></param>\n        /// <returns></returns>\n        Task<KiteResult> UpdateAsync(UpdateWhitelistDto updateWhiteList);\n        /// <summary>\n        /// 获取白名单列表\n        /// </summary>\n        /// <param name=\"kw\"></param>\n        /// <param name=\"page\"></param>\n        /// <param name=\"pageSize\"></param>\n        /// <returns></returns>\n        Task<KitePageResult<List<WhitelistDto>>> GetListAsync(string kw = \"\", int page = 1, int pageSize = 10);\n        /// <summary>\n        /// 删除白名单\n        /// </summary>\n        /// <param name=\"id\">白名单ID</param>\n        /// <returns></returns>\n        Task<KiteResult> DeleteAsync(Guid id);\n        /// <summary>\n        /// 创建白名单\n        /// </summary>\n        /// <param name=\"createWhiteList\"></param>\n        /// <returns></returns>\n        Task<KiteResult> CreateAsync(CreateWhitelistDto createWhiteList);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/Kite.Gateway.Application.Contracts.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net7.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n    <GenerateDocumentationFile>False</GenerateDocumentationFile>\n    <DocumentationFile>Kite.Gateway.Application.Contracts.xml</DocumentationFile>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|AnyCPU'\">\n    <NoWarn>1701;1702;8618</NoWarn>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\n    <NoWarn>1701;1702;8618</NoWarn>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Volo.Abp.Ddd.Application\" Version=\"7.0.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Kite.Gateway.Domain.Shared\\Kite.Gateway.Domain.Shared.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/KitePageResult.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application\n{\n    public class KitePageResult<TResult> : KiteResult<TResult>\n    {\n        /// <summary>\n        /// 分页获取数据时有作用\n        /// </summary>\n        public int Count { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Application.Contracts/KiteResult.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Application\n{\n    public class KiteResult<TResult>\n    {\n        /// <summary>\n        /// 结果码(为0则表示请求成功)\n        /// </summary>\n        public int Code { get; set; }\n        /// <summary>\n        /// 结果消息\n        /// </summary>\n        public string Message { get; set; }\n        /// <summary>\n        /// 结果数据\n        /// </summary>\n        public TResult Data { get; set; }\n\n    }\n    public class KiteResult\n    {\n        /// <summary>\n        /// 结果码(为0则表示请求成功)\n        /// </summary>\n        public int Code { get; set; }\n        /// <summary>\n        /// 结果消息\n        /// </summary>\n        public string Message { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Administrator/AdministratorManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Services;\nusing Volo.Abp.Domain.Repositories;\nusing Kite.Gateway.Domain.Shared;\n\nnamespace Kite.Gateway.Domain.Administrator\n{\n    internal class AdministratorManager : DomainService, IAdministratorManager\n    {\n        private readonly IRepository<Entities.Administrator> _repository;\n\n        public AdministratorManager(IRepository<Entities.Administrator> repository)\n        {\n            _repository = repository;\n        }\n        public async Task<Entities.Administrator> LoginAsync(string adminName, string password)\n        {\n            \n            //查询账号信息\n            var administrator = await _repository.FirstOrDefaultAsync(x => x.AdminName == adminName && x.Password == password);\n            if (administrator == null)\n            {\n                throw new ArgumentException(\"管理员账号或登录密码错误\");\n            }\n            return administrator;\n        }\n\n        public async Task<Entities.Administrator> CreateAsync(string adminName)\n        {\n            if (await _repository.AnyAsync(x => x.AdminName == adminName))\n            {\n                throw new ArgumentException(\"管理员账号已经存在\");\n            }\n            return new Entities.Administrator(GuidGenerator.Create())\n            { \n                Created = DateTime.Now,\n                Updated=DateTime.Now\n            };\n        }\n\n        \n\n        public async Task<Entities.Administrator> UpdateAsync(Guid id, string adminName)\n        {\n            if (await _repository.AnyAsync(x => x.AdminName == adminName && x.Id!=id))\n            {\n                throw new ArgumentException(\"管理员账号已经存在\");\n            }\n            var administrator = await _repository.FirstOrDefaultAsync(x => x.Id == id);\n            administrator.Updated = DateTime.Now;\n            return administrator;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Administrator/IAdministratorManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Administrator\n{\n    public interface IAdministratorManager\n    {\n        /// <summary>\n        /// 账号登录\n        /// </summary>\n        /// <param name=\"adminName\">管理员账号名</param>\n        /// <param name=\"password\">登录密码</param>\n        /// <returns></returns>\n        Task<Entities.Administrator> LoginAsync(string adminName,string password);\n        /// <summary>\n        /// 更新管理员账号信息\n        /// </summary>\n        /// <param name=\"id\"></param>\n        /// <param name=\"adminName\"></param>\n        /// <returns></returns>\n        Task<Entities.Administrator> UpdateAsync(Guid id, string adminName);\n        /// <summary>\n        /// 创建管理员账号\n        /// </summary>\n        /// <param name=\"adminName\"></param>\n        /// <returns></returns>\n        Task<Entities.Administrator> CreateAsync(string adminName);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Authorization/AuthenticationManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Services;\nusing Volo.Abp.Domain.Repositories;\nusing Microsoft.Extensions.Caching.Memory;\n\nnamespace Kite.Gateway.Domain.Authorization\n{\n    internal class AuthenticationManager : DomainService, IAuthenticationManager\n    {\n        private const string CacheKey = \"AuthenticationConfigure\";\n        //\n        private readonly IRepository<AuthenticationConfigure> _repository;\n        private readonly IMemoryCache _memoryCache;\n\n        public AuthenticationManager(IMemoryCache memoryCache, IRepository<AuthenticationConfigure> repository)\n        {\n            _memoryCache = memoryCache;\n            _repository = repository;\n        }\n\n        public async Task<AuthenticationConfigure> GetConfigureAsync()\n        {\n            var data = _memoryCache.Get<AuthenticationConfigure>(CacheKey);\n            if (data == null)\n            {\n                data =await _repository.FirstOrDefaultAsync();\n                if (data == null)\n                {\n                    throw new ArgumentNullException(\"身份认证信息未配置\");\n                }\n                _memoryCache.Set(CacheKey, data, DateTimeOffset.Now.AddDays(7));\n            }\n            return data;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Authorization/ClaimModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Authorization\n{\n    public class ClaimModel\n    {\n        /// <summary>\n        /// 声明名\n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        /// 声明值\n        /// </summary>\n        public string Value { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Authorization/IAuthenticationManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Authorization\n{\n    public interface IAuthenticationManager\n    {\n        /// <summary>\n        /// 获取身份认证配置项信息\n        /// </summary>\n        /// <returns></returns>\n        Task<AuthenticationConfigure> GetConfigureAsync();\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Authorization/IJwtTokenManager.cs",
    "content": "﻿using Microsoft.AspNetCore.Http;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Authorization\n{\n    public interface IJwtTokenManager\n    {\n        /// <summary>\n        /// 验证Token\n        /// </summary>\n        /// <param name=\"httpContext\">请求上下文</param>\n        /// <returns></returns>\n        Task<JwtTokenValidationResult> ValidationTokenAsync(HttpContext httpContext);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Authorization/JwtTokenManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.IdentityModel.Tokens.Jwt;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Authentication;\nusing Microsoft.AspNetCore.Authentication.JwtBearer;\nusing Microsoft.IdentityModel.Tokens;\nusing Microsoft.Extensions.Options;\nusing System.Security.Cryptography.X509Certificates;\nusing Microsoft.AspNetCore.Hosting;\nusing System.IO;\nusing Microsoft.AspNetCore.Http;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Volo.Abp.Domain.Services;\nusing Serilog;\n\nnamespace Kite.Gateway.Domain.Authorization\n{\n    internal class JwtTokenManager: DomainService,IJwtTokenManager\n    {\n        private readonly TokenValidationParameters _tokenValidationParameters;\n        public JwtTokenManager(IOptions<TokenValidationParameters> tokenValidationParameters)\n        {\n            _tokenValidationParameters = tokenValidationParameters.Value;\n        }\n\n        public Task<JwtTokenValidationResult> ValidationTokenAsync(HttpContext httpContext)\n        {\n            return Task.Factory.StartNew(() => \n            {\n                var jwtTokenValidationResult = new JwtTokenValidationResult()\n                {\n                    Successed = false,\n                    Claims = new List<ClaimModel>(),\n                    Message = string.Empty\n                };\n                if (!httpContext.Request.Headers.ContainsKey(\"Authorization\"))\n                {\n                    jwtTokenValidationResult.Successed = false;\n                    jwtTokenValidationResult.Message = \"401 Authorization is empty\";\n                    return jwtTokenValidationResult;\n                }\n                var token = httpContext.Request.Headers[\"Authorization\"].ToString().Replace(\"Bearer \", \"\");\n                if (token.Trim() == \"\")\n                {\n                    jwtTokenValidationResult.Successed = false;\n                    jwtTokenValidationResult.Message = \"401 Authorization token is empty\";\n                    return jwtTokenValidationResult;\n                }\n                try\n                {\n                    var jwtSecurityTokenHandler = new JwtSecurityTokenHandler();\n                    var claimsPrincipal = jwtSecurityTokenHandler\n                        .ValidateToken(token, _tokenValidationParameters, out SecurityToken securityToken);\n                    //校验通过\n                    if (claimsPrincipal.Claims.Any())\n                    {\n                        foreach (var claim in claimsPrincipal.Claims)\n                        {\n                            jwtTokenValidationResult.Claims.Add(new ClaimModel() \n                            {\n                                Name=claim.Type,\n                                Value=claim.Value\n                            });\n                        }\n                    }\n                    jwtTokenValidationResult.Successed = true;\n                    return jwtTokenValidationResult;\n                }\n                catch (Exception ex)\n                {\n                    Log.Error(ex, ex.Message);\n                    jwtTokenValidationResult.Successed = false;\n                    jwtTokenValidationResult.Message = $\"401 Unauthorized\";\n                    return jwtTokenValidationResult;\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Authorization/JwtTokenOptions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Authorization\n{\n    public class JwtTokenOptions\n    {\n        /// <summary>\n        /// 颁发者\n        /// </summary>\n        public string Issuer { get; set; }\n        /// <summary>\n        /// 观察者\n        /// </summary>\n        public string Audience { get; set; }\n        /// <summary>\n        /// 时间偏移(秒)\n        /// </summary>\n        public int ClockSkew { get; set; }\n        /// <summary>\n        /// 是否验证签名\n        /// </summary>\n        public bool ValidateIssuerSigningKey { get; set; }\n        /// <summary>\n        /// 是否验证颁发者\n        /// </summary>\n        public bool ValidateIssuer { get; set; }\n        /// <summary>\n        /// 是否验证观察者\n        /// </summary>\n        public bool ValidateAudience { get; set; }\n        /// <summary>\n        /// 是否验证失效时间\n        /// </summary>\n        public bool ValidateLifetime { get; set; }\n        /// <summary>\n        /// 是否需要扩展时间\n        /// </summary>\n        public bool RequireExpirationTime { get; set; }\n        /// <summary>\n        /// 是否启用SSL证书\n        /// </summary>\n        public bool UseSSL { get; set; }\n        /// <summary>\n        /// 秘钥字符串\n        /// </summary>\n        public string SecurityKeyStr { get; set; }\n        /// <summary>\n        /// 证书路径(文件后缀名.pfx或者.cer)\n        /// </summary>\n        public string CertificatePath { get; set; }\n        /// <summary>\n        /// 证书密码\n        /// </summary>\n        public string CertificatePassword { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Authorization/JwtTokenValidationResult.cs",
    "content": "﻿using Microsoft.IdentityModel.Tokens;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security.Claims;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Authorization\n{\n    public class JwtTokenValidationResult\n    {\n        /// <summary>\n        /// 验证是否成功\n        /// </summary>\n        public bool Successed { get; set; }\n        /// <summary>\n        /// 消息\n        /// </summary>\n        public string Message { get; set; }\n        /// <summary>\n        /// 声明信息(验证成功时返回)\n        /// </summary>\n        public List<ClaimModel> Claims { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ConfigureManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Options;\nusing Microsoft.Extensions.DependencyInjection;\nusing Volo.Abp.Domain.Services;\nusing Volo.Abp.Domain.Repositories;\nusing Volo.Abp.Uow;\nusing Mapster;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Kite.Gateway.Domain.Entities;\nusing Serilog;\nusing Microsoft.IdentityModel.Tokens;\nusing System.Security.Cryptography.X509Certificates;\nusing Kite.Gateway.Domain.Shared.Enums;\nusing System.Text.RegularExpressions;\n\nnamespace Kite.Gateway.Domain\n{\n    internal class ConfigureManager : DomainService, IConfigureManager\n    {\n        private readonly TokenValidationParameters _tokenValidationParameters;\n        private readonly AuthenticationOption _authenticationOption;\n        private readonly List<MiddlewareOption> _middlewareOptions;\n        private readonly List<WhitelistOption> _whitelistOptions;\n        private readonly YarpOption _yarpOption;\n        public ConfigureManager(IOptions<List<MiddlewareOption>> middlewareOptions\n            , IOptions<List<WhitelistOption>> whitelistOptions\n            , IOptions<TokenValidationParameters> tokenValidationParameters, IOptions<AuthenticationOption> authenticationOption\n            , IOptions<YarpOption> yarpOption)\n        {\n            _middlewareOptions = middlewareOptions.Value;\n            _whitelistOptions = whitelistOptions.Value;\n            _tokenValidationParameters = tokenValidationParameters.Value;\n            _authenticationOption = authenticationOption.Value;\n            _yarpOption = yarpOption.Value;\n        }\n\n        public void ReloadAuthentication(AuthenticationOption authenticationOption)\n        {\n            TypeAdapter.Adapt(authenticationOption, _authenticationOption);\n            //同步刷新token验证\n            GetTokenValidationParameters();\n        }\n        private void GetTokenValidationParameters()\n        {\n            if (_authenticationOption.UseState)\n            {\n                SecurityKey securityKey;\n                //判断是否启用\n                if (_authenticationOption.UseSSL)\n                {\n                    var certificateFile = Convert.FromBase64String(_authenticationOption.CertificateFile);\n                    var x509Certificate2 = new X509Certificate2(certificateFile, _authenticationOption.CertificatePassword);\n                    securityKey = new X509SecurityKey(x509Certificate2);\n                }\n                else\n                {\n                    //\n                    securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_authenticationOption.SecurityKeyStr));\n                }\n                _tokenValidationParameters.ValidateIssuerSigningKey = _authenticationOption.ValidateIssuerSigningKey;//是否验证签名,不验证的画可以篡改数据，不安全\n                _tokenValidationParameters.IssuerSigningKey = securityKey;//解密的密钥\n                _tokenValidationParameters.ValidateIssuer = _authenticationOption.ValidateIssuer;//是否验证发行人，就是验证载荷中的Iss是否对应ValidIssuer参数\n                _tokenValidationParameters.ValidIssuer = _authenticationOption.Issuer;//发行人\n                _tokenValidationParameters.ValidateAudience = _authenticationOption.ValidateAudience;//是否验证订阅人，就是验证载荷中的Aud是否对应ValidAudience参数\n                _tokenValidationParameters.ValidAudience = _authenticationOption.Audience;//订阅人\n                _tokenValidationParameters.ValidateLifetime = _authenticationOption.ValidateLifetime;//是否验证过期时间，过期了就拒绝访问\n                _tokenValidationParameters.ClockSkew = TimeSpan.FromSeconds(_authenticationOption.ClockSkew);//这个是缓冲过期时间，也就是说，即使我们配置了过期时间，这里也要考虑进去，过期时间+缓冲，默认好像是7分钟，你可以直接设置为0\n                _tokenValidationParameters.RequireExpirationTime = _authenticationOption.RequireExpirationTime;\n            }\n        }\n        public void ReloadMiddleware(List<MiddlewareOption> middlewareOptions)\n        {\n            //删除原有中间件配置信息\n            _middlewareOptions.Clear();\n\n            foreach (var middlewareOption in middlewareOptions)\n            {\n                _middlewareOptions.Add(middlewareOption);\n            }\n            \n        }\n\n        public void ReloadWhitelist(List<WhitelistOption> whitelistOptions)\n        {\n            _whitelistOptions.Clear();\n            foreach (var whitelistOption in whitelistOptions)\n            {\n                _whitelistOptions.Add(whitelistOption);\n            }\n        }\n\n        public void ReloadYayp(YarpOption yarpOption)\n        {\n            //路由数据\n            _yarpOption.Routes.Clear();\n            _yarpOption.Routes.AddRange(yarpOption.Routes);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/DomainModule.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared;\nusing Kite.Gateway.Domain;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Modularity;\nusing Microsoft.Extensions.DependencyInjection;\nusing Yarp.ReverseProxy.Configuration;\nusing Kite.Gateway.Domain.ReverseProxy;\n\nnamespace Kite.Gateway.Domain\n{\n    [DependsOn(\n        typeof(DomainSharedModule)\n    )]\n    public class DomainModule:AbpModule\n    {\n        public override void ConfigureServices(ServiceConfigurationContext context)\n        {\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/Administrator.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    public class Administrator : Entity<Guid>\n    {\n        public Administrator() { }\n        public Administrator(Guid id) : base(id)\n        {\n        }\n        /// <summary>\n        /// 管理员名\n        /// </summary>\n        [MaxLength(32)]\n        public string AdminName { get; set; }\n        /// <summary>\n        /// 登录密码\n        /// </summary>\n        [MaxLength(64)]\n        public string Password { get; set; }\n        /// <summary>\n        /// 昵称\n        /// </summary>\n        [MaxLength(64)]\n        public string NickName { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 最后更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/AuthenticationConfigure.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\nusing System.ComponentModel.DataAnnotations;\nnamespace Kite.Gateway.Domain.Entities\n{\n    public class AuthenticationConfigure : Entity<Guid>\n    {\n        public AuthenticationConfigure() { }\n        public AuthenticationConfigure(Guid id) : base(id)\n        {\n            \n        }\n        /// <summary>\n        /// 是否开启\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 颁发者\n        /// </summary>\n        [MaxLength(512)]\n        public string Issuer { get; set; }\n        /// <summary>\n        /// 观察者\n        /// </summary>\n        [MaxLength(512)]\n        public string Audience { get; set; }\n        /// <summary>\n        /// 时间偏移(秒)\n        /// </summary>\n        public int ClockSkew { get; set; }\n        /// <summary>\n        /// 是否验证签名\n        /// </summary>\n        public bool ValidateIssuerSigningKey { get; set; }\n        /// <summary>\n        /// 是否验证颁发者\n        /// </summary>\n        public bool ValidateIssuer { get; set; }\n        /// <summary>\n        /// 是否验证观察者\n        /// </summary>\n        public bool ValidateAudience { get; set; }\n        /// <summary>\n        /// 是否验证失效时间\n        /// </summary>\n        public bool ValidateLifetime { get; set; }\n        /// <summary>\n        /// 是否需要扩展时间\n        /// </summary>\n        public bool RequireExpirationTime { get; set; }\n        /// <summary>\n        /// 是否启用SSL证书\n        /// </summary>\n        public bool UseSSL { get; set; }\n        /// <summary>\n        /// 秘钥字符串\n        /// </summary>\n        [MaxLength(512)]\n        public string SecurityKeyStr { get; set; }\n        /// <summary>\n        /// 证书文件内容(BASE64)\n        /// </summary>\n        public string CertificateFile { get; set; }\n        /// <summary>\n        /// 证书文件名(文件后缀名.pfx或者.cer 文件内容)\n        /// </summary>\n        [MaxLength(128)]\n        public string CertificateFileName { get; set; }\n        /// <summary>\n        /// 证书密码\n        /// </summary>\n        [MaxLength(128)]\n        public string CertificatePassword { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/Cluster.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 集群配置表\n    /// </summary>\n    public class Cluster : Entity<Guid>\n    {\n        public Cluster() { }\n        public Cluster(Guid id) : base(id)\n        {\n        }\n        /// <summary>\n        /// 关联路由ID\n        /// </summary>\n        public Guid RouteId { get; set; }\n        /// <summary>\n        /// 集群名称\n        /// </summary>\n        [MaxLength(128)]\n        public string ClusterName { get; set; }\n        /// <summary>\n        /// 负载均衡策略\n        /// FirstAlphabetical: 在不考虑负载的情况下选择按字母顺序排列的第一个可用目的地。这对于双目的地故障转移系统很有用。\n        /// Random: 随机选择一个目的地。\n        /// PowerOfTwoChoices (默认): 选择两个随机目标，然后选择分配请求最少的目标。这避免了它选择繁忙目的地的开销LeastRequests和最坏情况。Random\n        /// RoundRobin: 通过按顺序循环选择目的地。\n        /// LeastRequests: 选择分配的请求最少的目标。这需要检查所有目的地。\n        /// </summary>\n        [MaxLength(128)]\n        public string LoadBalancingPolicy { get; set; }\n        /// <summary>\n        /// 服务治理类型(0.Default  1.Consul  2.Nacos)\n        /// </summary>\n        public ServiceGovernanceType ServiceGovernanceType { get; set; }\n        /// <summary>\n        /// 服务治理名称\n        /// </summary>\n        [MaxLength(128)]\n        public string ServiceGovernanceName { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/ClusterDestination.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 集群目的地信息表\n    /// </summary>\n    public class ClusterDestination : Entity<Guid>\n    {\n        public ClusterDestination() { }\n        public ClusterDestination(Guid id) : base(id)\n        {\n        }\n        /// <summary>\n        /// 所属集群ID\n        /// </summary>\n        public Guid ClusterId { get; set; }\n        /// <summary>\n        /// 目的地名称\n        /// </summary>\n        [MaxLength(128)]\n        public string DestinationName { get; set; }\n        /// <summary>\n        /// 目的地地址\n        /// </summary>\n        [MaxLength(1024)]\n        public string DestinationAddress { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/ClusterHealthCheck.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 集群健康检查表\n    /// </summary>\n    public class ClusterHealthCheck : Entity<Guid>\n    {\n        public ClusterHealthCheck() { }\n        public ClusterHealthCheck(Guid id) : base(id)\n        {\n        }\n        /// <summary>\n        /// 关联集群ID\n        /// </summary>\n        public Guid ClusterId { get; set; }\n        /// <summary>\n        /// 是否开启健康检查\n        /// </summary>\n        public bool Enabled { get; set; }\n        /// <summary>\n        /// 检查间隔时间(秒)\n        /// </summary>\n        public int Interval { get; set; }\n        /// <summary>\n        /// 超时时间\n        /// </summary>\n        public int Timeout { get; set; }\n        /// <summary>\n        /// 检查策略\n        /// </summary>\n        [MaxLength(64)]\n        public string Policy { get; set; }\n        /// <summary>\n        /// 健康检查地址\n        /// </summary>\n        [MaxLength(128)]\n        public string Path { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/Middleware.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 中间件信息记录表\n    /// </summary>\n    public class Middleware : Entity<Guid>\n    {\n        public Middleware() { }\n        public Middleware(Guid id) : base(id)\n        {\n        }\n        /// <summary>\n        /// 中间件名称\n        /// </summary>\n        [MaxLength(64)]\n        public string Name { get; set; }\n        /// <summary>\n        /// 服务端地址\n        /// </summary>\n        [MaxLength(1024)]\n        public string Server { get; set; }\n        /// <summary>\n        /// 通信类型\n        /// </summary>\n        public SignalTypeEnum SignalType { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 执行权重(数字越大越靠前)\n        /// </summary>\n        public int ExecWeight { get; set; }\n        /// <summary>\n        /// 中间件描述\n        /// </summary>\n        [MaxLength(1024)]\n        public string Description { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/Node.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 网关集群部署节点信息表\n    /// </summary>\n    public class Node : Entity<Guid>\n    {\n        public Node() { }\n        public Node(Guid id) : base(id)\n        {\n\n        }\n        /// <summary>\n        /// 节点名称\n        /// </summary>\n        [MaxLength(128)]\n        public string NodeName { get; set; }\n        /// <summary>\n        /// 节点描述\n        /// </summary>\n        [MaxLength(512)]\n        public string Description { get; set; }\n        /// <summary>\n        /// 节点服务端地址\n        /// </summary>\n        [MaxLength(1024)]\n        public string Server { get; set; }\n        /// <summary>\n        /// 访问Token\n        /// </summary>\n        [MaxLength(512)]\n        public string AccessToken { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 最后更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/Route.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 服务配置表\n    /// </summary>\n    public class Route : Entity<Guid>\n    {\n        public Route() { }\n        public Route(Guid id) : base(id)\n        {\n        }\n        /// <summary>\n        /// 路由ID同主键ID\n        /// </summary>\n        [MaxLength(64)]\n        public string RouteId { get; set; }\n        /// <summary>\n        /// 路由名称\n        /// </summary>\n        [MaxLength(64)]\n        public string RouteName { get; set; }\n        /// <summary>\n        /// 描述\n        /// </summary>\n        [MaxLength(512)]\n        public string Description { get; set; }\n        /// <summary>\n        /// 状态\n        /// </summary>\n        public bool UseState { get; set; }\n\n        /// <summary>\n        /// 路由路径规则\n        /// </summary>\n        [MaxLength(128)]\n        public string RouteMatchPath { get; set; }\n\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        /// <summary>\n        /// 更新时间\n        /// </summary>\n        public DateTime? Updated { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/RouteTransform.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 服务交换配置表\n    /// </summary>\n    public class RouteTransform : Entity<Guid>\n    {\n        public RouteTransform() { }\n        public RouteTransform(Guid id) : base(id)\n        {\n        }\n        /// <summary>\n        /// 关联路由ID\n        /// </summary>\n        public Guid RouteId { get; set; }\n        /// <summary>\n        /// 交换配置项名称\n        /// </summary>\n        [MaxLength(128)]\n        public string TransformsName { get; set; }\n        /// <summary>\n        /// 交换配置项值\n        /// </summary>\n        [MaxLength(128)]\n        public string TransformsValue { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/ServiceGovernanceConfigure.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\nusing System.ComponentModel.DataAnnotations;\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 服务治理配置\n    /// </summary>\n    public class ServiceGovernanceConfigure : Entity<Guid>\n    {\n        public ServiceGovernanceConfigure() { }\n        public ServiceGovernanceConfigure(Guid id) : base(id)\n        {\n\n        }\n        /// <summary>\n        /// Consul服务端地址\n        /// </summary>\n        [MaxLength(512)]\n        public string ConsulServer { get; set; }\n        /// <summary>\n        /// Consul数据中心\n        /// </summary>\n        [MaxLength(128)]\n        public string ConsulDatacenter { get; set; }\n        /// <summary>\n        /// Consul访问令牌\n        /// </summary>\n        [MaxLength(128)]\n        public string ConsulToken { get; set; }\n        /// <summary>\n        /// Nacos服务器地址\n        /// </summary>\n        [MaxLength(512)]\n        public string NacosServer { get; set; }\n        /// <summary>\n        /// Nacos群组名\n        /// </summary>\n        [MaxLength(128)]\n        public string NacosGroupName { get; set; }\n        /// <summary>\n        /// Nacos命名空间ID\n        /// </summary>\n        [MaxLength(128)]\n        public string NacosNamespaceId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Entities/Whitelist.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Entities\n{\n    /// <summary>\n    /// 白名单\n    /// </summary>\n    public class Whitelist : Entity<Guid>\n    {\n        public Whitelist() { }\n        public Whitelist(Guid id) : base(id)\n        {\n        }\n        /// <summary>\n        /// 所属路由(为空则全局)\n        /// </summary>\n        public Guid? RouteId { get; set; }\n        /// <summary>\n        /// 白名单名称\n        /// </summary>\n        [MaxLength(64)]\n        public string Name { get; set; }\n        /// <summary>\n        /// 过滤文本(* 号则表示过滤所有)\n        /// </summary>\n        [MaxLength(128)]\n        public string FilterText { get; set; }\n        /// <summary>\n        /// 请求方式(多请求方式使用,分隔)\n        /// </summary>\n        [MaxLength(64)]\n        public string RequestMethod { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 创建时间\n        /// </summary>\n        public DateTime Created { get; set; }\n        \n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/IConfigureManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.Shared.Options;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain\n{\n    /// <summary>\n    /// 公共配置项处理服务\n    /// </summary>\n    public interface IConfigureManager\n    {\n        /// <summary>\n        /// 重新加载Yarp反向代理配置数据\n        /// </summary>\n        /// <param name=\"yarpOption\"></param>\n        void ReloadYayp(YarpOption yarpOption);\n        /// <summary>\n        /// 重新加载身份认证配置信息\n        /// </summary>\n        /// <returns></returns>\n        void ReloadAuthentication(AuthenticationOption authenticationOption);\n        /// <summary>\n        /// 重新加载白名单配置信息\n        /// </summary>\n        /// <returns></returns>\n        void ReloadWhitelist(List<WhitelistOption> whitelistOptions);\n        /// <summary>\n        /// 重新加载中间件配置信息\n        /// </summary>\n        /// <returns></returns>\n        void ReloadMiddleware(List<MiddlewareOption> middlewareOptions);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Kite.Gateway.Domain.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net7.0</TargetFramework>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Volo.Abp.Ddd.Domain\" Version=\"7.0.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Kite.Gateway.Domain.Shared\\Kite.Gateway.Domain.Shared.csproj\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Middlewares/IMiddlewareContext.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Middlewares\n{\n    public interface IMiddlewareContext\n    {\n        /// <summary>\n        /// 执行中间件\n        /// </summary>\n        /// <param name=\"context\"></param>\n        /// <returns></returns>\n        Task<MiddlewareResult> InvokeMiddlewareAsync();\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Middlewares/IMiddlewareManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Middlewares\n{\n    public interface IMiddlewareManager\n    {\n        /// <summary>\n        /// 获取所有中间件配置信息\n        /// </summary>\n        /// <returns></returns>\n        Task<List<Middleware>> GetListAsync();\n        /// <summary>\n        /// 更新中间件信息\n        /// </summary>\n        /// <param name=\"id\">中间件ID</param>\n        /// <param name=\"name\">中间件名称</param>\n        /// <param name=\"server\">服务端地址</param>\n        /// <returns></returns>\n        Task<Middleware> UpdateAsync(Guid id,string name, string server);\n        /// <summary>\n        /// 创建中间件\n        /// </summary>\n        /// <param name=\"name\">名称</param>\n        /// <param name=\"server\">服务端地址</param>\n        /// <returns></returns>\n        Task<Middleware> CreateAsync(string name,string server);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Middlewares/MiddlewareManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing Microsoft.Extensions.Caching.Memory;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\nusing Volo.Abp.Domain.Services;\n\nnamespace Kite.Gateway.Domain.Middlewares\n{\n    internal class MiddlewareManager : DomainService, IMiddlewareManager\n    {\n        private const string CacheKey = \"AuthenticationConfigure\";\n        //\n        private readonly IMemoryCache _memoryCache;\n        private readonly IRepository<Middleware> _repository;\n\n        public MiddlewareManager(IRepository<Middleware> repository, IMemoryCache memoryCache)\n        {\n            _repository = repository;\n            _memoryCache = memoryCache;\n        }\n        public async Task<List<Middleware>> GetListAsync()\n        {\n            var data = _memoryCache.Get<List<Middleware>>(CacheKey);\n            if (data == null)\n            {\n                data = await _repository.GetListAsync();\n                if (data == null)\n                {\n                    throw new ArgumentNullException(\"身份认证信息未配置\");\n                }\n                _memoryCache.Set(CacheKey, data, DateTimeOffset.Now.AddDays(7));\n            }\n            return data;\n        }\n\n        public async Task<Middleware> CreateAsync(string name, string server)\n        {\n            if (await _repository.AnyAsync(x => x.Name == name))\n            {\n                throw new ArgumentException(\"中间件名称不能重复\");\n            }\n            if (await _repository.AnyAsync(x => x.Server == server))\n            {\n                throw new ArgumentException(\"中间件远程调用服务端地址不能重复\");\n            }\n            return new Middleware(GuidGenerator.Create())\n            {\n                Created = DateTime.Now,\n                Updated = DateTime.Now\n            };\n        }\n\n        \n\n        public async Task<Middleware> UpdateAsync(Guid id, string name, string server)\n        {\n\n            if (await _repository.AnyAsync(x => x.Name == name && x.Id != id))\n            {\n                throw new ArgumentException(\"中间件名称不能重复\");\n            }\n            if (await _repository.AnyAsync(x => x.Server == server && x.Id != id))\n            {\n                throw new ArgumentException(\"中间件远程调用服务端地址不能重复\");\n            }\n            var model = await _repository.FirstOrDefaultAsync(x => x.Id == id);\n            if (model == null)\n            {\n                throw new ArgumentNullException(\"中间件信息不存在\");\n            }\n            model.Updated = DateTime.Now;\n            return model;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Middlewares/MiddlewareResult.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Middlewares\n{\n    public class MiddlewareResult\n    {\n        /// <summary>\n        /// Http状态码(为200时表示成功)\n        /// </summary>\n        public int HttpStatusCode { get; set; }\n        /// <summary>\n        /// 结果(希望通过返回给调用者的结果)\n        /// </summary>\n        public string Result { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Node/INodeManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Node\n{\n    public interface INodeManager\n    {\n        /// <summary>\n        /// 更新网关节点\n        /// </summary>\n        /// <param name=\"id\">节点ID</param>\n        /// <param name=\"nodeName\">节点名称</param>\n        /// <param name=\"server\">服务地址</param>\n        /// <returns></returns>\n        Task<Entities.Node> UpdateAsync(Guid id,string nodeName, string server);\n        /// <summary>\n        /// 创建网关节点\n        /// </summary>\n        /// <param name=\"nodeName\">节点名称</param>\n        /// <param name=\"server\">服务地址</param>\n        /// <returns></returns>\n        Task<Entities.Node> CreateAsync(string nodeName,string server);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Node/NodeManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Services;\nusing Volo.Abp.Domain.Repositories;\nusing Mapster;\n\nnamespace Kite.Gateway.Domain.Node\n{\n    internal class NodeManager : DomainService, INodeManager\n    {\n\n        private readonly IRepository<Entities.Node> _repository;\n\n        public NodeManager(IRepository<Entities.Node> repository)\n        {\n            _repository = repository;\n        }\n\n        public async Task<Entities.Node> CreateAsync(string nodeName, string server)\n        {\n            if (await _repository.AnyAsync(x => x.NodeName == nodeName))\n            {\n                throw new ArgumentException(\"节点名称已经存在\");\n            }\n            if (await _repository.AnyAsync(x => x.Server == server))\n            {\n                throw new ArgumentException(\"节点服务器地址已经存在\");\n            }\n            return new Entities.Node(GuidGenerator.Create())\n            {\n                Created = DateTime.Now,\n                Updated = DateTime.Now,\n                Description = \"\",\n                NodeName = nodeName,\n                Server = server,\n                AccessToken = \"\"\n            };\n        }\n\n        public async Task<Entities.Node> UpdateAsync(Guid id, string nodeName, string server)\n        {\n            if (await _repository.AnyAsync(x => x.NodeName == nodeName && x.Id != id))\n            {\n                throw new ArgumentException(\"节点名称已经存在\");\n            }\n            if (await _repository.AnyAsync(x => x.Server == server && x.Id != id))\n            {\n                throw new ArgumentException(\"节点服务器地址已经存在\");\n            }\n            var model= await _repository.FirstOrDefaultAsync(x => x.Id == id);\n            model.Updated = DateTime.Now;\n            return model;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/ClusterManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\nusing Volo.Abp.Domain.Services;\nusing Volo.Abp.Guids;\nusing Mapster;\nusing Yarp.ReverseProxy.Health;\nusing Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.Shared.Enums;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    internal class ClusterManager: DomainService, IClusterManager\n    {\n        private readonly IRepository<Cluster> _clusterRepository;\n        public ClusterManager(IRepository<Cluster> clusterRepository)\n        {\n            _clusterRepository = clusterRepository;\n        }\n\n        public async Task<Cluster> CreateAsync(Guid routeId, string clusterName, ServiceGovernanceType serviceGovernanceType, string serviceGovernanceName,string loadBalancingPolicy)\n        {\n            var cluster = await _clusterRepository.FindAsync(x => x.RouteId == routeId);\n            if (cluster != null)\n            {\n                throw  new Exception(\"同一个路由下只能创建一个集群\");\n            }\n            return  new Cluster(GuidGenerator.Create())\n            {\n                ClusterName= clusterName,\n                RouteId= routeId,\n                ServiceGovernanceName=string.IsNullOrEmpty(serviceGovernanceName)?\"\": serviceGovernanceName,\n                ServiceGovernanceType= serviceGovernanceType,\n                LoadBalancingPolicy= loadBalancingPolicy\n            };\n        }\n        public Task<ClusterDestination> CreateClusterDestinationAsync(Guid clusterId, string destinationName, string destinationAddress)\n        {\n            return Task.Factory.StartNew(() => {\n                return new ClusterDestination(GuidGenerator.Create())\n                {\n                    DestinationAddress = destinationAddress,\n                    ClusterId = clusterId,\n                    DestinationName = destinationName\n                };\n            });\n        }\n\n        public Task<ClusterHealthCheck> CreateHealthCheckAsync<TDto>(TDto healthCheck) where TDto : class\n        {\n            return Task.Factory.StartNew(() => {\n                var model= new ClusterHealthCheck(GuidGenerator.Create());\n                model.Policy = HealthCheckConstants.ActivePolicy.ConsecutiveFailures;\n                TypeAdapter.Adapt(healthCheck, model);\n                return model;\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/GatewayOptions.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public class GatewayOptions\n    {\n\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/IClusterManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public interface IClusterManager\n    {\n        /// <summary>\n        /// 创建健康检查\n        /// </summary>\n        /// <typeparam name=\"TDto\"></typeparam>\n        /// <param name=\"healthCheck\"></param>\n        /// <returns></returns>\n        Task<ClusterHealthCheck> CreateHealthCheckAsync<TDto>(TDto healthCheck) where TDto : class;\n        /// <summary>\n        /// 创建集群 \n        /// </summary>\n        /// <param name=\"routeId\">路由ID</param>\n        /// <param name=\"clusterName\">集群名称</param>\n        /// <param name=\"serviceGovernanceType\">服务治理类型</param>\n        /// <param name=\"serviceGovernanceName\">服务名称</param>\n        /// <param name=\"loadBalancingPolicy\">负载均衡策略</param>\n        /// <returns></returns>\n        Task<Cluster> CreateAsync(Guid routeId,string clusterName, ServiceGovernanceType serviceGovernanceType,string serviceGovernanceName, string loadBalancingPolicy);\n        /// <summary>\n        /// 创建集群目的地\n        /// </summary>\n        /// <param name=\"clusterId\">所属集群ID</param>\n        /// <param name=\"destinationName\">目的地名称</param>\n        /// <param name=\"destinationAddress\">目的地地址</param>\n        /// <returns></returns>\n        Task<ClusterDestination> CreateClusterDestinationAsync(Guid clusterId,string destinationName,string destinationAddress);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/IRefreshManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public  interface IRefreshManager\n    {\n        /// <summary>\n        /// 重载网关配置\n        /// </summary>\n        /// <returns></returns>\n        Task ReloadConfigAsync();\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/IReverseProxyDatabaseStore.cs",
    "content": "﻿using Microsoft.Extensions.Primitives;\nusing System.Threading.Tasks;\nusing Yarp.ReverseProxy.Configuration;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public interface IReverseProxyDatabaseStore\n    {\n        /// <summary>\n        /// 获取反向代理配置\n        /// </summary>\n        /// <returns></returns>\n        InDatabaseStoreConfig GetConfig();\n        /// <summary>\n        /// 重新加载配置\n        /// </summary>\n        void Reload();\n        /// <summary>\n        /// 获取重新加载所需token\n        /// </summary>\n        /// <returns></returns>\n        IChangeToken GetReloadToken();\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/IRouteManager.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public interface IRouteManager\n    {\n        /// <summary>\n        /// 创建路由 \n        /// </summary>\n        /// <param name=\"routeName\">路由名称</param>\n        /// <param name=\"routeMatchPath\">路由路径</param>\n        /// <param name=\"useState\">服务状态</param>\n        /// <param name=\"description\">路由描述</param>\n        /// <returns></returns>\n        Task<Route> CreateAsync(string routeName,string routeMatchPath, bool useState, string description);\n        /// <summary>\n        /// 创建路由交换\n        /// </summary>\n        /// <param name=\"routeId\">路由ID</param>\n        /// <param name=\"transformsName\">交换项名称</param>\n        /// <param name=\"transformsValue\">交换项值</param>\n        /// <returns></returns>\n        Task<RouteTransform> CreateRouteTransformAsync(Guid routeId,string transformsName,string transformsValue);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/IYarpManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Kite.Gateway.Domain.Shared.Options;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public interface IYarpManager\n    {\n        /// <summary>\n        /// 获取Yarp配置数据\n        /// </summary>\n        /// <returns></returns>\n        Task<YarpOption> GetConfigureAsync();\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/InDatabaseReloadToken.cs",
    "content": "﻿using Microsoft.Extensions.Primitives;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public class InDatabaseReloadToken : IChangeToken\n    {\n        private CancellationTokenSource tokenSource = new CancellationTokenSource();\n        public void OnReload() => tokenSource.Cancel();\n        public bool ActiveChangeCallbacks { get; } = true;\n\n        public bool HasChanged { get { return tokenSource.IsCancellationRequested; } }\n\n        public IDisposable RegisterChangeCallback(Action<object> callback, object state)\n        {\n            return tokenSource.Token.Register(callback, state);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/InDatabaseStoreConfig.cs",
    "content": "﻿using Microsoft.Extensions.Primitives;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Yarp.ReverseProxy.Configuration;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public class InDatabaseStoreConfig : IProxyConfig\n    {\n        private readonly CancellationTokenSource _cts = new CancellationTokenSource();\n        public InDatabaseStoreConfig(IReadOnlyList<RouteConfig> routes, IReadOnlyList<ClusterConfig> clusters)\n        {\n            Routes = routes;\n            Clusters = clusters;\n            ChangeToken = new CancellationChangeToken(_cts.Token);\n        }\n        public IReadOnlyList<RouteConfig> Routes { get; }\n\n        public IReadOnlyList<ClusterConfig> Clusters { get; }\n\n        public IChangeToken ChangeToken { get; internal set; }\n        internal void SignalChange()\n        {\n            _cts.Cancel();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/InDatabaseStoreConfigProvider.cs",
    "content": "﻿using Microsoft.Extensions.Logging;\nusing Microsoft.Extensions.Primitives;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Yarp.ReverseProxy.Configuration;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public class InDatabaseStoreConfigProvider : IProxyConfigProvider, IDisposable\n    {\n        private readonly object _lockObject = new object();\n        private readonly IReverseProxyDatabaseStore _strore;\n        private InDatabaseStoreConfig _config;\n        private CancellationTokenSource _changeToken;\n        private bool _disposed;\n        private IDisposable _subscription;\n\n        private ILogger<InDatabaseStoreConfigProvider> _logger;\n        public InDatabaseStoreConfigProvider(IReverseProxyDatabaseStore strore, ILogger<InDatabaseStoreConfigProvider> logger)\n        {\n            _strore = strore;\n            _logger = logger;\n        }\n        public IProxyConfig GetConfig()\n        {\n            if (_config == null)\n            {\n                _subscription = ChangeToken.OnChange(_strore.GetReloadToken, UpdateConfig);\n                UpdateConfig();\n            }\n            return _config;\n        }\n        public void Dispose()\n        {\n            if (!_disposed)\n            {\n                _subscription?.Dispose();\n                _changeToken?.Dispose();\n                _disposed = true;\n            }\n        }\n        private void UpdateConfig()\n        {\n            lock (_lockObject)\n            {\n                InDatabaseStoreConfig newConfig = null;\n                try\n                {\n                    newConfig = _strore.GetConfig();\n                }\n                catch (Exception ex)\n                {\n                    _logger.LogError(ex, ex.Message);\n                    return;\n                }\n\n                var oldToken = _changeToken;\n                _changeToken = new CancellationTokenSource();\n                newConfig.ChangeToken = new CancellationChangeToken(_changeToken.Token);\n                _config = newConfig;\n                try\n                {\n                    oldToken?.Cancel(throwOnFirstException: false);\n                }\n                catch (Exception ex)\n                {\n                    _logger.LogError(ex, ex.Message);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/InDatabaseStoreReloadToken.cs",
    "content": "﻿using Microsoft.Extensions.Primitives;\nusing System;\nusing System.Threading;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public class InDatabaseStoreReloadToken : IChangeToken\n    {\n        private CancellationTokenSource tokenSource = new CancellationTokenSource();\n        public void OnReload() => tokenSource.Cancel();\n        public bool ActiveChangeCallbacks { get; } = true;\n\n        public bool HasChanged { get { return tokenSource.IsCancellationRequested; } }\n\n        public IDisposable RegisterChangeCallback(Action<object> callback, object state)\n        {\n            return tokenSource.Token.Register(callback, state);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/Models/NacosServiceHostModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.ReverseProxy.Models\n{\n    public class NacosServiceHostModel\n    {\n        /// <summary>\n        /// \n        /// </summary>\n        public string InstanceId { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string IP { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public int Port { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string Weight { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string Healthy { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string Enabled { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string Ephemeral { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string ClusterName { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string ServiceName { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public int InstanceHeartBeatInterval { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string InstanceIdGenerator { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public int InstanceHeartBeatTimeOut { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public int IpDeleteTimeout { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/Models/NacosServiceModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.ReverseProxy.Models\n{\n    public class NacosServiceModel\n    {\n        // <summary>\n        /// \n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string GroupName { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string Clusters { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public int CacheMillis { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public List<NacosServiceHostModel> Hosts { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public long  LastRefTime { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public string Checksum { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public bool AllIPs { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public bool ReachProtectionThreshold { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public bool Valid { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/Models/ServiceGovernanceModel.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.ReverseProxy.Models\n{\n    /// <summary>\n    /// 服务治理配置项\n    /// </summary>\n    public class ServiceGovernanceModel\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        public Guid? Id { get; set; }\n        /// <summary>\n        /// Consul服务端地址\n        /// </summary>\n        public string ConsulServer { get; set; }\n        /// <summary>\n        /// Consul数据中心\n        /// </summary>\n        public string ConsulDatacenter { get; set; }\n        /// <summary>\n        /// Consul访问令牌\n        /// </summary>\n        public string ConsulToken { get; set; }\n        /// <summary>\n        /// Nacos服务器地址\n        /// </summary>\n        public string NacosServer { get; set; }\n        /// <summary>\n        /// Nacos群组名\n        /// </summary>\n        public string NacosGroupName { get; set; }\n        /// <summary>\n        /// Nacos命名空间ID\n        /// </summary>\n        public string NacosNamespaceId { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/RefreshManager.cs",
    "content": "﻿using Kite.Gateway.Domain.ReverseProxy;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Services;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    internal class RefreshManager:DomainService, IRefreshManager\n    {\n        private readonly IReverseProxyDatabaseStore _reverseProxyMemoryStore;\n        public RefreshManager(IReverseProxyDatabaseStore reverseProxyMemoryStore)\n        {\n            _reverseProxyMemoryStore = reverseProxyMemoryStore;\n        }\n        public Task ReloadConfigAsync()\n        {\n            return Task.Factory.StartNew(() => \n            {\n                _reverseProxyMemoryStore.Reload();\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/ReverseProxyDatabaseStore.cs",
    "content": "﻿using Microsoft.Extensions.Primitives;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Yarp.ReverseProxy.Configuration;\nusing Yarp.ReverseProxy.Health;\nusing Microsoft.Extensions.Options;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Volo.Abp.DependencyInjection;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    public class ReverseProxyDatabaseStore : ISingletonDependency, IReverseProxyDatabaseStore\n    {\n        private InDatabaseReloadToken _reloadToken=new InDatabaseReloadToken();\n        private YarpOption _yarpOption;\n        public ReverseProxyDatabaseStore(IOptions<YarpOption> options)\n        {\n            _yarpOption = options.Value;\n        }\n        public InDatabaseStoreConfig GetConfig()\n        {\n            //\n            var routeConfigs = new List<RouteConfig>();\n            var clusterConfigs = new List<ClusterConfig>();\n            //处理配置项\n            foreach (var route in _yarpOption.Routes)\n            {\n                var transforms = new List<Dictionary<string, string>>();\n                var transformData = new Dictionary<string, string>();\n                if (route.RouteTransforms.Any())\n                {\n                    foreach (var transform in route.RouteTransforms)\n                    {\n                        transformData.Add(transform.TransformsName, transform.TransformsValue);\n                    }\n                    transforms.Add(transformData);\n                }\n                //路由配置\n                routeConfigs.Add(new RouteConfig()\n                {\n                    RouteId = route.RouteId,\n                    ClusterId = route.RouteId,\n                    Match = new RouteMatch()\n                    {\n                        Path = route.RouteMatchPath\n                    },\n                    Transforms = transforms,\n                });\n                //集群配置\n                //集群目的地配置数据\n                var destinations = new Dictionary<string, DestinationConfig>(StringComparer.OrdinalIgnoreCase);\n                foreach (var item in route.Cluster.ClusterDestinations)\n                {\n                    destinations.Add(item.DestinationName, new DestinationConfig()\n                    {\n                        Address = item.DestinationAddress\n                    });\n                }\n                //健康检查配置数据\n                HealthCheckConfig healthCheck = null;\n                if (route.Cluster.ClusterHealthCheck != null)\n                {\n                    healthCheck = new HealthCheckConfig()\n                    {\n                        Active = new ActiveHealthCheckConfig()\n                        {\n                            Enabled = route.Cluster.ClusterHealthCheck.Enabled,\n                            Interval = TimeSpan.FromSeconds(route.Cluster.ClusterHealthCheck.Interval),\n                            Timeout = TimeSpan.FromSeconds(route.Cluster.ClusterHealthCheck.Timeout),\n                            Path = route.Cluster.ClusterHealthCheck.Path,\n                            Policy = HealthCheckConstants.ActivePolicy.ConsecutiveFailures\n                        }\n                    };\n                }\n                //\n                clusterConfigs.Add(new ClusterConfig()\n                {\n                    ClusterId = route.RouteId,\n                    Destinations = destinations,\n                    LoadBalancingPolicy = route.Cluster.LoadBalancingPolicy,\n                    HealthCheck = healthCheck\n                });\n            }\n            var proxyConfig = new InDatabaseStoreConfig(routeConfigs, clusterConfigs);\n            return proxyConfig;\n        }\n\n        public IChangeToken GetReloadToken()\n        {\n            return _reloadToken;\n        }\n\n        public void Reload()\n        {\n            Interlocked.Exchange(ref this._reloadToken,\n                new InDatabaseReloadToken()).OnReload();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/RouteManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\nusing Volo.Abp.Domain.Services;\nusing Mapster;\nusing Volo.Abp.Guids;\nusing Kite.Gateway.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    internal class RouteManager: DomainService,IRouteManager\n    {\n        private readonly IRepository<Route> _routeRepository;\n        public RouteManager(IRepository<Route> routeRepository)\n        {\n            _routeRepository = routeRepository;\n        }\n\n        public async Task<Route> CreateAsync(string routeName, string routeMatchPath, bool useState, string description)\n        {\n            var route = await _routeRepository.FirstOrDefaultAsync(x => x.RouteName == routeName || x.RouteMatchPath == routeMatchPath);\n            if (route != null)\n            {\n                throw new Exception(\"路由名称或者路由路径已经存在\");\n            }\n            var id = GuidGenerator.Create();\n            return new Route(id) \n            {\n                Created=DateTime.Now,\n                RouteMatchPath = routeMatchPath,\n                UseState = useState,\n                RouteName = routeName,\n                Updated=DateTime.Now,\n                Description=string.IsNullOrEmpty(description)?\"\":description,\n                RouteId= id.ToString(),\n            };\n        }\n\n        public Task<RouteTransform> CreateRouteTransformAsync(Guid routeId, string transformsName, string transformsValue)\n        {\n            return Task.Run(() => \n            {\n                return new RouteTransform(GuidGenerator.Create()) \n                {\n                    RouteId = routeId,\n                    TransformsName = transformsName,\n                    TransformsValue = transformsValue\n                };\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/ReverseProxy/YarpManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading.Tasks;\nusing Volo.Abp.DependencyInjection;\nusing Volo.Abp.Domain.Repositories;\nusing Mapster;\nusing Yarp.ReverseProxy.Health;\nusing Consul;\nusing Volo.Abp.Uow;\nusing Serilog;\nusing Kite.Gateway.Domain.Entities;\nusing Kite.Gateway.Domain.Shared.Enums;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Microsoft.Extensions.Options;\nusing Yarp.ReverseProxy.Configuration;\nusing Volo.Abp.Domain.Services;\nusing Kite.Gateway.Domain.ReverseProxy.Models;\nusing System.Net.Http;\nnamespace Kite.Gateway.Domain.ReverseProxy\n{\n    internal class YarpManager : DomainService, IYarpManager\n    {\n        private readonly IRepository<Route> _routeRepository;\n        private readonly IRepository<RouteTransform> _routeTransformRepository;\n        private readonly IRepository<Cluster> _clusterRepository;\n        private readonly IRepository<ClusterDestination> _clusterDestinationRepository;\n        private readonly IRepository<ClusterHealthCheck> _clusterHealthCheckRepository;\n        private readonly IRepository<ServiceGovernanceConfigure> _serviceGovernanceRepository;\n        private readonly IUnitOfWorkManager _unitOfWorkManager;\n        private readonly IHttpClientFactory _httpClientFactory;\n        //\n        private ServiceGovernanceModel _serviceGovernanceModel;\n        private ConsulClient _consulClient;\n        public YarpManager(IRepository<Route> routeRepository, IRepository<RouteTransform> routeTransformRepository\n            , IRepository<Cluster> clusterRepository, IRepository<ClusterDestination> clusterDestinationRepository\n            , IUnitOfWorkManager unitOfWorkManager, IRepository<ClusterHealthCheck> clusterHealthCheckRepository, IRepository<ServiceGovernanceConfigure> serviceGovernanceRepository\n            , IHttpClientFactory httpClientFactory)\n        {\n            _routeRepository = routeRepository;\n            _routeTransformRepository = routeTransformRepository;\n            _clusterRepository = clusterRepository;\n            _clusterDestinationRepository = clusterDestinationRepository;\n            _unitOfWorkManager = unitOfWorkManager;\n            _clusterHealthCheckRepository = clusterHealthCheckRepository;\n            _serviceGovernanceRepository = serviceGovernanceRepository;\n            _httpClientFactory = httpClientFactory;\n        }\n        public async Task<YarpOption> GetConfigureAsync()\n        {\n            var result = new YarpOption()\n            {\n                Routes=new List<RouteOption>()\n            };\n            using var unitOfWork = _unitOfWorkManager.Begin();\n            //获取所有数据\n            var routes = await _routeRepository.GetListAsync(x => x.UseState);\n            var routeTransforms = await _routeTransformRepository.GetListAsync();\n            var clusters = await _clusterRepository.GetListAsync();\n            var clusterDestinations = await _clusterDestinationRepository.GetListAsync();\n            var clusterHealthChecks = await _clusterHealthCheckRepository.GetListAsync();\n            //\n            if (_serviceGovernanceModel == null)\n            {\n                _serviceGovernanceModel = (await _serviceGovernanceRepository.GetQueryableAsync())\n                    .ProjectToType<ServiceGovernanceModel>()\n                    .FirstOrDefault();\n            }\n            //处理数据集\n            RouteOption routeOption;\n            Cluster cluster;\n            foreach (var route in routes)\n            {\n                routeOption = new RouteOption()\n                {\n                    RouteId = route.RouteId,\n                    RouteMatchPath = route.RouteMatchPath,\n                    RouteName = route.RouteName,\n                    RouteTransforms = routeTransforms.Where(x => x.RouteId == route.Id).Select(x => new RouteTransformOption()\n                    {\n                        TransformsName = x.TransformsName,\n                        TransformsValue = x.TransformsValue\n                    })\n                    .ToList()\n                };\n                //集群相关数据\n                cluster = clusters.Where(x => x.RouteId == route.Id).FirstOrDefault();\n                routeOption.Cluster = new ClusterOption() \n                {\n                    ClusterName= cluster.ClusterName,\n                    LoadBalancingPolicy= cluster.LoadBalancingPolicy\n                };\n                if (cluster.ServiceGovernanceType == ServiceGovernanceType.Consul)\n                {\n                    var consulDestinations = await GetConsulServiceAsync(cluster.ServiceGovernanceName);\n                    if (consulDestinations == null)\n                    {\n                        continue;\n                    }\n                    routeOption.Cluster.ClusterDestinations = consulDestinations;\n                }\n                else if (cluster.ServiceGovernanceType == ServiceGovernanceType.Nacos)\n                {\n                    var consulDestinations = await GetNacosServiceAsync(cluster.ServiceGovernanceName);\n                    if (consulDestinations == null)\n                    {\n                        continue;\n                    }\n                    routeOption.Cluster.ClusterDestinations = consulDestinations;\n                }\n                else\n                {\n                    routeOption.Cluster.ClusterDestinations = clusterDestinations.Where(x => x.ClusterId == cluster?.Id)\n                        .Select(x => new ClusterDestinationOption()\n                        {\n                            DestinationAddress = x.DestinationAddress,\n                            DestinationName = x.DestinationName\n                        })\n                        .ToList();\n                }\n                routeOption.Cluster.ClusterHealthCheck = clusterHealthChecks.Where(x => x.ClusterId == cluster?.Id)\n                    .Select(x => new ClusterHealthCheckOption()\n                    {\n                        Enabled = x.Enabled,\n                        Interval = x.Interval,\n                        Path = x.Path,\n                        Policy = x.Policy,\n                        Timeout = x.Timeout\n                    })\n                    .FirstOrDefault();\n                //\n                result.Routes.Add(routeOption);\n            }\n            return result;\n        }\n        private async Task<List<ClusterDestinationOption>> GetConsulServiceAsync(string serviceGovernanceName)\n        {\n            \n            if (_serviceGovernanceModel == null)\n            {\n                return null;\n            }\n            if (_consulClient == null)\n            {\n                var consulClientConfiguration = new ConsulClientConfiguration();\n                consulClientConfiguration.Datacenter = _serviceGovernanceModel.ConsulDatacenter;\n                consulClientConfiguration.Address = new Uri(_serviceGovernanceModel.ConsulServer);\n                if (!string.IsNullOrEmpty(_serviceGovernanceModel.ConsulToken) && _serviceGovernanceModel.ConsulToken != \"\")\n                {\n                    consulClientConfiguration.Token = _serviceGovernanceModel.ConsulToken;\n                }\n                _consulClient = new ConsulClient(consulClientConfiguration);\n            }\n            try\n            {\n                var queryResult = await _consulClient.Catalog.Service(serviceGovernanceName);\n                if (queryResult.StatusCode != System.Net.HttpStatusCode.OK)\n                {\n                    Log.Error(new NotImplementedException(), $\"未发现名称为{serviceGovernanceName}的服务\");\n                    return null;\n                }\n                var servcies = queryResult.Response;\n                if (servcies == null || !servcies.Any())\n                {\n                    Log.Error(new NotImplementedException(), $\"名称为{serviceGovernanceName}的服务未包含任何节点\");\n                    return null;\n                }\n                var destinations = servcies.Select(x => new ClusterDestinationOption()\n                {\n                    DestinationAddress = $\"http://{x.ServiceAddress}:{x.ServicePort}\",\n                    DestinationName = Guid.NewGuid().ToString().Replace(\"-\", \"\")\n                })\n                .ToList();\n                return destinations;\n            }\n            catch (Exception ex)\n            {\n                Log.Error(ex, $\"Consul连接异常:{ex.Message}\");\n                return null;\n            }\n        }\n        private async Task<List<ClusterDestinationOption>> GetNacosServiceAsync(string serviceGovernanceName)\n        {\n\n            if (_serviceGovernanceModel == null)\n            {\n                return null;\n            }\n            try\n            {\n                var requestData = $\"serviceName={serviceGovernanceName}\";\n                if (!string.IsNullOrEmpty(_serviceGovernanceModel.NacosNamespaceId) && _serviceGovernanceModel.NacosNamespaceId != \"\")\n                {\n                    requestData += $\"&namespaceId={_serviceGovernanceModel.NacosNamespaceId}\";\n                }\n                if (!string.IsNullOrEmpty(_serviceGovernanceModel.NacosGroupName) && _serviceGovernanceModel.NacosGroupName != \"\")\n                {\n                    requestData += $\"&groupName={_serviceGovernanceModel.NacosGroupName}\";\n                }\n                //\n                var httpClient = _httpClientFactory.CreateClient();\n                var httpResponse = await httpClient.GetAsync($\"{_serviceGovernanceModel.NacosServer}/nacos/v1/ns/instance/list?{requestData}\");\n                if (httpResponse.StatusCode != System.Net.HttpStatusCode.OK)\n                {\n                    Log.Error(new NotImplementedException(), $\"从Nacos获取服务信息失败,服务名:{serviceGovernanceName}|命名空间{_serviceGovernanceModel?.NacosNamespaceId}|群组名称:{_serviceGovernanceModel.NacosGroupName}\");\n                    return null;\n                }\n                var httpResult = Newtonsoft.Json.JsonConvert.DeserializeObject<NacosServiceModel>(await httpResponse.Content.ReadAsStringAsync());\n                var destinations = httpResult.Hosts.Select(x => new ClusterDestinationOption()\n                {\n                    DestinationAddress = $\"http://{x.IP}:{x.Port}\",\n                    DestinationName = Guid.NewGuid().ToString().Replace(\"-\", \"\")\n                })\n                .ToList();\n                return destinations;\n            }\n            catch (Exception ex)\n            {\n                Log.Error(ex, $\"Nacos服务发现异常:{ex.Message}\");\n                return null;\n            }\n        }\n\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Whitelist/IWhiteListManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Whitelist\n{\n    public interface IWhiteListManager\n    {\n        Task<List<Entities.Whitelist>> GetListAsync();\n        /// <summary>\n        /// 创建白名单\n        /// </summary>\n        /// <param name=\"whiteList\"></param>\n        /// <returns></returns>\n        Task<Entities.Whitelist> CreateAsync<T>(T whiteList);\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain/Whitelist/WhiteListManager.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Domain.Repositories;\nusing Volo.Abp.Domain.Services;\nusing Mapster;\nusing Kite.Gateway.Domain.Entities;\n\nnamespace Kite.Gateway.Domain.Whitelist\n{\n    internal class WhiteListManager : DomainService, IWhiteListManager\n    {\n        private readonly IRepository<Entities.Whitelist> _repository;\n        public WhiteListManager(IRepository<Entities.Whitelist> repository)\n        {\n            _repository = repository;\n        }\n        public async Task<Entities.Whitelist> CreateAsync<T>(T whiteList)\n        {\n            var model= new Entities.Whitelist(GuidGenerator.Create())\n            {\n                Created = DateTime.Now\n            };\n            TypeAdapter.Adapt(whiteList, model);\n            if (await _repository.AnyAsync(x => x.RouteId == model.RouteId  && x.FilterText == model.FilterText))\n            {\n                throw new Exception(\"同一路由下已经存在相同的过滤文本值\");\n            }\n            return model;\n        }\n        public Task<List<Entities.Whitelist>> GetListAsync()\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/DomainSharedModule.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.Modularity;\n\nnamespace Kite.Gateway.Domain.Shared\n{\n    [DependsOn(\n        \n    )]\n    public class DomainSharedModule:AbpModule\n    {\n        public override void ConfigureServices(ServiceConfigurationContext context)\n        {\n            //在此处注入依赖项\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Enums/FilterTypeEnum.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Enums\n{\n    /// <summary>\n    /// 白名单过滤类型\n    /// </summary>\n    public enum FilterTypeEnum\n    {\n        /// <summary>\n        /// 路径\n        /// </summary>\n        [Display(Name = \"路径\")]\n        Path =0,\n        /// <summary>\n        /// 正则\n        /// </summary>\n        [Display(Name = \"正则\")]\n        Regular =1\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Enums/ServiceGovernanceType.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Enums\n{\n    /// <summary>\n    /// 服务治理类型\n    /// </summary>\n    public enum ServiceGovernanceType\n    {\n        /// <summary>\n        /// 默认\n        /// </summary>\n        [Display(Name = \"默认\")]\n        Default = 0,\n        /// <summary>\n        /// Consul\n        /// </summary>\n        [Display(Name = \"Consul\")]\n        Consul = 1,\n        /// <summary>\n        /// Nacos\n        /// </summary>\n        [Display(Name = \"Nacos\")]\n        Nacos = 2\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Enums/SignalTypeEnum.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Enums\n{\n    /// <summary>\n    /// 通信方式\n    /// </summary>\n    public enum SignalTypeEnum\n    {\n        /// <summary>\n        /// Http(仅支持post)\n        /// </summary>\n        [Display(Name = \"Http(仅支持POST请求)\")]\n        Http =0,\n        /// <summary>\n        /// GRPC\n        /// </summary>\n        [Display(Name = \"GRPC(暂时不支持)\")]\n        Grpc =1\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Kite.Gateway.Domain.Shared.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net7.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Consul\" Version=\"1.6.10.8\" />\n    <PackageReference Include=\"Mapster\" Version=\"7.3.0\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Authentication.JwtBearer\" Version=\"7.0.2\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.RateLimiting\" Version=\"7.0.0-rc.2.22476.2\" />\n    <PackageReference Include=\"Serilog.AspNetCore\" Version=\"6.1.0\" />\n    <PackageReference Include=\"Volo.Abp.Ddd.Domain\" Version=\"7.0.1\" />\n    <PackageReference Include=\"Yarp.ReverseProxy\" Version=\"2.0.0-rc.1.23068.3\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/AuthenticationOption.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    /// <summary>\n    /// 身份认证配置项\n    /// </summary>\n    public class AuthenticationOption\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 是否开启\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 颁发者\n        /// </summary>\n        public string Issuer { get; set; }\n        /// <summary>\n        /// 观察者\n        /// </summary>\n        public string Audience { get; set; }\n        /// <summary>\n        /// 时间偏移(秒)\n        /// </summary>\n        public int ClockSkew { get; set; }\n        /// <summary>\n        /// 是否验证签名\n        /// </summary>\n        public bool ValidateIssuerSigningKey { get; set; }\n        /// <summary>\n        /// 是否验证颁发者\n        /// </summary>\n        public bool ValidateIssuer { get; set; }\n        /// <summary>\n        /// 是否验证观察者\n        /// </summary>\n        public bool ValidateAudience { get; set; }\n        /// <summary>\n        /// 是否验证失效时间\n        /// </summary>\n        public bool ValidateLifetime { get; set; }\n        /// <summary>\n        /// 是否需要扩展时间\n        /// </summary>\n        public bool RequireExpirationTime { get; set; }\n        /// <summary>\n        /// 是否启用SSL证书\n        /// </summary>\n        public bool UseSSL { get; set; }\n        /// <summary>\n        /// 秘钥字符串\n        /// </summary>\n        public string SecurityKeyStr { get; set; }\n        /// <summary>\n        /// 证书文件内容(BASE64)\n        /// </summary>\n        public string CertificateFile { get; set; }\n        /// <summary>\n        /// 证书文件名(文件后缀名.pfx或者.cer 文件内容)\n        /// </summary>\n        public string CertificateFileName { get; set; }\n        /// <summary>\n        /// 证书密码\n        /// </summary>\n        public string CertificatePassword { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/ClusterDestinationOption.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    public class ClusterDestinationOption\n    {\n        /// <summary>\n        /// 目的地名称\n        /// </summary>\n        public string DestinationName { get; set; }\n        /// <summary>\n        /// 目的地地址\n        /// </summary>\n        public string DestinationAddress { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/ClusterHealthCheckOption.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    public class ClusterHealthCheckOption\n    {\n        /// <summary>\n        /// 是否开启健康检查\n        /// </summary>\n        public bool Enabled { get; set; }\n        /// <summary>\n        /// 检查间隔时间(秒)\n        /// </summary>\n        public int Interval { get; set; }\n        /// <summary>\n        /// 超时时间\n        /// </summary>\n        public int Timeout { get; set; }\n        /// <summary>\n        /// 检查策略\n        /// </summary>\n        public string Policy { get; set; }\n        /// <summary>\n        /// 健康检查地址\n        /// </summary>\n        public string Path { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/ClusterOption.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    public class ClusterOption\n    {\n        /// <summary>\n        /// 集群名称\n        /// </summary>\n        public string ClusterName { get; set; }\n        /// <summary>\n        /// 负载均衡策略\n        /// FirstAlphabetical: 在不考虑负载的情况下选择按字母顺序排列的第一个可用目的地。这对于双目的地故障转移系统很有用。\n        /// Random: 随机选择一个目的地。\n        /// PowerOfTwoChoices (默认): 选择两个随机目标，然后选择分配请求最少的目标。这避免了它选择繁忙目的地的开销LeastRequests和最坏情况。Random\n        /// RoundRobin: 通过按顺序循环选择目的地。\n        /// LeastRequests: 选择分配的请求最少的目标。这需要检查所有目的地。\n        /// </summary>\n        public string LoadBalancingPolicy { get; set; }\n        /// <summary>\n        /// 集群目的地配置项\n        /// </summary>\n        public List<ClusterDestinationOption> ClusterDestinations { get; set; }\n        /// <summary>\n        /// 集群健康检查配置项\n        /// </summary>\n        public ClusterHealthCheckOption ClusterHealthCheck { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/KiteGatewayOption.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    public class KiteGatewayOption\n    {\n        /// <summary>\n        /// 网关管理端服务器地址\n        /// </summary>\n        public string AdminServer { get; set; }\n        /// <summary>\n        /// 配置数据热更新访问授权token\n        /// </summary>\n        public string AccessToken { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/MiddlewareOption.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    /// <summary>\n    /// 中间件配置项\n    /// </summary>\n    public class MiddlewareOption\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 中间件名称\n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        /// 服务端地址\n        /// </summary>\n        public string Server { get; set; }\n        /// <summary>\n        /// 通信类型\n        /// </summary>\n        public SignalTypeEnum SignalType { get; set; }\n        /// <summary>\n        /// 启用状态\n        /// </summary>\n        public bool UseState { get; set; }\n        /// <summary>\n        /// 执行权重(数字越大越靠前)\n        /// </summary>\n        public int ExecWeight { get; set; }\n        /// <summary>\n        /// 中间件描述\n        /// </summary>\n        public string Description { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/RouteOption.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    public class RouteOption\n    {\n        /// <summary>\n        /// 路由ID\n        /// </summary>\n        public string RouteId { get; set; }\n        /// <summary>\n        /// 路由名称\n        /// </summary>\n        public string RouteName { get; set; }\n\n        /// <summary>\n        /// 路由路径规则\n        /// </summary>\n        public string RouteMatchPath { get; set; }\n        /// <summary>\n        /// 路由转换\n        /// </summary>\n        public List<RouteTransformOption> RouteTransforms { get; set; }\n        /// <summary>\n        /// 集群配置项\n        /// </summary>\n        public ClusterOption Cluster { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/RouteTransformOption.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    public class RouteTransformOption\n    {\n        /// <summary>\n        /// 交换配置项名称\n        /// </summary>\n        public string TransformsName { get; set; }\n        /// <summary>\n        /// 交换配置项值\n        /// </summary>\n        public string TransformsValue { get; set; }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/WhitelistOption.cs",
    "content": "﻿using Kite.Gateway.Domain.Shared.Enums;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Text.RegularExpressions;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    /// <summary>\n    /// 白名单配置项\n    /// </summary>\n    public class WhitelistOption\n    {\n        /// <summary>\n        /// ID\n        /// </summary>\n        public Guid Id { get; set; }\n        /// <summary>\n        /// 所属路由(为空则全局)\n        /// </summary>\n        public string RouteId { get; set; }\n        /// <summary>\n        /// 白名单名称\n        /// </summary>\n        public string Name { get; set; }\n        /// <summary>\n        /// 过滤文本(根据类型保存的值为路径或者正则表达式)\n        /// </summary>\n        public string FilterText { get; set; }\n        /// <summary>\n        /// 请求方式(多请求方式使用,分隔)\n        /// </summary>\n        public string RequestMethod { get; set; }\n\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/Options/YarpOption.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Yarp.ReverseProxy.Configuration;\n\nnamespace Kite.Gateway.Domain.Shared.Options\n{\n    public class YarpOption\n    {\n        /// <summary>\n        /// 路由配置数据\n        /// </summary>\n        public List<RouteOption> Routes { get; set; } \n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Domain.Shared/TextHelper.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Text;\nusing System.Security.Cryptography;\nnamespace Kite.Gateway.Domain.Shared\n{\n    public class TextHelper\n    {\n        /// <summary>\n        /// MD5加密\n        /// </summary>\n        /// <param name=\"SourceText\">待加密原字符串</param>\n        /// <returns></returns>\n        public static string MD5Encrypt(string SourceText)\n        {\n            string tempStr = \"\";\n            MD5 md5 = MD5.Create();\n            byte[] data = System.Text.Encoding.UTF8.GetBytes(SourceText);//将字符编码为一个字节序列 \n            byte[] md5data = md5.ComputeHash(data);//计算data字节数组的哈希值 \n            md5.Dispose();\n\n            for (int i = 0; i < md5data.Length; i++)\n            {\n                tempStr += md5data[i].ToString(\"x\").PadLeft(2, '0');\n            }\n            return tempStr.ToLower();\n        }\n        /// <summary>\n        /// SHA1加密\n        /// </summary>\n        /// <param name=\"Source_String\"></param>\n        /// <returns></returns>\n        public static string SHA1_Encrypt(string Source_String)\n        {\n            byte[] StrRes = Encoding.Default.GetBytes(Source_String);\n            HashAlgorithm iSHA = new SHA1CryptoServiceProvider();\n            StrRes = iSHA.ComputeHash(StrRes);\n            StringBuilder EnText = new StringBuilder();\n            foreach (byte iByte in StrRes)\n            {\n                EnText.AppendFormat(\"{0:x2}\", iByte);\n            }\n            return EnText.ToString();\n        }\n        /// <summary>\n        /// HmacSHA256加密\n        /// </summary>\n        /// <param name=\"message\"></param>\n        /// <param name=\"secret\"></param>\n        /// <returns></returns>\n        public static string HmacSHA256(string message, string secret)\n        {\n            secret = secret ?? \"\";\n            var encoding = new System.Text.UTF8Encoding();\n            byte[] keyByte = encoding.GetBytes(secret);\n            byte[] messageBytes = encoding.GetBytes(message);\n            using (var hmacsha256 = new HMACSHA256(keyByte))\n            {\n                byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);\n                return Convert.ToBase64String(hashmessage);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/EntityFrameworkCoreModule.cs",
    "content": "﻿using Microsoft.Extensions.DependencyInjection;\nusing Kite.Gateway.Domain;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Volo.Abp.EntityFrameworkCore;\nusing Volo.Abp.EntityFrameworkCore.Sqlite;\nusing Volo.Abp.Modularity;\nusing Volo.Abp;\nusing Microsoft.EntityFrameworkCore;\n\nnamespace Kite.Gateway.EntityFrameworkCore\n{\n    [DependsOn(\n        typeof(DomainModule),\n        typeof(AbpEntityFrameworkCoreSqliteModule)\n        )]\n    public class EntityFrameworkCoreModule: AbpModule\n    {\n        public override void ConfigureServices(ServiceConfigurationContext context)\n        {\n            var configuration = context.Services.GetConfiguration();\n            Configure<AbpDbContextOptions>(options =>\n            {\n                options.UseSqlite();\n            });\n            context.Services.AddAbpDbContext<KiteDbContext>(options =>\n            {\n                options.AddDefaultRepositories(includeAllEntities: true);\n            });\n        }\n        public override void OnApplicationInitialization(ApplicationInitializationContext context)\n        {\n            var dbContext = context.ServiceProvider.GetService<KiteDbContext>();\n            if (dbContext != null)\n            {\n                dbContext.Database.Migrate();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Kite.Gateway.EntityFrameworkCore.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net7.0</TargetFramework>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Volo.Abp.EntityFrameworkCore\" Version=\"7.0.1\" />\n    <PackageReference Include=\"Volo.Abp.EntityFrameworkCore.Sqlite\" Version=\"7.0.1\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <ProjectReference Include=\"..\\Kite.Gateway.Domain\\Kite.Gateway.Domain.csproj\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <Folder Include=\"Migrations\\\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/KiteDbContext.cs",
    "content": "﻿using Kite.Gateway.Domain.Entities;\nusing Microsoft.EntityFrameworkCore;\nusing Volo.Abp.Data;\nusing Volo.Abp.DependencyInjection;\nusing Volo.Abp.EntityFrameworkCore;\n\nnamespace Kite.Gateway.EntityFrameworkCore\n{\n    [ConnectionStringName(\"Default\")]\n    public class KiteDbContext : AbpDbContext<KiteDbContext>\n    {\n\n        #region Entities from the modules\n        public DbSet<ServiceGovernanceConfigure> ServiceGovernanceConfigures { get; set; }\n        public DbSet<AuthenticationConfigure> AuthenticationConfigures { get; set; }\n        public DbSet<Node> Nodes { get; set; }\n        public DbSet<Middleware> Middlewares { get; set; }\n        public DbSet<Route> Routes { get; set; }\n        public DbSet<Cluster> Clusters { get; set; }\n        public DbSet<ClusterHealthCheck> ClusterHealthChecks { get; set; }\n        public DbSet<RouteTransform> RouteTransforms { get; set; }\n        public DbSet<ClusterDestination> ClusterDestinations { get; set; }\n        public DbSet<Administrator> Administrators { get; set; }\n        public DbSet<Whitelist> Whitelists { get; set; }\n        #endregion\n\n        public KiteDbContext(DbContextOptions<KiteDbContext> options): base(options)\n        {\n\n        }\n\n        protected override void OnModelCreating(ModelBuilder builder)\n        {\n            base.OnModelCreating(builder);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/20220726095023_Migration_v1.0.0.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing Kite.Gateway.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\nusing Volo.Abp.EntityFrameworkCore;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    [DbContext(typeof(KiteDbContext))]\n    [Migration(\"20220726095023_Migration_v1.0.0\")]\n    partial class Migration_v100\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"_Abp_DatabaseProvider\", EfCoreDatabaseProvider.Sqlite)\n                .HasAnnotation(\"ProductVersion\", \"6.0.7\");\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Administrator\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AdminName\")\n                        .HasMaxLength(32)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NickName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Password\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Administrators\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.AuthenticationConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Audience\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFile\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFileName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificatePassword\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ClockSkew\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Issuer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"RequireExpirationTime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"SecurityKeyStr\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseSSL\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateAudience\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuer\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuerSigningKey\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateLifetime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"AuthenticationConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Cluster\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ClusterName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"LoadBalancingPolicy\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ServiceGovernanceName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ServiceGovernanceType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Clusters\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterDestination\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationAddress\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterDestinations\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterHealthCheck\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<int>(\"Interval\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Path\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Policy\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"Timeout\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterHealthChecks\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Middleware\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ExecWeight\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"SignalType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Middlewares\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Node\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NodeName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Token\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Nodes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Route\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteId\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteMatchPath\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Routes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.RouteTransform\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsValue\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"RouteTransforms\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ServiceGovernanceConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulDatacenter\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulServer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulToken\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ServiceGovernanceConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Whitelist\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"FilterText\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"FilterType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RequestMethod\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid?>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Whitelists\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/20220726095023_Migration_v1.0.0.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    public partial class Migration_v100 : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"Administrators\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    AdminName = table.Column<string>(type: \"TEXT\", maxLength: 32, nullable: true),\n                    Password = table.Column<string>(type: \"TEXT\", maxLength: 64, nullable: true),\n                    NickName = table.Column<string>(type: \"TEXT\", maxLength: 64, nullable: true),\n                    Created = table.Column<DateTime>(type: \"TEXT\", nullable: false),\n                    Updated = table.Column<DateTime>(type: \"TEXT\", nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Administrators\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"AuthenticationConfigures\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    UseState = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    Issuer = table.Column<string>(type: \"TEXT\", maxLength: 512, nullable: true),\n                    Audience = table.Column<string>(type: \"TEXT\", maxLength: 512, nullable: true),\n                    ClockSkew = table.Column<int>(type: \"INTEGER\", nullable: false),\n                    ValidateIssuerSigningKey = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    ValidateIssuer = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    ValidateAudience = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    ValidateLifetime = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    RequireExpirationTime = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    UseSSL = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    SecurityKeyStr = table.Column<string>(type: \"TEXT\", maxLength: 512, nullable: true),\n                    CertificateFile = table.Column<string>(type: \"TEXT\", nullable: true),\n                    CertificateFileName = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    CertificatePassword = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_AuthenticationConfigures\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClusterDestinations\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    ClusterId = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    DestinationName = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    DestinationAddress = table.Column<string>(type: \"TEXT\", maxLength: 1024, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClusterDestinations\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ClusterHealthChecks\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    ClusterId = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    Enabled = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    Interval = table.Column<int>(type: \"INTEGER\", nullable: false),\n                    Timeout = table.Column<int>(type: \"INTEGER\", nullable: false),\n                    Policy = table.Column<string>(type: \"TEXT\", maxLength: 64, nullable: true),\n                    Path = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ClusterHealthChecks\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Clusters\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    RouteId = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    ClusterName = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    LoadBalancingPolicy = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    ServiceGovernanceType = table.Column<int>(type: \"INTEGER\", nullable: false),\n                    ServiceGovernanceName = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Clusters\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Middlewares\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    Name = table.Column<string>(type: \"TEXT\", maxLength: 64, nullable: true),\n                    Server = table.Column<string>(type: \"TEXT\", maxLength: 1024, nullable: true),\n                    SignalType = table.Column<int>(type: \"INTEGER\", nullable: false),\n                    UseState = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    ExecWeight = table.Column<int>(type: \"INTEGER\", nullable: false),\n                    Description = table.Column<string>(type: \"TEXT\", maxLength: 1024, nullable: true),\n                    Created = table.Column<DateTime>(type: \"TEXT\", nullable: false),\n                    Updated = table.Column<DateTime>(type: \"TEXT\", nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Middlewares\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Nodes\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    NodeName = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    Description = table.Column<string>(type: \"TEXT\", maxLength: 512, nullable: true),\n                    Server = table.Column<string>(type: \"TEXT\", maxLength: 1024, nullable: true),\n                    Token = table.Column<string>(type: \"TEXT\", maxLength: 512, nullable: true),\n                    Created = table.Column<DateTime>(type: \"TEXT\", nullable: false),\n                    Updated = table.Column<DateTime>(type: \"TEXT\", nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Nodes\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Routes\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    RouteId = table.Column<string>(type: \"TEXT\", maxLength: 64, nullable: true),\n                    RouteName = table.Column<string>(type: \"TEXT\", maxLength: 64, nullable: true),\n                    Description = table.Column<string>(type: \"TEXT\", maxLength: 512, nullable: true),\n                    UseState = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    RouteMatchPath = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    Created = table.Column<DateTime>(type: \"TEXT\", nullable: false),\n                    Updated = table.Column<DateTime>(type: \"TEXT\", nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Routes\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"RouteTransforms\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    RouteId = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    TransformsName = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    TransformsValue = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_RouteTransforms\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"ServiceGovernanceConfigures\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    ConsulServer = table.Column<string>(type: \"TEXT\", maxLength: 512, nullable: true),\n                    ConsulDatacenter = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    ConsulToken = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_ServiceGovernanceConfigures\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Whitelists\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(type: \"TEXT\", nullable: false),\n                    RouteId = table.Column<Guid>(type: \"TEXT\", nullable: true),\n                    Name = table.Column<string>(type: \"TEXT\", maxLength: 64, nullable: true),\n                    FilterType = table.Column<int>(type: \"INTEGER\", nullable: false),\n                    FilterText = table.Column<string>(type: \"TEXT\", maxLength: 128, nullable: true),\n                    RequestMethod = table.Column<string>(type: \"TEXT\", maxLength: 64, nullable: true),\n                    UseState = table.Column<bool>(type: \"INTEGER\", nullable: false),\n                    Created = table.Column<DateTime>(type: \"TEXT\", nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Whitelists\", x => x.Id);\n                });\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"Administrators\");\n\n            migrationBuilder.DropTable(\n                name: \"AuthenticationConfigures\");\n\n            migrationBuilder.DropTable(\n                name: \"ClusterDestinations\");\n\n            migrationBuilder.DropTable(\n                name: \"ClusterHealthChecks\");\n\n            migrationBuilder.DropTable(\n                name: \"Clusters\");\n\n            migrationBuilder.DropTable(\n                name: \"Middlewares\");\n\n            migrationBuilder.DropTable(\n                name: \"Nodes\");\n\n            migrationBuilder.DropTable(\n                name: \"Routes\");\n\n            migrationBuilder.DropTable(\n                name: \"RouteTransforms\");\n\n            migrationBuilder.DropTable(\n                name: \"ServiceGovernanceConfigures\");\n\n            migrationBuilder.DropTable(\n                name: \"Whitelists\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/20220727061321_Migration_v1.0.1.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing Kite.Gateway.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\nusing Volo.Abp.EntityFrameworkCore;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    [DbContext(typeof(KiteDbContext))]\n    [Migration(\"20220727061321_Migration_v1.0.1\")]\n    partial class Migration_v101\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"_Abp_DatabaseProvider\", EfCoreDatabaseProvider.Sqlite)\n                .HasAnnotation(\"ProductVersion\", \"6.0.7\");\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Administrator\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AdminName\")\n                        .HasMaxLength(32)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NickName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Password\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Administrators\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.AuthenticationConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Audience\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFile\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFileName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificatePassword\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ClockSkew\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Issuer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"RequireExpirationTime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"SecurityKeyStr\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseSSL\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateAudience\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuer\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuerSigningKey\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateLifetime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"AuthenticationConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Cluster\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ClusterName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"LoadBalancingPolicy\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ServiceGovernanceName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ServiceGovernanceType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Clusters\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterDestination\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationAddress\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterDestinations\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterHealthCheck\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<int>(\"Interval\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Path\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Policy\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"Timeout\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterHealthChecks\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Middleware\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ExecWeight\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"SignalType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Middlewares\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Node\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AccessToken\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NodeName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Nodes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Route\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteId\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteMatchPath\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Routes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.RouteTransform\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsValue\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"RouteTransforms\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ServiceGovernanceConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulDatacenter\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulServer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulToken\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ServiceGovernanceConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Whitelist\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"FilterText\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"FilterType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RequestMethod\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid?>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Whitelists\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/20220727061321_Migration_v1.0.1.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    public partial class Migration_v101 : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.RenameColumn(\n                name: \"Token\",\n                table: \"Nodes\",\n                newName: \"AccessToken\");\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.RenameColumn(\n                name: \"AccessToken\",\n                table: \"Nodes\",\n                newName: \"Token\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/20220731131935_Migration_v1.0.2.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing Kite.Gateway.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\nusing Volo.Abp.EntityFrameworkCore;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    [DbContext(typeof(KiteDbContext))]\n    [Migration(\"20220731131935_Migration_v1.0.2\")]\n    partial class Migration_v102\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"_Abp_DatabaseProvider\", EfCoreDatabaseProvider.Sqlite)\n                .HasAnnotation(\"ProductVersion\", \"6.0.7\");\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Administrator\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AdminName\")\n                        .HasMaxLength(32)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NickName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Password\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Administrators\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.AuthenticationConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Audience\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFile\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFileName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificatePassword\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ClockSkew\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Issuer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"RequireExpirationTime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"SecurityKeyStr\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseSSL\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateAudience\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuer\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuerSigningKey\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateLifetime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"AuthenticationConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Cluster\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ClusterName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"LoadBalancingPolicy\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ServiceGovernanceName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ServiceGovernanceType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Clusters\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterDestination\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationAddress\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterDestinations\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterHealthCheck\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<int>(\"Interval\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Path\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Policy\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"Timeout\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterHealthChecks\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Middleware\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ExecWeight\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"SignalType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Middlewares\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Node\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AccessToken\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NodeName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Nodes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Route\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteId\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteMatchPath\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Routes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.RouteTransform\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsValue\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"RouteTransforms\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ServiceGovernanceConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulDatacenter\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulServer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulToken\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosGroupName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosNamespaceId\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosServer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ServiceGovernanceConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Whitelist\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"FilterText\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"FilterType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RequestMethod\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid?>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Whitelists\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/20220731131935_Migration_v1.0.2.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    public partial class Migration_v102 : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<string>(\n                name: \"NacosGroupName\",\n                table: \"ServiceGovernanceConfigures\",\n                type: \"TEXT\",\n                maxLength: 128,\n                nullable: true);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"NacosNamespaceId\",\n                table: \"ServiceGovernanceConfigures\",\n                type: \"TEXT\",\n                maxLength: 128,\n                nullable: true);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"NacosServer\",\n                table: \"ServiceGovernanceConfigures\",\n                type: \"TEXT\",\n                maxLength: 512,\n                nullable: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"NacosGroupName\",\n                table: \"ServiceGovernanceConfigures\");\n\n            migrationBuilder.DropColumn(\n                name: \"NacosNamespaceId\",\n                table: \"ServiceGovernanceConfigures\");\n\n            migrationBuilder.DropColumn(\n                name: \"NacosServer\",\n                table: \"ServiceGovernanceConfigures\");\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/20220801073938_Migration_v1.0.3.Designer.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing Kite.Gateway.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\nusing Volo.Abp.EntityFrameworkCore;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    [DbContext(typeof(KiteDbContext))]\n    [Migration(\"20220801073938_Migration_v1.0.3\")]\n    partial class Migration_v103\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"_Abp_DatabaseProvider\", EfCoreDatabaseProvider.Sqlite)\n                .HasAnnotation(\"ProductVersion\", \"6.0.7\");\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Administrator\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AdminName\")\n                        .HasMaxLength(32)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NickName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Password\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Administrators\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.AuthenticationConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Audience\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFile\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFileName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificatePassword\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ClockSkew\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Issuer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"RequireExpirationTime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"SecurityKeyStr\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseSSL\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateAudience\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuer\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuerSigningKey\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateLifetime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"AuthenticationConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Cluster\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ClusterName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"LoadBalancingPolicy\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ServiceGovernanceName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ServiceGovernanceType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Clusters\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterDestination\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationAddress\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterDestinations\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterHealthCheck\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<int>(\"Interval\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Path\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Policy\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"Timeout\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterHealthChecks\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Middleware\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ExecWeight\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"SignalType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Middlewares\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Node\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AccessToken\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NodeName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Nodes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Route\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteId\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteMatchPath\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Routes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.RouteTransform\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsValue\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"RouteTransforms\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ServiceGovernanceConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulDatacenter\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulServer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulToken\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosGroupName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosNamespaceId\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosServer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ServiceGovernanceConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Whitelist\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"FilterText\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RequestMethod\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid?>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Whitelists\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/20220801073938_Migration_v1.0.3.cs",
    "content": "﻿using Microsoft.EntityFrameworkCore.Migrations;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    public partial class Migration_v103 : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"FilterType\",\n                table: \"Whitelists\");\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<int>(\n                name: \"FilterType\",\n                table: \"Whitelists\",\n                type: \"INTEGER\",\n                nullable: false,\n                defaultValue: 0);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.EntityFrameworkCore/Migrations/KiteDbContextModelSnapshot.cs",
    "content": "﻿// <auto-generated />\nusing System;\nusing Kite.Gateway.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Storage.ValueConversion;\nusing Volo.Abp.EntityFrameworkCore;\n\n#nullable disable\n\nnamespace Kite.Gateway.EntityFrameworkCore.Migrations\n{\n    [DbContext(typeof(KiteDbContext))]\n    partial class KiteDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n#pragma warning disable 612, 618\n            modelBuilder\n                .HasAnnotation(\"_Abp_DatabaseProvider\", EfCoreDatabaseProvider.Sqlite)\n                .HasAnnotation(\"ProductVersion\", \"6.0.7\");\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Administrator\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AdminName\")\n                        .HasMaxLength(32)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NickName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Password\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Administrators\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.AuthenticationConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Audience\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFile\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificateFileName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"CertificatePassword\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ClockSkew\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Issuer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"RequireExpirationTime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"SecurityKeyStr\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseSSL\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateAudience\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuer\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateIssuerSigningKey\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<bool>(\"ValidateLifetime\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"AuthenticationConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Cluster\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ClusterName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"LoadBalancingPolicy\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ServiceGovernanceName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ServiceGovernanceType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Clusters\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterDestination\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationAddress\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"DestinationName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterDestinations\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ClusterHealthCheck\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"ClusterId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"Enabled\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<int>(\"Interval\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Path\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Policy\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"Timeout\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ClusterHealthChecks\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Middleware\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"ExecWeight\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<int>(\"SignalType\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Middlewares\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Node\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"AccessToken\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NodeName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Server\")\n                        .HasMaxLength(1024)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Nodes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Route\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Description\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteId\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteMatchPath\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RouteName\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime?>(\"Updated\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Routes\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.RouteTransform\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"TransformsValue\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"RouteTransforms\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.ServiceGovernanceConfigure\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulDatacenter\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulServer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"ConsulToken\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosGroupName\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosNamespaceId\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"NacosServer\")\n                        .HasMaxLength(512)\n                        .HasColumnType(\"TEXT\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"ServiceGovernanceConfigures\");\n                });\n\n            modelBuilder.Entity(\"Kite.Gateway.Domain.Entities.Whitelist\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<DateTime>(\"Created\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"FilterText\")\n                        .HasMaxLength(128)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"Name\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<string>(\"RequestMethod\")\n                        .HasMaxLength(64)\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<Guid?>(\"RouteId\")\n                        .HasColumnType(\"TEXT\");\n\n                    b.Property<bool>(\"UseState\")\n                        .HasColumnType(\"INTEGER\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Whitelists\");\n                });\n#pragma warning restore 612, 618\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Web/Controllers/RefreshController.cs",
    "content": "﻿using Kite.Gateway.Application;\nusing Kite.Gateway.Application.Contracts;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing System.Linq;\nusing Kite.Gateway.Application.Contracts.Dtos;\n\nnamespace Kite.Gateway.Web.Controllers\n{\n    [Route(\"api/[controller]\")]\n    [ApiController]\n    public class RefreshController : ControllerBase\n    {\n        private readonly IRefreshAppService _refreshAppService;\n        public RefreshController(IRefreshAppService refreshAppService)\n        {\n            _refreshAppService = refreshAppService;\n        }\n        [HttpPost(\"/api/kite/refresh/configure\")]\n        public async Task<KiteResult> ReloadConfigureAsync(RefreshConfigureDto refreshConfigure)\n        {\n            return await _refreshAppService.RefreshConfigureAsync(refreshConfigure);\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Web/Dockerfile",
    "content": "#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.\n\nFROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base\nWORKDIR /app\nEXPOSE 80\n\nFROM mcr.microsoft.com/dotnet/sdk:6.0 AS build\nWORKDIR /src\nCOPY [\"src/Kite.Gateway.Web/Kite.Gateway.Web.csproj\", \"src/Kite.Gateway.Web/\"]\nCOPY [\"src/Kite.Gateway.Application/Kite.Gateway.Application.csproj\", \"src/Kite.Gateway.Application/\"]\nCOPY [\"src/Kite.Gateway.Application.Contracts/Kite.Gateway.Application.Contracts.csproj\", \"src/Kite.Gateway.Application.Contracts/\"]\nCOPY [\"src/Kite.Gateway.Domain.Shared/Kite.Gateway.Domain.Shared.csproj\", \"src/Kite.Gateway.Domain.Shared/\"]\nCOPY [\"src/Kite.Gateway.Domain/Kite.Gateway.Domain.csproj\", \"src/Kite.Gateway.Domain/\"]\nRUN dotnet restore \"src/Kite.Gateway.Web/Kite.Gateway.Web.csproj\"\nCOPY . .\nWORKDIR \"/src/src/Kite.Gateway.Web\"\nRUN dotnet build \"Kite.Gateway.Web.csproj\" -c Release -o /app/build\n\nFROM build AS publish\nRUN dotnet publish \"Kite.Gateway.Web.csproj\" -c Release -o /app/publish /p:UseAppHost=false\n\nFROM base AS final\nWORKDIR /app\nCOPY --from=publish /app/publish .\nENTRYPOINT [\"dotnet\", \"Kite.Gateway.Web.dll\"]"
  },
  {
    "path": "src/Kite.Gateway.Web/Filters/AbpCoreExceptionFilter.cs",
    "content": "﻿using Microsoft.AspNetCore.Mvc.Filters;\nusing System;\nusing Kite.Gateway.Application;\nusing Serilog;\nusing Microsoft.AspNetCore.Mvc;\n\nnamespace Kite.Gateway.Web.Filters\n{\n    public class AbpCoreExceptionFilter : IExceptionFilter\n    {\n        public void OnException(ExceptionContext context)\n        {\n            Log.Error(context.Exception,context.Exception.Message);\n\n            context.Result = new JsonResult(new KiteResult() \n            {\n                Code = 500,\n                Message = context.Exception.Message\n            });\n            context.ExceptionHandled = true;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Web/Filters/KiteCoreActionFilter.cs",
    "content": "﻿using Kite.Gateway.Application;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.AspNetCore.Mvc.Filters;\nusing Microsoft.Extensions.Options;\nusing System.Text.Json;\nnamespace Kite.Gateway.Web.Filters\n{\n    public class KiteCoreActionFilter : IActionFilter\n    {\n        public void OnActionExecuted(ActionExecutedContext context)\n        {\n            \n        }\n\n        public void OnActionExecuting(ActionExecutingContext context)\n        {\n            var options = context.HttpContext.RequestServices.GetService<IOptions<KiteGatewayOption>>();\n            if (options != null)\n            {\n                var accessToken = options.Value.AccessToken;\n                if (!context.HttpContext.Request.Headers.Where(x => x.Key == \"AccessToken\").Any())\n                {\n                    context.Result = new ContentResult()\n                    {\n                        Content = \"授权访问Token为空\",\n                        StatusCode = 401\n                    };\n                }\n                if (context.HttpContext.Request.Headers[\"AccessToken\"].ToString() != accessToken)\n                {\n                    context.Result = new ContentResult()\n                    {\n                        Content = \"授权访问Token错误\",\n                        StatusCode = 401\n                    };\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Web/Kite.Gateway.Web.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>net7.0</TargetFramework>\n    <Nullable>enable</Nullable>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>\n    <DockerfileContext>..\\..</DockerfileContext>\n  </PropertyGroup>\n\t<ItemGroup>\n\t\t<PackageReference Include=\"Volo.Abp.AspNetCore\" Version=\"7.0.1\" />\n\t\t<PackageReference Include=\"Volo.Abp.AspNetCore.Mvc\" Version=\"7.0.1\" />\n\t\t<PackageReference Include=\"Volo.Abp.Autofac\" Version=\"7.0.1\" />\n\t\t<PackageReference Include=\"Volo.Abp.Swashbuckle\" Version=\"7.0.1\" />\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t\t<ProjectReference Include=\"..\\Kite.Gateway.Application\\Kite.Gateway.Application.csproj\" />\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t  <Content Update=\"appsettings.json\">\n\t    <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n\t    <ExcludeFromSingleFile>true</ExcludeFromSingleFile>\n\t    <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n\t  </Content>\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t  <Folder Include=\"data\\logs\\\" />\n\t</ItemGroup>\n</Project>\n"
  },
  {
    "path": "src/Kite.Gateway.Web/Middlewares/KiteAuthorizationMiddleware.cs",
    "content": "﻿using Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.DependencyInjection;\nusing Serilog;\nusing System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Options;\nusing Kite.Gateway.Domain.Shared.Options;\nusing System.Text.Json;\nusing System.Text.RegularExpressions;\nusing Kite.Gateway.Domain.Shared.Enums;\nusing Kite.Gateway.Domain.Authorization;\n\nnamespace Kite.Gateway.Web.Middlewares\n{\n    public class KiteAuthorizationMiddleware\n    {\n        private readonly RequestDelegate _next;\n        private readonly List<WhitelistOption> _whitelistOptions;\n        private readonly AuthenticationOption _authenticationOption;\n        private readonly IJwtTokenManager _jwtTokenManager;\n        public KiteAuthorizationMiddleware(RequestDelegate next\n            , IOptions<List<WhitelistOption>> whitelistOptions, IJwtTokenManager jwtTokenManager, IOptions<AuthenticationOption> authenticationOption)\n        {\n            _next = next ?? throw new ArgumentNullException(nameof(next));\n            _whitelistOptions = whitelistOptions.Value;\n            _jwtTokenManager = jwtTokenManager;\n            _authenticationOption = authenticationOption.Value;\n        }\n        public async Task Invoke(HttpContext context)\n        {\n            if (context == null)\n            {\n                throw new ArgumentNullException(nameof(context));\n            }\n            if (!_authenticationOption.UseState)\n            {\n                await _next(context);\n                return;\n            }\n            if (CheckWhitelist(context))\n            {\n                await _next(context);\n                return;\n            }\n            //token验证\n            var tokenResult= await _jwtTokenManager.ValidationTokenAsync(context);\n            if (!tokenResult.Successed)\n            {\n                context.Response.StatusCode = 401;\n                await context.Response.WriteAsync(tokenResult.Message);\n                return;\n            }\n            var claimTypes = new[] { \"iat\", \"nbf\", \"exp\", \"iss\", \"aud\" };\n            var claims = tokenResult.Claims.Where(x => !claimTypes.Contains(x.Name)).ToList();\n            foreach (var claim in claims)\n            {\n                if (!context.Request.Headers.ContainsKey(claim.Name))\n                {\n                    context.Request.Headers.Add(claim.Name, System.Net.WebUtility.UrlEncode(claim.Value));\n                    context.Items.Add(claim.Name, System.Net.WebUtility.UrlEncode(claim.Value));\n                }\n            }\n            await _next(context);\n            return;\n        }\n        private bool CheckWhitelist(HttpContext context)\n        {\n            var proxyFeature = context.GetReverseProxyFeature();\n            //白名单验证\n            var requestPath = context.Request.Path.Value.ToLower();\n            var reqeustMethod = context.Request.Method.ToUpper();\n            \n            //白名单优先匹配局部作用域\n            if (_whitelistOptions.Any(x => x.RouteId == proxyFeature.Route.Config.RouteId))\n            {\n                Log.Warning($\"CheckWhitelist:{requestPath}|{reqeustMethod}\");\n                //如果局部作用域中有带*的项则直接匹配通过\n                if (_whitelistOptions.Any(x => x.RouteId == proxyFeature.Route.Config.RouteId && x.FilterText == \"*\"))\n                {\n                    return true;\n                }\n                //如果没有带*匹配的则每项都需要匹配\n                if (_whitelistOptions.Any(x => x.RouteId == proxyFeature.Route.Config.RouteId\n                    && requestPath == $\"/{x.FilterText.ToLower().TrimStart('/')}\"\n                    && x.RequestMethod.Contains(reqeustMethod)))\n                {\n                    return true;\n                }\n            }\n            else\n            {\n                //如果全局作用域中有带*的项则直接匹配通过\n                if (_whitelistOptions.Any(x => x.RouteId == \"00000000-0000-0000-0000-000000000000\" && x.FilterText == \"*\"))\n                {\n                    return true;\n                }\n                //匹配全局\n                if (_whitelistOptions.Any(x => x.RouteId == \"00000000-0000-0000-0000-000000000000\"\n                    && requestPath == $\"/{x.FilterText.ToLower().TrimStart('/')}\"\n                    && x.RequestMethod.Contains(reqeustMethod)))\n                {\n                    return true;\n                }\n            }\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Web/Middlewares/KiteExternalMiddleware.cs",
    "content": "﻿using Microsoft.AspNetCore.Http;\nusing Microsoft.Extensions.DependencyInjection;\nusing Serilog;\nusing System;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Options;\nusing System.Text.Json;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Kite.Gateway.Domain.Shared.Enums;\nusing Kite.Gateway.Domain.Middlewares;\nusing System.Text;\n\nnamespace Kite.Gateway.Web.Middlewares\n{\n    public class KiteExternalMiddleware\n    {\n        private readonly RequestDelegate _next;\n        private readonly List<MiddlewareOption> _middlewares;\n        private readonly IHttpClientFactory _httpClientFactory;\n        public KiteExternalMiddleware(RequestDelegate next\n            , IOptions<List<MiddlewareOption>> options, IHttpClientFactory httpClientFactory)\n        {\n            _next = next ?? throw new ArgumentNullException(nameof(next));\n            _middlewares = options.Value;\n            _httpClientFactory = httpClientFactory;\n        }\n        public async Task Invoke(HttpContext context)\n        {\n            if (context == null)\n            {\n                throw new ArgumentNullException(nameof(context));\n            }\n            foreach (var middleware in _middlewares)\n            {\n                var middlewareResult = await HttpRequestAsync(middleware, context);\n                if (middlewareResult.HttpStatusCode != 200)\n                {\n                    context.Response.StatusCode = middlewareResult.HttpStatusCode;\n                    context.Response.ContentType = \"application/json\";\n                    await context.Response.WriteAsync(middlewareResult.Result, Encoding.UTF8);\n                    return;\n                }\n            }\n            await _next(context);\n            return;\n        }\n        private async Task<MiddlewareResult> HttpRequestAsync(MiddlewareOption middleware, HttpContext context)\n        {\n            var middlewareResult = new MiddlewareResult()\n            {\n                HttpStatusCode = 0,\n                Result = \"\"\n            };\n            if (middleware.SignalType == SignalTypeEnum.Http)\n            {\n                var httpClient = _httpClientFactory.CreateClient();\n                //转发原请求头中带(K-)开头的请求头参数\n                foreach (var header in context.Request.Headers.Where(x => x.Key.Contains(\"K-\")).ToList())\n                {\n                    httpClient.DefaultRequestHeaders.Add(header.Key, header.Value.ToString());\n                }\n                foreach (var item in context.Items)\n                {\n                    httpClient.DefaultRequestHeaders.Add(Convert.ToString(item.Key), item.Value?.ToString());\n                }\n                var response = await httpClient.PostAsync(middleware.Server, null);\n                var responseContent = await response.Content.ReadAsStringAsync();\n                middlewareResult.Result = responseContent;\n                middlewareResult.HttpStatusCode = (int)response.StatusCode;\n            }\n            return middlewareResult;\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Web/Program.cs",
    "content": "using Kite.Gateway.Web;\nusing Microsoft.AspNetCore.Http.Features;\nusing Serilog;\nusing Serilog.Events;\n\nvar builder = WebApplication.CreateBuilder(args);\n\n//־\nbuilder.Logging.ClearProviders();\nLog.Logger = new LoggerConfiguration()\n          .Enrich.FromLogContext()\n          .WriteTo.Console()// ־̨\n          .WriteTo.File($\"data/logs/log-.txt\", restrictedToMinimumLevel: LogEventLevel.Warning, rollingInterval: RollingInterval.Day)\n          .MinimumLevel.Information()\n          .MinimumLevel.Override(\"Microsoft\", LogEventLevel.Information)\n          .CreateLogger();\nbuilder.Host\n     .UseSerilog(dispose: true)\n     .UseAutofac();\n\n\n//С\nbuilder.WebHost.ConfigureKestrel((context, options) =>\n{\n    options.Limits.MaxRequestBodySize = int.MaxValue;\n});\nbuilder.Services.Configure<FormOptions>(options =>\n{\n    options.MultipartBodyLengthLimit = int.MaxValue;\n});\nbuilder.Services.ReplaceConfiguration(builder.Configuration);//ô\n\nbuilder.Services.AddApplication<WebModule>();\nvar app = builder.Build();\napp.InitializeApplication();\napp.MapGet(\"/\", context => context.Response.WriteAsync(\"kite gateway run success!\"));\napp.Run();\n"
  },
  {
    "path": "src/Kite.Gateway.Web/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"Kite.Gateway.Web\": {\n      \"commandName\": \"Project\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      },\n      \"dotnetRunMessages\": true,\n      \"applicationUrl\": \"http://localhost:55662\"\n    },\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Development\"\n      }\n    },\n    \"Docker (1)\": {\n      \"commandName\": \"Docker\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"{Scheme}://{ServiceHost}:{ServicePort}\",\n      \"publishAllPorts\": true\n    }\n  },\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:63924\",\n      \"sslPort\": 0\n    }\n  }\n}"
  },
  {
    "path": "src/Kite.Gateway.Web/WebModule.cs",
    "content": "﻿using Microsoft.AspNetCore.Builder;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\nusing Microsoft.OpenApi.Models;\nusing Kite.Gateway.Application;\nusing Kite.Gateway.Domain;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Volo.Abp;\nusing Volo.Abp.AspNetCore.Mvc;\nusing Volo.Abp.Autofac;\nusing Volo.Abp.Modularity;\nusing Volo.Abp.Swashbuckle;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Authentication.JwtBearer;\nusing Microsoft.IdentityModel.Tokens;\nusing System.Security.Cryptography.X509Certificates;\nusing System.Text;\nusing Microsoft.AspNetCore.Mvc;\nusing Volo.Abp.AspNetCore.Mvc.Validation;\nusing Volo.Abp.AspNetCore.Mvc.ExceptionHandling;\nusing Kite.Gateway.Web.Filters;\nusing Newtonsoft.Json;\nusing Volo.Abp.Json;\nusing Consul;\nusing Kite.Gateway.Domain.Authorization;\nusing Yarp.ReverseProxy.Configuration;\nusing Kite.Gateway.Domain.ReverseProxy;\nusing Kite.Gateway.Domain.Shared.Options;\nusing Kite.Gateway.Web.Middlewares;\nusing Kite.Gateway.Domain.Shared.Enums;\nusing Microsoft.Extensions.Options;\nusing Kite.Gateway.Application.Contracts.Dtos;\nusing Kite.Gateway.Application.Contracts;\nusing Serilog;\nusing Microsoft.AspNetCore.HttpOverrides;\n\nnamespace Kite.Gateway.Web\n{\n    [DependsOn(\n         typeof(AbpAutofacModule),\n         typeof(ApplicationModule),\n         typeof(AbpSwashbuckleModule)\n     )]\n    public class WebModule:AbpModule\n    {\n        #region 中间件注入\n        public override void ConfigureServices(ServiceConfigurationContext context)\n        {\n            context.Services.Configure<ForwardedHeadersOptions>(options =>\n            {\n                options.ForwardedHeaders =\n                    ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;\n                options.KnownNetworks.Clear();\n                options.KnownProxies.Clear();\n            });\n            context.Services.AddHttpClient();\n            //注入会话\n            context.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();\n            //\n            ConfigureCore(context);\n            ConfigureCors(context);\n            ConfigureMvc(context);\n            ConfigureReverseProxy(context);\n            \n        }\n        /// <summary>\n        /// 网关核心配置项\n        /// </summary>\n        /// <param name=\"context\"></param>\n        private void ConfigureCore(ServiceConfigurationContext context)\n        {\n            //注入网关基础配置\n            context.Services.Configure<KiteGatewayOption>(context.Services.GetConfiguration().GetSection(\"KiteGateway\"));\n            //白名单配置\n            context.Services.Configure<List<WhitelistOption>>(opt => { });\n            //中间件配置\n            context.Services.Configure<List<MiddlewareOption>>(opt => { });\n            //Jwt身份认证配置\n            context.Services.Configure<AuthenticationOption>(opt =>\n            {\n                opt.UseState = false;\n            });\n            context.Services.Configure<TokenValidationParameters>(opt => { });\n            //Yarp反向代理配置\n            context.Services.Configure<YarpOption>(opt => \n            {\n                opt.Routes = new List<RouteOption>();\n            });\n        }\n        /// <summary>\n        /// MVC中间件注入配置\n        /// </summary>\n        /// <param name=\"context\"></param>\n        private void ConfigureMvc(ServiceConfigurationContext context)\n        {\n            context.Services.AddControllers(options =>\n            {\n                // 移除 AbpValidationActionFilter\n                var filterMetadata = options.Filters.FirstOrDefault(x => x is ServiceFilterAttribute attribute && attribute.ServiceType.Equals(typeof(AbpValidationActionFilter)));\n                if (filterMetadata != null)\n                    options.Filters.Remove(filterMetadata);\n                //移除全局异常过滤器\n                var errIndex = options.Filters.ToList().FindIndex(filter => filter is ServiceFilterAttribute attr && attr.ServiceType.Equals(typeof(AbpExceptionFilter)));\n                if (errIndex > -1)\n                    options.Filters.RemoveAt(errIndex);\n                //\n                options.Filters.Add(typeof(AbpCoreExceptionFilter));\n                options.Filters.Add<KiteCoreActionFilter>();\n            })\n            .AddJsonOptions(opt => { });\n            Configure<AbpJsonOptions>(options => options.DefaultDateTimeFormat = \"yyyy-MM-dd HH:mm:ss\");\n        }\n        /// <summary>\n        /// 配置反向代理\n        /// </summary>\n        /// <param name=\"context\"></param>\n        private void ConfigureReverseProxy(ServiceConfigurationContext context)\n        {\n            //注入反向代理\n            context.Services.AddSingleton<IProxyConfigProvider, InDatabaseStoreConfigProvider>();\n            context.Services.AddReverseProxy();\n        }\n        /// <summary>\n        /// 跨域注入\n        /// </summary>\n        /// <param name=\"context\"></param>\n        private void ConfigureCors(ServiceConfigurationContext context)\n        {\n            //跨域配置\n            context.Services.AddCors(options =>\n            {\n                options.AddDefaultPolicy(policy =>\n                {\n                    policy\n                    .AllowAnyHeader()\n                    .AllowAnyMethod()\n                    .SetIsOriginAllowed(o => true)\n                    .AllowCredentials();\n                });\n            });\n        }\n        #endregion\n        public override void OnApplicationInitialization(ApplicationInitializationContext context)\n        {\n            \n            LoadMainConfigureAsync(context);\n            //\n            var app = context.GetApplicationBuilder();\n            var env = context.GetEnvironment();\n\n            if (env.IsDevelopment())\n            {\n                app.UseDeveloperExceptionPage();\n\n            }\n            else\n            {\n                app.UseExceptionHandler(\"/Error\");\n            }\n            app.UseForwardedHeaders();\n            app.UseCors();\n            app.UseRouting();\n           \n            app.UseEndpoints(endpoints =>\n            {\n                endpoints.MapControllers();\n                \n                endpoints.MapReverseProxy(proxyPipeline =>\n                {\n                    proxyPipeline.UseMiddleware<KiteAuthorizationMiddleware>();\n                    proxyPipeline.UseMiddleware<KiteExternalMiddleware>();\n                });\n            });\n        }\n        /// <summary>\n        /// 加载基础配置项\n        /// </summary>\n        /// <param name=\"context\"></param>\n        /// <returns></returns>\n        private void LoadMainConfigureAsync(ApplicationInitializationContext context)\n        {\n            try\n            {\n\n                //初始化时刷新所有数据配置项\n                var options = context.ServiceProvider.GetService<IOptions<KiteGatewayOption>>();\n                if (options != null)\n                {\n                    var httpClientFactory = context.ServiceProvider.GetService<IHttpClientFactory>();\n                    var httpClient = httpClientFactory.CreateClient();\n                    var configureResult =  httpClient.GetFromJsonAsync<KiteResult<RefreshConfigureDto>>($\"{options.Value.AdminServer}/api/kite/refresh/configure\").Result;\n                    if (configureResult != null && configureResult.Code == 0)\n                    {\n                        var refreshAppService = context.ServiceProvider.GetService<IRefreshAppService>();\n                        if (refreshAppService != null)\n                        {\n                           var res= refreshAppService.RefreshConfigureAsync(configureResult.Data).Result;\n                        }\n                    }\n                }\n\n            }\n            catch (Exception ex)\n            {\n                Log.Error(ex, ex.Message);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "src/Kite.Gateway.Web/appsettings.json",
    "content": "{\n  \"Logging\": {\n    \"LogLevel\": {\n      \"Default\": \"Information\",\n      \"Microsoft.AspNetCore\": \"Warning\"\n    }\n  },\n  \"AllowedHosts\": \"*\",\n  \"KiteGateway\": {\n    \"AdminServer\": \"http://localhost:55661\",\n    \"AccessToken\": \"DJ3Ed1IqOHJ62eBZ8z5v5cKjfEAdFssH\"\n  }\n}\n"
  }
]