From 8c107de92e29e11db7f971725ebfb774741fd798 Mon Sep 17 00:00:00 2001 From: runebaas Date: Mon, 14 May 2018 02:33:49 +0200 Subject: [PATCH] Replace nancy with kestrel --- Geekbot.net/Geekbot.net.csproj | 6 +- Geekbot.net/Program.cs | 5 +- .../Commands}/CommandDto.cs | 2 +- .../Commands}/CommandParamDto.cs | 2 +- .../Controllers/Commands/HelpController.cs | 41 ++++++++++ .../{ => Controllers}/Status/ApiStatusDto.cs | 2 +- .../Controllers/Status/StatusController.cs | 22 ++++++ Geekbot.net/WebApi/Help/HelpController.cs | 44 ----------- Geekbot.net/WebApi/Logging/AspLogProvider.cs | 29 +++++++ Geekbot.net/WebApi/Logging/AspLogger.cs | 75 +++++++++++++++++++ Geekbot.net/WebApi/Status/StatusController.cs | 22 ------ Geekbot.net/WebApi/WebApiStartup.cs | 50 +++++++++++++ Geekbot.net/WebApi/WebConfig.cs | 39 ---------- 13 files changed, 222 insertions(+), 117 deletions(-) rename Geekbot.net/WebApi/{Help => Controllers/Commands}/CommandDto.cs (85%) rename Geekbot.net/WebApi/{Help => Controllers/Commands}/CommandParamDto.cs (74%) create mode 100644 Geekbot.net/WebApi/Controllers/Commands/HelpController.cs rename Geekbot.net/WebApi/{ => Controllers}/Status/ApiStatusDto.cs (75%) create mode 100644 Geekbot.net/WebApi/Controllers/Status/StatusController.cs delete mode 100644 Geekbot.net/WebApi/Help/HelpController.cs create mode 100644 Geekbot.net/WebApi/Logging/AspLogProvider.cs create mode 100644 Geekbot.net/WebApi/Logging/AspLogger.cs delete mode 100644 Geekbot.net/WebApi/Status/StatusController.cs create mode 100644 Geekbot.net/WebApi/WebApiStartup.cs delete mode 100644 Geekbot.net/WebApi/WebConfig.cs diff --git a/Geekbot.net/Geekbot.net.csproj b/Geekbot.net/Geekbot.net.csproj index 27e5dad..83a37d9 100755 --- a/Geekbot.net/Geekbot.net.csproj +++ b/Geekbot.net/Geekbot.net.csproj @@ -24,6 +24,7 @@ + @@ -34,8 +35,6 @@ - - @@ -43,9 +42,6 @@ - - 1.2.6 - diff --git a/Geekbot.net/Program.cs b/Geekbot.net/Program.cs index e5b3f59..c9b53b3 100755 --- a/Geekbot.net/Program.cs +++ b/Geekbot.net/Program.cs @@ -19,9 +19,7 @@ using Geekbot.net.Lib.Logger; using Geekbot.net.Lib.Media; using Geekbot.net.Lib.ReactionListener; using Geekbot.net.Lib.UserRepository; -using Geekbot.net.WebApi; using Microsoft.Extensions.DependencyInjection; -using Nancy.Hosting.Self; using StackExchange.Redis; using WikipediaApi; @@ -203,8 +201,7 @@ namespace Geekbot.net { _logger.Information(LogSource.Api, "Starting Webserver"); var webApiUrl = new Uri($"http://{_runParameters.ApiHost}:{_runParameters.ApiPort}"); - var webConfig = new WebConfig(_logger, _commands); - new NancyHost(webConfig, webApiUrl).Start(); + WebApi.WebApiStartup.StartWebApi(_logger, _runParameters, _commands); _logger.Information(LogSource.Api, $"Webserver now running on {webApiUrl}"); } } diff --git a/Geekbot.net/WebApi/Help/CommandDto.cs b/Geekbot.net/WebApi/Controllers/Commands/CommandDto.cs similarity index 85% rename from Geekbot.net/WebApi/Help/CommandDto.cs rename to Geekbot.net/WebApi/Controllers/Commands/CommandDto.cs index 5921fa6..50f7872 100644 --- a/Geekbot.net/WebApi/Help/CommandDto.cs +++ b/Geekbot.net/WebApi/Controllers/Commands/CommandDto.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace Geekbot.net.WebApi.Help +namespace Geekbot.net.WebApi.Controllers.Commands { public class CommandDto { diff --git a/Geekbot.net/WebApi/Help/CommandParamDto.cs b/Geekbot.net/WebApi/Controllers/Commands/CommandParamDto.cs similarity index 74% rename from Geekbot.net/WebApi/Help/CommandParamDto.cs rename to Geekbot.net/WebApi/Controllers/Commands/CommandParamDto.cs index f7ce0ea..5f7519d 100644 --- a/Geekbot.net/WebApi/Help/CommandParamDto.cs +++ b/Geekbot.net/WebApi/Controllers/Commands/CommandParamDto.cs @@ -1,4 +1,4 @@ -namespace Geekbot.net.WebApi.Help +namespace Geekbot.net.WebApi.Controllers.Commands { public class CommandParamDto { diff --git a/Geekbot.net/WebApi/Controllers/Commands/HelpController.cs b/Geekbot.net/WebApi/Controllers/Commands/HelpController.cs new file mode 100644 index 0000000..9105706 --- /dev/null +++ b/Geekbot.net/WebApi/Controllers/Commands/HelpController.cs @@ -0,0 +1,41 @@ +using System.Linq; +using Discord.Commands; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.Mvc; + +namespace Geekbot.net.WebApi.Controllers.Commands +{ + [EnableCors("AllowSpecificOrigin")] + public class HelpController : Controller + { + private readonly CommandService _commands; + + public HelpController(CommandService commands) + { + _commands = commands; + } + + [Route("/v1/commands")] + public IActionResult GetCommands() + { + var commandList = (from cmd in _commands.Commands + let cmdParamsObj = cmd.Parameters.Select(cmdParam => new CommandParamDto + { + Summary = cmdParam.Summary, + Default = cmdParam.DefaultValue?.ToString() ?? null, + Type = cmdParam.Type?.ToString() + }) + .ToList() + let param = string.Join(", !", cmd.Aliases) + select new CommandDto + { + Name = cmd.Name, + Summary = cmd.Summary, + IsAdminCommand = (param.Contains("admin")), + Aliases = cmd.Aliases.ToArray(), + Params = cmdParamsObj + }).ToList(); + return Ok(commandList); + } + } +} \ No newline at end of file diff --git a/Geekbot.net/WebApi/Status/ApiStatusDto.cs b/Geekbot.net/WebApi/Controllers/Status/ApiStatusDto.cs similarity index 75% rename from Geekbot.net/WebApi/Status/ApiStatusDto.cs rename to Geekbot.net/WebApi/Controllers/Status/ApiStatusDto.cs index 242bf58..0d5e6ad 100644 --- a/Geekbot.net/WebApi/Status/ApiStatusDto.cs +++ b/Geekbot.net/WebApi/Controllers/Status/ApiStatusDto.cs @@ -1,4 +1,4 @@ -namespace Geekbot.net.WebApi.Status +namespace Geekbot.net.WebApi.Controllers.Status { public class ApiStatusDto { diff --git a/Geekbot.net/WebApi/Controllers/Status/StatusController.cs b/Geekbot.net/WebApi/Controllers/Status/StatusController.cs new file mode 100644 index 0000000..e9af6bb --- /dev/null +++ b/Geekbot.net/WebApi/Controllers/Status/StatusController.cs @@ -0,0 +1,22 @@ +using Geekbot.net.Lib; +using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.Mvc; + +namespace Geekbot.net.WebApi.Controllers.Status +{ + [EnableCors("AllowSpecificOrigin")] + public class StatusController : Controller + { + [Route("/")] + public IActionResult GetCommands() + { + var responseBody = new ApiStatusDto + { + GeekbotVersion = Constants.BotVersion(), + ApiVersion = Constants.ApiVersion.ToString(), + Status = "Online" + }; + return Ok(responseBody); + } + } +} \ No newline at end of file diff --git a/Geekbot.net/WebApi/Help/HelpController.cs b/Geekbot.net/WebApi/Help/HelpController.cs deleted file mode 100644 index 8aaed12..0000000 --- a/Geekbot.net/WebApi/Help/HelpController.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Linq; -using System.Reflection; -using System.Threading.Tasks; -using Discord.Commands; -using Nancy; - -namespace Geekbot.net.WebApi.Help -{ - public sealed class HelpController : NancyModule - { - public HelpController(CommandService commands) - { - Get("/v1/commands", args => - { - var commandList = (from cmd in commands.Commands - let cmdParamsObj = cmd.Parameters.Select(cmdParam => new CommandParamDto - { - Summary = cmdParam.Summary, - Default = cmdParam.DefaultValue?.ToString() ?? null, - Type = cmdParam.Type?.ToString() - }) - .ToList() - let param = string.Join(", !", cmd.Aliases) - select new CommandDto - { - Name = cmd.Name, - Summary = cmd.Summary, - IsAdminCommand = (param.Contains("admin")), - Aliases = cmd.Aliases.ToArray(), - Params = cmdParamsObj - }).ToList(); - return Response.AsJson(commandList); - - }); - } - - private async Task GetCommands() - { - var commands = new CommandService(); - await commands.AddModulesAsync(Assembly.GetEntryAssembly()); - return commands; - } - } -} \ No newline at end of file diff --git a/Geekbot.net/WebApi/Logging/AspLogProvider.cs b/Geekbot.net/WebApi/Logging/AspLogProvider.cs new file mode 100644 index 0000000..9a1599a --- /dev/null +++ b/Geekbot.net/WebApi/Logging/AspLogProvider.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Concurrent; +using Geekbot.net.Lib.Logger; +using Microsoft.Extensions.Logging; + +namespace Geekbot.net.WebApi.Logging +{ + public class AspLogProvider : ILoggerProvider + { + private readonly IGeekbotLogger _geekbotLogger; + + private readonly ConcurrentDictionary _loggers = new ConcurrentDictionary(); + + public AspLogProvider(IGeekbotLogger geekbotLogger) + { + _geekbotLogger = geekbotLogger; + } + + public void Dispose() + { + _loggers.Clear(); + } + + public ILogger CreateLogger(string categoryName) + { + return _loggers.GetOrAdd(categoryName, name => new AspLogger(categoryName, _geekbotLogger)); + } + } +} \ No newline at end of file diff --git a/Geekbot.net/WebApi/Logging/AspLogger.cs b/Geekbot.net/WebApi/Logging/AspLogger.cs new file mode 100644 index 0000000..37c9de1 --- /dev/null +++ b/Geekbot.net/WebApi/Logging/AspLogger.cs @@ -0,0 +1,75 @@ +using System; +using Geekbot.net.Lib.Logger; +using Microsoft.Extensions.Logging; + +namespace Geekbot.net.WebApi.Logging +{ + public class AspLogger : ILogger + { + private readonly string _categoryName; + private readonly IGeekbotLogger _geekbotLogger; + + public AspLogger(string categoryName, IGeekbotLogger geekbotLogger) + { + geekbotLogger.Trace(LogSource.Api, $"Adding {categoryName}"); + _categoryName = categoryName; + _geekbotLogger = geekbotLogger; + } + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + switch (logLevel) + { + case LogLevel.Trace: + _geekbotLogger.Trace(LogSource.Api, $"{eventId.Id} - {_categoryName} - {state}"); + break; + case LogLevel.Debug: + _geekbotLogger.Debug(LogSource.Api, $"{eventId.Id} - {_categoryName} - {state}"); + break; + case LogLevel.Information: + _geekbotLogger.Information(LogSource.Api, $"{eventId.Id} - {_categoryName} - {state}"); + break; + case LogLevel.Warning: + _geekbotLogger.Warning(LogSource.Api, $"{eventId.Id} - {_categoryName} - {state}", exception); + break; + case LogLevel.Error: + case LogLevel.Critical: + _geekbotLogger.Error(LogSource.Api, $"{eventId.Id} - {_categoryName} - {state}", exception); + break; + default: + throw new ArgumentOutOfRangeException(nameof(logLevel)); + } + } + + public bool IsEnabled(LogLevel logLevel) + { + return !_geekbotLogger.LogAsJson() && _geekbotLogger.GetNLogger().IsEnabled(ToGeekbotLogLevel(logLevel)); + } + + public IDisposable BeginScope(TState state) + { + return null; + } + + private static NLog.LogLevel ToGeekbotLogLevel(LogLevel level) + { + switch (level) + { + case LogLevel.Trace: + return NLog.LogLevel.Trace; + case LogLevel.Debug: + return NLog.LogLevel.Debug; + case LogLevel.Information: + return NLog.LogLevel.Info; + case LogLevel.Warning: + return NLog.LogLevel.Warn; + case LogLevel.Error: + return NLog.LogLevel.Error; + case LogLevel.Critical: + return NLog.LogLevel.Fatal; + default: + throw new ArgumentOutOfRangeException(nameof(level)); + } + } + } +} \ No newline at end of file diff --git a/Geekbot.net/WebApi/Status/StatusController.cs b/Geekbot.net/WebApi/Status/StatusController.cs deleted file mode 100644 index a2c692c..0000000 --- a/Geekbot.net/WebApi/Status/StatusController.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Geekbot.net.Lib; -using Nancy; - -namespace Geekbot.net.WebApi.Status -{ - public sealed class StatusController : NancyModule - { - public StatusController() - { - Get("/", args => - { - var responseBody = new ApiStatusDto - { - GeekbotVersion = Constants.BotVersion(), - ApiVersion = Constants.ApiVersion.ToString(), - Status = "Online" - }; - return Response.AsJson(responseBody); - }); - } - } -} \ No newline at end of file diff --git a/Geekbot.net/WebApi/WebApiStartup.cs b/Geekbot.net/WebApi/WebApiStartup.cs new file mode 100644 index 0000000..675ba1b --- /dev/null +++ b/Geekbot.net/WebApi/WebApiStartup.cs @@ -0,0 +1,50 @@ +using System; +using System.Net; +using System.Reflection; +using Discord.Commands; +using Geekbot.net.Lib; +using Geekbot.net.Lib.Logger; +using Geekbot.net.WebApi.Logging; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Geekbot.net.WebApi +{ + public class WebApiStartup + { + public static void StartWebApi(IGeekbotLogger logger, RunParameters runParameters, CommandService commandService) + { + WebHost.CreateDefaultBuilder() + .UseKestrel(options => + { + options.Listen(IPAddress.Any, int.Parse(runParameters.ApiPort)); + }) + .ConfigureServices(services => + { + services.AddMvc(); + services.AddSingleton(commandService); + services.AddCors(options => + { + options.AddPolicy("AllowSpecificOrigin", + builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); + }); + }) + .Configure(app => + { + app.UseMvc(); + app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().Build()); + }) + .ConfigureLogging(logging => + { + logging.ClearProviders(); + logging.SetMinimumLevel(LogLevel.Debug); + logging.AddProvider(new AspLogProvider(logger)); + }) + .UseSetting(WebHostDefaults.ApplicationKey, typeof(Program).GetTypeInfo().Assembly.FullName) + .Build().Run(); + } + } +} \ No newline at end of file diff --git a/Geekbot.net/WebApi/WebConfig.cs b/Geekbot.net/WebApi/WebConfig.cs deleted file mode 100644 index 6c5a70c..0000000 --- a/Geekbot.net/WebApi/WebConfig.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Diagnostics; -using Discord.Commands; -using Geekbot.net.Lib.Logger; -using Nancy; -using Nancy.Bootstrapper; -using Nancy.TinyIoc; - -namespace Geekbot.net.WebApi -{ - public class WebConfig : DefaultNancyBootstrapper - { - private readonly GeekbotLogger _logger; - private readonly CommandService _commands; - - public WebConfig(GeekbotLogger logger, CommandService commands) - { - _logger = logger; - _commands = commands; - } - - protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context) - { - // Register Dependencies - container.Register(_logger); - container.Register(_commands); - - // Enable CORS - pipelines.AfterRequest.AddItemToEndOfPipeline(ctx => - { - _logger.Information(LogSource.Api, ctx.Request.Path.ToString()); - - ctx.Response.WithHeader("Access-Control-Allow-Origin", "*") - .WithHeader("Access-Control-Allow-Methods", "GET") - .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type") - .WithHeader("Last-Modified", Process.GetCurrentProcess().StartTime.ToString()); - }); - } - } -} \ No newline at end of file