天天看点

写个重新加载 ocelot 配置的接口

写个重新加载 ocelot 配置的接口

Intro

我们想把 ocelot 的配置放在自己的存储中,放在 Redis 或者数据库中,当修改了 Ocelot 的配置之后希望即时生效,又不想在网关这边定时刷新 ocelot 配置,ocelot 配置没变化的时候,定时刷新配置是一种无意义的资源浪费,,ocelot 自带的有一个 Administration ,感觉对于我来说,有点太重了,不想去集成这个东西,于是就想自己实现一个重新加载配置的接口。

实现代码

在集成 Ocelot 网关的项目的 Startup 里的

Configure

方法中添加如下代码:

#region 更新 Ocelot 配置接口

            // PUT /ocelot/admin/configuration 需要 Admin 的角色
            app.Map(new PathString("/ocelot/admin/configuration"), appBuilder =>
            {
                appBuilder.Use(async (context, next) =>
                {
                    if (context.Request.Method.ToUpper() != "PUT")
                    {
                        context.Response.StatusCode = 404;
                        return;
                    }
                    var authenticateResult = await context.AuthenticateAsync(AuthenticationProviderKey);
                    if (!authenticateResult.Succeeded)
                    {
                        context.Response.StatusCode = 401;
                        return;
                    }
                    if (authenticateResult.Principal.IsInRole("Admin"))
                    {
                        var configurationRepo =
                            context.RequestServices.GetRequiredService<IFileConfigurationRepository>();
                        var ocelotConfiguration = await configurationRepo.Get();
                        var logger = context.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger("OcelotConfiguration");
                        if (!ocelotConfiguration.IsError)
                        {
                            var internalConfigurationRepo = context.RequestServices.GetRequiredService<IInternalConfigurationRepository>();
                            var internalConfigurationCreator =
                                context.RequestServices.GetRequiredService<IInternalConfigurationCreator>();
                            var internalConfiguration = await internalConfigurationCreator.Create(ocelotConfiguration.Data);
                            if (!internalConfiguration.IsError)
                            {
                                internalConfigurationRepo.AddOrReplace(internalConfiguration.Data);
                                context.Response.StatusCode = 200;
                                return;
                            }
                            else
                            {
                                logger.LogError($"update ocelot configuration error, error in create ocelot internal configuration, error messages:{string.Join(", ", ocelotConfiguration.Errors)}");
                            }
                        }
                        else
                        {
                            logger.LogError($"update ocelot configuration error, error in get ocelot configuration from configurationRepo, error messages:{string.Join(", ", ocelotConfiguration.Errors)}");
                        }
                        context.Response.StatusCode = 500;
                    }
                    else
                    {
                        context.Response.StatusCode = 403;
                    }
                });
            });

            #endregion 更新 Ocelot 配置接口           

这里的代码包含了一些逻辑,检查了要操作的用户是否拥有

Admin

的角色,可以自己根据自己的需要自行修改进行定制,可以自定义要操作的角色,自定义要操作的接口地址以及请求方式。

AuthenticationProviderKey

是在

ConfigureServices

方法中定义的认证方式,示例代码如下:

public IConfiguration Configuration { get; }

        private readonly string AuthenticationProviderKey = "IdentityApiKey";

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //…
            services.AddAuthentication()
                .AddIdentityServerAuthentication(AuthenticationProviderKey, x =>
                {
                    x.Authority = Configuration["Authorization:Authority"];
                    x.ClaimsIssuer = Configuration["Authorization:ClaimsIssuer"];
                    x.RequireHttpsMetadata = false;
                });
            services.AddOcelot();
            // ......
        }           

调用 API 接口更新配置

可以使用 Postman 或者 fiddler 等调用 API 来测试

写个重新加载 ocelot 配置的接口

返回 200 即配置更新成功

Memo

Enjoy it~