Browse Source

auto commit 1.3.4

lith 3 years ago
commit
a92553d544
85 changed files with 4395 additions and 0 deletions
  1. 66 0
      .github/workflows/action-main.yml
  2. 167 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/GatewayHost.cs
  3. 29 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/Program.cs
  4. 27 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/Properties/launchSettings.json
  5. 50 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/ServiceAdaptor.NetCore.Gateway.csproj
  6. 51 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/Startup.cs
  7. 243 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/appsettings.json
  8. 4 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/contentTypeMap.json
  9. 12 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/web.config
  10. 9 0
      02.Gateway/ServiceAdaptor.NetCore.Gateway/wwwroot/index.html
  11. 64 0
      11.ServiceProvider/ServiceProvider/Controllers/ValuesController.cs
  12. 27 0
      11.ServiceProvider/ServiceProvider/Program.cs
  13. 17 0
      11.ServiceProvider/ServiceProvider/Properties/launchSettings.json
  14. 23 0
      11.ServiceProvider/ServiceProvider/ServiceProvider.csproj
  15. 41 0
      11.ServiceProvider/ServiceProvider/Startup.cs
  16. 9 0
      11.ServiceProvider/ServiceProvider/appsettings.Development.json
  17. 188 0
      11.ServiceProvider/ServiceProvider/appsettings.json
  18. 42 0
      12.ServiceConsumer/ServiceConsumer/Controllers/ValuesController.cs
  19. 28 0
      12.ServiceConsumer/ServiceConsumer/Program.cs
  20. 17 0
      12.ServiceConsumer/ServiceConsumer/Properties/launchSettings.json
  21. 20 0
      12.ServiceConsumer/ServiceConsumer/Service/ServiceProvider/Contract/UserInfo.cs
  22. 58 0
      12.ServiceConsumer/ServiceConsumer/Service/ServiceProvider/ServiceProviderService.cs
  23. 23 0
      12.ServiceConsumer/ServiceConsumer/ServiceConsumer.csproj
  24. 41 0
      12.ServiceConsumer/ServiceConsumer/Startup.cs
  25. 9 0
      12.ServiceConsumer/ServiceConsumer/appsettings.Development.json
  26. 186 0
      12.ServiceConsumer/ServiceConsumer/appsettings.json
  27. 201 0
      LICENSE
  28. 72 0
      Library/ServiceAdaptor.NetCore.Be.Eureka/ApiClient.cs
  29. 38 0
      Library/ServiceAdaptor.NetCore.Be.Eureka/ServiceAdaptor.NetCore.Be.Eureka.csproj
  30. 52 0
      Library/ServiceAdaptor.NetCore.Be.Eureka/ServiceAdaptor.cs
  31. BIN
      Library/ServiceAdaptor.NetCore.Be.Eureka/dll/EurekaRestTemplate.dll
  32. BIN
      Library/ServiceAdaptor.NetCore.Be.Eureka/dll/Steeltoe.Discovery.ClientAutofac.dll
  33. BIN
      Library/ServiceAdaptor.NetCore.Be.Eureka/dll/Steeltoe.Discovery.ClientCore.dll
  34. BIN
      Library/ServiceAdaptor.NetCore.Be.Eureka/dll/Steeltoe.Discovery.EurekaBase.dll
  35. BIN
      Library/ServiceAdaptor.NetCore.Be.Eureka/dll/cn.jpush.api.dll
  36. BIN
      Library/ServiceAdaptor.NetCore.Be.Eureka/dll/cn.jpush.api.dll.refresh
  37. 80 0
      Library/ServiceAdaptor.NetCore.Consul/ApiClient.cs
  38. 34 0
      Library/ServiceAdaptor.NetCore.Consul/ServiceAdaptor.NetCore.Consul.csproj
  39. 165 0
      Library/ServiceAdaptor.NetCore.Consul/ServiceAdaptor.cs
  40. 93 0
      Library/ServiceAdaptor.NetCore.MinHttp/ApiClient.cs
  41. 26 0
      Library/ServiceAdaptor.NetCore.MinHttp/ServiceAdaptor.NetCore.MinHttp.csproj
  42. 42 0
      Library/ServiceAdaptor.NetCore.MinHttp/ServiceAdaptor.cs
  43. 157 0
      Library/ServiceAdaptor.NetCore.Sers/ApiClient.cs
  44. 32 0
      Library/ServiceAdaptor.NetCore.Sers/ServiceAdaptor.NetCore.Sers.csproj
  45. 19 0
      Library/ServiceAdaptor.NetCore.Sers/ServiceAdaptor.cs
  46. 140 0
      Library/ServiceAdaptor.NetCore/Client/ApiClient.cs
  47. 36 0
      Library/ServiceAdaptor.NetCore/Client/ApiRequest.cs
  48. 32 0
      Library/ServiceAdaptor.NetCore/Client/ApiResponse.cs
  49. 261 0
      Library/ServiceAdaptor.NetCore/Client/Extendsions/IApiClientExtensions.cs
  50. 39 0
      Library/ServiceAdaptor.NetCore/Client/IApiClient.cs
  51. 20 0
      Library/ServiceAdaptor.NetCore/Client/IApiEvent.cs
  52. 25 0
      Library/ServiceAdaptor.NetCore/Extensions/ApiRequestExtensions.cs
  53. 74 0
      Library/ServiceAdaptor.NetCore/Extensions/IWebHostBuilderExtensions_UseServiceAdaptor.cs
  54. 11 0
      Library/ServiceAdaptor.NetCore/IServiceAdaptor.cs
  55. 13 0
      Library/ServiceAdaptor.NetCore/Properties/PublishProfiles/FolderProfile.pubxml
  56. 32 0
      Library/ServiceAdaptor.NetCore/ServiceAdaptor.NetCore.csproj
  57. 19 0
      Library/ServiceAdaptor/ServiceAdaptor.csproj
  58. 38 0
      Publish/DevOps/github/30.nuget-pack.sh
  59. 35 0
      Publish/DevOps/github/31.nuget-push.sh
  60. 61 0
      Publish/DevOps/github/40.dotnet-publish.sh
  61. 48 0
      Publish/DevOps/github/70.docker-image-create.sh
  62. 65 0
      Publish/DevOps/github/71.docker-image-build.sh
  63. 67 0
      Publish/DevOps/github/90.release-build.sh
  64. 58 0
      Publish/DevOps/github/91.release-github.sh
  65. 57 0
      Publish/DevOps/github/startup.bash
  66. 243 0
      Publish/ReleaseFile/docker-deploy/adaptor-gateway/appsettings.json
  67. 68 0
      Publish/ReleaseFile/docker-deploy/adaptor-gateway/docker部署adaptor-gateway.md
  68. 9 0
      Publish/ReleaseFile/docker-deploy/adaptor-gateway/wwwroot/index.html
  69. 4 0
      Publish/ReleaseFile/docker-image/adaptor-gateway/Dockerfile
  70. 60 0
      Publish/ReleaseFile/docker-image/制作镜像.txt
  71. 10 0
      Publish/ReleaseFile/publish/40.启动Gateway.bat
  72. 11 0
      Publish/ReleaseFile/publish/50.循环启动Gateway.bat
  73. 45 0
      Publish/cmd/docker-image-create.bat
  74. 50 0
      Publish/cmd/dotnet-publish.bat
  75. 18 0
      Publish/cmd/nuget delete from NugetServer.Sers.bat
  76. 23 0
      Publish/cmd/nuget-pack.bat
  77. 16 0
      Publish/cmd/nuget-push to NugetServer.Sers.bat
  78. 9 0
      Publish/cmd/nuget-一键发布并上传.bat
  79. 14 0
      Publish/cmd/一键发布.bat
  80. 34 0
      Publish/cmd/更新为下一大版本号.bat
  81. 34 0
      Publish/cmd/更新为下一小版本号.bat
  82. 34 0
      Publish/cmd/更新为当前preview版本号.bat
  83. 34 0
      Publish/cmd/更新为当前版本号.bat
  84. 1 0
      Publish/cmd/清理-发布文件.bat
  85. 85 0
      ServiceAdaptor.sln

+ 66 - 0
.github/workflows/action-main.yml

