mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-30 00:22:40 +01:00
Finish IServerPortProvider stuff
This commit is contained in:
@@ -35,6 +35,6 @@ namespace Tgstation.Server.Api.Models.Internal
|
||||
/// <summary>
|
||||
/// The DMAPI <see cref="Version"/>.
|
||||
/// </summary>
|
||||
public Version DMApiVersion { get; set;
|
||||
public Version DMApiVersion { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,6 +216,8 @@ namespace Tgstation.Server.Host.Components.Deployment
|
||||
default:
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Session controller returned unexpected ApiValidationStatus: {0}", validationStatus));
|
||||
}
|
||||
|
||||
job.DMApiVersion = controller.DMApiVersion;
|
||||
}
|
||||
|
||||
throw new JobException("DMAPI validation timed out!");
|
||||
|
||||
@@ -112,6 +112,11 @@ namespace Tgstation.Server.Host.Components
|
||||
/// </summary>
|
||||
readonly IRepositoryFactory repositoryFactory;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IServerPortProvider"/> for the <see cref="InstanceFactory"/>.
|
||||
/// </summary>
|
||||
readonly IServerPortProvider serverPortProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Construct an <see cref="InstanceFactory"/>
|
||||
/// </summary>
|
||||
@@ -133,6 +138,7 @@ namespace Tgstation.Server.Host.Components
|
||||
/// <param name="gitHubClientFactory">The value of <see cref="gitHubClientFactory"/></param>
|
||||
/// <param name="platformIdentifier">The value of <see cref="platformIdentifier"/></param>
|
||||
/// <param name="repositoryFactory">The value of <see cref="repositoryFactory"/>.</param>
|
||||
/// <param name="serverPortProvider">The value of <see cref="serverPortProvider"/>.</param>
|
||||
public InstanceFactory(
|
||||
IIOManager ioManager,
|
||||
IDatabaseContextFactory databaseContextFactory,
|
||||
@@ -151,7 +157,8 @@ namespace Tgstation.Server.Host.Components
|
||||
INetworkPromptReaper networkPromptReaper,
|
||||
IGitHubClientFactory gitHubClientFactory,
|
||||
IPlatformIdentifier platformIdentifier,
|
||||
IRepositoryFactory repositoryFactory)
|
||||
IRepositoryFactory repositoryFactory,
|
||||
IServerPortProvider serverPortProvider)
|
||||
{
|
||||
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
|
||||
this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
|
||||
@@ -171,6 +178,7 @@ namespace Tgstation.Server.Host.Components
|
||||
this.gitHubClientFactory = gitHubClientFactory ?? throw new ArgumentNullException(nameof(gitHubClientFactory));
|
||||
this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier));
|
||||
this.repositoryFactory = repositoryFactory ?? throw new ArgumentNullException(nameof(repositoryFactory));
|
||||
this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -215,6 +223,7 @@ namespace Tgstation.Server.Host.Components
|
||||
networkPromptReaper,
|
||||
platformIdentifier,
|
||||
bridgeRegistrar,
|
||||
serverPortProvider,
|
||||
loggerFactory,
|
||||
metadata.CloneMetadata());
|
||||
|
||||
|
||||
@@ -63,16 +63,17 @@ namespace Tgstation.Server.Host.Components.Interop.Runtime
|
||||
/// <param name="channelsJson">The value of <see cref="RuntimeFileList.ChatChannelsJson"/>.</param>
|
||||
/// <param name="commandsJson">The value of <see cref="RuntimeFileList.ChatCommandsJson"/>.</param>
|
||||
/// <param name="securityLevel">The value of <see cref="SecurityLevel"/>.</param>
|
||||
/// <param name="serverPort">The value of <see cref="ServerPort"/>.</param>
|
||||
public RuntimeInformation(
|
||||
IApplication application,
|
||||
ICryptographySuite cryptographySuite,
|
||||
IServerPortProvider portProvider,
|
||||
IEnumerable<RuntimeTestMerge> testMerges,
|
||||
Api.Models.Instance instance,
|
||||
Api.Models.Internal.RevisionInformation revision,
|
||||
string channelsJson,
|
||||
string commandsJson,
|
||||
DreamDaemonSecurity securityLevel)
|
||||
DreamDaemonSecurity securityLevel,
|
||||
ushort serverPort)
|
||||
{
|
||||
ServerVersion = application?.Version ?? throw new ArgumentNullException(nameof(application));
|
||||
AccessIdentifier = cryptographySuite?.GetSecureString() ?? throw new ArgumentNullException(nameof(cryptographySuite));
|
||||
@@ -82,6 +83,7 @@ namespace Tgstation.Server.Host.Components.Interop.Runtime
|
||||
ChatChannelsJson = channelsJson ?? throw new ArgumentNullException(nameof(channelsJson));
|
||||
ChatChannelsJson = commandsJson ?? throw new ArgumentNullException(nameof(commandsJson));
|
||||
SecurityLevel = securityLevel;
|
||||
ServerPort = serverPort;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Byond.TopicSender;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -76,6 +75,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// </summary>
|
||||
readonly IBridgeRegistrar bridgeRegistrar;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IServerPortProvider"/> for the <see cref="SessionControllerFactory"/>.
|
||||
/// </summary>
|
||||
readonly IServerPortProvider serverPortProvider;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILoggerFactory"/> for the <see cref="SessionControllerFactory"/>
|
||||
/// </summary>
|
||||
@@ -120,6 +124,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
/// <param name="networkPromptReaper">The value of <see cref="networkPromptReaper"/></param>
|
||||
/// <param name="platformIdentifier">The value of <see cref="platformIdentifier"/></param>
|
||||
/// <param name="bridgeRegistrar">The value of <see cref="bridgeRegistrar"/>.</param>
|
||||
/// <param name="serverPortProvider">The value of <see cref="serverPortProvider"/>.</param>
|
||||
/// <param name="loggerFactory">The value of <see cref="loggerFactory"/></param>
|
||||
public SessionControllerFactory(
|
||||
IProcessExecutor processExecutor,
|
||||
@@ -132,6 +137,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
INetworkPromptReaper networkPromptReaper,
|
||||
IPlatformIdentifier platformIdentifier,
|
||||
IBridgeRegistrar bridgeRegistrar,
|
||||
IServerPortProvider serverPortProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
Api.Models.Instance instance)
|
||||
{
|
||||
@@ -146,6 +152,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
this.networkPromptReaper = networkPromptReaper ?? throw new ArgumentNullException(nameof(networkPromptReaper));
|
||||
this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier));
|
||||
this.bridgeRegistrar = bridgeRegistrar ?? throw new ArgumentNullException(nameof(bridgeRegistrar));
|
||||
this.serverPortProvider = serverPortProvider ?? throw new ArgumentNullException(nameof(serverPortProvider));
|
||||
this.loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
@@ -212,7 +219,8 @@ namespace Tgstation.Server.Host.Components.Watchdog
|
||||
revisionInfo,
|
||||
JsonFile("chat_channels"),
|
||||
JsonFile("chat_commands"),
|
||||
securityLevelToUse);
|
||||
securityLevelToUse,
|
||||
await serverPortProvider.HttpApiPort.ConfigureAwait(false));
|
||||
|
||||
var interopJsonFile = JsonFile("interop");
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
@@ -340,6 +341,7 @@ namespace Tgstation.Server.Host.Core
|
||||
services.AddSingleton<ISynchronousIOManager, SynchronousIOManager>();
|
||||
services.AddSingleton<IGitHubClientFactory, GitHubClientFactory>();
|
||||
services.AddSingleton<IProcessExecutor, ProcessExecutor>();
|
||||
services.AddSingleton<IServerPortProvider, ServerPortProivder>();
|
||||
services.AddSingleton<IByondTopicSender>(new ByondTopicSender
|
||||
{
|
||||
ReceiveTimeout = generalConfiguration.ByondTopicTimeout,
|
||||
@@ -373,6 +375,7 @@ namespace Tgstation.Server.Host.Core
|
||||
IApplicationBuilder applicationBuilder,
|
||||
IServerControl serverControl,
|
||||
ITokenFactory tokenFactory,
|
||||
IServerPortProvider serverPortProvider,
|
||||
IOptions<ControlPanelConfiguration> controlPanelConfigurationOptions,
|
||||
IOptions<GeneralConfiguration> generalConfigurationOptions,
|
||||
ILogger<Application> logger)
|
||||
@@ -384,6 +387,12 @@ namespace Tgstation.Server.Host.Core
|
||||
|
||||
this.tokenFactory = tokenFactory ?? throw new ArgumentNullException(nameof(tokenFactory));
|
||||
|
||||
if (serverPortProvider == null)
|
||||
throw new ArgumentNullException(nameof(serverPortProvider));
|
||||
|
||||
var addressFeature = applicationBuilder?.ServerFeatures.Get<IServerAddressesFeature>();
|
||||
serverPortProvider.Configure(addressFeature);
|
||||
|
||||
var controlPanelConfiguration = controlPanelConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(controlPanelConfigurationOptions));
|
||||
var generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tgstation.Server.Host.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to the server's <see cref="HttpApiPort"/>.
|
||||
/// </summary>
|
||||
interface IServerPortProvider
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="Task{TResult}"/> resulting in the port the server listens on.
|
||||
/// </summary>
|
||||
Task<ushort> HttpApiPort { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Configures the <see cref="ServerPortProivder"/>.
|
||||
/// </summary>
|
||||
/// <param name="addressFeature">The <see cref="IServerAddressesFeature"/> to use.</param>
|
||||
void Configure(IServerAddressesFeature addressFeature);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tgstation.Server.Host.Core
|
||||
{
|
||||
/// <inheritdoc />
|
||||
sealed class ServerPortProivder : IServerPortProvider
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Task<ushort> HttpApiPort => taskCompletionSource.Task;
|
||||
|
||||
/// <summary>
|
||||
/// Backing <see cref="TaskCompletionSource{TResult}"/> field for <see cref="HttpApiPort"/>/
|
||||
/// </summary>
|
||||
readonly TaskCompletionSource<ushort> taskCompletionSource;
|
||||
|
||||
/// <summary>
|
||||
/// In
|
||||
/// </summary>
|
||||
public ServerPortProivder()
|
||||
{
|
||||
taskCompletionSource = new TaskCompletionSource<ushort>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServerAddressesFeature addressFeature)
|
||||
{
|
||||
if (addressFeature == null)
|
||||
throw new ArgumentNullException(nameof(addressFeature));
|
||||
|
||||
var enumerator = addressFeature.Addresses.Select(GetPortFromAddress);
|
||||
var newPort = enumerator.FirstOrDefault(x => x.HasValue);
|
||||
|
||||
if(!newPort.HasValue)
|
||||
throw new InvalidOperationException("At least one plain HTTP endpoint must be configured. Neded for BYOND -> Server communications!");
|
||||
|
||||
if (!addressFeature.Addresses.Select(GetPortFromAddress).All(x => !x.HasValue || x == newPort))
|
||||
throw new InvalidOperationException("All configured HTTP server addresses must use the same port!");
|
||||
|
||||
// Will fail if set twice
|
||||
taskCompletionSource.SetResult(newPort.Value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a given <paramref name="address"/> to its port.
|
||||
/// </summary>
|
||||
/// <param name="address">The address <see cref="string"/>.</param>
|
||||
/// <returns>The parsed port.</returns>
|
||||
static ushort? GetPortFromAddress(string address)
|
||||
{
|
||||
var splits = address.Split(":", StringSplitOptions.RemoveEmptyEntries);
|
||||
if (splits.First().Equals("https", StringComparison.OrdinalIgnoreCase))
|
||||
return null;
|
||||
|
||||
var portString = splits.Last();
|
||||
portString = portString.TrimEnd('/');
|
||||
if (UInt16.TryParse(portString, out var result))
|
||||
return result;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user