diff --git a/src/Tgstation.Server.Host.Startup/IServer.cs b/src/Tgstation.Server.Host.Startup/IServer.cs index 8dad58bdcc..28a2428211 100644 --- a/src/Tgstation.Server.Host.Startup/IServer.cs +++ b/src/Tgstation.Server.Host.Startup/IServer.cs @@ -7,7 +7,7 @@ namespace Tgstation.Server.Host.Startup /// /// Represents the host /// - public interface IServer : IDisposable + public interface IServer { /// /// The path to the updated assembly to run if any. Populated once returns @@ -17,9 +17,8 @@ namespace Tgstation.Server.Host.Startup /// /// Runs the /// - /// The arguments for the /// The for the operation /// A representing the running operation - Task RunAsync(string[] args, CancellationToken cancellationToken); + Task RunAsync(CancellationToken cancellationToken); } } diff --git a/src/Tgstation.Server.Host.Startup/IServerFactory.cs b/src/Tgstation.Server.Host.Startup/IServerFactory.cs index 43668a1049..ed92399240 100644 --- a/src/Tgstation.Server.Host.Startup/IServerFactory.cs +++ b/src/Tgstation.Server.Host.Startup/IServerFactory.cs @@ -5,10 +5,11 @@ /// public interface IServerFactory { - /// - /// Create a - /// - /// A new - IServer CreateServer(); + /// + /// Create a + /// + /// The arguments for the + /// A new + IServer CreateServer(string[] args); } } diff --git a/src/Tgstation.Server.Host.Watchdog/IsolatedServerFactory.cs b/src/Tgstation.Server.Host.Watchdog/IsolatedServerFactory.cs index c7fe7f49cc..2545747721 100644 --- a/src/Tgstation.Server.Host.Watchdog/IsolatedServerFactory.cs +++ b/src/Tgstation.Server.Host.Watchdog/IsolatedServerFactory.cs @@ -25,8 +25,9 @@ namespace Tgstation.Server.Host.Watchdog /// /// Loads the at and creates an from it /// + /// The arguments for the /// A new - public IServer CreateServer() + public IServer CreateServer(string[] args) { var assembly = LoadFromAssemblyPath(assemblyPath); //find the IServerFactory implementation @@ -35,7 +36,7 @@ namespace Tgstation.Server.Host.Watchdog var serverFactoryImplementationType = assembly.GetTypes().Where(x => serverFactoryInterfaceType.IsAssignableFrom(x)).First(); var serverFactory = (IServerFactory)Activator.CreateInstance(serverFactoryImplementationType); - return serverFactory.CreateServer(); + return serverFactory.CreateServer(args); } //honestly have no idea what this is for, but the examples i see just return null and it seems to work just fine diff --git a/src/Tgstation.Server.Host.Watchdog/Watchdog.cs b/src/Tgstation.Server.Host.Watchdog/Watchdog.cs index 540955d094..ef74711534 100644 --- a/src/Tgstation.Server.Host.Watchdog/Watchdog.cs +++ b/src/Tgstation.Server.Host.Watchdog/Watchdog.cs @@ -43,24 +43,19 @@ namespace Tgstation.Server.Host.Watchdog //first run the host we started with var serverFactory = initialServerFactory; var assemblyPath = serverFactory.GetType().Assembly.Location; - do - { - string updatePath; - using (var server = serverFactory.CreateServer()) - { - serverFactory = null; - await server.RunAsync(args, cancellationToken).ConfigureAwait(false); - updatePath = server.UpdatePath; - } + do + { + var server = serverFactory.CreateServer(args); + await server.RunAsync(cancellationToken).ConfigureAwait(false); - if (updatePath == null) - break; - - activeAssemblyDeleter.DeleteActiveAssembly(assemblyPath); - File.Move(updatePath, assemblyPath); - serverFactory = isolatedAssemblyLoader.CreateIsolatedServerFactory(assemblyPath); - } - while (!cancellationToken.IsCancellationRequested); + if (server.UpdatePath == null) + break; + + activeAssemblyDeleter.DeleteActiveAssembly(assemblyPath); + File.Move(server.UpdatePath, assemblyPath); + serverFactory = isolatedAssemblyLoader.CreateIsolatedServerFactory(assemblyPath); + } + while (!cancellationToken.IsCancellationRequested); } } } diff --git a/src/Tgstation.Server.Host/Core/Application.cs b/src/Tgstation.Server.Host/Core/Application.cs new file mode 100644 index 0000000000..83e0a44524 --- /dev/null +++ b/src/Tgstation.Server.Host/Core/Application.cs @@ -0,0 +1,76 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Tgstation.Server.Host.Core +{ + /// + /// Configures the ASP.NET Core web application + /// + sealed class Application + { + /// + /// The for the + /// + readonly IConfiguration configuration; + + /// + /// Construct an + /// + /// The value of + public Application(IConfiguration configuration) => this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); + + /// + /// Configure dependency injected services + /// + /// The to configure +#pragma warning disable CA1822 // Mark members as static + public void ConfigureServices(IServiceCollection services) +#pragma warning restore CA1822 // Mark members as static + { + if (services == null) + throw new ArgumentNullException(nameof(services)); + + services.AddMvc(); + services.AddOptions(); + services.AddLocalization(); + } + + /// + /// Configure the + /// + /// The to configure + /// The of the + public void Configure(IApplicationBuilder applicationBuilder, IHostingEnvironment hostingEnvironment) + { + if (applicationBuilder == null) + throw new ArgumentNullException(nameof(applicationBuilder)); + if (hostingEnvironment == null) + throw new ArgumentNullException(nameof(hostingEnvironment)); + + if (hostingEnvironment.IsDevelopment()) + applicationBuilder.UseDeveloperExceptionPage(); + + var defaultCulture = new CultureInfo("en"); + var supportedCultures = new List + { + defaultCulture + }; + + CultureInfo.CurrentCulture = defaultCulture; + CultureInfo.CurrentUICulture = defaultCulture; + + applicationBuilder.UseRequestLocalization(new RequestLocalizationOptions + { + SupportedCultures = supportedCultures, + SupportedUICultures = supportedCultures, + }); + + applicationBuilder.UseMvc(); + } + } +} \ No newline at end of file diff --git a/src/Tgstation.Server.Host/Server.cs b/src/Tgstation.Server.Host/Server.cs index 50406a988d..5de89070ff 100644 --- a/src/Tgstation.Server.Host/Server.cs +++ b/src/Tgstation.Server.Host/Server.cs @@ -1,5 +1,9 @@ -using System.Threading; +using Microsoft.AspNetCore.Hosting; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading; using System.Threading.Tasks; +using Tgstation.Server.Host.Core; using Tgstation.Server.Host.Startup; namespace Tgstation.Server.Host @@ -10,10 +14,23 @@ namespace Tgstation.Server.Host /// public string UpdatePath => null; - /// - public void Dispose() { } + /// + /// The for the + /// + readonly IWebHostBuilder webHostBuilder; + + /// + /// Construct a + /// + /// The value of + public Server(IWebHostBuilder webHostBuilder) => this.webHostBuilder = webHostBuilder ?? throw new ArgumentNullException(nameof(webHostBuilder)); /// - public Task RunAsync(string[] args, CancellationToken cancellationToken) => Task.CompletedTask; + [ExcludeFromCodeCoverage] + public async Task RunAsync(CancellationToken cancellationToken) + { + using (var webHost = webHostBuilder.UseStartup().Build()) + await webHost.RunAsync(cancellationToken).ConfigureAwait(false); + } } } diff --git a/src/Tgstation.Server.Host/ServerFactory.cs b/src/Tgstation.Server.Host/ServerFactory.cs index e0f9291516..f934789cf6 100644 --- a/src/Tgstation.Server.Host/ServerFactory.cs +++ b/src/Tgstation.Server.Host/ServerFactory.cs @@ -1,4 +1,6 @@ -using Tgstation.Server.Host.Startup; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Tgstation.Server.Host.Startup; namespace Tgstation.Server.Host { @@ -6,6 +8,6 @@ namespace Tgstation.Server.Host public sealed class ServerFactory : IServerFactory { /// - public IServer CreateServer() => new Server(); + public IServer CreateServer(string[] args) => new Server(WebHost.CreateDefaultBuilder(args)); } } diff --git a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj index d204eda12b..9f4dc2c1ea 100644 --- a/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj +++ b/src/Tgstation.Server.Host/Tgstation.Server.Host.csproj @@ -18,6 +18,7 @@ + diff --git a/tests/Tgstation.Server.Host.Tests/TestServer.cs b/tests/Tgstation.Server.Host.Tests/TestServer.cs deleted file mode 100644 index 5e20bd627e..0000000000 --- a/tests/Tgstation.Server.Host.Tests/TestServer.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Tgstation.Server.Host.Tests -{ - [TestClass] - public sealed class TestServer - { - [TestMethod] - public async Task TestRunAndDispose() - { - using (var server = new Server()) - { - await server.RunAsync(null, default).ConfigureAwait(false); - Assert.IsNull(server.UpdatePath); - } - } - } -} diff --git a/tests/Tgstation.Server.Host.Tests/Tgstation.Server.Host.Tests.csproj b/tests/Tgstation.Server.Host.Tests/Tgstation.Server.Host.Tests.csproj index f637b93ead..6481ec2802 100644 --- a/tests/Tgstation.Server.Host.Tests/Tgstation.Server.Host.Tests.csproj +++ b/tests/Tgstation.Server.Host.Tests/Tgstation.Server.Host.Tests.csproj @@ -9,8 +9,9 @@ - - + + + diff --git a/tests/Tgstation.Server.Host.Watchdog.Tests/TestIsolatedServerFactory.cs b/tests/Tgstation.Server.Host.Watchdog.Tests/TestIsolatedServerFactory.cs index 33187c485b..ab382bff97 100644 --- a/tests/Tgstation.Server.Host.Watchdog.Tests/TestIsolatedServerFactory.cs +++ b/tests/Tgstation.Server.Host.Watchdog.Tests/TestIsolatedServerFactory.cs @@ -20,7 +20,7 @@ namespace Tgstation.Server.Host.Watchdog.Tests public void TestLoading() { var isf = new IsolatedServerFactory(typeof(ServerFactory).Assembly.Location); - Assert.IsNotNull(isf.CreateServer()); + Assert.IsNotNull(isf.CreateServer(Array.Empty())); } } } diff --git a/tests/Tgstation.Server.Host.Watchdog.Tests/TestWatchdog.cs b/tests/Tgstation.Server.Host.Watchdog.Tests/TestWatchdog.cs index 00b492d110..5d74371f08 100644 --- a/tests/Tgstation.Server.Host.Watchdog.Tests/TestWatchdog.cs +++ b/tests/Tgstation.Server.Host.Watchdog.Tests/TestWatchdog.cs @@ -26,7 +26,7 @@ namespace Tgstation.Server.Host.Watchdog.Tests { readonly IServer server; public MockServerFactory(IServer server) => this.server = server; - public IServer CreateServer() => server; + public IServer CreateServer(string[] args) => server; } [TestMethod] @@ -41,7 +41,7 @@ namespace Tgstation.Server.Host.Watchdog.Tests using (var cts = new CancellationTokenSource()) { - mockServer.Setup(x => x.RunAsync(It.IsNotNull(), cts.Token)).Returns(Task.CompletedTask).Verifiable(); + mockServer.Setup(x => x.RunAsync(cts.Token)).Returns(Task.CompletedTask).Verifiable(); await wd.RunAsync(Array.Empty(), cts.Token).ConfigureAwait(false); mockServer.VerifyAll(); } @@ -62,7 +62,7 @@ namespace Tgstation.Server.Host.Watchdog.Tests using (var cts = new CancellationTokenSource()) { int count = 0; - mockServer.Setup(x => x.RunAsync(It.IsNotNull(), cts.Token)).Callback(() => + mockServer.Setup(x => x.RunAsync(cts.Token)).Callback(() => { if (++count > 1) cts.Cancel();