From ed7bc9afc68801bc6ddf9a9883ebd8b888eb6f51 Mon Sep 17 00:00:00 2001 From: 867824092 Date: Sat, 21 Aug 2021 20:18:34 +0800 Subject: [PATCH] Added Apollo configuration center --- Blog.Core.Api/Blog.Core.xml | 5 ++ Blog.Core.Api/Controllers/ValuesController.cs | 20 +++++ Blog.Core.Api/Program.cs | 3 + Blog.Core.Api/appsettings.apollo.json | 18 ++++ Blog.Core.Extensions/Apollo/ApolloOptions.cs | 27 ++++++ .../Apollo/ConfigurationBuilderExtensions.cs | 84 +++++++++++++++++++ .../Blog.Core.Extensions.csproj | 2 + 7 files changed, 159 insertions(+) create mode 100644 Blog.Core.Api/appsettings.apollo.json create mode 100644 Blog.Core.Extensions/Apollo/ApolloOptions.cs create mode 100644 Blog.Core.Extensions/Apollo/ConfigurationBuilderExtensions.cs diff --git a/Blog.Core.Api/Blog.Core.xml b/Blog.Core.Api/Blog.Core.xml index adb43a7..6510d66 100644 --- a/Blog.Core.Api/Blog.Core.xml +++ b/Blog.Core.Api/Blog.Core.xml @@ -813,6 +813,11 @@ + + + 此处的key格式为 xx:xx:x + + 服务管理 diff --git a/Blog.Core.Api/Controllers/ValuesController.cs b/Blog.Core.Api/Controllers/ValuesController.cs index 7399d8f..7bca6d8 100644 --- a/Blog.Core.Api/Controllers/ValuesController.cs +++ b/Blog.Core.Api/Controllers/ValuesController.cs @@ -1,4 +1,5 @@ using AutoMapper; +using Blog.Core.Common; using Blog.Core.Common.HttpContextUser; using Blog.Core.Common.HttpRestSharp; using Blog.Core.Common.WebApiClients.HttpApis; @@ -12,6 +13,7 @@ using Blog.Core.Model.Models; using Blog.Core.Model.ViewModels; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -349,5 +351,23 @@ namespace Blog.Core.Controllers public void Delete(int id) { } + + #region Apollo 配置 + [HttpGet("/apollo")] + [AllowAnonymous] + public async Task>> GetAllConfigByAppllo([FromServices]IConfiguration configuration) + { + return await Task.FromResult(configuration.AsEnumerable()); + } + /// + /// 此处的key格式为 xx:xx:x + /// + [HttpGet("/apollo/{key}")] + [AllowAnonymous] + public async Task GetConfigByAppllo(string key) + { + return await Task.FromResult(Appsettings.app(key)); + } + #endregion } } diff --git a/Blog.Core.Api/Program.cs b/Blog.Core.Api/Program.cs index 30615a3..d405b82 100644 --- a/Blog.Core.Api/Program.cs +++ b/Blog.Core.Api/Program.cs @@ -1,4 +1,5 @@ using Autofac.Extensions.DependencyInjection; +using Blog.Core.Extensions.Apollo; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; @@ -25,6 +26,8 @@ namespace Blog.Core config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) //.AddJsonFile($"appsettings{ GetAppSettingsConfigName() }json", optional: true, reloadOnChange: false) ; + //接入Apollo配置中心 + config.AddConfigurationApollo("appsettings.apollo.json"); }) .UseUrls("http://*:8081") .ConfigureLogging((hostingContext, builder) => diff --git a/Blog.Core.Api/appsettings.apollo.json b/Blog.Core.Api/appsettings.apollo.json new file mode 100644 index 0000000..f938acd --- /dev/null +++ b/Blog.Core.Api/appsettings.apollo.json @@ -0,0 +1,18 @@ +{ + //apollo 配置 + "Apollo": { + "Enable": true, + "Config": { + "AppId": "blog.core", + "Env": "DEV", + "MetaServer": "http://localhost:8080/", + "ConfigServer": [ "http://localhost:8080/" ] + }, + "Namespaces": [ //Namespaces的数据格式Properties,Xml,Json,Yml,Yaml,Txt + { + "Name": "test", + "Format": "json" + } + ] + } +} \ No newline at end of file diff --git a/Blog.Core.Extensions/Apollo/ApolloOptions.cs b/Blog.Core.Extensions/Apollo/ApolloOptions.cs new file mode 100644 index 0000000..6610ba4 --- /dev/null +++ b/Blog.Core.Extensions/Apollo/ApolloOptions.cs @@ -0,0 +1,27 @@ + +using System.Collections.Generic; + + +namespace Blog.Core.Extensions.Apollo +{ + /// + /// Apollo配置项 + /// + public class ApolloOptions + { + public bool Enable { get; set; } + public List Namespaces { get; set; } + + public class ChildNamespace + { + /// + /// 命名空间名字 + /// + public string Name { get; set; } + /// + /// 数据格式 Json/Yml/Yaml等 + /// + public string Format { get; set; } + } + } +} diff --git a/Blog.Core.Extensions/Apollo/ConfigurationBuilderExtensions.cs b/Blog.Core.Extensions/Apollo/ConfigurationBuilderExtensions.cs new file mode 100644 index 0000000..909e9a1 --- /dev/null +++ b/Blog.Core.Extensions/Apollo/ConfigurationBuilderExtensions.cs @@ -0,0 +1,84 @@ +using Com.Ctrip.Framework.Apollo; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using Com.Ctrip.Framework.Apollo.Enums; +using Com.Ctrip.Framework.Apollo.Logging; +using Microsoft.Extensions.Primitives; +using System.Reflection; + +namespace Blog.Core.Extensions.Apollo +{ + public static class ConfigurationBuilderExtensions + { + /// + /// 接入Apollo + /// + /// + /// apollo配置文件路径 如果写入appsettings.json中 则jsonPath传null即可 + public static void AddConfigurationApollo(this IConfigurationBuilder builder,string jsonPath) + { + if (!string.IsNullOrEmpty(jsonPath)) + { + builder.AddJsonFile(jsonPath, true, false); + } + //阿波罗的日志级别调整 + LogManager.UseConsoleLogging(LogLevel.Warn); + var options = new ApolloOptions(); + var root = builder.Build(); + root.Bind("Apollo", options); + if (options.Enable) + { + var apolloBuilder = builder.AddApollo(root.GetSection("Apollo:Config")); + + foreach (var item in options.Namespaces) + { + apolloBuilder.AddNamespace(item.Name, MatchConfigFileFormat(item.Format)); + } + //监听apollo配置 + Monitor(builder.Build()); + } + + } + #region private + /// + /// 监听配置 + /// + private static void Monitor(IConfigurationRoot root) + { + //TODO 需要根据改变执行特定的操作 如 mq redis 等其他跟配置相关的中间件 + //TODO 初步思路:将需要执行特定的操作key和value放入内存字典中,在赋值操作时通过标准事件来执行特定的操作。 + + //要重新Build 此时才将Apollo provider加入到ConfigurationBuilder中 + ChangeToken.OnChange(() => root.GetReloadToken(), () => + { + foreach (var apolloProvider in root.Providers.Where(p => p is ApolloConfigurationProvider)) + { + var property = apolloProvider.GetType().BaseType.GetProperty("Data", BindingFlags.Instance | BindingFlags.NonPublic); + var data = property.GetValue(apolloProvider) as IDictionary; + foreach (var item in data) + { + Console.WriteLine($"key {item.Key} value {item.Value}"); + } + } + }); + } + + //匹配格式 + private static ConfigFileFormat MatchConfigFileFormat(string value) => value switch + { + "json" => ConfigFileFormat.Json, + "properties" => ConfigFileFormat.Properties, + "xml" => ConfigFileFormat.Xml, + "yml" => ConfigFileFormat.Yml, + "yaml" => ConfigFileFormat.Yaml, + "txt" => ConfigFileFormat.Txt, + _ => throw new FormatException($"与apollo命名空间的所允许的类型不匹配:{string.Join(",", GetConfigFileFormat())}"), + }; + //获取数据格式对应的枚举 + private static IEnumerable GetConfigFileFormat() => Enum.GetValues().Select(u => u.ToString().ToLower()); + #endregion + + } +} diff --git a/Blog.Core.Extensions/Blog.Core.Extensions.csproj b/Blog.Core.Extensions/Blog.Core.Extensions.csproj index e10b8f5..90d5ed9 100644 --- a/Blog.Core.Extensions/Blog.Core.Extensions.csproj +++ b/Blog.Core.Extensions/Blog.Core.Extensions.csproj @@ -8,6 +8,8 @@ + +