@@ -0,0 +1,66 @@
+# This is a basic workflow to help you get started with Actions
+
+name: CI
+
+# Controls when the action will run. 
+on:
+  
+  push:
+    # Triggers the workflow on push events but only for the master branch
+    #branches: [ master ]
+
+    # Triggers the workflow on push tag
+    tags: ['*']
+    
+  # Allows you to run this workflow manually from the Actions tab
+  workflow_dispatch:
+
+# A workflow run is made up of one or more jobs that can run sequentially or in parallel
+jobs:
+  # This workflow contains a single job called "build"
+  build:
+    # The type of runner that the job will run on
+    runs-on: ubuntu-latest
+
+    # Steps represent a sequence of tasks that will be executed as part of the job
+    steps:
+      # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
+      - uses: actions/checkout@v2
+
+      # Runs a set of commands using the runners shell
+      - name: Run startup.bash
+        run: |
+           set -e
+           echo start build
+           export DOCKER_USERNAME="${{ secrets.DOCKER_USERNAME  }}"
+           export DOCKER_PASSWORD="${{ secrets.DOCKER_PASSWORD }}"
+           export NUGET_SERVER="${{ secrets.NUGET_SERVER  }}"
+           export NUGET_KEY="${{ secrets.NUGET_KEY }}"
+           export GIT_SSH_SECRET="${{ secrets.GIT_SSH_SECRET }}"
+           cd ./Publish/DevOps/github
+           bash startup.bash
+           echo build succeed!
+
+      - name: Release-Create
+        id: create_release
+        uses: actions/create-release@v1
+        if: hashFiles(env.release_assetPath)
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          release_name: ${{ env.release_name }}
+          tag_name: ${{ env.release_tag }}
+          draft: ${{ env.release_draft }}
+          prerelease: ${{ env.release_prerelease }}
+          body: ${{ env.release_body }}
+      - name: Release-Upload
+        id: upload-release-asset
+        uses: actions/upload-release-asset@v1
+        if: hashFiles(env.release_assetPath)
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a   `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps
+          asset_path: ${{ env.release_assetPath }}
+          asset_name: ${{ env.release_assetName }}
+          asset_content_type: ${{ env.release_contentType }}

+ 167 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/GatewayHost.cs

@@ -0,0 +1,167 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using ServiceAdaptor.NetCore.Client;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using Vit.Core.Module.Log;
+using Vit.Core.Util.ConfigurationManager;
+using Vit.Extensions;
+using Vit.WebHost;
+
+namespace ServiceAdaptor.NetCore.Gateway
+{
+    public class GatewayHost
+    {
+
+        static string prefixOfCopyIpToHeader = Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetStringByPath("Gateway.prefixOfCopyIpToHeader");
+
+        static string ResponseDefaultContentType = (ConfigurationManager.Instance.GetStringByPath("Gateway.ResponseDefaultContentType") ?? ("application/json; charset=" + Vit.Core.Module.Serialization.Serialization_Newtonsoft.Instance.charset));
+        static async Task Bridge(HttpContext context)
+        {
+            try
+            {
+                #region (x.1)build apiRequest
+
+                var request = context.Request;
+
+                var url = request.PathBase + request.Path.Value + request.QueryString.Value;
+
+
+                #region (x.x.2)headers
+                //(x.x.x.1)
+                var headers = new Dictionary<string, string>();
+                foreach (var kv in request.Headers)
+                {
+                    headers[kv.Key] = kv.Value.ToString();
+                }
+
+                //(x.x.x.2)记录Ip 到 headers
+                if (prefixOfCopyIpToHeader != null)
+                {
+                    headers[prefixOfCopyIpToHeader + "RemoteIpAddress"] = context.Connection.RemoteIpAddress.MapToIPv4().ToString();
+                    headers[prefixOfCopyIpToHeader + "RemotePort"] = context.Connection.RemotePort.ToString();
+
+                    headers[prefixOfCopyIpToHeader + "LocalIpAddress"] = context.Connection.LocalIpAddress.MapToIPv4().ToString();
+                    headers[prefixOfCopyIpToHeader + "LocalPort"] = context.Connection.LocalPort.ToString();
+                }
+                #endregion
+
+
+                #region (x.x.3)body
+                byte[] arg = null;
+                using (MemoryStream ms = new MemoryStream())
+                {
+                    request.Body.CopyTo(ms);
+                    if (ms.Length > 0)
+                    {
+                        arg = ms.ToArray();
+                    }
+                }
+                #endregion
+
+                //(x.x.4)build apiRequest
+                var apiRequest = new ApiRequest { url = url, arg = arg, httpMethod = request.Method, headers = headers };
+
+                #endregion
+
+                #region (x.2)CallApi             
+               
+                var apiResponse = await ApiClient.Instance.CallApiAsync<byte[]>(apiRequest);
+                #endregion
+
+                #region (x.3)Write ApiResponse
+
+                var response = context.Response;
+
+                //(x.x.1)StatusCode
+                response.StatusCode = apiResponse.StatusCode;
+
+                #region (x.x.2) header
+                {
+                    //(x.x.x.1)原始header
+                    var responseHeaders = response.Headers;
+                    if (null != apiResponse.headers)
+                    {
+                        foreach (var item in apiResponse.headers)
+                        {
+                            responseHeaders.TryAdd(item.Key, item.Value);
+                        }
+                    }
+
+
+                    //(x.x.x.2)Content-Type → application/json
+                    if (!headers.ContainsKey("Content-Type"))
+                    {
+                        headers["Content-Type"] = ResponseDefaultContentType;
+                        //response.ContentType = "application/json";
+                    }
+                }
+                #endregion
+
+                //(x.x.3) Body             
+                if (apiResponse.data != null && apiResponse.data.Length > 0)
+                {                  
+                    await response.Body.WriteAsync(apiResponse.data);
+                }
+                #endregion                 
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+            }
+        }
+
+
+
+        public static void StartWebHost()
+        {
+            try
+            {
+
+                HostRunArg arg = ConfigurationManager.Instance.GetByPath<HostRunArg>("Gateway");
+                if (arg == null || arg.urls == null || arg.urls.Length == 0) return;
+
+
+                #region (x.3)初始化WebHost
+
+                //(x.x.1)指定可以与iis集成(默认无法与iis集成)
+                arg.OnCreateWebHostBuilder = () => Microsoft.AspNetCore.WebHost.CreateDefaultBuilder().UseVitConfig();
+
+
+                #region (x.x.2)转发web请求调用(网关核心功能)
+                arg.OnConfigure = (app) =>
+                {
+                    app.Run(Bridge);
+                };
+                #endregion
+
+
+                //(x.x.3)设置非异步启动
+                arg.RunAsync = true;
+
+
+                #region (x.x.4)启动           
+                Logger.Info("[WebHost]will listening on: " + string.Join(",", arg.urls));
+
+                if (arg.staticFiles?.rootPath != null)
+                    Logger.Info("[WebHost]wwwroot : " + arg.staticFiles?.rootPath);
+
+                Vit.WebHost.Host.Run(arg);
+                #endregion
+
+
+                #endregion
+
+            }
+            catch (Exception ex)
+            {
+                Logger.Error(ex);
+                Console.WriteLine("Exception:" + ex.Message);
+            }
+
+
+        }
+    }
+}

+ 29 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/Program.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Gateway
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            Task.Run(()=> { GatewayHost.StartWebHost();  });
+
+            CreateWebHostBuilder(args).Build().Run();
+        }
+
+        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
+            WebHost.CreateDefaultBuilder(args)               
+                .UseStartup<Startup>()
+                .UseUrls(Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<string[]>("server.urls"))
+                .UseServiceAdaptor();
+    }
+}

+ 27 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/Properties/launchSettings.json

@@ -0,0 +1,27 @@
+{
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:50417/",
+      "sslPort": 44386
+    }
+  },
+  "profiles": {
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "ServiceAdaptor.NetCore.Gateway": {
+      "commandName": "Project",
+      "launchBrowser": true,
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      },
+      "applicationUrl": "https://localhost:5001;http://localhost:5000"
+    }
+  }
+}

+ 50 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/ServiceAdaptor.NetCore.Gateway.csproj

@@ -0,0 +1,50 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+	<PropertyGroup>
+		<publish>Gateway</publish>
+		<docker>adaptor-gateway</docker>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<TargetFramework>netcoreapp2.1</TargetFramework>
+		<Version>1.3.4</Version>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<Authors>Lith</Authors>
+		<Description>微服务适配器-网关</Description>
+		<PackageProjectUrl>https://github.com/serset/ServiceAdaptor.NetCore</PackageProjectUrl>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<DocumentationFile>bin\Debug\netstandard2.0\ServiceAdaptor.NetCore.Gateway.xml</DocumentationFile>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<Folder Include="wwwroot\" />
+	</ItemGroup>
+
+
+	<ItemGroup>
+		<PackageReference Include="Microsoft.AspNetCore.App" />
+		
+		<ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj" />
+		<ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.MinHttp\ServiceAdaptor.NetCore.MinHttp.csproj" />
+		<ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.Consul\ServiceAdaptor.NetCore.Consul.csproj" />
+		<ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.Sers\ServiceAdaptor.NetCore.Sers.csproj" />
+		<!--<ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.Be.Eureka\ServiceAdaptor.NetCore.Be.Eureka.csproj" />-->
+	</ItemGroup>
+
+
+
+	<ItemGroup>
+		<Content Update="contentTypeMap.json">
+			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
+		</Content>
+		<Content Update="web.config">
+			<CopyToOutputDirectory>Always</CopyToOutputDirectory>
+		</Content>
+	</ItemGroup>
+
+</Project>
+

+ 51 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/Startup.cs

@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+using ServiceAdaptor.NetCore.Client;
+using Vit.Core.Module.Log;
+using Vit.Core.Util.ConfigurationManager;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Gateway
+{
+    public class Startup
+    {
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
+        {    
+
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }    
+
+        }
+
+
+    }
+}

+ 243 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/appsettings.json

@@ -0,0 +1,243 @@
+{
+  "//Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+
+
+  /* 网关配置 */
+  "Gateway": {
+
+    /* url,可多个 */
+    "urls": [ "http://*:4580" ],
+
+    /* 是否允许跨域访问,默认true */
+    "allowAnyOrigin": true,
+
+    /* 把请求的ip地址、端口号复制到请求头中的前缀。若不指定则不复制。 */
+    "prefixOfCopyIpToHeader": "Sers-Gateway-",
+
+    /* http回应中的默认Content-Type。若不指定则默认为 "application/json; charset="+Serialization.Instance.charset  */
+    "//ResponseDefaultContentType": "application/json; charset=UTF-8",
+
+
+    /* 映射静态文件。若不指定则不映射静态文件 */
+    "staticFiles": {
+
+      /* 静态文件路径。可为相对路径或绝对路径。若为空或空字符串则为默认路径(wwwroot)。demo:"wwwroot/demo" */
+      //"rootPath": "wwwroot",
+
+      /* 默认页面(可不指定)。An ordered list of file names to select by default. List length and ordering  may affect performance */
+      "defaultFileNames": ["index.html"],
+
+      /* 是否可浏览目录(default false)。Enables directory browsing */
+      //"useDirectoryBrowser": false,
+
+      /* 静态文件类型映射配置的文件路径。可为相对路径或绝对路径。例如"contentTypeMap.json"。若不指定(或指定的文件不存在)则不指定文件类型映射配置 */
+      "contentTypeMapFile": "contentTypeMap.json",
+
+      /* 回应静态文件时额外添加的http回应头。可不指定。 */
+      "responseHeaders": {
+
+        //设置浏览器静态文件缓存3600秒
+        "Cache-Control": "public,max-age=3600"
+      }
+
+    }
+  },
+
+
+
+  /* asp.net core 原始web服务配置 */
+  "server": {
+    "urls": [ "http://*:4580" ] 
+  },
+
+
+  /* 微服务适配器 配置 */
+  "ServiceAdaptor": [
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Sers.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "className": "ServiceAdaptor.NetCore.Sers.ServiceAdaptor"
+
+      /* 配置 */
+
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.MinHttp.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.MinHttp.ServiceAdaptor",
+
+      /* 配置 */
+      /* 网关地址,必须指定 */
+      "gatewayAddress": "http://127.0.0.1:6080",
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Consul.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.Consul.ServiceAdaptor",
+
+      /* 配置 */
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600,
+
+      /* consul的地址。如 http://127.0.0.1:8500 */
+      "ConsulEndpoint": "http://127.0.0.1:8500",
+
+      /* 提供的服务的地址,如 127.0.0.1、sers.cloud */
+      "serviceHost": "127.0.0.1",
+
+      /* 提供的服务的端口号 */
+      "servicePort": 6003,
+
+      /* 提供的服务的名称,如 ServiceProvider */
+      "serviceName": "Gateway"
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Be.Eureka.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.Be.Eureka.ServiceAdaptor",
+
+      /* 配置 */
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600
+    }
+
+  ],
+
+
+
+
+  /* Sers配置 begin */
+
+  "Sers": {
+    /* 通讯层配置 */
+    "CL": {
+      /* one conn is one channel.can be multiable */
+      "Client": [
+        {
+          // Ipc.NamedPipe
+          /* (x.1) type */
+          /* 在此Assembly中查找Builder */
+          "assemblyFile": "Sers.CL.Ipc.NamedPipe.dll",
+          /* the class of Builder in assemblyFile  */
+          "className": "Sers.CL.Ipc.NamedPipe.OrganizeClientBuilder",
+
+
+          /* (x.2) config */
+          // 命名管道只支持本机或局域网。
+          /* 服务端机器名或者ip地址(如 103.23.23.23 、win10f),默认 "." */
+          "serverName": ".",
+          /* 命名管道名称。例如: "Sers.CL.Ipc" */
+          "pipeName": "Sers.CL.Ipc.4501",
+          /* 连接秘钥,用以验证连接安全性。服务端和客户端必须一致 */
+          "secretKey": "SersCL",
+
+          /* 请求超时时间(单位ms,默认60000) */
+          "requestTimeoutMs": 3600000
+        },
+        {
+          // Socket.Iocp
+          /* (x.1) type - Iocp */
+          /* the class of builder in assemblyFile  */
+          //"className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
+
+          /* (x.2) conn config */
+          /* 服务端 host地址。例如: "127.0.0.1"、"serset.com" */
+          "host": "127.0.0.1",
+          /* 服务端 监听端口号。例如: 4501 */
+          "port": 4501,
+          /* 连接秘钥,用以验证连接安全性。服务端和客户端必须一致 */
+          "secretKey": "SersCL",
+
+          /* 请求超时时间(单位ms,默认60000) */
+          "requestTimeoutMs": 3600000
+        }
+      ]
+    },
+
+    /* LocalApiService 配置,可不指定 */
+    "LocalApiService": {
+
+      /* 是否 输出本地Api的调用信息到(ApiTrace)Log文件。默认:false */
+      //"PrintTrace": true,
+
+      /* 后台服务的线程个数(单位个,默认0,代表不开启服务) */
+      "workThreadCount": 16
+    },
+
+    /* ServiceStation配置,可不指定 */
+    "ServiceStation": {
+      /* serviceStation站点信息 */
+      "serviceStationInfo": {
+        /* 服务站点名称 */
+        "serviceStationName": "Gateway"
+      }
+    }
+  },
+
+
+  /* Vit工具配置,可不指定 */
+  "Vit": {
+    /* 日志配置,可不指定 */
+    "Logger": {
+      /* print the log to console. default:false  */
+      "PrintToConsole": true
+    },
+
+
+    "Kestrel": {
+      /* (int64) the maximum allowed size of any request body in bytes.  When set to null, the maximum request body size is unlimited. */
+      "MaxRequestBodySize": 2000000000,
+
+      /* (int32) A limit on the length of individual form values. Forms containing values that exceed this limit will throw an System.IO.InvalidDataException when parsed. */
+      "ValueLengthLimit": 2000000000,
+
+      /* (int64) A limit for the length of each multipart body. Forms sections that exceed this limit will throw an System.IO.InvalidDataException when parsed. */
+      "MultipartBodyLengthLimit": 2000000000
+    }
+  },
+
+  /* Sers配置 end */
+
+
+
+
+
+  /* BeEureka配置 begin */
+  "spring": {
+    "application": {
+      "name": "ServiceAdaptor_Gateway" //服务名称
+    }
+  },
+  "eureka": {
+    "client": {
+      "serviceUrl": "http://direwolf:direwolf@192.168.1.204:8762/eureka/", //注册中心地址
+      "validate_certificates": false
+    },
+    "instance": {
+      "leaseRenewalIntervalInSeconds": 120,
+      "leaseExpirationDurationInSeconds": 120,
+      "port": 6003, //服务端口
+      "preferIpAddress": true, //表示使用当前ip作为服务的ip
+      "metadataMap": { //里面的参数都是国网要求
+        "auth-code": "HWJCGliay4uXH3xhUTaXnB==",
+        "service-name": "ServiceAdaptor_Gateway", //服务中文名称
+        "service-desc": "ServiceAdaptor_Gateway", //服务描述
+        "service-namespace": "XMGL",
+        "service-sys": "JJQGC"
+      }
+    }
+  }
+  /* BeEureka配置 end */
+
+}

+ 4 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/contentTypeMap.json

@@ -0,0 +1,4 @@
+{
+  /* wwwroot静态文件类型映射配置,可不指定  */
+  ".json": "application/json"
+}

+ 12 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/web.config

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+  <location path="." inheritInChildApplications="false">
+    <system.webServer>
+      <handlers>
+        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
+      </handlers>
+      <aspNetCore processPath="dotnet" arguments=".\ServiceAdaptor.NetCore.Gateway.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" />
+    </system.webServer>
+  </location>
+</configuration>
+<!--ProjectGuid: c9869c8c-011c-46a8-9e99-88fe982ece67-->

+ 9 - 0
02.Gateway/ServiceAdaptor.NetCore.Gateway/wwwroot/index.html

@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <title>Gateway</title> 
+</head>
+<body>
+    ServiceAdaptor.Gateway
+</body>
+</html>

+ 64 - 0
11.ServiceProvider/ServiceProvider/Controllers/ValuesController.cs

@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Vit.Core.Util.ComponentModel.Data;
+using Vit.Extensions;
+
+namespace ServiceProvider.Controllers
+{
+    [Route("ServiceProvider/[controller]")]
+    [ApiController]
+    public class ValuesController : ControllerBase
+    {
+
+        #region model
+        public class UserInfo 
+        {
+            public string name;
+            public int? age;
+            public List<string> callStack;
+            public object headers;
+        }
+        #endregion
+
+
+
+        #region (x.1)Get
+        // GET api/values/5
+        [HttpGet("item")]
+        public ApiReturn<object> Get([FromQuery]string name, [FromQuery]int age, [FromQuery] string callStack)
+        {
+            var userInfo= new UserInfo { name = name, age = age , callStack =  callStack.Deserialize<List<string>>() };
+
+            if (userInfo.callStack == null) 
+            {
+                userInfo.callStack = new List<string>();
+            }
+            userInfo.callStack.Add("ServiceProvider_" + DateTime.Now.ToString("HH:mm:ss.fff"));
+            userInfo.headers = Request.Headers;
+            return userInfo;
+        }
+
+        #endregion
+
+
+        #region (x.2)Post
+    
+        [HttpPost("item")]
+        public ApiReturn<UserInfo> Post([FromBody]UserInfo userInfo)
+        {
+            if (userInfo.callStack == null)
+            {
+                userInfo.callStack = new List<string>();
+            }
+            userInfo.callStack.Add("ServiceProvider_" + DateTime.Now.ToString("HH:mm:ss.fff"));
+            userInfo.headers = Request.Headers;
+            return userInfo;
+        }
+
+        #endregion
+         
+    }
+}

+ 27 - 0
11.ServiceProvider/ServiceProvider/Program.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Vit.Extensions;
+
+namespace ServiceProvider
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            CreateWebHostBuilder(args).Build().Run();
+        }
+
+        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
+            WebHost.CreateDefaultBuilder(args)               
+                .UseStartup<Startup>()
+                .UseUrls(Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<string[]>("server.urls"))
+                .UseServiceAdaptor();
+    }
+}

+ 17 - 0
11.ServiceProvider/ServiceProvider/Properties/launchSettings.json

@@ -0,0 +1,17 @@
+{
+  "$schema": "http://json.schemastore.org/launchsettings.json",
+  "iisSettings": {
+    "windowsAuthentication": false, 
+    "anonymousAuthentication": true, 
+    "iisExpress": {
+      "applicationUrl": "http://localhost:56041",
+      "sslPort": 0
+    }
+  },
+  "profiles": {
+    "console": {
+      "commandName": "Project",
+      "launchBrowser": false 
+    }
+  }
+}

+ 23 - 0
11.ServiceProvider/ServiceProvider/ServiceProvider.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Folder Include="wwwroot\" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.App" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj" />
+    <ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.MinHttp\ServiceAdaptor.NetCore.MinHttp.csproj" />
+    <ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.Consul\ServiceAdaptor.NetCore.Consul.csproj" />
+    <ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.Sers\ServiceAdaptor.NetCore.Sers.csproj" />
+  </ItemGroup>
+  
+  
+</Project>

+ 41 - 0
11.ServiceProvider/ServiceProvider/Startup.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace ServiceProvider
+{
+    public class Startup
+    {
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+
+            app.UseMvc();
+        }
+    }
+}

+ 9 - 0
11.ServiceProvider/ServiceProvider/appsettings.Development.json

@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Debug",
+      "System": "Information",
+      "Microsoft": "Information"
+    }
+  }
+}

+ 188 - 0
11.ServiceProvider/ServiceProvider/appsettings.json

@@ -0,0 +1,188 @@
+{
+  "//Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+
+
+  /* asp.net core 原始web服务配置 */
+  "server": {
+    "urls": [ "http://*:6001" ]
+  },
+
+  /* 微服务适配器 配置 */
+  "ServiceAdaptor": [
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Sers.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "className": "ServiceAdaptor.NetCore.Sers.ServiceAdaptor"
+
+      /* 配置 */
+
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.MinHttp.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.MinHttp.ServiceAdaptor",
+
+      /* 配置 */
+      /* 网关地址,必须指定 */
+      "gatewayAddress": "http://127.0.0.1:6080",
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Consul.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.Consul.ServiceAdaptor",
+
+      /* 配置 */
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600,
+
+      /* consul的地址。如 http://127.0.0.1:8500 */
+      "ConsulEndpoint": "http://127.0.0.1:8500",
+
+      /* 提供的服务的地址,如 127.0.0.1、sers.cloud */
+      "serviceHost": "127.0.0.1",
+
+      /* 提供的服务的端口号 */
+      "servicePort": 6001,
+
+      /* 提供的服务的名称,如 ServiceProvider */
+      "serviceName": "ServiceProvider"
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Be.Eureka.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.Be.Eureka.ServiceAdaptor",
+
+      /* 配置 */
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600
+
+    }
+
+  ],
+ 
+
+
+
+  /* Sers配置 begin */
+
+  "Sers": {
+    /* 通讯层配置 */
+    "CL": {
+      /* one conn is one channel.can be multiable */
+      "Client": [
+        {
+          // Ipc.NamedPipe
+          /* (x.1) type */
+          /* 在此Assembly中查找Builder */
+          "assemblyFile": "Sers.CL.Ipc.NamedPipe.dll",
+          /* the class of Builder in assemblyFile  */
+          "className": "Sers.CL.Ipc.NamedPipe.OrganizeClientBuilder",
+
+
+          /* (x.2) config */
+          // 命名管道只支持本机或局域网。
+          /* 服务端机器名或者ip地址(如 103.23.23.23 、win10f),默认 "." */
+          "serverName": ".",
+          /* 命名管道名称。例如: "Sers.CL.Ipc" */
+          "pipeName": "Sers.CL.Ipc.4501",
+          /* 连接秘钥,用以验证连接安全性。服务端和客户端必须一致 */
+          "secretKey": "SersCL",
+
+          /* 请求超时时间(单位ms,默认60000) */
+          "requestTimeoutMs": 3600000
+        },
+        {
+          // Socket.Iocp
+          /* (x.1) type - Iocp */
+          /* the class of builder in assemblyFile  */
+          //"className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
+
+          /* (x.2) conn config */
+          /* 服务端 host地址。例如: "127.0.0.1"、"serset.com" */
+          "host": "127.0.0.1",
+          /* 服务端 监听端口号。例如: 4501 */
+          "port": 4501,
+          /* 连接秘钥,用以验证连接安全性。服务端和客户端必须一致 */
+          "secretKey": "SersCL",
+
+          /* 请求超时时间(单位ms,默认60000) */
+          "requestTimeoutMs": 3600000
+        }
+      ]
+    },
+
+    /* LocalApiService 配置,可不指定 */
+    "LocalApiService": {
+
+      /* 是否 输出本地Api的调用信息到(ApiTrace)Log文件。默认:false */
+      //"PrintTrace": true,
+
+      /* 后台服务的线程个数(单位个,默认0,代表不开启服务) */
+      "workThreadCount": 16
+    },
+
+    /* ServiceStation配置,可不指定 */
+    "ServiceStation": {
+      /* serviceStation站点信息 */
+      "serviceStationInfo": {
+        /* 服务站点名称 */
+        "serviceStationName": "ServiceProvider"
+      }
+    }
+  },
+
+
+  /* Vit工具配置,可不指定 */
+  "Vit": {
+    /* 日志配置,可不指定 */
+    "Logger": {
+      /* print the log to console. default:false  */
+      "PrintToConsole": true
+    }
+  },
+
+  /* Sers配置 end */
+
+
+
+
+
+  /* BeEureka配置 begin */
+  "spring": {
+    "application": {
+      "name": "ServiceProvider" //服务名称
+    }
+  },
+  "eureka": {
+    "client": {
+      "serviceUrl": "http://direwolf:direwolf@192.168.1.204:8762/eureka/", //注册中心地址
+      "validate_certificates": false
+    },
+    "instance": {
+      "leaseRenewalIntervalInSeconds": 120,
+      "leaseExpirationDurationInSeconds": 120,
+      "port": 6001, //服务端口
+      "preferIpAddress": true, //表示使用当前ip作为服务的ip
+      "metadataMap": { //里面的参数都是国网要求
+        "auth-code": "HWJCGliay4uXH3xhUTaXnB==",
+        "service-name": "ServiceProvider", //服务中文名称
+        "service-desc": "ServiceProvider", //服务描述
+        "service-namespace": "XMGL",
+        "service-sys": "JJQGC"
+      }
+    }
+  }
+  /* BeEureka配置 end */
+
+}

+ 42 - 0
12.ServiceConsumer/ServiceConsumer/Controllers/ValuesController.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Service.ServiceProvider;
+
+namespace ServiceConsumer.Controllers
+{
+    [Route("ServiceConsumer/[controller]")]
+    [ApiController]
+    public class ValuesController : ControllerBase
+    {
+        // GET api/values
+        [HttpGet("get")]
+        public object Get()
+        {
+            var result = ServiceProviderService.GetItem(new Service.ServiceProvider.Contract.UserInfo { 
+                name = "lith",
+                age = 10,
+                callStack=new List<string> {"ServiceConsumer_"+DateTime.Now.ToString("HH:mm:ss.fff") } 
+            });
+            return result;
+        }
+
+        // GET api/values
+        [HttpGet("post")]
+        public object Post()
+        {
+            var result = ServiceProviderService.PostApiReturnAsync(new Service.ServiceProvider.Contract.UserInfo
+            {
+                name = "lith" ,
+                age = 10,
+                callStack = new List<string> { "ServiceConsumer_" + DateTime.Now.ToString("HH:mm:ss.fff") }
+            }).Result;
+            return result;
+        }
+
+
+
+    }
+}

+ 28 - 0
12.ServiceConsumer/ServiceConsumer/Program.cs

@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Logging;
+using Vit.Extensions;
+
+namespace ServiceConsumer
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            CreateWebHostBuilder(args).Build().Run();
+        }
+
+        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
+            WebHost.CreateDefaultBuilder(args)
+                .UseStartup<Startup>()
+                .UseUrls(Vit.Core.Util.ConfigurationManager.ConfigurationManager.Instance.GetByPath<string[]>("server.urls"))
+                .UseServiceAdaptor()
+            ;
+    }
+}

+ 17 - 0
12.ServiceConsumer/ServiceConsumer/Properties/launchSettings.json

@@ -0,0 +1,17 @@
+{
+  "$schema": "http://json.schemastore.org/launchsettings.json",
+  "iisSettings": {
+    "windowsAuthentication": false, 
+    "anonymousAuthentication": true, 
+    "iisExpress": {
+      "applicationUrl": "http://localhost:59060",
+      "sslPort": 0
+    }
+  },
+  "profiles": {
+    "console": {
+      "commandName": "Project",
+      "launchBrowser": false
+    }
+  }
+}

+ 20 - 0
12.ServiceConsumer/ServiceConsumer/Service/ServiceProvider/Contract/UserInfo.cs

@@ -0,0 +1,20 @@
+ 
+
+
+using Newtonsoft.Json;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+
+namespace Service.ServiceProvider.Contract
+{
+
+    public class UserInfo
+    {
+        public string name;
+        public int? age;
+        public List<string> callStack;
+    }
+
+
+
+}

+ 58 - 0
12.ServiceConsumer/ServiceConsumer/Service/ServiceProvider/ServiceProviderService.cs

@@ -0,0 +1,58 @@
+
+
+using Vit.Core.Util.ComponentModel.Data;
+using System.Threading.Tasks;
+using Service.ServiceProvider.Contract;
+using ServiceAdaptor.NetCore.Client;
+using Vit.Extensions;
+
+namespace Service.ServiceProvider
+{
+    public class ServiceProviderService
+    {
+
+
+        #region Get
+
+        public static async Task<ApiReturn<UserInfo>> GetApiReturnAsync(UserInfo userInfo)
+        {
+
+            //var apiRequest = new ApiRequest { url = "/ServiceProvider/Values/item", arg = userInfo, httpMethod = ApiClient.Get };
+            //apiRequest.SetServiceName("ServiceProvider");
+
+            return await ApiClient.CallApiAsync<ApiReturn<UserInfo>>("/ServiceProvider/Values/item", userInfo, ApiClient.Get);
+        }
+
+
+        public static async Task<UserInfo> GetItemAsync(UserInfo userInfo)
+        {
+            return await ApiClient.CallVitApiAsync<UserInfo>("/ServiceProvider/Values/item", userInfo, ApiClient.Get);
+        }
+
+
+        public static ApiReturn<UserInfo> GetApiReturn(UserInfo userInfo)
+        {
+            return ApiClient.CallApi<ApiReturn<UserInfo>>("/ServiceProvider/Values/item", userInfo, ApiClient.Get);
+        }
+
+        public static UserInfo GetItem(UserInfo userInfo)
+        {
+            return ApiClient.CallVitApi<UserInfo>("/ServiceProvider/Values/item", userInfo, ApiClient.Get);
+        }
+
+        #endregion
+
+
+
+        #region Post
+
+        public static async Task<ApiReturn<UserInfo>> PostApiReturnAsync(UserInfo userInfo)
+        {
+            return await ApiClient.CallApiAsync<ApiReturn<UserInfo>>("/ServiceProvider/Values/item", userInfo, ApiClient.Post);
+        }
+       
+        #endregion
+
+
+    }
+}

+ 23 - 0
12.ServiceConsumer/ServiceConsumer/ServiceConsumer.csproj

@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Folder Include="wwwroot\" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.App" />  
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj" />
+    <ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.MinHttp\ServiceAdaptor.NetCore.MinHttp.csproj" />
+    <ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.Consul\ServiceAdaptor.NetCore.Consul.csproj" />
+    <ProjectReference Include="..\..\Library\ServiceAdaptor.NetCore.Sers\ServiceAdaptor.NetCore.Sers.csproj" />
+  </ItemGroup>
+
+
+</Project>

+ 41 - 0
12.ServiceConsumer/ServiceConsumer/Startup.cs

@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace ServiceConsumer
+{
+    public class Startup
+    {
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+
+            app.UseMvc();
+        }
+    }
+}

+ 9 - 0
12.ServiceConsumer/ServiceConsumer/appsettings.Development.json

@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Debug",
+      "System": "Information",
+      "Microsoft": "Information"
+    }
+  }
+}

+ 186 - 0
12.ServiceConsumer/ServiceConsumer/appsettings.json

@@ -0,0 +1,186 @@
+{
+  "//Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+
+
+  /* asp.net core 原始web服务配置 */
+  "server": {
+    "urls": [ "http://*:6002" ]
+  },
+
+  /* 微服务适配器 配置 */
+  "ServiceAdaptor": [
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Sers.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "className": "ServiceAdaptor.NetCore.Sers.ServiceAdaptor"
+
+      /* 配置 */
+
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.MinHttp.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.MinHttp.ServiceAdaptor",
+
+      /* 配置 */
+      /* 网关地址,必须指定 */
+      "gatewayAddress": "http://127.0.0.1:6080",
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Consul.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.Consul.ServiceAdaptor",
+
+      /* 配置 */
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600,
+
+      /* consul的地址。如 http://127.0.0.1:8500 */
+      "ConsulEndpoint": "http://127.0.0.1:8500",
+
+      /* 提供的服务的地址,如 127.0.0.1、sers.cloud */
+      "serviceHost": "127.0.0.1",
+
+      /* 提供的服务的端口号 */
+      "servicePort": 6002,
+
+      /* 提供的服务的名称,如 ServiceProvider */
+      "serviceName": "ServiceConsumer"
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Be.Eureka.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.Be.Eureka.ServiceAdaptor",
+
+      /* 配置 */
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600
+    }
+
+  ],
+
+
+  /* Sers配置 begin */
+  "Sers": {
+    /* 通讯层配置 */
+    "CL": {
+      /* one conn is one channel.can be multiable */
+      "Client": [
+        {
+          // Ipc.NamedPipe
+          /* (x.1) type */
+          /* 在此Assembly中查找Builder */
+          "assemblyFile": "Sers.CL.Ipc.NamedPipe.dll",
+          /* the class of Builder in assemblyFile  */
+          "className": "Sers.CL.Ipc.NamedPipe.OrganizeClientBuilder",
+
+
+          /* (x.2) config */
+          // 命名管道只支持本机或局域网。
+          /* 服务端机器名或者ip地址(如 103.23.23.23 、win10f),默认 "." */
+          "serverName": ".",
+          /* 命名管道名称。例如: "Sers.CL.Ipc" */
+          "pipeName": "Sers.CL.Ipc.4501",
+          /* 连接秘钥,用以验证连接安全性。服务端和客户端必须一致 */
+          "secretKey": "SersCL",
+
+          /* 请求超时时间(单位ms,默认60000) */
+          "requestTimeoutMs": 3600000
+        },
+        {
+          // Socket.Iocp
+          /* (x.1) type - Iocp */
+          /* the class of builder in assemblyFile  */
+          //"className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
+
+          /* (x.2) conn config */
+          /* 服务端 host地址。例如: "127.0.0.1"、"serset.com" */
+          "host": "127.0.0.1",
+          /* 服务端 监听端口号。例如: 4501 */
+          "port": 4501,
+          /* 连接秘钥,用以验证连接安全性。服务端和客户端必须一致 */
+          "secretKey": "SersCL",
+
+          /* 请求超时时间(单位ms,默认60000) */
+          "requestTimeoutMs": 3600000
+        }
+      ]
+    },
+
+    /* LocalApiService 配置,可不指定 */
+    "LocalApiService": {
+
+      /* 是否 输出本地Api的调用信息到(ApiTrace)Log文件。默认:false */
+      //"PrintTrace": true,
+
+      /* 后台服务的线程个数(单位个,默认0,代表不开启服务) */
+      "workThreadCount": 16
+    },
+
+    /* ServiceStation配置,可不指定 */
+    "ServiceStation": {
+      /* serviceStation站点信息 */
+      "serviceStationInfo": {
+        /* 服务站点名称 */
+        "serviceStationName": "ServiceConsumer"
+      }
+    }
+  },
+
+
+  /* Vit工具配置,可不指定 */
+  "Vit": {
+    /* 日志配置,可不指定 */
+    "Logger": {
+      /* print the log to console. default:false  */
+      "PrintToConsole": true
+    }
+  },
+
+  /* Sers配置 end */
+
+
+
+
+
+  /* BeEureka配置 begin */
+  "spring": {
+    "application": {
+      "name": "ServiceConsumer" //服务名称
+    }
+  },
+  "eureka": {
+    "client": {
+      "serviceUrl": "http://direwolf:direwolf@192.168.1.204:8762/eureka/", //注册中心地址
+      "validate_certificates": false
+    },
+    "instance": {
+      "leaseRenewalIntervalInSeconds": 120,
+      "leaseExpirationDurationInSeconds": 120,
+      "port": 6002, //服务端口
+      "preferIpAddress": true, //表示使用当前ip作为服务的ip
+      "metadataMap": { //里面的参数都是国网要求
+        "auth-code": "HWJCGliay4uXH3xhUTaXnB==",
+        "service-name": "ServiceConsumer", //服务中文名称
+        "service-desc": "ServiceConsumer", //服务描述
+        "service-namespace": "XMGL",
+        "service-sys": "JJQGC"
+      }
+    }
+  }
+  /* BeEureka配置 end */
+
+
+
+}

+ 201 - 0
LICENSE

@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

+ 72 - 0
Library/ServiceAdaptor.NetCore.Be.Eureka/ApiClient.cs

@@ -0,0 +1,72 @@
+
+using RestTemplateCore;
+using ServiceAdaptor.NetCore.Client;
+using Steeltoe.Discovery.Eureka.Transport;
+using System.Collections.Generic;
+using System.Net;
+using System.Threading.Tasks;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Be.Eureka
+{
+    public class ApiClient : global::ServiceAdaptor.NetCore.MinHttp.ApiClient
+    {
+        EurekaHttpClient client => Blueearth.Common.MyHttpContext.EurekaClient;
+
+
+        #region ApiEvent
+        class ApiEvent : IApiEvent
+        {
+            public ApiClient apiClient; 
+            public async Task<ApiResponse<ReturnType>> BeforeCallApi<ReturnType>(ApiRequest req)
+            {
+
+                #region header.Authorization
+                {
+                    var Authorization = BlueearthHttpContext.Current?.Request?.Headers["Authorization"].ToString();
+                    if (!string.IsNullOrEmpty(Authorization))
+                    {
+                        var header = req.headers;
+                        if (header == null)
+                        {
+                            req.headers = header = new Dictionary<string, string>();                      
+                        }
+                        header.TryAdd("Authorization", Authorization);
+                    }
+                }
+                #endregion
+
+
+                #region redirect url
+                {
+                    //"http://client-test-service/client/Enterprise_project/GetCompaniesby"
+                    var beEurekaUrl = "http://" + req.GetServiceName() + req.url;
+
+                    var rest = new RestTemplate(apiClient.client, apiClient.vitHttpClient.httpClient);
+                    //var service = await rest.ResolveRootUrlAsync("file-service");
+                    try
+                    {
+                        req.url = await rest.ResolveUrlAsync(beEurekaUrl);
+                    }
+                    catch (System.Exception)
+                    {
+                        return new ApiResponse<ReturnType> { StatusCode = (int)HttpStatusCode.NotFound };
+                    }
+                }
+                #endregion
+
+                return null;
+            }
+        }
+        #endregion
+
+
+
+        public ApiClient() 
+        {
+            this.AddEvent(new ApiEvent { apiClient=this});
+        }  
+
+
+    }
+}

+ 38 - 0
Library/ServiceAdaptor.NetCore.Be.Eureka/ServiceAdaptor.NetCore.Be.Eureka.csproj

@@ -0,0 +1,38 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp2.1</TargetFramework>
+    <Version>1.3.4</Version>
+    <PackageProjectUrl>https://github.com/serset/ServiceAdaptor.NetCore</PackageProjectUrl>
+  </PropertyGroup>
+
+  <PropertyGroup>
+    <DocumentationFile>bin\Debug\netstandard2.0\ServiceAdaptor.NetCore.Be.Eureka.xml</DocumentationFile>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\ServiceAdaptor.NetCore.MinHttp\ServiceAdaptor.NetCore.MinHttp.csproj" />
+    <ProjectReference Include="..\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj" />
+  </ItemGroup>
+
+
+  <ItemGroup>
+    <PackageReference Include="Vit.WebHost" Version="2.1.1.499" />    
+    <PackageReference Include="Blueearth" Version="4.0.29" />
+ 
+    
+    <Reference Include="EurekaRestTemplate">
+      <HintPath>dll\EurekaRestTemplate.dll</HintPath>
+    </Reference>
+    <Reference Include="Steeltoe.Discovery.ClientAutofac">
+      <HintPath>dll\Steeltoe.Discovery.ClientAutofac.dll</HintPath>
+    </Reference>
+    <Reference Include="Steeltoe.Discovery.ClientCore">
+      <HintPath>dll\Steeltoe.Discovery.ClientCore.dll</HintPath>
+    </Reference>
+    <Reference Include="Steeltoe.Discovery.EurekaBase">
+      <HintPath>dll\Steeltoe.Discovery.EurekaBase.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  
+</Project>

+ 52 - 0
Library/ServiceAdaptor.NetCore.Be.Eureka/ServiceAdaptor.cs

@@ -0,0 +1,52 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json.Linq;
+using ServiceAdaptor.NetCore.Client;
+using Steeltoe.Discovery.Client;
+using Vit.Core.Module.Log;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Be.Eureka
+{
+    public class ServiceAdaptor : IServiceAdaptor
+    {
+        public IWebHostBuilder InitWebHostBuilder(IWebHostBuilder builder, JObject config, out IApiClient apiClient)
+        {
+            var httpApi = new ApiClient();
+            apiClient = httpApi;
+
+            #region 超时时间
+            var timeoutSeconds = config["timeoutSeconds"].ConvertBySerialize<int?>();
+            if (timeoutSeconds.HasValue)
+            {
+                httpApi.vitHttpClient.TimeoutSeconds = timeoutSeconds.Value;
+            }
+            #endregion
+
+            builder.ConfigureServices((WebHostBuilderContext context, IServiceCollection services) =>
+            {               
+
+                var env = services.BuildServiceProvider().GetService<IHostingEnvironment>();
+                var configBuilder = new ConfigurationBuilder().SetBasePath(env.ContentRootPath)
+                  .AddJsonFile("appsettings.json")
+                  .AddEnvironmentVariables();
+                var Configuration = configBuilder.Build();
+
+                //services.AddBlueearthProvider(Configuration);          
+                //services.AddBlueearthProvider(Configuration, false, false, true);
+                services.AddBlueearthProvider(Configuration, false, false, false);
+
+                services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
+
+            }).AddConfigure(app=> 
+            {              
+                app.UseDiscoveryClient();
+            });    
+
+
+            return builder;
+        }
+    }
+}

BIN
Library/ServiceAdaptor.NetCore.Be.Eureka/dll/EurekaRestTemplate.dll


BIN
Library/ServiceAdaptor.NetCore.Be.Eureka/dll/Steeltoe.Discovery.ClientAutofac.dll


BIN
Library/ServiceAdaptor.NetCore.Be.Eureka/dll/Steeltoe.Discovery.ClientCore.dll


BIN
Library/ServiceAdaptor.NetCore.Be.Eureka/dll/Steeltoe.Discovery.EurekaBase.dll


BIN
Library/ServiceAdaptor.NetCore.Be.Eureka/dll/cn.jpush.api.dll


BIN
Library/ServiceAdaptor.NetCore.Be.Eureka/dll/cn.jpush.api.dll.refresh


+ 80 - 0
Library/ServiceAdaptor.NetCore.Consul/ApiClient.cs

@@ -0,0 +1,80 @@
+using Consul;
+using ServiceAdaptor.NetCore.Client;
+using System;
+using System.Linq;
+using System.Net;
+using System.Threading.Tasks;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Consul
+{
+    public class ApiClient : global::ServiceAdaptor.NetCore.MinHttp.ApiClient
+    {
+        public ApiClient(string ConsulAddress) 
+        {
+            this.ConsulAddress = ConsulAddress;
+        }
+
+
+        /// <summary>
+        ///  http://127.0.0.1:8500
+        /// </summary>
+        string ConsulAddress;
+
+
+        #region FindServiceByServiceName
+
+        async Task<CatalogService> FindServiceByServiceNameAsync(string serviceName) 
+        {
+            using (var consulClient = new ConsulClient(a => a.Address = new Uri(ConsulAddress)))
+            {         
+                var services = (await consulClient.Catalog.Service(serviceName)).Response;
+                if (services != null && services.Any())
+                {
+                    // 模拟随机一台进行请求,这里只是测试,可以选择合适的负载均衡工具或框架
+                    Random r = new Random();
+                    int index = r.Next(services.Count());
+                    var service = services.ElementAt(index);
+                    return service;
+                    //using (HttpClient client = new HttpClient())
+                    //{
+                    //    var response = await client.GetAsync($"http://{service.ServiceAddress}:{service.ServicePort}/values/test");
+                    //    var result = await response.Content.ReadAsStringAsync();
+                    //    return result;
+                    //}
+                }
+                return null;
+            } 
+        }
+        #endregion
+
+
+
+ 
+        #region ApiEvent
+        class ApiEvent : IApiEvent
+        {
+            public ApiClient apiClient;
+            public async Task<ApiResponse<ReturnType>> BeforeCallApi<ReturnType>(ApiRequest req)
+            {
+                var serviceInfo = await apiClient.FindServiceByServiceNameAsync(req.GetServiceName());
+                if (serviceInfo == null)
+                {
+                    return new ApiResponse<ReturnType> { StatusCode = (int)HttpStatusCode.NotFound };
+                }
+                req.url = "http://" + serviceInfo.ServiceAddress + ":" + serviceInfo.ServicePort + req.url;
+                return null;
+            }
+        }
+        #endregion
+
+
+
+        public ApiClient()
+        {
+            this.AddEvent(new ApiEvent { apiClient = this });
+        }       
+
+
+    }
+}

+ 34 - 0
Library/ServiceAdaptor.NetCore.Consul/ServiceAdaptor.NetCore.Consul.csproj

@@ -0,0 +1,34 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<pack/>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<TargetFramework>netstandard2.0</TargetFramework>
+		<Version>1.3.4</Version>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<Authors>Lith</Authors>
+		<Description>微服务适配器</Description>
+		<PackageProjectUrl>https://github.com/serset/ServiceAdaptor.NetCore</PackageProjectUrl>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<DocumentationFile>bin\Debug\netstandard2.0\ServiceAdaptor.NetCore.Consul.xml</DocumentationFile>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="Consul" Version="0.7.2.6" />
+		<PackageReference Include="Vit.WebHost" Version="2.1.5" />
+	</ItemGroup>
+
+
+	<ItemGroup>
+		<ProjectReference Include="..\ServiceAdaptor.NetCore.MinHttp\ServiceAdaptor.NetCore.MinHttp.csproj" />
+		<ProjectReference Include="..\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj" />
+	</ItemGroup>
+
+
+</Project>

+ 165 - 0
Library/ServiceAdaptor.NetCore.Consul/ServiceAdaptor.cs

@@ -0,0 +1,165 @@
+using Consul;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json.Linq;
+using ServiceAdaptor.NetCore.Client;
+using System;
+using System.Threading.Tasks;
+using Vit.Core.Module.Log;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Consul
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public class ServiceAdaptor : IServiceAdaptor
+    {
+        //参考 https://www.jianshu.com/p/4aaaee6e9ce1
+
+        #region config Model
+        internal class ConsulConfig
+        {
+            /// <summary>
+            /// consul的地址。如 http://127.0.0.1:8500
+            /// </summary>
+            public string ConsulEndpoint;
+
+            /// <summary>
+            /// 提供的服务的地址,如 127.0.0.1、sers.cloud
+            /// </summary>
+            public string serviceHost;
+            /// <summary>
+            /// 提供的服务的端口号
+            /// </summary>
+            public int servicePort;
+            /// <summary>
+            /// 提供的服务的名称,如 ServiceProvider
+            /// </summary>
+            public string serviceName;
+
+            public string serviceId => $"ID_{serviceHost}:{servicePort}/{serviceName}";
+            public string healthCheckUrl => "/_Consul_/HealthCheck";
+        }
+        #endregion
+
+
+
+
+        public IWebHostBuilder InitWebHostBuilder(IWebHostBuilder builder, JObject config, out IApiClient apiClient)
+        {
+            var consulConfig = config.ConvertBySerialize<ConsulConfig>();
+
+            var httpApi = new ApiClient(consulConfig.ConsulEndpoint);
+            apiClient = httpApi;
+
+
+            #region 超时时间
+            var timeoutSeconds = config["timeoutSeconds"].ConvertBySerialize<int?>();
+            if (timeoutSeconds.HasValue)
+            {
+                httpApi.vitHttpClient.TimeoutSeconds = timeoutSeconds.Value;
+            }
+            #endregion
+
+
+            builder.ConfigureServices((WebHostBuilderContext context, IServiceCollection services) =>
+            {
+                services.AddSingleton<IConsulClient>(sp => new global::Consul.ConsulClient(c =>
+                {
+                    c.Address = new Uri(consulConfig.ConsulEndpoint);
+                }));
+
+            }).ConfigureApp(app =>
+            {
+                Logger.Info("[ServiceAdaptor.NetCore.Consul]注册... ");
+
+                Logger.Info("[ServiceAdaptor.NetCore.Consul]配置:" + consulConfig.Serialize());
+
+                #region Configure
+
+                #region (x.1) 注册Consul服务         
+
+                var serviceProvider = app.ApplicationServices;
+
+                //(x.x.1)向Consul注册服务
+                IConsulClient consul = serviceProvider.GetRequiredService<IConsulClient>();
+                IApplicationLifetime appLife = serviceProvider.GetRequiredService<IApplicationLifetime>();
+
+                var registration = new AgentServiceRegistration()
+                {
+                    Checks = new[] {
+                        new AgentServiceCheck()
+                        {
+                            DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1),
+                            Interval = TimeSpan.FromSeconds(30),
+                            HTTP = $"{Uri.UriSchemeHttp}://{consulConfig.serviceHost}:{consulConfig.servicePort}{consulConfig.healthCheckUrl}",
+                        }
+                    },
+                    Address = consulConfig.serviceHost,
+                    ID = consulConfig.serviceId,
+                    Name = consulConfig.serviceName,
+                    Port = consulConfig.servicePort
+                };
+                try
+                {
+                    var result = consul.Agent.ServiceRegister(registration).GetAwaiter().GetResult();
+
+                    if ((result?.StatusCode) != System.Net.HttpStatusCode.OK)
+                    {
+                        Logger.Info("[ServiceAdaptor.NetCore.Consul]注册失败!");
+                        Task.Run(() =>
+                        {
+                            appLife.StopApplication();
+                        });
+                        return;
+                    }
+                }
+                catch (Exception ex)
+                {
+                    Logger.Error(ex);
+
+                    Logger.Info("[ServiceAdaptor.NetCore.Consul]注册失败!");
+                    Task.Run(() =>
+                    {
+                        appLife.StopApplication();
+                    });
+                    return;
+                    //throw;
+                }
+
+
+
+                //(x.x.2)send consul request after service stop
+                appLife.ApplicationStopping.Register(() =>
+                {
+                    consul.Agent.ServiceDeregister(consulConfig.serviceId).GetAwaiter().GetResult();
+                });
+                #endregion
+
+
+
+                #region (x.2) 添加健康检查接口              
+                app.Map(consulConfig.healthCheckUrl, s =>
+                {
+                    s.Run(async context =>
+                    {
+                        await context.Response.WriteAsync("ok");
+                    });
+                });
+                #endregion
+
+
+
+                #endregion
+
+                Logger.Info("[ServiceAdaptor.NetCore.Consul]注册成功!");
+
+            });
+
+            return builder;
+        }
+    }
+}

+ 93 - 0
Library/ServiceAdaptor.NetCore.MinHttp/ApiClient.cs

@@ -0,0 +1,93 @@
+#region << 版本注释-v1 >>
+/*
+ * ========================================================================
+ * 版本:v1
+ * 时间:2020-04-03
+ * 说明: 
+ * ========================================================================
+*/
+#endregion
+
+
+using ServiceAdaptor.NetCore.Client;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Vit.Core.Util.Net;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.MinHttp
+{
+    public class ApiClient : IApiClient
+    {
+
+        public readonly HttpClient vitHttpClient = new HttpClient();
+
+        public List<IApiEvent> apiEvents { get; set; }
+
+
+
+        #region CallApi
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="req"></param>
+        /// <returns></returns>
+        public virtual ApiResponse<ReturnType> CallApi<ReturnType>(ApiRequest req) 
+        {
+            //(x.0)BeforeCallApi
+            var apiResponse = this.BeforeCallApi<ReturnType>(req).Result;
+            if (apiResponse != null) return apiResponse;
+
+
+            var request = new HttpRequest { url = req.url, body = req.arg, httpMethod = req.httpMethod, headers = req.headers };
+
+            if (request.body != null && request.httpMethod == "GET")
+            {
+                request.url = HttpClient.UrlAddParams(request.url, request.body);
+                request.body = null;
+            }
+
+            var response = vitHttpClient.Send<ReturnType>(request);
+            if (response == null)
+            {
+                return null;
+            }
+            return new ApiResponse<ReturnType> { StatusCode= response.StatusCode,data= response.data,headers= response.headers};
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="req"></param>
+        /// <returns></returns>
+        public virtual async Task<ApiResponse<ReturnType>> CallApiAsync<ReturnType>(ApiRequest req)
+        {
+            //(x.0)BeforeCallApi
+            var apiResponse = this.BeforeCallApi<ReturnType>(req).Result;
+            if (apiResponse != null) return apiResponse;
+
+            var request = new HttpRequest { url = req.url, body = req.arg, httpMethod = req.httpMethod, headers = req.headers };
+
+            if (request.body != null && request.httpMethod == "GET")
+            {
+                request.url = HttpClient.UrlAddParams(request.url, request.body);
+                request.body = null;
+            }
+
+            var response = await vitHttpClient.SendAsync<ReturnType>(request);
+            if (response == null)
+            {
+                return null;
+            }
+            return new ApiResponse<ReturnType> { StatusCode = response.StatusCode, data = response.data, headers = response.headers };
+        }
+
+        #endregion
+
+
+
+    }
+}

+ 26 - 0
Library/ServiceAdaptor.NetCore.MinHttp/ServiceAdaptor.NetCore.MinHttp.csproj

@@ -0,0 +1,26 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<pack/>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<TargetFramework>netstandard2.0</TargetFramework>
+		<Version>1.3.4</Version>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<Authors>Lith</Authors>
+		<Description>微服务适配器</Description>
+		<PackageProjectUrl>https://github.com/serset/ServiceAdaptor.NetCore</PackageProjectUrl>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<DocumentationFile>bin\Debug\netstandard2.0\ServiceAdaptor.NetCore.MinHttp.xml</DocumentationFile>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<ProjectReference Include="..\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj" />
+	</ItemGroup>
+
+</Project>

+ 42 - 0
Library/ServiceAdaptor.NetCore.MinHttp/ServiceAdaptor.cs

@@ -0,0 +1,42 @@
+using Microsoft.AspNetCore.Hosting;
+using Newtonsoft.Json.Linq;
+using ServiceAdaptor.NetCore.Client;
+using Vit.Core.Module.Log;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.MinHttp
+{
+    public class ServiceAdaptor : IServiceAdaptor
+    {
+        public IWebHostBuilder InitWebHostBuilder(IWebHostBuilder builder, JObject config, out IApiClient apiClient)
+        {       
+
+            #region (x.)构建ApiClient     
+
+            var httpApi = new ApiClient();
+            apiClient = httpApi;
+
+
+            #region (x.x.1)gatewayAddress
+            var gatewayAddress = config["gatewayAddress"].ConvertToString();
+            httpApi.vitHttpClient.BaseAddress = gatewayAddress;
+            #endregion
+
+
+            #region (x.x.2)超时时间
+            var timeoutSeconds = config["timeoutSeconds"].ConvertBySerialize<int?>(); 
+            if (timeoutSeconds.HasValue)
+            {
+                httpApi.vitHttpClient.TimeoutSeconds = timeoutSeconds.Value;
+            }
+            #endregion
+
+            #endregion
+
+            Logger.Info("[ServiceAdaptor.NetCore.MinHttp]配置:" + new { gatewayAddress }.Serialize());
+
+
+            return builder;
+        }
+    }
+}

+ 157 - 0
Library/ServiceAdaptor.NetCore.Sers/ApiClient.cs

@@ -0,0 +1,157 @@
+#region << 版本注释-v4 >>
+/*
+ * ========================================================================
+ * 版本:v4
+ * 时间:2020-04-09
+ * 说明: 
+ * ========================================================================
+*/
+#endregion
+
+
+using Sers.Core.Module.Message;
+using Sers.Core.Module.Rpc;
+using ServiceAdaptor.NetCore.Client;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Vit.Core.Util.Net;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Sers
+{
+    public class ApiClient : IApiClient
+    {
+
+        public List<IApiEvent> apiEvents { get; set; }
+
+
+        #region CallApi
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="req"></param>
+        /// <returns></returns>
+        public ApiResponse<ReturnType> CallApi<ReturnType>(ApiRequest req)
+        {
+            //(x.0)BeforeCallApi
+            var apiResponse = this.BeforeCallApi<ReturnType>(req).Result;
+            if (apiResponse != null) return apiResponse;
+
+
+            #region (x.1)构建请求           
+            var url = req.url;
+            var arg = req.arg;
+            if (arg != null && req.httpMethod == "GET")
+            {
+                url = HttpClient.UrlAddParams(url, arg);
+                arg = null;
+            }
+
+
+            #region init rpc
+            Action<RpcContextData> InitRpc = null;
+            if (req.headers == null)
+            {
+                req.headers = new Dictionary<string, string>();
+            }
+            req.headers.IDictionaryTryAdd("Content-Type", "application/json");            
+            InitRpc =
+                rpcData =>
+                {
+                    var header = rpcData.http.Headers();
+                    foreach (var item in req.headers)
+                    {
+                        header[item.Key]= item.Value;
+                    }
+                };
+
+            #endregion
+
+            ApiMessage request = new ApiMessage().InitAsApiRequestMessage(url, arg, req.httpMethod, InitRpc);         
+
+            #endregion
+
+            //(x.2)发送请求
+            ApiMessage response = global::Sers.Core.Module.Api.ApiClient.CallRemoteApi(request);
+
+            #region (x.3)处理回应           
+            var replyRpcData = RpcContextData.FromBytes(response.rpcContextData_OriData);             
+
+            return new ApiResponse<ReturnType>
+            {
+                StatusCode = replyRpcData.http.statusCode?? 0,
+                data = response.value_OriData.DeserializeFromArraySegmentByte<ReturnType>(),
+                headers = replyRpcData.http.headers
+            };
+            #endregion
+
+        }
+
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="req"></param>
+        /// <returns></returns>
+        public async Task<ApiResponse<ReturnType>> CallApiAsync<ReturnType>(ApiRequest req)
+        {
+            //(x.0)BeforeCallApi
+            var apiResponse = this.BeforeCallApi<ReturnType>(req).Result;
+            if (apiResponse != null) return apiResponse;
+
+
+            #region (x.1)构建请求           
+            var url = req.url;
+            var arg = req.arg;
+            if (arg != null && req.httpMethod == "GET")
+            {
+                url = HttpClient.UrlAddParams(url, arg);
+                arg = null;
+            }
+
+            #region init rpc
+            Action<RpcContextData> InitRpc = null;
+            if (req.headers == null)
+            {
+                req.headers = new Dictionary<string, string>();
+            }
+            req.headers.IDictionaryTryAdd("Content-Type", "application/json");
+
+            InitRpc =
+                rpcData =>
+                {
+                    var header = rpcData.http.Headers();
+                    foreach (var item in req.headers)
+                    {
+                        header[item.Key] = item.Value;
+                    }
+                };
+            #endregion
+            ApiMessage request = new ApiMessage().InitAsApiRequestMessage(url, arg, req.httpMethod, InitRpc);
+            #endregion
+
+            //(x.2)发送请求
+            ApiMessage response = await global::Sers.Core.Module.Api.ApiClient.CallRemoteApiAsync(request);
+
+            #region (x.3)处理回应           
+            var replyRpcData =  RpcContextData.FromBytes(response.rpcContextData_OriData);
+
+            return new ApiResponse<ReturnType>
+            {
+                StatusCode = replyRpcData.http.statusCode ?? 200,
+                data = response.value_OriData.DeserializeFromArraySegmentByte<ReturnType>(),
+                headers = replyRpcData.http.headers
+            };
+            #endregion
+
+        }
+
+        #endregion
+
+
+    }
+}

+ 32 - 0
Library/ServiceAdaptor.NetCore.Sers/ServiceAdaptor.NetCore.Sers.csproj

@@ -0,0 +1,32 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<pack/>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<TargetFramework>netstandard2.0</TargetFramework>
+		<Version>1.3.4</Version>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<Authors>Lith</Authors>
+		<Description>微服务适配器</Description>
+		<PackageProjectUrl>https://github.com/serset/ServiceAdaptor.NetCore</PackageProjectUrl>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<DocumentationFile>bin\Debug\netstandard2.0\ServiceAdaptor.NetCore.Sers.xml</DocumentationFile>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<!-- Sers -->
+		<PackageReference Include="Sers.Serslot" Version="2.1.5.701" />
+	</ItemGroup>
+
+	<ItemGroup>
+		<ProjectReference Include="..\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj" />
+	</ItemGroup>
+
+
+</Project>

+ 19 - 0
Library/ServiceAdaptor.NetCore.Sers/ServiceAdaptor.cs

@@ -0,0 +1,19 @@
+using Microsoft.AspNetCore.Hosting;
+using Newtonsoft.Json.Linq;
+using ServiceAdaptor.NetCore.Client;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Sers
+{
+    public class ServiceAdaptor : IServiceAdaptor
+    {
+        public IWebHostBuilder InitWebHostBuilder(IWebHostBuilder builder, JObject config, out IApiClient apiClient)
+        {
+            apiClient = new ApiClient();
+
+            builder.UseSerslot();
+
+            return builder;
+        }
+    }
+}

+ 140 - 0
Library/ServiceAdaptor.NetCore/Client/ApiClient.cs

@@ -0,0 +1,140 @@
+#region << 版本注释-v1 >>
+/*
+ * ========================================================================
+ * 版本:v1
+ * 时间:2020-04-03
+ * 说明: 
+ * ========================================================================
+*/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Vit.Extensions;
+
+namespace ServiceAdaptor.NetCore.Client
+{
+
+    public class ApiClient
+    {
+
+        public static IApiClient Instance { get; internal set; } 
+        
+
+        #region CallApi
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <param name="headers"></param>
+        /// <returns></returns>
+        public static async Task<ReturnType> CallApiAsync<ReturnType>(string route, Object arg, string httpMethod = null, IDictionary<string, string> headers=null)
+        {
+            var response = await Instance.CallApiAsync<ReturnType>(new ApiRequest { url = route, arg = arg, httpMethod = httpMethod, headers= headers });
+            if (response == null)
+            {
+                return default;
+            }
+            return response.data;
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <returns></returns>
+        public static ReturnType CallApi<ReturnType>(string route, Object arg, string httpMethod = null)
+        {
+            var response = Instance.CallApi<ReturnType>(new ApiRequest { url = route, arg = arg, httpMethod = httpMethod });
+            if (response == null) 
+            {
+                return default;
+            }
+            return response.data;
+        }
+
+        #endregion
+
+
+        #region CallVitApi
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <returns></returns>
+        public static void CallVitApi(string route, Object arg, string httpMethod = null)
+        {
+            Instance.CallVitApi(route, arg, httpMethod);
+        }
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>     
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <returns></returns>
+        public static async Task CallVitApiAsync(string route, Object arg, string httpMethod = null)
+        {
+            await Instance.CallVitApiAsync(route, arg, httpMethod);
+        }
+
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <returns></returns>
+        public static ReturnType CallVitApi<ReturnType>(string route, Object arg, string httpMethod = null)
+        {
+            return Instance.CallVitApi<ReturnType>(route, arg, httpMethod);
+        }
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <returns></returns>
+        public static async Task<ReturnType> CallVitApiAsync<ReturnType>(string route, Object arg, string httpMethod = null)
+        {
+            return await Instance.CallVitApiAsync<ReturnType>(route, arg, httpMethod);
+        }
+
+        #endregion
+
+
+
+
+        #region httpMethod
+        public const string Get = "GET";
+        public const string Post = "POST";
+        public const string Delete = "DELETE";
+        public const string Put = "PUT";
+        public const string Patch = "PATCH";
+        #endregion
+
+
+
+
+    }
+}

+ 36 - 0
Library/ServiceAdaptor.NetCore/Client/ApiRequest.cs

@@ -0,0 +1,36 @@
+#region << 版本注释-v1 >>
+/*
+ * ========================================================================
+ * 版本:v1
+ * 时间:2020-04-03
+ * 说明: 
+ * ========================================================================
+*/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+
+namespace ServiceAdaptor.NetCore.Client
+{
+    public class ApiRequest:Vit.Core.Util.Extensible.Extensible
+    {
+        /// <summary>
+        /// 为相对路径,如 "/api/Values/get"
+        /// </summary>
+        public string url;
+        /// <summary>
+        /// 
+        /// </summary>
+        public Object arg;
+        /// <summary>
+        /// 可为 GET、POST、DELETE、PUT等,可不指定
+        /// </summary>
+        public string httpMethod;
+        /// <summary>
+        /// 
+        /// </summary>
+        public IDictionary<string, string> headers;
+    }
+}

+ 32 - 0
Library/ServiceAdaptor.NetCore/Client/ApiResponse.cs

@@ -0,0 +1,32 @@
+#region << 版本注释-v1 >>
+/*
+ * ========================================================================
+ * 版本:v1
+ * 时间:2020-04-03
+ * 说明: 
+ * ========================================================================
+*/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+
+namespace ServiceAdaptor.NetCore.Client
+{
+    public class ApiResponse<T> : Vit.Core.Util.Extensible.Extensible
+    {
+        public T data;
+
+        public int StatusCode = 200;
+
+        public IDictionary<string, string> headers;
+
+        /// <summary>
+        /// 返回结果:
+        ///     A value that indicates if the HTTP response was successful. true if System.Net.Http.HttpResponseMessage.StatusCode
+        ///     was in the range 200-299; otherwise false.
+        /// </summary>
+        public bool IsSuccessStatusCode => StatusCode >= 200 && StatusCode <= 299;
+    }
+}

+ 261 - 0
Library/ServiceAdaptor.NetCore/Client/Extendsions/IApiClientExtensions.cs

@@ -0,0 +1,261 @@
+#region << 版本注释-v1 >>
+/*
+ * ========================================================================
+ * 版本:v1
+ * 时间:2020-04-03
+ * 说明: 
+ * ========================================================================
+*/
+#endregion
+
+
+using ServiceAdaptor.NetCore.Client;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Vit.Core.Util.ComponentModel.Data;
+
+namespace Vit.Extensions
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public static partial class IApiClientExtensions
+    {
+
+        #region Event
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="Instance"></param>
+        /// <param name="apiEvent"></param>
+        public static void AddEvent(this IApiClient Instance, IApiEvent apiEvent)
+        {
+            if (Instance.apiEvents == null) Instance.apiEvents = new System.Collections.Generic.List<IApiEvent>();
+            Instance.apiEvents.Add(apiEvent);
+        }
+
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="Instance"></param>
+        /// <param name="apiEvent"></param>
+        public static void RemoveEvent(this IApiClient Instance, IApiEvent apiEvent)
+        {
+            Instance.apiEvents?.Remove(apiEvent);
+        }
+
+
+        public static async Task<ApiResponse<ReturnType>> BeforeCallApi<ReturnType>(this IApiClient apiClient, ApiRequest req)
+        {
+            if (apiClient.apiEvents != null)
+            {
+                foreach (var apiEvent in apiClient.apiEvents)
+                {
+                    var apiResponse = await apiEvent.BeforeCallApi<ReturnType>(req);
+                    if (apiResponse != null) return apiResponse;
+                }
+            }
+            return null;
+        }
+        #endregion
+
+
+
+
+        #region CallApi
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="Instance"></param>
+        /// <param name="url"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <param name="headers">请求的header,可不指定</param>
+        /// <returns></returns>
+        public static ReturnType CallApi<ReturnType>(this IApiClient Instance, string url, Object arg,
+            string httpMethod = null, IDictionary<string, string> headers = null)
+        {
+            var response = Instance.CallApi<ReturnType>(new ApiRequest { url = url, arg = arg, httpMethod = httpMethod, headers = headers });
+            if (response == null)
+            {
+                return default;
+            }
+            return response.data;
+        }
+
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="Instance"></param>
+        /// <param name="url"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <param name="headers">请求的header,可不指定</param>
+        /// <returns></returns>
+        public static async Task<ReturnType> CallApiAsync<ReturnType>(this IApiClient Instance, string url, Object arg,
+            string httpMethod = null, IDictionary<string, string> headers = null)
+        {
+            var response = await Instance.CallApiAsync<ReturnType>(new ApiRequest { url = url, arg = arg, httpMethod = httpMethod, headers = headers });
+            if (response == null)
+            {
+                return default;
+            }
+            return response.data;
+        }
+
+        #endregion
+
+
+
+        #region CallVitApi by ApiRequest
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary> 
+        /// <param name="Instance"></param>
+        /// <param name="arg"></param>
+        /// <returns></returns>
+        public static void CallVitApi(this IApiClient Instance, ApiRequest arg)
+        {
+            var apiRet = Instance.CallApi<ApiReturn>(arg)?.data;
+            if (apiRet?.success != true)
+            {
+                throw (apiRet?.error).ToException("服务出错");
+            }   
+        }
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <param name="Instance"></param>
+        /// <param name="arg"></param>
+        /// <returns></returns>
+        public static async Task CallVitApiAsync(this IApiClient Instance, ApiRequest arg)
+        {
+            var apiRet = (await Instance.CallApiAsync<ApiReturn>(arg))?.data;
+            if (apiRet?.success != true)
+            {
+                throw (apiRet?.error).ToException("服务出错");
+            }      
+        }
+
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="Instance"></param>
+        /// <param name="arg"></param>
+        /// <returns></returns>
+        public static ReturnType CallVitApi<ReturnType>(this IApiClient Instance, ApiRequest arg)
+        {
+            var apiRet = Instance.CallApi<ApiReturn<ReturnType>>(arg)?.data;
+            if (apiRet?.success != true)
+            {
+                throw (apiRet?.error).ToException("服务出错");
+            }
+            return apiRet.data;
+        }
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="Instance"></param>
+        /// <param name="arg"></param>
+        /// <returns></returns>
+        public static async Task<ReturnType> CallVitApiAsync<ReturnType>(this IApiClient Instance, ApiRequest arg)
+        {
+            var apiRet = (await Instance.CallApiAsync<ApiReturn<ReturnType>>(arg))?.data;
+            if (apiRet?.success != true)
+            {
+                throw (apiRet?.error).ToException("服务出错");
+            }
+            return apiRet.data;
+        }
+
+
+        #endregion
+
+        #region CallVitApi by route arg httpMethod headers
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <param name="Instance"></param>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <param name="headers">请求的header,可不指定</param>
+        /// <returns></returns>
+        public static void CallVitApi(this IApiClient Instance, string route, Object arg,
+            string httpMethod = null, IDictionary<string, string> headers = null)
+        {
+            CallVitApi(Instance, new ApiRequest { url = route, arg = arg, httpMethod = httpMethod, headers = headers });
+        }
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <param name="Instance"></param>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <param name="headers">请求的header,可不指定</param>
+        /// <returns></returns>
+        public static async Task CallVitApiAsync(this IApiClient Instance, string route, Object arg,
+            string httpMethod = null, IDictionary<string, string> headers = null)
+        {
+            await CallVitApiAsync(Instance, new ApiRequest { url = route, arg = arg, httpMethod = httpMethod, headers = headers });
+        }
+
+
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="Instance"></param>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <param name="headers">请求的header,可不指定</param>
+        /// <returns></returns>
+        public static ReturnType CallVitApi<ReturnType>(this IApiClient Instance, string route, Object arg,
+            string httpMethod = null, IDictionary<string, string> headers = null)
+        {
+            return CallVitApi<ReturnType>(Instance, new ApiRequest { url = route, arg = arg, httpMethod = httpMethod, headers = headers });
+        }
+
+
+        /// <summary>
+        /// 接口返回数据为 ApiReturn格式,若接口返回不成功(apiRet?.success != true),则直接抛异常。
+        /// </summary>
+        /// <typeparam name="ReturnType"></typeparam>
+        /// <param name="Instance"></param>
+        /// <param name="route"></param>
+        /// <param name="arg"></param>
+        /// <param name="httpMethod">可为 GET、POST、DELETE、PUT等,可不指定</param>
+        /// <param name="headers">请求的header,可不指定</param>
+        /// <returns></returns>
+        public static async Task<ReturnType> CallVitApiAsync<ReturnType>(this IApiClient Instance, string route, Object arg,
+            string httpMethod = null, IDictionary<string, string> headers = null)
+        {
+            return await CallVitApiAsync<ReturnType>(Instance, new ApiRequest { url = route, arg = arg, httpMethod = httpMethod, headers = headers });
+        }
+
+        #endregion
+
+    }
+}

+ 39 - 0
Library/ServiceAdaptor.NetCore/Client/IApiClient.cs

@@ -0,0 +1,39 @@
+#region << 版本注释-v1 >>
+/*
+ * ========================================================================
+ * 版本:v1
+ * 时间:2020-04-03
+ * 说明: 
+ * ========================================================================
+*/
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace ServiceAdaptor.NetCore.Client
+{
+
+    public interface IApiClient
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="req"></param>
+        /// <returns></returns>
+        ApiResponse<ReturnType> CallApi<ReturnType>(ApiRequest req);
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="req"></param>
+        /// <returns></returns>
+        Task<ApiResponse<ReturnType>> CallApiAsync<ReturnType>(ApiRequest req);
+
+
+        List<IApiEvent> apiEvents{ get; set; }
+
+    }
+}

+ 20 - 0
Library/ServiceAdaptor.NetCore/Client/IApiEvent.cs

@@ -0,0 +1,20 @@
+#region << 版本注释-v1 >>
+/*
+ * ========================================================================
+ * 版本:v1
+ * 时间:2020-04-03
+ * 说明: 
+ * ========================================================================
+*/
+#endregion
+
+
+using System.Threading.Tasks;
+
+namespace ServiceAdaptor.NetCore.Client
+{
+    public interface IApiEvent
+    {
+        Task<ApiResponse<ReturnType>> BeforeCallApi<ReturnType>(ApiRequest req);
+    }
+}

+ 25 - 0
Library/ServiceAdaptor.NetCore/Extensions/ApiRequestExtensions.cs

@@ -0,0 +1,25 @@
+using ServiceAdaptor.NetCore.Client;
+
+namespace Vit.Extensions
+{
+    public static class ApiRequestExtensions
+    {
+        
+        public static string GetServiceName(this ApiRequest data)
+        {
+            var serviceName= data.GetData<string>("serviceName");
+
+            if (string.IsNullOrEmpty(serviceName)) 
+            {
+                var apiStation = data.url.Split('/')[1];
+                return  apiStation; 
+            }
+            return serviceName;
+        }
+
+        public static void SetServiceName(this ApiRequest data,string serviceName)
+        {
+            data.SetData("serviceName", serviceName);
+        }
+    }
+}

+ 74 - 0
Library/ServiceAdaptor.NetCore/Extensions/IWebHostBuilderExtensions_UseServiceAdaptor.cs

@@ -0,0 +1,74 @@
+using System;
+using Microsoft.AspNetCore.Hosting;
+using Vit.Core.Util.ConfigurationManager;
+using Newtonsoft.Json.Linq;
+using Vit.Core.Module.Log;
+using ServiceAdaptor.NetCore.Client;
+using ServiceAdaptor.NetCore;
+using Vit.Core.Util.Reflection;
+
+namespace Vit.Extensions
+{
+    public static class IWebHostBuilderExtensions_UseServiceAdaptor
+    {
+        
+        public static IWebHostBuilder UseServiceAdaptor(this IWebHostBuilder hostBuilder)
+        {
+            var configs = ConfigurationManager.Instance.GetByPath<JArray>("ServiceAdaptor");
+            if (configs  == null|| configs.Count==0)
+            {
+                return hostBuilder;
+            }
+
+            foreach (JObject msConfig in configs)
+            {
+                try
+                {
+                    //(x.1) GetInstance
+                    IServiceAdaptor msAdaptor = GetInstance(msConfig);
+                    if (msAdaptor == null) continue;
+
+
+                    //(x.2) init
+                    Logger.Info("[ServiceAdaptor.NetCore]启用微服务适配器:"+ msAdaptor.GetType().FullName);
+                    var builder = msAdaptor.InitWebHostBuilder(hostBuilder, msConfig, out var apiClient);
+                    ApiClient.Instance = apiClient;
+
+                    return builder;
+                }
+                catch (Exception ex)
+                {
+                    Logger.Error(ex);                  
+                }
+            }
+
+            return hostBuilder;
+
+
+            #region GetInstance
+            IServiceAdaptor GetInstance(JObject config)
+            {
+                //(x.1) get className    
+                var className = config["className"].ConvertToString();
+                if (string.IsNullOrEmpty(className)) return null;
+
+                var assemblyFile = config["assemblyFile"].ConvertToString();
+                if (string.IsNullOrEmpty(assemblyFile)) return null;
+ 
+
+                //(x.2)get assembly 
+                var assembly = ObjectLoader.LoadAssemblyFromFile(assemblyFile);              
+
+                //(x.3) create class
+                return assembly?.CreateInstance(className) as IServiceAdaptor;
+            }
+            #endregion
+        }
+
+
+
+
+
+    
+    }
+}

+ 11 - 0
Library/ServiceAdaptor.NetCore/IServiceAdaptor.cs

@@ -0,0 +1,11 @@
+using Microsoft.AspNetCore.Hosting;
+using Newtonsoft.Json.Linq;
+using ServiceAdaptor.NetCore.Client;
+
+namespace ServiceAdaptor.NetCore
+{
+    public interface IServiceAdaptor
+    {
+        IWebHostBuilder InitWebHostBuilder(IWebHostBuilder builder, JObject config,out IApiClient apiClient);
+    }
+}

+ 13 - 0
Library/ServiceAdaptor.NetCore/Properties/PublishProfiles/FolderProfile.pubxml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+https://go.microsoft.com/fwlink/?LinkID=208121. 
+-->
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <PublishProtocol>FileSystem</PublishProtocol>
+    <Configuration>Release</Configuration>
+    <Platform>Any CPU</Platform>
+    <TargetFramework>netstandard2.0</TargetFramework>
+    <PublishDir>bin\Release\netstandard2.0\publish\</PublishDir>
+  </PropertyGroup>
+</Project>

+ 32 - 0
Library/ServiceAdaptor.NetCore/ServiceAdaptor.NetCore.csproj

@@ -0,0 +1,32 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+	<PropertyGroup>
+		<pack/>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<TargetFramework>netstandard2.0</TargetFramework>
+		<Version>1.3.4</Version>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<Authors>Lith</Authors>
+		<Description>微服务适配器</Description>
+		<PackageProjectUrl>https://github.com/serset/ServiceAdaptor.NetCore</PackageProjectUrl>
+	</PropertyGroup>
+
+	<PropertyGroup>
+		<DocumentationFile>bin\Debug\netstandard2.0\ServiceAdaptor.NetCore.xml</DocumentationFile>
+	</PropertyGroup>
+
+	<ItemGroup>
+		<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.1.0" />
+
+		<!-- Sers -->
+		<PackageReference Include="Vit.Core" Version="2.1.5" />
+	</ItemGroup>
+
+
+
+
+</Project>

+ 19 - 0
Library/ServiceAdaptor/ServiceAdaptor.csproj

@@ -0,0 +1,19 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>netstandard2.0</TargetFramework>
+    <Version>1.0.0.0-preview</Version>
+    <Description>https://github.com/serset/ServiceAdaptor/tree/1.0/release</Description>
+  </PropertyGroup>
+
+	<PropertyGroup>
+		<Authors>Lith</Authors>
+		<Description>微服务适配器</Description>
+		<PackageProjectUrl>https://github.com/serset/ServiceAdaptor.NetCore</PackageProjectUrl>
+	</PropertyGroup>
+
+  <PropertyGroup>
+    <DocumentationFile>bin\Debug\netstandard2.0\ServiceAdaptor.xml</DocumentationFile>
+  </PropertyGroup>
+
+</Project>

+ 38 - 0
Publish/DevOps/github/30.nuget-pack.sh

@@ -0,0 +1,38 @@
+set -e
+
+# bash 30.nuget-pack.sh
+
+
+#---------------------------------------------------------------------
+#(x.1)参数
+args_="
+
+export codePath=/root/temp/svn
+
+# "
+
+mkdir -p $codePath/Publish/release/release/nuget
+nugetPath=Publish/release/release/nuget
+
+
+
+#----------------------------------------------
+echo "(x.2)nuget-pack"
+docker run -i --rm \
+--env LANG=C.UTF-8 \
+-v $codePath:/root/code \
+serset/dotnet:6.0-sdk \
+bash -c "
+cd /root/code
+for file in \$(grep -a '<pack/>' . -rl --include *.csproj)
+do
+	echo pack \$file
+	cd /root/code
+	cd \$(dirname \"\$file\")
+	dotnet build --configuration Release
+	dotnet pack --configuration Release --output '/root/code/$nugetPath'
+done
+" 
+
+
+ 

+ 35 - 0
Publish/DevOps/github/31.nuget-push.sh

@@ -0,0 +1,35 @@
+set -e
+
+
+
+#---------------------------------------------------------------------
+#(x.1)参数
+args_="
+
+export codePath=/root/temp/svn
+
+export NUGET_SERVER=https://api.nuget.org/v3/index.json
+export NUGET_KEY=xxxxxxxxxx
+
+# "
+
+
+nugetPath=Publish/release/release/nuget
+ 
+
+#----------------------------------------------
+echo "(x.2)nuget-push"
+docker run -i --rm \
+--env LANG=C.UTF-8 \
+-v $codePath:/root/code \
+serset/dotnet:6.0-sdk \
+bash -c "
+for file in /root/code/$nugetPath/*.nupkg
+do
+    echo nuget push \$file
+    #dotnet nuget push \$file -k ${NUGET_KEY} -s ${NUGET_SERVER}
+done
+" || true
+
+
+ 

+ 61 - 0
Publish/DevOps/github/40.dotnet-publish.sh

@@ -0,0 +1,61 @@
+set -e
+
+
+#---------------------------------------------------------------------
+#(x.1)参数
+args_="
+
+export codePath=/root/temp/svn
+
+# "
+
+
+
+#----------------------------------------------
+echo "(x.2)dotnet-publish"
+echo "dotnet version: ${netVersion}"
+
+
+mkdir -p $codePath/Publish/release/release/publish
+
+docker run -i --rm \
+--env LANG=C.UTF-8 \
+-v $codePath:/root/code \
+serset/dotnet:6.0-sdk \
+bash -c "
+set -e
+
+basePath=/root/code
+publishPath=\$basePath/Publish/release/release/publish
+
+#(x.3)查找所有需要发布的项目并发布
+cd \$basePath
+for file in \$(grep -a '<publish>' . -rl --include *.csproj)
+do
+	cd \$basePath
+	
+	#get publishName
+	publishName=\`grep '<publish>' \$file -r | grep -oP '>(.*)<' | tr -d '<>'\`
+
+	echo publish \$publishName
+
+	#publish
+	cd \$(dirname \"\$file\")
+	dotnet build --configuration Release
+	dotnet publish --configuration Release --output \$publishPath/\$publishName
+done
+
+"
+
+
+#(x.4)copy bat
+\cp -rf $codePath/Publish/ReleaseFile/publish/. $codePath/Publish/release/release/publish
+
+
+echo 'publish succeed!'
+
+
+
+
+
+

+ 48 - 0
Publish/DevOps/github/70.docker-image-create.sh

@@ -0,0 +1,48 @@
+set -e
+
+
+#---------------------------------------------------------------------
+#(x.1)参数
+args_="
+
+export codePath=/root/temp/svn
+
+
+# "
+
+ 
+
+
+#---------------------------------------------------------------------
+echo "(x.2)docker-image-create"
+
+
+publishPath=$codePath/Publish/release/release/publish
+dockerPath=$codePath/Publish/release/release/docker-image
+
+
+
+echo "copy dir"
+mkdir -p $dockerPath
+\cp -rf $codePath/Publish/ReleaseFile/docker-image/. $dockerPath
+
+
+#查找所有需要发布的项目并发布
+cd $codePath
+for file in $(grep -a '<docker>' . -rl --include *.csproj)
+do
+	cd $codePath
+	
+	#get publishName
+	publishName=`grep '<publish>' $file -r | grep -oP '>(.*)<' | tr -d '<>'`
+	
+	#get dockerName
+	dockerName=`grep '<docker>' $file -r | grep -oP '>(.*)<' | tr -d '<>'`
+
+	echo create $dockerName
+
+	#copy file
+	\cp -rf "$publishPath/$publishName" "$dockerPath/$dockerName/app"
+done
+
+

+ 65 - 0
Publish/DevOps/github/71.docker-image-build.sh

@@ -0,0 +1,65 @@
+set -e
+
+
+#---------------------------------------------------------------------
+#(x.1)参数
+args_="
+
+export codePath=/root/temp/svn
+
+
+export DOCKER_USERNAME=serset
+export DOCKER_PASSWORD=xxx
+
+# "
+
+
+
+
+#---------------------------------------------------------------------
+#(x.2)docker-初始化多架构构建器
+
+#启用 buildx 插件
+export DOCKER_CLI_EXPERIMENTAL=enabled
+
+#验证是否开启
+docker buildx version
+
+#启用 binfmt_misc
+docker run --rm --privileged docker/binfmt:66f9012c56a8316f9244ffd7622d7c21c1f6f28d
+
+#验证是 binfmt_misc 否开启
+ls -al /proc/sys/fs/binfmt_misc/
+
+
+#创建一个新的构建器
+docker buildx create --use --name mybuilder
+
+#启动构建器
+docker buildx inspect mybuilder --bootstrap
+
+#查看当前使用的构建器及构建器支持的 CPU 架构,可以看到支持很多 CPU 架构:
+docker buildx ls
+
+
+
+#---------------------------------------------------------------------
+#(x.3)docker-构建多架构镜像( arm、arm64 和 amd64 )并推送到 Docker Hub
+
+docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
+
+
+dockerPath=$codePath/Publish/release/release/docker-image
+
+for dockerName in `ls $dockerPath`
+do
+  if [ -d $dockerPath/$dockerName ]
+  then 
+    echo "docker build $dockerName"
+    #docker buildx build $dockerPath/$dockerName -t $DOCKER_USERNAME/$dockerName:$version -t $DOCKER_USERNAME/$dockerName --platform=linux/amd64,linux/arm64,linux/arm/v7 --push
+  fi
+done
+
+
+
+ 

+ 67 - 0
Publish/DevOps/github/90.release-build.sh

@@ -0,0 +1,67 @@
+set -e
+
+
+#---------------------------------------------------------------------
+#(x.1)参数
+args_="
+
+export codePath=/root/temp/svn
+
+export version=`grep '<Version>' $(grep '<pack/>\|<publish>' ${codePath} -r --include *.csproj -l | head -n 1) | grep -oP '>(.*)<' | tr -d '<>'`
+
+export name=ServiceAdaptor
+
+export export GIT_SSH_SECRET=xxxxxx
+
+# "
+
+ 
+
+
+
+#----------------------------------------------
+echo "(x.2)发布文件-压缩"
+
+
+\cp -rf $codePath/Publish/ReleaseFile/docker-deploy $codePath/Publish/release/release/docker-deploy
+
+
+docker run --rm -i \
+-v $codePath:/root/code \
+serset/filezip filezip zip -p -i /root/code/Publish/release/release -o /root/code/Publish/release/${name}-${version}.zip 
+
+
+
+
+
+
+
+#----------------------------------------------
+echo "(x.3)github-提交release文件到release仓库"
+# releaseFile=$codePath/Publish/release/${name}-${version}.zip
+
+#复制ssh key
+echo "${GIT_SSH_SECRET}" > $codePath/Publish/release/serset
+chmod 600 $codePath/Publish/release/serset
+
+#推送到github
+docker run -i --rm \
+-v $codePath/Publish/release:/root/release serset/git-client bash -c "
+set -e
+ssh-agent bash -c \"
+ssh-add /root/release/serset
+ssh -T git@github.com -o StrictHostKeyChecking=no
+git config --global user.email 'serset@yeah.com'
+git config --global user.name 'lith'
+mkdir -p /root/code
+cd /root/code
+git clone git@github.com:serset/release.git /root/code
+mkdir -p /root/code/file/${name}
+cp /root/release/${name}-${version}.zip /root/code/file/${name}
+git add file/${name}/${name}-${version}.zip
+git commit -m 'auto commit ${version}'
+git push -u origin master \" "
+
+
+ 
+ 

+ 58 - 0
Publish/DevOps/github/91.release-github.sh

@@ -0,0 +1,58 @@
+set -e
+
+
+#---------------------------------------------------------------------
+#(x.1)参数
+args_="
+
+export codePath=/root/temp/svn
+
+export version=`grep '<Version>' $(grep '<pack/>\|<publish>' ${codePath} -r --include *.csproj -l | head -n 1) | grep -oP '>(.*)<' | tr -d '<>'`
+
+export name=ServiceAdaptor
+
+# "
+
+
+ 
+
+
+#---------------------------------------------------------------------
+#(x.2)初始化github release环境变量
+releaseFile=$codePath/Publish/release/${name}-${version}.zip
+
+filePath=${releaseFile}
+#name=Vit.Library
+#version=2.5
+
+
+fileType="${filePath##*.}"
+echo "release_name=${name}-${version}" >> $GITHUB_ENV
+echo "release_tag=${version}" >> $GITHUB_ENV
+
+echo "release_draft=false" >> $GITHUB_ENV
+echo "release_prerelease=false" >> $GITHUB_ENV
+
+echo "release_body=" >> $GITHUB_ENV
+
+echo "release_assetPath=${filePath}" >> $GITHUB_ENV
+echo "release_assetName=${name}-${version}.${fileType}" >> $GITHUB_ENV
+echo "release_contentType=application/${fileType}" >> $GITHUB_ENV
+
+
+
+# draft or preivew
+if [[ $version =~ "preview" ]]
+then
+  echo preivew
+  echo "release_prerelease=true" >> $GITHUB_ENV
+else
+  if  [[ "" = $(echo $version | tr -d "0-9\.") ]]
+  then
+    echo release
+  else
+    echo draft
+    echo "release_draft=true" >> $GITHUB_ENV
+  fi
+fi
+

+ 57 - 0
Publish/DevOps/github/startup.bash

@@ -0,0 +1,57 @@
+set -e
+
+# cd /root/temp/svn/Publish/DevOps/github;bash startup.bash;
+
+#----------------------------------------------
+#(x.1)当前路径 
+curWorkDir=$PWD
+
+cd $curWorkDir/../../..
+export codePath=$PWD
+cd $curWorkDir
+
+
+# export codePath=/root/temp/svn
+
+export name=ServiceAdaptor
+
+#export DOCKER_USERNAME=serset
+#export DOCKER_PASSWORD=xxx
+
+#export NUGET_SERVER=https://api.nuget.org/v3/index.json
+#export NUGET_KEY=xxxxxxxxxx
+
+#export export GIT_SSH_SECRET=xxxxxx
+
+
+
+
+
+
+#----------------------------------------------
+echo "(x.2)get version" 
+export version=`grep '<Version>' $(grep '<pack/>\|<publish>' ${codePath} -r --include *.csproj -l | head -n 1) | grep -oP '>(.*)<' | tr -d '<>'`
+echo $version
+
+ 
+
+
+#----------------------------------------------
+echo "(x.3)自动发布 $name-$version"
+
+for file in *.sh
+do
+    echo %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    echo bash $file
+    bash $file
+done
+
+
+
+
+
+
+ 
+#----------------------------------------------
+#(x.9)
+#cd $curWorkDir

+ 243 - 0
Publish/ReleaseFile/docker-deploy/adaptor-gateway/appsettings.json

@@ -0,0 +1,243 @@
+{
+  "//Logging": {
+    "LogLevel": {
+      "Default": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+
+
+  /* 网关配置 */
+  "Gateway": {
+
+    /* url,可多个 */
+    "urls": [ "http://*:4580" ],
+
+    /* 是否允许跨域访问,默认true */
+    "allowAnyOrigin": true,
+
+    /* 把请求的ip地址、端口号复制到请求头中的前缀。若不指定则不复制。 */
+    "prefixOfCopyIpToHeader": "Sers-Gateway-",
+
+    /* http回应中的默认Content-Type。若不指定则默认为 "application/json; charset="+Serialization.Instance.charset  */
+    "//ResponseDefaultContentType": "application/json; charset=UTF-8",
+
+
+    /* 映射静态文件。若不指定则不映射静态文件 */
+    "staticFiles": {
+
+      /* 静态文件路径。可为相对路径或绝对路径。若为空或空字符串则为默认路径(wwwroot)。demo:"wwwroot/demo" */
+      //"rootPath": "wwwroot",
+
+      /* 默认页面(可不指定)。An ordered list of file names to select by default. List length and ordering  may affect performance */
+      "defaultFileNames": ["index.html"],
+
+      /* 是否可浏览目录(default false)。Enables directory browsing */
+      //"useDirectoryBrowser": false,
+
+      /* 静态文件类型映射配置的文件路径。可为相对路径或绝对路径。例如"contentTypeMap.json"。若不指定(或指定的文件不存在)则不指定文件类型映射配置 */
+      "contentTypeMapFile": "contentTypeMap.json",
+
+      /* 回应静态文件时额外添加的http回应头。可不指定。 */
+      "responseHeaders": {
+
+        //设置浏览器静态文件缓存3600秒
+        "Cache-Control": "public,max-age=3600"
+      }
+
+    }
+  },
+
+
+
+  /* asp.net core 原始web服务配置 */
+  "server": {
+    "urls": [ "http://*:4580" ] 
+  },
+
+
+  /* 微服务适配器 配置 */
+  "ServiceAdaptor": [
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Sers.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "className": "ServiceAdaptor.NetCore.Sers.ServiceAdaptor"
+
+      /* 配置 */
+
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.MinHttp.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.MinHttp.ServiceAdaptor",
+
+      /* 配置 */
+      /* 网关地址,必须指定 */
+      "gatewayAddress": "http://127.0.0.1:6080",
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Consul.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.Consul.ServiceAdaptor",
+
+      /* 配置 */
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600,
+
+      /* consul的地址。如 http://127.0.0.1:8500 */
+      "ConsulEndpoint": "http://127.0.0.1:8500",
+
+      /* 提供的服务的地址,如 127.0.0.1、sers.cloud */
+      "serviceHost": "127.0.0.1",
+
+      /* 提供的服务的端口号 */
+      "servicePort": 6003,
+
+      /* 提供的服务的名称,如 ServiceProvider */
+      "serviceName": "Gateway"
+    },
+    {
+      /* 在此Assembly中加载类 */
+      "assemblyFile": "ServiceAdaptor.NetCore.Be.Eureka.dll",
+      /* 动态加载的类名,必须继承接口 ServiceAdaptor.NetCore.IServiceAdaptor */
+      "//className": "ServiceAdaptor.NetCore.Be.Eureka.ServiceAdaptor",
+
+      /* 配置 */
+      /* 超时时间(单位:秒,可不指定)。1小时 */
+      "//timeoutSeconds": 3600
+    }
+
+  ],
+
+
+
+
+  /* Sers配置 begin */
+
+  "Sers": {
+    /* 通讯层配置 */
+    "CL": {
+      /* one conn is one channel.can be multiable */
+      "Client": [
+        {
+          // Ipc.NamedPipe
+          /* (x.1) type */
+          /* 在此Assembly中查找Builder */
+          "assemblyFile": "Sers.CL.Ipc.NamedPipe.dll",
+          /* the class of Builder in assemblyFile  */
+          "className": "Sers.CL.Ipc.NamedPipe.OrganizeClientBuilder",
+
+
+          /* (x.2) config */
+          // 命名管道只支持本机或局域网。
+          /* 服务端机器名或者ip地址(如 103.23.23.23 、win10f),默认 "." */
+          "serverName": ".",
+          /* 命名管道名称。例如: "Sers.CL.Ipc" */
+          "pipeName": "Sers.CL.Ipc.4501",
+          /* 连接秘钥,用以验证连接安全性。服务端和客户端必须一致 */
+          "secretKey": "SersCL",
+
+          /* 请求超时时间(单位ms,默认60000) */
+          "requestTimeoutMs": 3600000
+        },
+        {
+          // Socket.Iocp
+          /* (x.1) type - Iocp */
+          /* the class of builder in assemblyFile  */
+          //"className": "Sers.CL.Socket.Iocp.OrganizeClientBuilder",
+
+          /* (x.2) conn config */
+          /* 服务端 host地址。例如: "127.0.0.1"、"serset.com" */
+          "host": "127.0.0.1",
+          /* 服务端 监听端口号。例如: 4501 */
+          "port": 4501,
+          /* 连接秘钥,用以验证连接安全性。服务端和客户端必须一致 */
+          "secretKey": "SersCL",
+
+          /* 请求超时时间(单位ms,默认60000) */
+          "requestTimeoutMs": 3600000
+        }
+      ]
+    },
+
+    /* LocalApiService 配置,可不指定 */
+    "LocalApiService": {
+
+      /* 是否 输出本地Api的调用信息到(ApiTrace)Log文件。默认:false */
+      //"PrintTrace": true,
+
+      /* 后台服务的线程个数(单位个,默认0,代表不开启服务) */
+      "workThreadCount": 16
+    },
+
+    /* ServiceStation配置,可不指定 */
+    "ServiceStation": {
+      /* serviceStation站点信息 */
+      "serviceStationInfo": {
+        /* 服务站点名称 */
+        "serviceStationName": "Gateway"
+      }
+    }
+  },
+
+
+  /* Vit工具配置,可不指定 */
+  "Vit": {
+    /* 日志配置,可不指定 */
+    "Logger": {
+      /* print the log to console. default:false  */
+      "PrintToConsole": true
+    },
+
+
+    "Kestrel": {
+      /* (int64) the maximum allowed size of any request body in bytes.  When set to null, the maximum request body size is unlimited. */
+      "MaxRequestBodySize": 2000000000,
+
+      /* (int32) A limit on the length of individual form values. Forms containing values that exceed this limit will throw an System.IO.InvalidDataException when parsed. */
+      "ValueLengthLimit": 2000000000,
+
+      /* (int64) A limit for the length of each multipart body. Forms sections that exceed this limit will throw an System.IO.InvalidDataException when parsed. */
+      "MultipartBodyLengthLimit": 2000000000
+    }
+  },
+
+  /* Sers配置 end */
+
+
+
+
+
+  /* BeEureka配置 begin */
+  "spring": {
+    "application": {
+      "name": "ServiceAdaptor_Gateway" //服务名称
+    }
+  },
+  "eureka": {
+    "client": {
+      "serviceUrl": "http://direwolf:direwolf@192.168.1.204:8762/eureka/", //注册中心地址
+      "validate_certificates": false
+    },
+    "instance": {
+      "leaseRenewalIntervalInSeconds": 120,
+      "leaseExpirationDurationInSeconds": 120,
+      "port": 6003, //服务端口
+      "preferIpAddress": true, //表示使用当前ip作为服务的ip
+      "metadataMap": { //里面的参数都是国网要求
+        "auth-code": "HWJCGliay4uXH3xhUTaXnB==",
+        "service-name": "ServiceAdaptor_Gateway", //服务中文名称
+        "service-desc": "ServiceAdaptor_Gateway", //服务描述
+        "service-namespace": "XMGL",
+        "service-sys": "JJQGC"
+      }
+    }
+  }
+  /* BeEureka配置 end */
+
+}

+ 68 - 0
Publish/ReleaseFile/docker-deploy/adaptor-gateway/docker部署adaptor-gateway.md

@@ -0,0 +1,68 @@
+docker部署adaptor-gateway
+
+ 
+
+---------------------------------
+#(x.1)配置文件
+  (x.1)把本文件所在目录中的wwwroot拷贝到宿主机
+  (x.2)修改配置文件 appsettings.json
+ 
+
+#(x.2)创建容器并运行
+(--name 容器名称,可自定义)
+(--restart=always 自动重启)
+(-v /etc/localtime:/etc/localtime)挂载宿主机localtime文件解决容器时间与主机时区不一致的问题
+(-v $PWD/data:/data 将主机中当前目录下的data挂载到容器的/data)
+(--net=host 网络直接使用宿主机网络)(-p 6022:6022 端口映射)
+
+cd /root/docker
+
+
+cd Gateway
+
+docker run --name=gateway --restart=always -d \
+-p 4580:4580 \
+-v /etc/localtime:/etc/localtime \
+-v $PWD/appsettings.json:/root/app/appsettings.json \
+-v $PWD/wwwroot:/root/app/wwwroot \
+-v $PWD/Logs:/root/app/Logs \
+serset/adaptor-gateway
+
+cd .. 
+
+
+#精简
+docker run --name=gateway --restart=always -d -p 4580:4580 serset/adaptor_gateway
+
+
+#(x.3)应用已经运行
+   可在文件夹Logs 中查看日志
+
+#地址 http://ip:4580
+
+#---------------------------------------
+#常用命令
+
+```bash
+
+#查看容器logs
+docker logs gateway
+
+#在容器内执行命令行
+docker  exec -it gateway bash
+
+#停止容器
+docker stop gateway
+
+#打开容器
+docker start gateway
+
+#重启容器
+docker restart gateway
+
+
+#删除容器
+docker rm gateway -f
+
+```
+

+ 9 - 0
Publish/ReleaseFile/docker-deploy/adaptor-gateway/wwwroot/index.html

@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <title>Gateway</title> 
+</head>
+<body>
+    ServiceAdaptor.Gateway
+</body>
+</html>

+ 4 - 0
Publish/ReleaseFile/docker-image/adaptor-gateway/Dockerfile

@@ -0,0 +1,4 @@
+FROM serset/dotnet:2.1
+COPY app /root/app
+WORKDIR /root/app
+CMD dotnet ServiceAdaptor.NetCore.Gateway.dll

+ 60 - 0
Publish/ReleaseFile/docker-image/制作镜像.txt

@@ -0,0 +1,60 @@
+#构建多架构镜像
+
+#docker login -u serset -p xxxxxxxxx
+
+#---------------------------------------------------------------------
+#(x.1)初始化构建器
+
+#启用 buildx 插件
+export DOCKER_CLI_EXPERIMENTAL=enabled
+
+#验证是否开启
+docker buildx version
+
+#启用 binfmt_misc
+docker run --rm --privileged docker/binfmt:66f9012c56a8316f9244ffd7622d7c21c1f6f28d
+
+#验证是 binfmt_misc 否开启
+ls -al /proc/sys/fs/binfmt_misc/
+
+
+#创建一个新的构建器
+docker buildx create --use --name mybuilder
+
+#启动构建器
+docker buildx inspect mybuilder --bootstrap
+
+#查看当前使用的构建器及构建器支持的 CPU 架构,可以看到支持很多 CPU 架构:
+docker buildx ls
+
+
+
+#---------------------------------------------------------------------
+#(x.2)构建多架构镜像( arm、arm64 和 amd64 )并推送到 Docker Hub
+
+#把文件夹拷贝到image下
+cd /root/image 
+
+
+#构建镜像并推送到 Docker Hub 
+cd adaptor-gateway
+docker buildx build . -t serset/adaptor-gateway:1.3.4 -t serset/adaptor-gateway --platform=linux/amd64,linux/arm64,linux/arm/v7 --push
+ 
+
+
+
+#强制删除镜像名称中包含 adaptor_gateway 的镜像
+# docker rmi --force $(docker images | grep adaptor-gateway | awk '{print $3}')
+
+
+
+
+
+
+
+
+
+
+
+
+ 

+ 10 - 0
Publish/ReleaseFile/publish/40.启动Gateway.bat

@@ -0,0 +1,10 @@
+title Gateway
+
+cd /d Gateway
+dotnet ServiceAdaptor.NetCore.Gateway.dll
+
+cd ..
+ 
+
+:: pause
+exit

+ 11 - 0
Publish/ReleaseFile/publish/50.循环启动Gateway.bat

@@ -0,0 +1,11 @@
+title Gateway
+
+cd /d Gateway 
+
+:begin
+
+dotnet ServiceAdaptor.NetCore.Gateway.dll
+ TIMEOUT /T 4
+
+@echo restart
+goto begin

+ 45 - 0
Publish/cmd/docker-image-create.bat

@@ -0,0 +1,45 @@
+@echo off
+
+::启用变量延迟
+setlocal EnableDelayedExpansion
+
+
+echo %~n0.bat start...
+
+
+::(x.1)获取basePath
+set curPath=%cd%
+cd /d "%~dp0"
+cd /d ../..
+set basePath=%cd%
+set publishPath=%basePath%/Publish/release/release/publish
+set dockerPath=%basePath%/Publish/release/release/docker-image
+
+
+rd /s /q "%dockerPath%"
+
+::(x.2)copy dir
+xcopy "%basePath%/Publish/ReleaseFile/docker-image" "%dockerPath%" /e /i /r /y
+
+
+
+::(x.3)查找所有需要发布的项目并发布
+for /f "delims=" %%f in ('findstr /M /s /i "<docker>" *.csproj') do (
+	::get publishName
+	for /f "tokens=3 delims=><" %%a in ('type "%basePath%\%%f"^|findstr "<publish>.*publish"') do set publishName=%%a
+	::get dockerName
+	for /f "tokens=3 delims=><" %%a in ('type "%basePath%\%%f"^|findstr "<docker>.*docker"') do set dockerName=%%a
+
+	echo create !dockerName!
+
+	::copy file
+	xcopy "%publishPath%/!publishName!" "%dockerPath%/!dockerName!/app" /e /i /r /y
+)
+
+
+
+
+
+echo %~n0.bat 执行成功!
+
+cd /d "%curPath%"

+ 50 - 0
Publish/cmd/dotnet-publish.bat

@@ -0,0 +1,50 @@
+@echo off
+
+::启用变量延迟
+setlocal EnableDelayedExpansion
+
+
+echo %~n0.bat start...
+
+
+::(x.1)获取basePath
+set curPath=%cd%
+cd /d "%~dp0"
+cd /d ../..
+set basePath=%cd%
+set publishPath=%basePath%/Publish/release/release/publish
+
+
+
+
+::(x.2)查找所有需要发布的项目并发布
+for /f "delims=" %%f in ('findstr /M /s /i "<publish>" *.csproj') do (
+	::get publishName
+	for /f "tokens=3 delims=><" %%a in ('type "%basePath%\%%f"^|findstr "<publish>.*publish"') do set publishName=%%a
+
+	echo publish !publishName!
+
+	::publish
+	cd /d "%basePath%\%%f\.."
+	dotnet build --configuration Release
+	dotnet publish --configuration Release --output "%publishPath%\!publishName!"
+	@if errorlevel 1 (echo . & echo .  & echo 出错,请排查!& pause) 
+)
+
+
+
+
+
+
+::(x.3)copy bat
+xcopy "%basePath%\Publish\ReleaseFile\publish" "%publishPath%" /e /i /r /y
+
+
+
+
+
+
+
+echo %~n0.bat 执行成功!
+
+cd /d "%curPath%"

+ 18 - 0
Publish/cmd/nuget delete from NugetServer.Sers.bat

@@ -0,0 +1,18 @@
+@echo off 
+
+set version=1.0.13.93
+
+dotnet nuget delete ServiceAdaptor.NetCore %version% -k ee28314c-f7fe-2550-bd77-e09eda3d0119  -s http://nuget.sers.cloud:8 --non-interactive
+
+dotnet nuget delete ServiceAdaptor.NetCore.Consul %version% -k ee28314c-f7fe-2550-bd77-e09eda3d0119  -s http://nuget.sers.cloud:8 --non-interactive
+
+dotnet nuget delete ServiceAdaptor.NetCore.MinHttp %version% -k ee28314c-f7fe-2550-bd77-e09eda3d0119  -s http://nuget.sers.cloud:8 --non-interactive
+
+dotnet nuget delete ServiceAdaptor.NetCore.Sers %version% -k ee28314c-f7fe-2550-bd77-e09eda3d0119  -s http://nuget.sers.cloud:8 --non-interactive
+
+dotnet nuget delete ServiceAdaptor.NetCore.Be.Eureka %version% -k ee28314c-f7fe-2550-bd77-e09eda3d0119  -s http://nuget.sers.cloud:8 --non-interactive
+
+echo 'delete succeed£¡'
+ 
+
+ 

+ 23 - 0
Publish/cmd/nuget-pack.bat

@@ -0,0 +1,23 @@
+@echo off
+
+::(x.1)获取basePath
+set curPath=%cd%
+cd /d "%~dp0"
+cd /d ../..
+set basePath=%cd%
+set nugetPath=%cd%/Publish/release/release/nuget
+
+::(x.2)查找所有需要发布nuget的项目并发布
+for /f "delims=" %%f in ('findstr /M /s /i "<pack/>" *.csproj') do (
+	echo pack %basePath%\%%f\..
+	cd /d "%basePath%\%%f\.."
+	dotnet build --configuration Release
+	dotnet pack --configuration Release --output "%nugetPath%"
+	@if errorlevel 1 (echo . & echo .  & echo 出错,请排查!& pause) 
+)
+
+
+echo %~n0.bat 执行成功!
+
+
+cd /d "%curPath%"

+ 16 - 0
Publish/cmd/nuget-push to NugetServer.Sers.bat

@@ -0,0 +1,16 @@
+@echo off 
+
+cd /d ../release/release/nuget
+ 
+for /R %%s in (*.nupkg) do ( 
+echo push %%s 
+dotnet nuget push "%%s"  -k ee28314c-f7fe-2550-bd77-e09eda3d0119  -s http://nuget.sers.cloud:8
+) 
+
+
+cd /d ../../../cmd
+
+echo %~n0.bat Ö´Ðгɹ¦£¡
+
+
+:: dotnet nuget delete ServiceAdaptor.NetCore.Sers 1.0.4.75 -k ee28314c-f7fe-2550-bd77-e09eda3d0119  -s http://nuget.sers.cloud --non-interactive

+ 9 - 0
Publish/cmd/nuget-一键发布并上传.bat

@@ -0,0 +1,9 @@
+
+call "nuget-pack.bat"
+
+call "nuget-push to NugetServer.Sers.bat"
+
+ 
+echo %~n0.bat Ö´Ðгɹ¦£¡
+
+pause

+ 14 - 0
Publish/cmd/一键发布.bat

@@ -0,0 +1,14 @@
+
+call "nuget-pack.bat"
+
+call "dotnet-publish.bat"
+
+call "docker-image-create.bat"
+
+xcopy  "../ReleaseFile/docker-deploy" "../release/release/docker-deploy"  /e /i /r /y
+
+
+
+echo %~n0.bat Ö´ĐĐłÉšŚŁĄ
+
+pause

+ 34 - 0
Publish/cmd/更新为下一大版本号.bat

@@ -0,0 +1,34 @@
+@echo off
+
+::获取当前版本号
+:: set version=2.1.3.356 
+for /f "tokens=3 delims=><" %%a in ('type ..\Library\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj^|findstr "<Version>.*Version"') do set version=%%a
+
+:: v1 v2 v3
+for /f "tokens=1 delims=." %%i in ("%version%") do set v1=%%i
+for /f "tokens=2 delims=." %%i in ("%version%") do set v2=%%i
+for /f "tokens=3 delims=." %%i in ("%version%") do set v3=%%i
+
+
+:: 获取最新版本号
+:: set v4=356 
+for /f "tokens=4 delims= " %%i in ('svn info "svn://svn.sers.cloud/2020LithProject"^|findstr "Rev:"') do set v4=%%i
+
+set /a v3=1+%v3%
+set /a v4=1+%v4%
+set  newVersion=%v1%.%v2%.%v3%.%v4%
+
+ 
+echo 自动修改版本号 [%version%]-^>[%newVersion%]
+echo.
+
+:: 调用工具 替换csproj文件中的dll版本
+VsTool.exe replace -r --path ".." --file "*.csproj" --old "%version%" --new "%newVersion%"
+VsTool.exe replace -r --path "06.Docker" --file "*.txt" --old "%version%" --new "%newVersion%"
+
+
+echo.
+echo.
+echo.
+echo 已经成功修改版本号 [%version%]-^>[%newVersion%]
+pause

+ 34 - 0
Publish/cmd/更新为下一小版本号.bat

@@ -0,0 +1,34 @@
+@echo off
+
+::获取当前版本号
+:: set version=2.1.3.356 
+for /f "tokens=3 delims=><" %%a in ('type ..\Library\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj^|findstr "<Version>.*Version"') do set version=%%a
+
+:: v1 v2 v3
+for /f "tokens=1 delims=." %%i in ("%version%") do set v1=%%i
+for /f "tokens=2 delims=." %%i in ("%version%") do set v2=%%i
+for /f "tokens=3 delims=." %%i in ("%version%") do set v3=%%i
+
+
+:: 获取最新版本号
+:: set v4=356 
+for /f "tokens=4 delims= " %%i in ('svn info "svn://svn.sers.cloud/2020LithProject"^|findstr "Rev:"') do set v4=%%i
+
+:: set /a v3=1+%v3%
+set /a v4=1+%v4%
+set  newVersion=%v1%.%v2%.%v3%.%v4%
+
+ 
+echo 自动修改版本号 [%version%]-^>[%newVersion%]
+echo.
+
+:: 调用工具 替换csproj文件中的dll版本
+VsTool.exe replace -r --path ".." --file "*.csproj" --old "%version%" --new "%newVersion%"
+VsTool.exe replace -r --path "06.Docker" --file "*.txt" --old "%version%" --new "%newVersion%"
+
+
+echo.
+echo.
+echo.
+echo 已经成功修改版本号 [%version%]-^>[%newVersion%]
+pause

+ 34 - 0
Publish/cmd/更新为当前preview版本号.bat

@@ -0,0 +1,34 @@
+@echo off
+
+::获取当前版本号
+:: set version=2.1.3.356 
+for /f "tokens=3 delims=><" %%a in ('type ..\Library\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj^|findstr "<Version>.*Version"') do set version=%%a
+
+:: v1 v2 v3
+for /f "tokens=1 delims=." %%i in ("%version%") do set v1=%%i
+for /f "tokens=2 delims=." %%i in ("%version%") do set v2=%%i
+for /f "tokens=3 delims=." %%i in ("%version%") do set v3=%%i
+
+
+:: 获取最新版本号
+:: set v4=356 
+for /f "tokens=4 delims= " %%i in ('svn info "svn://svn.sers.cloud/2020LithProject"^|findstr "Rev:"') do set v4=%%i
+
+:: set /a v3=1+%v3%
+:: set /a v4=1+%v4%
+set  newVersion=%v1%.%v2%.%v3%.%v4%-preview
+
+ 
+echo 自动修改版本号 [%version%]-^>[%newVersion%]
+echo.
+
+:: 调用工具 替换csproj文件中的dll版本
+VsTool.exe replace -r --path ".." --file "*.csproj" --old "%version%" --new "%newVersion%"
+VsTool.exe replace -r --path "06.Docker" --file "*.txt" --old "%version%" --new "%newVersion%"
+
+
+echo.
+echo.
+echo.
+echo 已经成功修改版本号 [%version%]-^>[%newVersion%]
+pause

+ 34 - 0
Publish/cmd/更新为当前版本号.bat

@@ -0,0 +1,34 @@
+@echo off
+
+::获取当前版本号
+:: set version=2.1.3.356 
+for /f "tokens=3 delims=><" %%a in ('type ..\Library\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj^|findstr "<Version>.*Version"') do set version=%%a
+
+:: v1 v2 v3
+for /f "tokens=1 delims=." %%i in ("%version%") do set v1=%%i
+for /f "tokens=2 delims=." %%i in ("%version%") do set v2=%%i
+for /f "tokens=3 delims=." %%i in ("%version%") do set v3=%%i
+
+
+:: 获取最新版本号
+:: set v4=356 
+for /f "tokens=4 delims= " %%i in ('svn info "svn://svn.sers.cloud/2020LithProject"^|findstr "Rev:"') do set v4=%%i
+
+:: set /a v3=1+%v3%
+:: set /a v4=1+%v4%
+set  newVersion=%v1%.%v2%.%v3%.%v4%
+
+ 
+echo 自动修改版本号 [%version%]-^>[%newVersion%]
+echo.
+
+:: 调用工具 替换csproj文件中的dll版本
+VsTool.exe replace -r --path ".." --file "*.csproj" --old "%version%" --new "%newVersion%"
+VsTool.exe replace -r --path "06.Docker" --file "*.txt" --old "%version%" --new "%newVersion%"
+
+
+echo.
+echo.
+echo.
+echo 已经成功修改版本号 [%version%]-^>[%newVersion%]
+pause

+ 1 - 0
Publish/cmd/清理-发布文件.bat

@@ -0,0 +1 @@
+rd /s/q ..\release

+ 85 - 0
ServiceAdaptor.sln

@@ -0,0 +1,85 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29503.13
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "11.ServiceProvider", "11.ServiceProvider", "{5FD7A36C-0963-4358-9EED-09178E4691D8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Library", "Library", "{7AC5E91A-C865-448A-8957-E635D02220D5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "12.ServiceConsumer", "12.ServiceConsumer", "{A4B7CA8C-B6B1-4C9F-8A08-C3BFFCACBC2F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceAdaptor", "Library\ServiceAdaptor\ServiceAdaptor.csproj", "{8D4408BC-C8AA-4CF0-B35E-7B22105F8F62}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceAdaptor.NetCore", "Library\ServiceAdaptor.NetCore\ServiceAdaptor.NetCore.csproj", "{D5DE0642-524C-43F7-9C19-2830CF953154}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceAdaptor.NetCore.Consul", "Library\ServiceAdaptor.NetCore.Consul\ServiceAdaptor.NetCore.Consul.csproj", "{284FE7D7-06AF-437D-A320-18FFCAF73291}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceAdaptor.NetCore.MinHttp", "Library\ServiceAdaptor.NetCore.MinHttp\ServiceAdaptor.NetCore.MinHttp.csproj", "{991E6163-0CD8-40F9-9BDC-75D75E6B8EFF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceAdaptor.NetCore.Sers", "Library\ServiceAdaptor.NetCore.Sers\ServiceAdaptor.NetCore.Sers.csproj", "{DA07DAB1-3D67-4C6F-B91A-5212B2B88E3F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02.Gateway", "02.Gateway", "{84EEB4B9-EFCF-4F3A-BAC9-358D82FB793B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceAdaptor.NetCore.Gateway", "02.Gateway\ServiceAdaptor.NetCore.Gateway\ServiceAdaptor.NetCore.Gateway.csproj", "{7FD3F62F-DB5B-4EBD-B0A4-CF4785232547}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceProvider", "11.ServiceProvider\ServiceProvider\ServiceProvider.csproj", "{73F81979-FED3-4AA8-8DD0-FCFD6ABB4DAD}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServiceConsumer", "12.ServiceConsumer\ServiceConsumer\ServiceConsumer.csproj", "{21B5E75C-533F-4E10-A448-2C6C5BB5F316}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8D4408BC-C8AA-4CF0-B35E-7B22105F8F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{8D4408BC-C8AA-4CF0-B35E-7B22105F8F62}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{8D4408BC-C8AA-4CF0-B35E-7B22105F8F62}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{8D4408BC-C8AA-4CF0-B35E-7B22105F8F62}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D5DE0642-524C-43F7-9C19-2830CF953154}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D5DE0642-524C-43F7-9C19-2830CF953154}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D5DE0642-524C-43F7-9C19-2830CF953154}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D5DE0642-524C-43F7-9C19-2830CF953154}.Release|Any CPU.Build.0 = Release|Any CPU
+		{284FE7D7-06AF-437D-A320-18FFCAF73291}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{284FE7D7-06AF-437D-A320-18FFCAF73291}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{284FE7D7-06AF-437D-A320-18FFCAF73291}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{284FE7D7-06AF-437D-A320-18FFCAF73291}.Release|Any CPU.Build.0 = Release|Any CPU
+		{991E6163-0CD8-40F9-9BDC-75D75E6B8EFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{991E6163-0CD8-40F9-9BDC-75D75E6B8EFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{991E6163-0CD8-40F9-9BDC-75D75E6B8EFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{991E6163-0CD8-40F9-9BDC-75D75E6B8EFF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DA07DAB1-3D67-4C6F-B91A-5212B2B88E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DA07DAB1-3D67-4C6F-B91A-5212B2B88E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DA07DAB1-3D67-4C6F-B91A-5212B2B88E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DA07DAB1-3D67-4C6F-B91A-5212B2B88E3F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7FD3F62F-DB5B-4EBD-B0A4-CF4785232547}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7FD3F62F-DB5B-4EBD-B0A4-CF4785232547}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7FD3F62F-DB5B-4EBD-B0A4-CF4785232547}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7FD3F62F-DB5B-4EBD-B0A4-CF4785232547}.Release|Any CPU.Build.0 = Release|Any CPU
+		{73F81979-FED3-4AA8-8DD0-FCFD6ABB4DAD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{73F81979-FED3-4AA8-8DD0-FCFD6ABB4DAD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{73F81979-FED3-4AA8-8DD0-FCFD6ABB4DAD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{73F81979-FED3-4AA8-8DD0-FCFD6ABB4DAD}.Release|Any CPU.Build.0 = Release|Any CPU
+		{21B5E75C-533F-4E10-A448-2C6C5BB5F316}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{21B5E75C-533F-4E10-A448-2C6C5BB5F316}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{21B5E75C-533F-4E10-A448-2C6C5BB5F316}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{21B5E75C-533F-4E10-A448-2C6C5BB5F316}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{8D4408BC-C8AA-4CF0-B35E-7B22105F8F62} = {7AC5E91A-C865-448A-8957-E635D02220D5}
+		{D5DE0642-524C-43F7-9C19-2830CF953154} = {7AC5E91A-C865-448A-8957-E635D02220D5}
+		{284FE7D7-06AF-437D-A320-18FFCAF73291} = {7AC5E91A-C865-448A-8957-E635D02220D5}
+		{991E6163-0CD8-40F9-9BDC-75D75E6B8EFF} = {7AC5E91A-C865-448A-8957-E635D02220D5}
+		{DA07DAB1-3D67-4C6F-B91A-5212B2B88E3F} = {7AC5E91A-C865-448A-8957-E635D02220D5}
+		{7FD3F62F-DB5B-4EBD-B0A4-CF4785232547} = {84EEB4B9-EFCF-4F3A-BAC9-358D82FB793B}
+		{73F81979-FED3-4AA8-8DD0-FCFD6ABB4DAD} = {5FD7A36C-0963-4358-9EED-09178E4691D8}
+		{21B5E75C-533F-4E10-A448-2C6C5BB5F316} = {A4B7CA8C-B6B1-4C9F-8A08-C3BFFCACBC2F}
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {C7DA16E3-9949-49FA-B0B4-F830636DE60F}
+	EndGlobalSection
+EndGlobal