mirror of
https://github.com/chylex/Minecraft-Phantom-Panel.git
synced 2024-11-25 16:42:54 +01:00
Compare commits
5 Commits
a89a8738f9
...
4ac60f61eb
Author | SHA1 | Date | |
---|---|---|---|
4ac60f61eb | |||
489c68ad8e | |||
5b74038c9d | |||
24d41dc9f8 | |||
627e7436fd |
@ -1,9 +1,9 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Server + Agent x3" type="CompoundRunConfigurationType">
|
<configuration default="false" name="Controller + Agent x3" type="CompoundRunConfigurationType">
|
||||||
<toRun name="Agent 1" type="DotNetProject" />
|
<toRun name="Agent 1" type="DotNetProject" />
|
||||||
<toRun name="Agent 2" type="DotNetProject" />
|
<toRun name="Agent 2" type="DotNetProject" />
|
||||||
<toRun name="Agent 3" type="DotNetProject" />
|
<toRun name="Agent 3" type="DotNetProject" />
|
||||||
<toRun name="Server" type="DotNetProject" />
|
<toRun name="Controller" type="DotNetProject" />
|
||||||
<method v="2" />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
7
.run/Controller + Agent.run.xml
Normal file
7
.run/Controller + Agent.run.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Controller + Agent" type="CompoundRunConfigurationType">
|
||||||
|
<toRun name="Agent 1" type="DotNetProject" />
|
||||||
|
<toRun name="Controller" type="DotNetProject" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
@ -1,7 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="Server + Agent" type="CompoundRunConfigurationType">
|
|
||||||
<toRun name="Agent 1" type="DotNetProject" />
|
|
||||||
<toRun name="Server" type="DotNetProject" />
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Agent.Minecraft.Command;
|
namespace Phantom.Agent.Minecraft.Command;
|
||||||
|
|
||||||
public static class MinecraftCommand {
|
public static class MinecraftCommand {
|
||||||
public const string SaveOn = "save-on";
|
public const string SaveOn = "save-on";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using Phantom.Utils.Collections;
|
using Phantom.Utils.Collections;
|
||||||
using Phantom.Utils.Processes;
|
using Phantom.Utils.Processes;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Instance;
|
namespace Phantom.Agent.Minecraft.Instance;
|
||||||
|
|
||||||
public sealed class InstanceProcess : IDisposable {
|
public sealed class InstanceProcess : IDisposable {
|
||||||
public InstanceProperties InstanceProperties { get; }
|
public InstanceProperties InstanceProperties { get; }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Phantom.Common.Data.Java;
|
using Phantom.Common.Data.Java;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Java;
|
namespace Phantom.Agent.Minecraft.Java;
|
||||||
|
|
||||||
public sealed class JavaRuntimeExecutable {
|
public sealed class JavaRuntimeExecutable {
|
||||||
internal string ExecutablePath { get; }
|
internal string ExecutablePath { get; }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Phantom.Agent.Minecraft.Java;
|
using Phantom.Agent.Minecraft.Java;
|
||||||
using Phantom.Agent.Minecraft.Server;
|
using Phantom.Agent.Minecraft.Server;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Launcher;
|
namespace Phantom.Agent.Minecraft.Launcher;
|
||||||
|
|
||||||
public sealed record LaunchServices(MinecraftServerExecutables ServerExecutables, JavaRuntimeRepository JavaRuntimeRepository);
|
public sealed record LaunchServices(MinecraftServerExecutables ServerExecutables, JavaRuntimeRepository JavaRuntimeRepository);
|
||||||
|
@ -3,7 +3,7 @@ using Phantom.Agent.Minecraft.Instance;
|
|||||||
using Phantom.Utils.IO;
|
using Phantom.Utils.IO;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Launcher.Types;
|
namespace Phantom.Agent.Minecraft.Launcher.Types;
|
||||||
|
|
||||||
public sealed class FabricLauncher : BaseLauncher {
|
public sealed class FabricLauncher : BaseLauncher {
|
||||||
public FabricLauncher(InstanceProperties instanceProperties) : base(instanceProperties) {}
|
public FabricLauncher(InstanceProperties instanceProperties) : base(instanceProperties) {}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using Phantom.Agent.Minecraft.Server;
|
using Phantom.Agent.Minecraft.Server;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Launcher.Types;
|
namespace Phantom.Agent.Minecraft.Launcher.Types;
|
||||||
|
|
||||||
public sealed class InvalidLauncher : IServerLauncher {
|
public sealed class InvalidLauncher : IServerLauncher {
|
||||||
public static InvalidLauncher Instance { get; } = new ();
|
public static InvalidLauncher Instance { get; } = new ();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Phantom.Agent.Minecraft.Instance;
|
using Phantom.Agent.Minecraft.Instance;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Launcher.Types;
|
namespace Phantom.Agent.Minecraft.Launcher.Types;
|
||||||
|
|
||||||
public sealed class VanillaLauncher : BaseLauncher {
|
public sealed class VanillaLauncher : BaseLauncher {
|
||||||
public VanillaLauncher(InstanceProperties instanceProperties) : base(instanceProperties) {}
|
public VanillaLauncher(InstanceProperties instanceProperties) : base(instanceProperties) {}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Phantom.Agent.Minecraft.Java;
|
using Phantom.Agent.Minecraft.Java;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Properties;
|
namespace Phantom.Agent.Minecraft.Properties;
|
||||||
|
|
||||||
abstract class MinecraftServerProperty<T> {
|
abstract class MinecraftServerProperty<T> {
|
||||||
private readonly string key;
|
private readonly string key;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Agent.Minecraft.Server;
|
namespace Phantom.Agent.Minecraft.Server;
|
||||||
|
|
||||||
public sealed class DownloadProgressEventArgs : EventArgs {
|
public sealed class DownloadProgressEventArgs : EventArgs {
|
||||||
public ulong DownloadedBytes { get; }
|
public ulong DownloadedBytes { get; }
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
namespace Phantom.Agent.Minecraft.Server;
|
namespace Phantom.Agent.Minecraft.Server;
|
||||||
|
|
||||||
sealed record MinecraftServerExecutableDownloadListener(EventHandler<DownloadProgressEventArgs> DownloadProgressEventHandler, CancellationToken CancellationToken);
|
sealed record MinecraftServerExecutableDownloadListener(EventHandler<DownloadProgressEventArgs> DownloadProgressEventHandler, CancellationToken CancellationToken);
|
||||||
|
@ -6,7 +6,7 @@ using System.Text;
|
|||||||
using Phantom.Common.Logging;
|
using Phantom.Common.Logging;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Agent.Minecraft.Server;
|
namespace Phantom.Agent.Minecraft.Server;
|
||||||
|
|
||||||
public sealed class ServerStatusProtocol {
|
public sealed class ServerStatusProtocol {
|
||||||
private readonly ILogger logger;
|
private readonly ILogger logger;
|
||||||
|
43
Agent/Phantom.Agent.Rpc/RpcClientRuntime.cs
Normal file
43
Agent/Phantom.Agent.Rpc/RpcClientRuntime.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using NetMQ;
|
||||||
|
using NetMQ.Sockets;
|
||||||
|
using Phantom.Common.Data.Agent;
|
||||||
|
using Phantom.Common.Messages.Agent;
|
||||||
|
using Phantom.Common.Messages.Agent.ToController;
|
||||||
|
using Phantom.Utils.Rpc;
|
||||||
|
using Phantom.Utils.Tasks;
|
||||||
|
|
||||||
|
namespace Phantom.Agent.Rpc;
|
||||||
|
|
||||||
|
public sealed class RpcClientRuntime : RpcClientRuntime<IMessageToAgentListener, IMessageToControllerListener, RegisterAgentMessage> {
|
||||||
|
public static Task Launch(RpcConfiguration config, AuthToken authToken, AgentInfo agentInfo, Func<RpcConnectionToServer<IMessageToControllerListener>, IMessageToAgentListener> listenerFactory, SemaphoreSlim disconnectSemaphore, CancellationToken receiveCancellationToken) {
|
||||||
|
return new RpcClientRuntime(config, agentInfo.Guid, listenerFactory, new RegisterAgentMessage(authToken, agentInfo), disconnectSemaphore, receiveCancellationToken).Launch();
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly RpcConfiguration config;
|
||||||
|
private readonly Guid agentGuid;
|
||||||
|
|
||||||
|
private RpcClientRuntime(RpcConfiguration config, Guid agentGuid, Func<RpcConnectionToServer<IMessageToControllerListener>, IMessageToAgentListener> messageListenerFactory, RegisterAgentMessage registerAgentMessage, SemaphoreSlim disconnectSemaphore, CancellationToken receiveCancellationToken) : base(config, AgentMessageRegistries.Definitions, messageListenerFactory, registerAgentMessage, disconnectSemaphore, receiveCancellationToken) {
|
||||||
|
this.config = config;
|
||||||
|
this.agentGuid = agentGuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void RunWithConnection(ClientSocket socket, RpcConnectionToServer<IMessageToControllerListener> connection, TaskManager taskManager) {
|
||||||
|
ServerMessaging.SetCurrentConnection(connection);
|
||||||
|
|
||||||
|
var keepAliveLoop = new KeepAliveLoop(connection);
|
||||||
|
try {
|
||||||
|
base.RunWithConnection(socket, connection, taskManager);
|
||||||
|
} finally {
|
||||||
|
keepAliveLoop.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task Disconnect(ClientSocket socket) {
|
||||||
|
var unregisterMessageBytes = AgentMessageRegistries.ToController.Write(new UnregisterAgentMessage(agentGuid)).ToArray();
|
||||||
|
try {
|
||||||
|
await socket.SendAsync(unregisterMessageBytes).AsTask().WaitAsync(TimeSpan.FromSeconds(5), CancellationToken.None);
|
||||||
|
} catch (TimeoutException) {
|
||||||
|
config.RuntimeLogger.Error("Timed out communicating agent shutdown with the controller.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,107 +0,0 @@
|
|||||||
using NetMQ;
|
|
||||||
using NetMQ.Sockets;
|
|
||||||
using Phantom.Common.Data.Agent;
|
|
||||||
using Phantom.Common.Messages.Agent;
|
|
||||||
using Phantom.Common.Messages.Agent.BiDirectional;
|
|
||||||
using Phantom.Common.Messages.Agent.ToController;
|
|
||||||
using Phantom.Utils.Rpc;
|
|
||||||
using Phantom.Utils.Rpc.Message;
|
|
||||||
using Phantom.Utils.Tasks;
|
|
||||||
using Serilog;
|
|
||||||
using Serilog.Events;
|
|
||||||
|
|
||||||
namespace Phantom.Agent.Rpc;
|
|
||||||
|
|
||||||
public sealed class RpcLauncher : RpcRuntime<ClientSocket> {
|
|
||||||
public static Task Launch(RpcConfiguration config, AuthToken authToken, AgentInfo agentInfo, Func<RpcConnectionToServer<IMessageToControllerListener>, IMessageToAgentListener> listenerFactory, SemaphoreSlim disconnectSemaphore, CancellationToken receiveCancellationToken) {
|
|
||||||
var socket = new ClientSocket();
|
|
||||||
var options = socket.Options;
|
|
||||||
|
|
||||||
options.CurveServerCertificate = config.ServerCertificate;
|
|
||||||
options.CurveCertificate = new NetMQCertificate();
|
|
||||||
options.HelloMessage = AgentMessageRegistries.ToController.Write(new RegisterAgentMessage(authToken, agentInfo)).ToArray();
|
|
||||||
|
|
||||||
return new RpcLauncher(config, socket, agentInfo.Guid, listenerFactory, disconnectSemaphore, receiveCancellationToken).Launch();
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly RpcConfiguration config;
|
|
||||||
private readonly Guid agentGuid;
|
|
||||||
private readonly Func<RpcConnectionToServer<IMessageToControllerListener>, IMessageToAgentListener> messageListenerFactory;
|
|
||||||
|
|
||||||
private readonly SemaphoreSlim disconnectSemaphore;
|
|
||||||
private readonly CancellationToken receiveCancellationToken;
|
|
||||||
|
|
||||||
private RpcLauncher(RpcConfiguration config, ClientSocket socket, Guid agentGuid, Func<RpcConnectionToServer<IMessageToControllerListener>, IMessageToAgentListener> messageListenerFactory, SemaphoreSlim disconnectSemaphore, CancellationToken receiveCancellationToken) : base(config, socket) {
|
|
||||||
this.config = config;
|
|
||||||
this.agentGuid = agentGuid;
|
|
||||||
this.messageListenerFactory = messageListenerFactory;
|
|
||||||
this.disconnectSemaphore = disconnectSemaphore;
|
|
||||||
this.receiveCancellationToken = receiveCancellationToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Connect(ClientSocket socket) {
|
|
||||||
var logger = config.RuntimeLogger;
|
|
||||||
var url = config.TcpUrl;
|
|
||||||
|
|
||||||
logger.Information("Starting ZeroMQ client and connecting to {Url}...", url);
|
|
||||||
socket.Connect(url);
|
|
||||||
logger.Information("ZeroMQ client ready.");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Run(ClientSocket socket, MessageReplyTracker replyTracker, TaskManager taskManager) {
|
|
||||||
var connection = new RpcConnectionToServer<IMessageToControllerListener>(socket, AgentMessageRegistries.ToController, replyTracker);
|
|
||||||
ServerMessaging.SetCurrentConnection(connection);
|
|
||||||
|
|
||||||
var logger = config.RuntimeLogger;
|
|
||||||
var handler = new MessageToAgentHandler(messageListenerFactory(connection), logger, taskManager, receiveCancellationToken);
|
|
||||||
var keepAliveLoop = new KeepAliveLoop(connection);
|
|
||||||
|
|
||||||
try {
|
|
||||||
while (!receiveCancellationToken.IsCancellationRequested) {
|
|
||||||
var data = socket.Receive(receiveCancellationToken);
|
|
||||||
|
|
||||||
LogMessageType(logger, data);
|
|
||||||
|
|
||||||
if (data.Length > 0) {
|
|
||||||
AgentMessageRegistries.ToAgent.Handle(data, handler);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (OperationCanceledException) {
|
|
||||||
// Ignore.
|
|
||||||
} finally {
|
|
||||||
logger.Debug("ZeroMQ client stopped receiving messages.");
|
|
||||||
|
|
||||||
disconnectSemaphore.Wait(CancellationToken.None);
|
|
||||||
keepAliveLoop.Cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LogMessageType(ILogger logger, ReadOnlyMemory<byte> data) {
|
|
||||||
if (!logger.IsEnabled(LogEventLevel.Verbose)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.Length > 0 && AgentMessageRegistries.ToAgent.TryGetType(data, out var type)) {
|
|
||||||
logger.Verbose("Received {MessageType} ({Bytes} B) from controller.", type.Name, data.Length);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
logger.Verbose("Received {Bytes} B message from controller.", data.Length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task Disconnect() {
|
|
||||||
var unregisterTimeoutTask = Task.Delay(TimeSpan.FromSeconds(5), CancellationToken.None);
|
|
||||||
var finishedTask = await Task.WhenAny(ServerMessaging.Send(new UnregisterAgentMessage(agentGuid)), unregisterTimeoutTask);
|
|
||||||
if (finishedTask == unregisterTimeoutTask) {
|
|
||||||
config.RuntimeLogger.Error("Timed out communicating agent shutdown with the controller.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private sealed class MessageToAgentHandler : MessageHandler<IMessageToAgentListener> {
|
|
||||||
public MessageToAgentHandler(IMessageToAgentListener listener, ILogger logger, TaskManager taskManager, CancellationToken cancellationToken) : base(listener, logger, taskManager, cancellationToken) {}
|
|
||||||
|
|
||||||
protected override Task SendReply(uint sequenceId, byte[] serializedReply) {
|
|
||||||
return ServerMessaging.Send(new ReplyMessage(sequenceId, serializedReply));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +1,3 @@
|
|||||||
namespace Phantom.Agent.Services;
|
namespace Phantom.Agent.Services;
|
||||||
|
|
||||||
public readonly record struct AgentServiceConfiguration(int MaxConcurrentCompressionTasks);
|
public readonly record struct AgentServiceConfiguration(int MaxConcurrentCompressionTasks);
|
||||||
|
@ -7,7 +7,7 @@ using Phantom.Common.Logging;
|
|||||||
using Phantom.Utils.IO;
|
using Phantom.Utils.IO;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Agent.Services.Backups;
|
namespace Phantom.Agent.Services.Backups;
|
||||||
|
|
||||||
sealed class BackupArchiver {
|
sealed class BackupArchiver {
|
||||||
private readonly string destinationBasePath;
|
private readonly string destinationBasePath;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using Phantom.Utils.Processes;
|
using Phantom.Utils.Processes;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Agent.Services.Backups;
|
namespace Phantom.Agent.Services.Backups;
|
||||||
|
|
||||||
static class BackupCompressor {
|
static class BackupCompressor {
|
||||||
private static ILogger Logger { get; } = PhantomLogger.Create(nameof(BackupCompressor));
|
private static ILogger Logger { get; } = PhantomLogger.Create(nameof(BackupCompressor));
|
||||||
|
@ -23,7 +23,7 @@ sealed class BackupScheduler : CancellableBackgroundTask {
|
|||||||
private readonly ServerStatusProtocol serverStatusProtocol;
|
private readonly ServerStatusProtocol serverStatusProtocol;
|
||||||
private readonly ManualResetEventSlim serverOutputWhileWaitingForOnlinePlayers = new ();
|
private readonly ManualResetEventSlim serverOutputWhileWaitingForOnlinePlayers = new ();
|
||||||
|
|
||||||
public event EventHandler<BackupCreationResult>? BackupCompleted;
|
public event EventHandler<BackupCreationResult>? BackupCompleted;
|
||||||
|
|
||||||
public BackupScheduler(TaskManager taskManager, BackupManager backupManager, InstanceProcess process, IInstanceContext context, int serverPort) : base(PhantomLogger.Create<BackupScheduler>(context.ShortName), taskManager, "Backup scheduler for " + context.ShortName) {
|
public BackupScheduler(TaskManager taskManager, BackupManager backupManager, InstanceProcess process, IInstanceContext context, int serverPort) : base(PhantomLogger.Create<BackupScheduler>(context.ShortName), taskManager, "Backup scheduler for " + context.ShortName) {
|
||||||
this.backupManager = backupManager;
|
this.backupManager = backupManager;
|
||||||
|
@ -3,7 +3,7 @@ using Phantom.Agent.Services.Instances.States;
|
|||||||
using Phantom.Common.Data.Instance;
|
using Phantom.Common.Data.Instance;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Agent.Services.Instances;
|
namespace Phantom.Agent.Services.Instances;
|
||||||
|
|
||||||
interface IInstanceContext {
|
interface IInstanceContext {
|
||||||
string ShortName { get; }
|
string ShortName { get; }
|
||||||
|
@ -27,7 +27,7 @@ sealed class Instance : IAsyncDisposable {
|
|||||||
private IInstanceState currentState;
|
private IInstanceState currentState;
|
||||||
public bool IsRunning => currentState is not InstanceNotRunningState;
|
public bool IsRunning => currentState is not InstanceNotRunningState;
|
||||||
|
|
||||||
public event EventHandler? IsRunningChanged;
|
public event EventHandler? IsRunningChanged;
|
||||||
|
|
||||||
private readonly InstanceProcedureManager procedureManager;
|
private readonly InstanceProcedureManager procedureManager;
|
||||||
|
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
using Phantom.Agent.Services.Backups;
|
using Phantom.Agent.Services.Backups;
|
||||||
using Phantom.Utils.Tasks;
|
using Phantom.Utils.Tasks;
|
||||||
|
|
||||||
namespace Phantom.Agent.Services.Instances;
|
namespace Phantom.Agent.Services.Instances;
|
||||||
|
|
||||||
sealed record InstanceServices(TaskManager TaskManager, PortManager PortManager, BackupManager BackupManager, LaunchServices LaunchServices);
|
sealed record InstanceServices(TaskManager TaskManager, PortManager PortManager, BackupManager BackupManager, LaunchServices LaunchServices);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Phantom.Agent.Services.Instances.States;
|
using Phantom.Agent.Services.Instances.States;
|
||||||
|
|
||||||
namespace Phantom.Agent.Services.Instances.Procedures;
|
namespace Phantom.Agent.Services.Instances.Procedures;
|
||||||
|
|
||||||
interface IInstanceProcedure {
|
interface IInstanceProcedure {
|
||||||
Task<IInstanceState?> Run(IInstanceContext context, CancellationToken cancellationToken);
|
Task<IInstanceState?> Run(IInstanceContext context, CancellationToken cancellationToken);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Agent.Services.Instances.States;
|
namespace Phantom.Agent.Services.Instances.States;
|
||||||
|
|
||||||
interface IInstanceState {
|
interface IInstanceState {
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Agent.Services.Instances.States;
|
namespace Phantom.Agent.Services.Instances.States;
|
||||||
|
|
||||||
sealed class InstanceNotRunningState : IInstanceState {
|
sealed class InstanceNotRunningState : IInstanceState {
|
||||||
public void Initialize() {}
|
public void Initialize() {}
|
||||||
|
@ -41,7 +41,7 @@ public sealed class MessageListener : IMessageToAgentListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await ServerMessaging.Send(new AdvertiseJavaRuntimesMessage(agent.JavaRuntimeRepository.All));
|
await connection.Send(new AdvertiseJavaRuntimesMessage(agent.JavaRuntimeRepository.All));
|
||||||
await agent.InstanceSessionManager.RefreshAgentStatus();
|
await agent.InstanceSessionManager.RefreshAgentStatus();
|
||||||
|
|
||||||
return NoReply.Instance;
|
return NoReply.Instance;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using NetMQ;
|
using NetMQ;
|
||||||
|
using Phantom.Common.Data;
|
||||||
using Phantom.Common.Data.Agent;
|
using Phantom.Common.Data.Agent;
|
||||||
using Phantom.Common.Logging;
|
using Phantom.Common.Logging;
|
||||||
using Phantom.Utils.Cryptography;
|
using Phantom.Utils.Cryptography;
|
||||||
|
@ -3,7 +3,7 @@ using Phantom.Common.Logging;
|
|||||||
using Phantom.Utils.IO;
|
using Phantom.Utils.IO;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Agent;
|
namespace Phantom.Agent;
|
||||||
|
|
||||||
static class GuidFile {
|
static class GuidFile {
|
||||||
private static ILogger Logger { get; } = PhantomLogger.Create(nameof(GuidFile));
|
private static ILogger Logger { get; } = PhantomLogger.Create(nameof(GuidFile));
|
||||||
|
@ -58,7 +58,7 @@ try {
|
|||||||
|
|
||||||
var rpcDisconnectSemaphore = new SemaphoreSlim(0, 1);
|
var rpcDisconnectSemaphore = new SemaphoreSlim(0, 1);
|
||||||
var rpcConfiguration = new RpcConfiguration(PhantomLogger.Create("Rpc"), PhantomLogger.Create<TaskManager>("Rpc"), controllerHost, controllerPort, controllerCertificate);
|
var rpcConfiguration = new RpcConfiguration(PhantomLogger.Create("Rpc"), PhantomLogger.Create<TaskManager>("Rpc"), controllerHost, controllerPort, controllerCertificate);
|
||||||
var rpcTask = RpcLauncher.Launch(rpcConfiguration, agentToken, agentInfo, MessageListenerFactory, rpcDisconnectSemaphore, shutdownCancellationToken);
|
var rpcTask = RpcClientRuntime.Launch(rpcConfiguration, agentToken, agentInfo, MessageListenerFactory, rpcDisconnectSemaphore, shutdownCancellationToken);
|
||||||
try {
|
try {
|
||||||
await rpcTask.WaitAsync(shutdownCancellationToken);
|
await rpcTask.WaitAsync(shutdownCancellationToken);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Tests;
|
namespace Phantom.Common.Data.Tests;
|
||||||
|
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public sealed class AllowedPortsTests {
|
public sealed class AllowedPortsTests {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Controller.Database.Enums;
|
namespace Phantom.Common.Data.Web.AuditLog;
|
||||||
|
|
||||||
public enum AuditLogEventType {
|
public enum AuditLogEventType {
|
||||||
AdministratorUserCreated,
|
AdministratorUserCreated,
|
||||||
@ -16,7 +16,7 @@ public enum AuditLogEventType {
|
|||||||
InstanceCommandExecuted
|
InstanceCommandExecuted
|
||||||
}
|
}
|
||||||
|
|
||||||
static class AuditLogEventTypeExtensions {
|
public static class AuditLogEventTypeExtensions {
|
||||||
private static readonly Dictionary<AuditLogEventType, AuditLogSubjectType> SubjectTypes = new () {
|
private static readonly Dictionary<AuditLogEventType, AuditLogSubjectType> SubjectTypes = new () {
|
||||||
{ AuditLogEventType.AdministratorUserCreated, AuditLogSubjectType.User },
|
{ AuditLogEventType.AdministratorUserCreated, AuditLogSubjectType.User },
|
||||||
{ AuditLogEventType.AdministratorUserModified, AuditLogSubjectType.User },
|
{ AuditLogEventType.AdministratorUserModified, AuditLogSubjectType.User },
|
||||||
@ -41,7 +41,7 @@ static class AuditLogEventTypeExtensions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static AuditLogSubjectType GetSubjectType(this AuditLogEventType type) {
|
public static AuditLogSubjectType GetSubjectType(this AuditLogEventType type) {
|
||||||
return SubjectTypes[type];
|
return SubjectTypes[type];
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Phantom.Controller.Database.Enums;
|
|
||||||
|
|
||||||
namespace Phantom.Controller.Services.Audit;
|
namespace Phantom.Common.Data.Web.AuditLog;
|
||||||
|
|
||||||
public sealed record AuditLogItem(DateTime UtcTime, Guid? UserGuid, string? UserName, AuditLogEventType EventType, AuditLogSubjectType SubjectType, string? SubjectId, JsonDocument? Data);
|
public sealed record AuditLogItem(DateTime UtcTime, Guid? UserGuid, string? UserName, AuditLogEventType EventType, AuditLogSubjectType SubjectType, string? SubjectId, JsonDocument? Data);
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Controller.Database.Enums;
|
namespace Phantom.Common.Data.Web.AuditLog;
|
||||||
|
|
||||||
public enum AuditLogSubjectType {
|
public enum AuditLogSubjectType {
|
||||||
User,
|
User,
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Controller.Database.Enums;
|
namespace Phantom.Common.Data.Web.EventLog;
|
||||||
|
|
||||||
public enum EventLogEventType {
|
public enum EventLogEventType {
|
||||||
InstanceLaunchSucceded,
|
InstanceLaunchSucceded,
|
||||||
@ -10,7 +10,7 @@ public enum EventLogEventType {
|
|||||||
InstanceBackupFailed,
|
InstanceBackupFailed,
|
||||||
}
|
}
|
||||||
|
|
||||||
static class EventLogEventTypeExtensions {
|
public static class EventLogEventTypeExtensions {
|
||||||
private static readonly Dictionary<EventLogEventType, EventLogSubjectType> SubjectTypes = new () {
|
private static readonly Dictionary<EventLogEventType, EventLogSubjectType> SubjectTypes = new () {
|
||||||
{ EventLogEventType.InstanceLaunchSucceded, EventLogSubjectType.Instance },
|
{ EventLogEventType.InstanceLaunchSucceded, EventLogSubjectType.Instance },
|
||||||
{ EventLogEventType.InstanceLaunchFailed, EventLogSubjectType.Instance },
|
{ EventLogEventType.InstanceLaunchFailed, EventLogSubjectType.Instance },
|
@ -1,6 +1,5 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Phantom.Controller.Database.Enums;
|
|
||||||
|
|
||||||
namespace Phantom.Controller.Services.Events;
|
namespace Phantom.Common.Data.Web.EventLog;
|
||||||
|
|
||||||
public sealed record EventLogItem(DateTime UtcTime, Guid? AgentGuid, EventLogEventType EventType, EventLogSubjectType SubjectType, string SubjectId, JsonDocument? Data);
|
public sealed record EventLogItem(DateTime UtcTime, Guid? AgentGuid, EventLogEventType EventType, EventLogSubjectType SubjectType, string SubjectId, JsonDocument? Data);
|
@ -0,0 +1,5 @@
|
|||||||
|
namespace Phantom.Common.Data.Web.EventLog;
|
||||||
|
|
||||||
|
public enum EventLogSubjectType {
|
||||||
|
Instance
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Controller.Services.Users.Roles;
|
namespace Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
public enum AddRoleError : byte {
|
public enum AddRoleError : byte {
|
||||||
NameIsEmpty,
|
NameIsEmpty,
|
||||||
|
@ -1,25 +1,28 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
using Phantom.Common.Data.Web.Users.AddUserErrors;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users {
|
||||||
|
[MemoryPackable]
|
||||||
[MemoryPackable]
|
[MemoryPackUnion(0, typeof(NameIsInvalid))]
|
||||||
[MemoryPackUnion(0, typeof(NameIsInvalid))]
|
[MemoryPackUnion(1, typeof(PasswordIsInvalid))]
|
||||||
[MemoryPackUnion(1, typeof(PasswordIsInvalid))]
|
[MemoryPackUnion(2, typeof(NameAlreadyExists))]
|
||||||
[MemoryPackUnion(2, typeof(NameAlreadyExists))]
|
[MemoryPackUnion(3, typeof(UnknownError))]
|
||||||
[MemoryPackUnion(3, typeof(UnknownError))]
|
public abstract partial record AddUserError {
|
||||||
public abstract record AddUserError {
|
internal AddUserError() {}
|
||||||
private AddUserError() {}
|
}
|
||||||
|
}
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
|
||||||
public sealed record NameIsInvalid([property: MemoryPackOrder(0)] UsernameRequirementViolation Violation) : AddUserError;
|
namespace Phantom.Common.Data.Web.Users.AddUserErrors {
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record NameIsInvalid([property: MemoryPackOrder(0)] UsernameRequirementViolation Violation) : AddUserError;
|
||||||
public sealed record PasswordIsInvalid([property: MemoryPackOrder(0)] ImmutableArray<PasswordRequirementViolation> Violations) : AddUserError;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record PasswordIsInvalid([property: MemoryPackOrder(0)] ImmutableArray<PasswordRequirementViolation> Violations) : AddUserError;
|
||||||
public sealed record NameAlreadyExists : AddUserError;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record NameAlreadyExists : AddUserError;
|
||||||
public sealed record UnknownError : AddUserError;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
|
public sealed partial record UnknownError : AddUserError;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
using Phantom.Common.Data.Web.Users.CreateOrUpdateAdministratorUserResults;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users {
|
||||||
|
[MemoryPackable]
|
||||||
[MemoryPackable]
|
[MemoryPackUnion(0, typeof(Success))]
|
||||||
[MemoryPackUnion(0, typeof(Success))]
|
[MemoryPackUnion(1, typeof(CreationFailed))]
|
||||||
[MemoryPackUnion(1, typeof(CreationFailed))]
|
[MemoryPackUnion(2, typeof(UpdatingFailed))]
|
||||||
[MemoryPackUnion(2, typeof(UpdatingFailed))]
|
[MemoryPackUnion(3, typeof(AddingToRoleFailed))]
|
||||||
[MemoryPackUnion(3, typeof(AddingToRoleFailed))]
|
[MemoryPackUnion(4, typeof(UnknownError))]
|
||||||
[MemoryPackUnion(4, typeof(UnknownError))]
|
public abstract partial record CreateOrUpdateAdministratorUserResult {
|
||||||
public abstract partial record CreateOrUpdateAdministratorUserResult {
|
internal CreateOrUpdateAdministratorUserResult() {}
|
||||||
private CreateOrUpdateAdministratorUserResult() {}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Phantom.Common.Data.Web.Users.CreateOrUpdateAdministratorUserResults {
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record Success([property: MemoryPackOrder(0)] UserInfo User) : CreateOrUpdateAdministratorUserResult;
|
public sealed partial record Success([property: MemoryPackOrder(0)] UserInfo User) : CreateOrUpdateAdministratorUserResult;
|
||||||
|
|
||||||
@ -19,10 +22,10 @@ public abstract partial record CreateOrUpdateAdministratorUserResult {
|
|||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record UpdatingFailed([property: MemoryPackOrder(0)] SetUserPasswordError Error) : CreateOrUpdateAdministratorUserResult;
|
public sealed partial record UpdatingFailed([property: MemoryPackOrder(0)] SetUserPasswordError Error) : CreateOrUpdateAdministratorUserResult;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record AddingToRoleFailed : CreateOrUpdateAdministratorUserResult;
|
public sealed partial record AddingToRoleFailed : CreateOrUpdateAdministratorUserResult;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record UnknownError : CreateOrUpdateAdministratorUserResult;
|
public sealed partial record UnknownError : CreateOrUpdateAdministratorUserResult;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
public enum DeleteUserResult : byte {
|
public enum DeleteUserResult : byte {
|
||||||
Deleted,
|
Deleted,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Web.Users.Permissions;
|
namespace Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
public sealed class IdentityPermissions {
|
public sealed class IdentityPermissions {
|
||||||
public static IdentityPermissions None { get; } = new (ImmutableHashSet<string>.Empty);
|
public static IdentityPermissions None { get; } = new (ImmutableHashSet<string>.Empty);
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
using Phantom.Common.Data.Web.Users.PasswordRequirementViolations;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users {
|
||||||
|
[MemoryPackable]
|
||||||
[MemoryPackable]
|
[MemoryPackUnion(0, typeof(TooShort))]
|
||||||
[MemoryPackUnion(0, typeof(TooShort))]
|
[MemoryPackUnion(1, typeof(MustContainLowercaseLetter))]
|
||||||
[MemoryPackUnion(1, typeof(LowercaseLetterRequired))]
|
[MemoryPackUnion(2, typeof(MustContainUppercaseLetter))]
|
||||||
[MemoryPackUnion(2, typeof(UppercaseLetterRequired))]
|
[MemoryPackUnion(3, typeof(MustContainDigit))]
|
||||||
[MemoryPackUnion(3, typeof(DigitRequired))]
|
public abstract partial record PasswordRequirementViolation {
|
||||||
public abstract record PasswordRequirementViolation {
|
internal PasswordRequirementViolation() {}
|
||||||
private PasswordRequirementViolation() {}
|
}
|
||||||
|
}
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
|
||||||
public sealed record TooShort([property: MemoryPackOrder(0)] int MinimumLength) : PasswordRequirementViolation;
|
namespace Phantom.Common.Data.Web.Users.PasswordRequirementViolations {
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record TooShort([property: MemoryPackOrder(0)] int MinimumLength) : PasswordRequirementViolation;
|
||||||
public sealed record LowercaseLetterRequired : PasswordRequirementViolation;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record MustContainLowercaseLetter : PasswordRequirementViolation;
|
||||||
public sealed record UppercaseLetterRequired : PasswordRequirementViolation;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record MustContainUppercaseLetter : PasswordRequirementViolation;
|
||||||
public sealed record DigitRequired : PasswordRequirementViolation;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
|
public sealed partial record MustContainDigit : PasswordRequirementViolation;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Web.Users.Permissions;
|
namespace Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
public sealed record Permission(string Id, Permission? Parent) {
|
public sealed record Permission(string Id, Permission? Parent) {
|
||||||
private static readonly List<Permission> AllPermissions = new ();
|
private static readonly List<Permission> AllPermissions = new ();
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record RoleInfo(
|
public sealed partial record RoleInfo(
|
||||||
|
@ -1,21 +1,24 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
using Phantom.Common.Data.Web.Users.SetUserPasswordErrors;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users {
|
||||||
|
[MemoryPackable]
|
||||||
[MemoryPackable]
|
[MemoryPackUnion(0, typeof(UserNotFound))]
|
||||||
[MemoryPackUnion(0, typeof(UserNotFound))]
|
[MemoryPackUnion(1, typeof(PasswordIsInvalid))]
|
||||||
[MemoryPackUnion(1, typeof(PasswordIsInvalid))]
|
[MemoryPackUnion(2, typeof(UnknownError))]
|
||||||
[MemoryPackUnion(2, typeof(UnknownError))]
|
public abstract partial record SetUserPasswordError {
|
||||||
public abstract record SetUserPasswordError {
|
internal SetUserPasswordError() {}
|
||||||
private SetUserPasswordError() {}
|
}
|
||||||
|
}
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
|
||||||
public sealed record UserNotFound : SetUserPasswordError;
|
namespace Phantom.Common.Data.Web.Users.SetUserPasswordErrors {
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record UserNotFound : SetUserPasswordError;
|
||||||
public sealed record PasswordIsInvalid(ImmutableArray<PasswordRequirementViolation> Violations) : SetUserPasswordError;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record PasswordIsInvalid([property: MemoryPackOrder(0)] ImmutableArray<PasswordRequirementViolation> Violations) : SetUserPasswordError;
|
||||||
public sealed record UnknownError : SetUserPasswordError;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
|
public sealed partial record UnknownError : SetUserPasswordError;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
public static class UserPasswords {
|
public static class UserPasswords {
|
||||||
public static string Hash(string password) {
|
public static string Hash(string password) {
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
using Phantom.Common.Data.Web.Users.UsernameRequirementViolations;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Web.Users;
|
namespace Phantom.Common.Data.Web.Users {
|
||||||
|
[MemoryPackable]
|
||||||
[MemoryPackable]
|
[MemoryPackUnion(0, typeof(IsEmpty))]
|
||||||
[MemoryPackUnion(0, typeof(IsEmpty))]
|
[MemoryPackUnion(1, typeof(TooLong))]
|
||||||
[MemoryPackUnion(1, typeof(TooLong))]
|
public abstract partial record UsernameRequirementViolation {
|
||||||
public abstract record UsernameRequirementViolation {
|
internal UsernameRequirementViolation() {}
|
||||||
private UsernameRequirementViolation() {}
|
}
|
||||||
|
}
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
|
||||||
public sealed record IsEmpty : UsernameRequirementViolation;
|
namespace Phantom.Common.Data.Web.Users.UsernameRequirementViolations {
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
public sealed partial record IsEmpty : UsernameRequirementViolation;
|
||||||
public sealed record TooLong(int MaxLength) : UsernameRequirementViolation;
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
|
public sealed partial record TooLong([property: MemoryPackOrder(0)] int MaxLength) : UsernameRequirementViolation;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Agent;
|
namespace Phantom.Common.Data;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Agent;
|
namespace Phantom.Common.Data;
|
||||||
|
|
||||||
public readonly record struct ConnectionCommonKey(byte[] CertificatePublicKey, AuthToken AuthToken) {
|
public readonly record struct ConnectionCommonKey(byte[] CertificatePublicKey, AuthToken AuthToken) {
|
||||||
private const byte TokenLength = AuthToken.Length;
|
private const byte TokenLength = AuthToken.Length;
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Instance;
|
namespace Phantom.Common.Data.Instance;
|
||||||
|
|
||||||
public interface IInstanceEventVisitor {
|
public interface IInstanceEventVisitor {
|
||||||
void OnLaunchSucceeded(InstanceLaunchSuccededEvent e);
|
void OnLaunchSucceeded(InstanceLaunchSuccededEvent e);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
using Phantom.Common.Data.Minecraft;
|
using Phantom.Common.Data.Minecraft;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Instance;
|
namespace Phantom.Common.Data.Instance;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record InstanceLaunchProperties(
|
public sealed partial record InstanceLaunchProperties(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Java;
|
namespace Phantom.Common.Data.Java;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record TaggedJavaRuntime(
|
public sealed partial record TaggedJavaRuntime(
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using Phantom.Utils.Cryptography;
|
using Phantom.Utils.Cryptography;
|
||||||
using Phantom.Utils.IO;
|
using Phantom.Utils.IO;
|
||||||
|
|
||||||
namespace Phantom.Common.Data.Minecraft;
|
namespace Phantom.Common.Data.Minecraft;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial class FileDownloadInfo {
|
public sealed partial class FileDownloadInfo {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Minecraft;
|
namespace Phantom.Common.Data.Minecraft;
|
||||||
|
|
||||||
public enum MinecraftServerKind : ushort {
|
public enum MinecraftServerKind : ushort {
|
||||||
Vanilla = 1,
|
Vanilla = 1,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Minecraft;
|
namespace Phantom.Common.Data.Minecraft;
|
||||||
|
|
||||||
public sealed record MinecraftVersion(
|
public sealed record MinecraftVersion(
|
||||||
string Id,
|
string Id,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Replies;
|
namespace Phantom.Common.Data.Replies;
|
||||||
|
|
||||||
public enum ConfigureInstanceResult : byte {
|
public enum ConfigureInstanceResult : byte {
|
||||||
Success
|
Success
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Common.Data.Replies;
|
namespace Phantom.Common.Data.Replies;
|
||||||
|
|
||||||
public enum RegisterAgentFailure : byte {
|
public enum RegisterAgentFailure : byte {
|
||||||
ConnectionAlreadyHasAnAgent,
|
ConnectionAlreadyHasAnAgent,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using Serilog.Events;
|
using Serilog.Events;
|
||||||
|
|
||||||
namespace Phantom.Common.Logging;
|
namespace Phantom.Common.Logging;
|
||||||
|
|
||||||
static class DefaultLogLevel {
|
static class DefaultLogLevel {
|
||||||
private const string ENVIRONMENT_VARIABLE = "LOG_LEVEL";
|
private const string ENVIRONMENT_VARIABLE = "LOG_LEVEL";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Common.Logging;
|
namespace Phantom.Common.Logging;
|
||||||
|
|
||||||
public static class LoggerExtensions {
|
public static class LoggerExtensions {
|
||||||
private static readonly string HeadingPadding = new (' ', 23);
|
private static readonly string HeadingPadding = new (' ', 23);
|
||||||
|
@ -5,7 +5,7 @@ using Phantom.Common.Messages.Agent.ToAgent;
|
|||||||
using Phantom.Common.Messages.Agent.ToController;
|
using Phantom.Common.Messages.Agent.ToController;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent;
|
namespace Phantom.Common.Messages.Agent;
|
||||||
|
|
||||||
public static class AgentMessageRegistries {
|
public static class AgentMessageRegistries {
|
||||||
public static MessageRegistry<IMessageToAgentListener> ToAgent { get; } = new (PhantomLogger.Create("MessageRegistry", nameof(ToAgent)));
|
public static MessageRegistry<IMessageToAgentListener> ToAgent { get; } = new (PhantomLogger.Create("MessageRegistry", nameof(ToAgent)));
|
||||||
@ -34,14 +34,18 @@ public static class AgentMessageRegistries {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private sealed class MessageDefinitions : IMessageDefinitions<IMessageToAgentListener, IMessageToControllerListener> {
|
private sealed class MessageDefinitions : IMessageDefinitions<IMessageToAgentListener, IMessageToControllerListener> {
|
||||||
public MessageRegistry<IMessageToAgentListener> Outgoing => ToAgent;
|
public MessageRegistry<IMessageToAgentListener> ToClient => ToAgent;
|
||||||
public MessageRegistry<IMessageToControllerListener> Incoming => ToController;
|
public MessageRegistry<IMessageToControllerListener> ToServer => ToController;
|
||||||
|
|
||||||
public bool IsRegistrationMessage(Type messageType) {
|
public bool IsRegistrationMessage(Type messageType) {
|
||||||
return messageType == typeof(RegisterAgentMessage);
|
return messageType == typeof(RegisterAgentMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMessage<IMessageToAgentListener, NoReply> CreateReplyMessage( uint sequenceId, byte[] serializedReply) {
|
public IMessage<IMessageToAgentListener, NoReply> CreateReplyToServerMessage( uint sequenceId, byte[] serializedReply) {
|
||||||
|
return new ReplyMessage(sequenceId, serializedReply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMessage<IMessageToControllerListener, NoReply> CreateReplyToClientMessage(uint sequenceId, byte[] serializedReply) {
|
||||||
return new ReplyMessage(sequenceId, serializedReply);
|
return new ReplyMessage(sequenceId, serializedReply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using Phantom.Common.Messages.Agent.ToController;
|
using Phantom.Common.Messages.Agent.ToController;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent;
|
namespace Phantom.Common.Messages.Agent;
|
||||||
|
|
||||||
public interface IMessageToControllerListener {
|
public interface IMessageToControllerListener {
|
||||||
Task<NoReply> HandleRegisterAgent(RegisterAgentMessage message);
|
Task<NoReply> HandleRegisterAgent(RegisterAgentMessage message);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
using Phantom.Common.Data.Replies;
|
using Phantom.Common.Data.Replies;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent.ToAgent;
|
namespace Phantom.Common.Messages.Agent.ToAgent;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record LaunchInstanceMessage(
|
public sealed partial record LaunchInstanceMessage(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
using Phantom.Common.Data.Replies;
|
using Phantom.Common.Data.Replies;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent.ToAgent;
|
namespace Phantom.Common.Messages.Agent.ToAgent;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record SendCommandToInstanceMessage(
|
public sealed partial record SendCommandToInstanceMessage(
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using Phantom.Common.Data.Minecraft;
|
using Phantom.Common.Data.Minecraft;
|
||||||
using Phantom.Common.Data.Replies;
|
using Phantom.Common.Data.Replies;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent.ToAgent;
|
namespace Phantom.Common.Messages.Agent.ToAgent;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record StopInstanceMessage(
|
public sealed partial record StopInstanceMessage(
|
||||||
|
@ -3,7 +3,7 @@ using MemoryPack;
|
|||||||
using Phantom.Common.Data.Java;
|
using Phantom.Common.Data.Java;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent.ToController;
|
namespace Phantom.Common.Messages.Agent.ToController;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record AdvertiseJavaRuntimesMessage(
|
public sealed partial record AdvertiseJavaRuntimesMessage(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent.ToController;
|
namespace Phantom.Common.Messages.Agent.ToController;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record AgentIsAliveMessage : IMessageToController {
|
public sealed partial record AgentIsAliveMessage : IMessageToController {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
|
using Phantom.Common.Data;
|
||||||
using Phantom.Common.Data.Agent;
|
using Phantom.Common.Data.Agent;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using Phantom.Common.Data;
|
using Phantom.Common.Data;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent.ToController;
|
namespace Phantom.Common.Messages.Agent.ToController;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record ReportAgentStatusMessage(
|
public sealed partial record ReportAgentStatusMessage(
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using Phantom.Common.Data.Instance;
|
using Phantom.Common.Data.Instance;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Agent.ToController;
|
namespace Phantom.Common.Messages.Agent.ToController;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record ReportInstanceEventMessage(
|
public sealed partial record ReportInstanceEventMessage(
|
||||||
|
@ -3,9 +3,10 @@ using Phantom.Common.Messages.Web.BiDirectional;
|
|||||||
using Phantom.Common.Messages.Web.ToController;
|
using Phantom.Common.Messages.Web.ToController;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Web;
|
namespace Phantom.Common.Messages.Web;
|
||||||
|
|
||||||
public interface IMessageToControllerListener {
|
public interface IMessageToControllerListener {
|
||||||
|
Task<NoReply> HandleRegisterWeb(RegisterWebMessage message);
|
||||||
Task<CreateOrUpdateAdministratorUserResult> CreateOrUpdateAdministratorUser(CreateOrUpdateAdministratorUser message);
|
Task<CreateOrUpdateAdministratorUserResult> CreateOrUpdateAdministratorUser(CreateOrUpdateAdministratorUser message);
|
||||||
Task<NoReply> HandleReply(ReplyMessage message);
|
Task<NoReply> HandleReply(ReplyMessage message);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using MemoryPack;
|
using MemoryPack;
|
||||||
using Phantom.Common.Data.Web.Users;
|
using Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Web.ToController;
|
namespace Phantom.Common.Messages.Web.ToController;
|
||||||
|
|
||||||
[MemoryPackable(GenerateType.VersionTolerant)]
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
public sealed partial record CreateOrUpdateAdministratorUser(
|
public sealed partial record CreateOrUpdateAdministratorUser(
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
using MemoryPack;
|
||||||
|
using Phantom.Common.Data;
|
||||||
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
|
namespace Phantom.Common.Messages.Web.ToController;
|
||||||
|
|
||||||
|
[MemoryPackable(GenerateType.VersionTolerant)]
|
||||||
|
public sealed partial record RegisterWebMessage(
|
||||||
|
[property: MemoryPackOrder(0)] AuthToken AuthToken
|
||||||
|
) : IMessageToController {
|
||||||
|
public Task<NoReply> Accept(IMessageToControllerListener listener) {
|
||||||
|
return listener.HandleRegisterWeb(this);
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,7 @@ using Phantom.Common.Messages.Web.BiDirectional;
|
|||||||
using Phantom.Common.Messages.Web.ToController;
|
using Phantom.Common.Messages.Web.ToController;
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Common.Messages.Web;
|
namespace Phantom.Common.Messages.Web;
|
||||||
|
|
||||||
public static class WebMessageRegistries {
|
public static class WebMessageRegistries {
|
||||||
public static MessageRegistry<IMessageToControllerListener> ToController { get; } = new (PhantomLogger.Create("MessageRegistry", nameof(ToController)));
|
public static MessageRegistry<IMessageToControllerListener> ToController { get; } = new (PhantomLogger.Create("MessageRegistry", nameof(ToController)));
|
||||||
@ -20,14 +20,18 @@ public static class WebMessageRegistries {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private sealed class MessageDefinitions : IMessageDefinitions<IMessageToWebListener, IMessageToControllerListener> {
|
private sealed class MessageDefinitions : IMessageDefinitions<IMessageToWebListener, IMessageToControllerListener> {
|
||||||
public MessageRegistry<IMessageToWebListener> Outgoing => ToWeb;
|
public MessageRegistry<IMessageToWebListener> ToClient => ToWeb;
|
||||||
public MessageRegistry<IMessageToControllerListener> Incoming => ToController;
|
public MessageRegistry<IMessageToControllerListener> ToServer => ToController;
|
||||||
|
|
||||||
public bool IsRegistrationMessage(Type messageType) {
|
public bool IsRegistrationMessage(Type messageType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMessage<IMessageToWebListener, NoReply> CreateReplyMessage( uint sequenceId, byte[] serializedReply) {
|
public IMessage<IMessageToWebListener, NoReply> CreateReplyToServerMessage( uint sequenceId, byte[] serializedReply) {
|
||||||
|
return new ReplyMessage(sequenceId, serializedReply);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMessage<IMessageToControllerListener, NoReply> CreateReplyToClientMessage(uint sequenceId, byte[] serializedReply) {
|
||||||
return new ReplyMessage(sequenceId, serializedReply);
|
return new ReplyMessage(sequenceId, serializedReply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
using Npgsql.EntityFrameworkCore.PostgreSQL.Infrastructure;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Postgres;
|
namespace Phantom.Controller.Database.Postgres;
|
||||||
|
|
||||||
public sealed class ApplicationDbContextFactory : IDbContextProvider {
|
public sealed class ApplicationDbContextFactory : IDbContextProvider {
|
||||||
private readonly PooledDbContextFactory<ApplicationDbContext> factory;
|
private readonly PooledDbContextFactory<ApplicationDbContext> factory;
|
||||||
|
@ -3,9 +3,10 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
using Phantom.Common.Data;
|
using Phantom.Common.Data;
|
||||||
using Phantom.Common.Data.Minecraft;
|
using Phantom.Common.Data.Minecraft;
|
||||||
|
using Phantom.Common.Data.Web.AuditLog;
|
||||||
|
using Phantom.Common.Data.Web.EventLog;
|
||||||
using Phantom.Controller.Database.Converters;
|
using Phantom.Controller.Database.Converters;
|
||||||
using Phantom.Controller.Database.Entities;
|
using Phantom.Controller.Database.Entities;
|
||||||
using Phantom.Controller.Database.Enums;
|
|
||||||
using Phantom.Controller.Database.Factories;
|
using Phantom.Controller.Database.Factories;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database;
|
namespace Phantom.Controller.Database;
|
||||||
|
@ -3,7 +3,7 @@ using Phantom.Common.Logging;
|
|||||||
using Phantom.Utils.Tasks;
|
using Phantom.Utils.Tasks;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database;
|
namespace Phantom.Controller.Database;
|
||||||
|
|
||||||
public static class DatabaseMigrator {
|
public static class DatabaseMigrator {
|
||||||
private static readonly ILogger Logger = PhantomLogger.Create(nameof(DatabaseMigrator));
|
private static readonly ILogger Logger = PhantomLogger.Create(nameof(DatabaseMigrator));
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Phantom.Controller.Database.Enums;
|
using Phantom.Common.Data.Web.AuditLog;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Entities;
|
namespace Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
[Table("AuditLog", Schema = "system")]
|
[Table("AuditLog", Schema = "system")]
|
||||||
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Phantom.Controller.Database.Enums;
|
using Phantom.Common.Data.Web.EventLog;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Entities;
|
namespace Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
[Table("EventLog", Schema = "system")]
|
[Table("EventLog", Schema = "system")]
|
||||||
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
||||||
|
@ -4,7 +4,7 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using Phantom.Common.Data;
|
using Phantom.Common.Data;
|
||||||
using Phantom.Common.Data.Minecraft;
|
using Phantom.Common.Data.Minecraft;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Entities;
|
namespace Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
[Table("Instances", Schema = "agents")]
|
[Table("Instances", Schema = "agents")]
|
||||||
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
[SuppressMessage("ReSharper", "AutoPropertyCanBeMadeGetOnly.Global")]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Entities;
|
namespace Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
[Table("Permissions", Schema = "identity")]
|
[Table("Permissions", Schema = "identity")]
|
||||||
public sealed class PermissionEntity {
|
public sealed class PermissionEntity {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Entities;
|
namespace Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
[Table("Roles", Schema = "identity")]
|
[Table("Roles", Schema = "identity")]
|
||||||
public sealed class RoleEntity {
|
public sealed class RoleEntity {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Entities;
|
namespace Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
[Table("RolePermissions", Schema = "identity")]
|
[Table("RolePermissions", Schema = "identity")]
|
||||||
public sealed class RolePermissionEntity {
|
public sealed class RolePermissionEntity {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Phantom.Common.Data.Web.Users;
|
using Phantom.Common.Data.Web.Users;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Entities;
|
namespace Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
[Table("Users", Schema = "identity")]
|
[Table("Users", Schema = "identity")]
|
||||||
public sealed class UserEntity {
|
public sealed class UserEntity {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Entities;
|
namespace Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
[Table("UserRoles", Schema = "identity")]
|
[Table("UserRoles", Schema = "identity")]
|
||||||
public sealed class UserRoleEntity {
|
public sealed class UserRoleEntity {
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
namespace Phantom.Controller.Database.Enums;
|
|
||||||
|
|
||||||
public enum EventLogSubjectType {
|
|
||||||
Instance
|
|
||||||
}
|
|
@ -1,7 +1,7 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Phantom.Controller.Database.Entities;
|
using Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Factories;
|
namespace Phantom.Controller.Database.Factories;
|
||||||
|
|
||||||
public sealed class AgentEntityUpsert : AbstractUpsertHelper<AgentEntity> {
|
public sealed class AgentEntityUpsert : AbstractUpsertHelper<AgentEntity> {
|
||||||
internal AgentEntityUpsert(ApplicationDbContext ctx) : base(ctx) {}
|
internal AgentEntityUpsert(ApplicationDbContext ctx) : base(ctx) {}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Phantom.Controller.Database.Entities;
|
using Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Factories;
|
namespace Phantom.Controller.Database.Factories;
|
||||||
|
|
||||||
public sealed class InstanceEntityUpsert : AbstractUpsertHelper<InstanceEntity> {
|
public sealed class InstanceEntityUpsert : AbstractUpsertHelper<InstanceEntity> {
|
||||||
internal InstanceEntityUpsert(ApplicationDbContext ctx) : base(ctx) {}
|
internal InstanceEntityUpsert(ApplicationDbContext ctx) : base(ctx) {}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Controller.Database;
|
namespace Phantom.Controller.Database;
|
||||||
|
|
||||||
public interface IDbContextProvider {
|
public interface IDbContextProvider {
|
||||||
ApplicationDbContext Eager();
|
ApplicationDbContext Eager();
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Controller.Database;
|
namespace Phantom.Controller.Database;
|
||||||
|
|
||||||
public interface ILazyDbContext : IAsyncDisposable {
|
public interface ILazyDbContext : IAsyncDisposable {
|
||||||
ApplicationDbContext Ctx { get; }
|
ApplicationDbContext Ctx { get; }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
using Phantom.Controller.Database.Entities;
|
using Phantom.Common.Data.Web.AuditLog;
|
||||||
using Phantom.Controller.Database.Enums;
|
using Phantom.Controller.Database.Entities;
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Repositories;
|
namespace Phantom.Controller.Database.Repositories;
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Phantom.Common.Data.Web.AuditLog;
|
||||||
using Phantom.Controller.Database.Entities;
|
using Phantom.Controller.Database.Entities;
|
||||||
using Phantom.Controller.Database.Enums;
|
|
||||||
using Phantom.Controller.Services.Audit;
|
|
||||||
|
|
||||||
namespace Phantom.Controller.Database.Repositories;
|
namespace Phantom.Controller.Database.Repositories;
|
||||||
|
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Phantom.Controller.Database;
|
using Phantom.Common.Data.Web.Users;
|
||||||
using Phantom.Controller.Database.Entities;
|
using Phantom.Controller.Database.Entities;
|
||||||
using Phantom.Controller.Services.Users.Roles;
|
|
||||||
using Phantom.Utils.Collections;
|
using Phantom.Utils.Collections;
|
||||||
using Phantom.Utils.Tasks;
|
using Phantom.Utils.Tasks;
|
||||||
|
|
||||||
namespace Phantom.Controller.Services.Users;
|
namespace Phantom.Controller.Database.Repositories;
|
||||||
|
|
||||||
public sealed class RoleRepository {
|
public sealed class RoleRepository {
|
||||||
private const int MaxRoleNameLength = 40;
|
private const int MaxRoleNameLength = 40;
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Phantom.Common.Data.Web.Users;
|
using Phantom.Common.Data.Web.Users;
|
||||||
|
using Phantom.Common.Data.Web.Users.AddUserErrors;
|
||||||
|
using Phantom.Common.Data.Web.Users.PasswordRequirementViolations;
|
||||||
|
using Phantom.Common.Data.Web.Users.UsernameRequirementViolations;
|
||||||
using Phantom.Controller.Database.Entities;
|
using Phantom.Controller.Database.Entities;
|
||||||
using Phantom.Utils.Collections;
|
using Phantom.Utils.Collections;
|
||||||
using Phantom.Utils.Tasks;
|
using Phantom.Utils.Tasks;
|
||||||
@ -13,10 +16,10 @@ public sealed class UserRepository {
|
|||||||
|
|
||||||
private static UsernameRequirementViolation? CheckUsernameRequirements(string username) {
|
private static UsernameRequirementViolation? CheckUsernameRequirements(string username) {
|
||||||
if (string.IsNullOrWhiteSpace(username)) {
|
if (string.IsNullOrWhiteSpace(username)) {
|
||||||
return new UsernameRequirementViolation.IsEmpty();
|
return new IsEmpty();
|
||||||
}
|
}
|
||||||
else if (username.Length > MaxUserNameLength) {
|
else if (username.Length > MaxUserNameLength) {
|
||||||
return new UsernameRequirementViolation.TooLong(MaxUserNameLength);
|
return new TooLong(MaxUserNameLength);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
@ -27,19 +30,19 @@ public sealed class UserRepository {
|
|||||||
var violations = ImmutableArray.CreateBuilder<PasswordRequirementViolation>();
|
var violations = ImmutableArray.CreateBuilder<PasswordRequirementViolation>();
|
||||||
|
|
||||||
if (password.Length < MinimumPasswordLength) {
|
if (password.Length < MinimumPasswordLength) {
|
||||||
violations.Add(new PasswordRequirementViolation.TooShort(MinimumPasswordLength));
|
violations.Add(new TooShort(MinimumPasswordLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!password.Any(char.IsLower)) {
|
if (!password.Any(char.IsLower)) {
|
||||||
violations.Add(new PasswordRequirementViolation.LowercaseLetterRequired());
|
violations.Add(new MustContainLowercaseLetter());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!password.Any(char.IsUpper)) {
|
if (!password.Any(char.IsUpper)) {
|
||||||
violations.Add(new PasswordRequirementViolation.UppercaseLetterRequired());
|
violations.Add(new MustContainUppercaseLetter());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!password.Any(char.IsDigit)) {
|
if (!password.Any(char.IsDigit)) {
|
||||||
violations.Add(new PasswordRequirementViolation.DigitRequired());
|
violations.Add(new MustContainDigit());
|
||||||
}
|
}
|
||||||
|
|
||||||
return violations.ToImmutable();
|
return violations.ToImmutable();
|
||||||
@ -73,16 +76,16 @@ public sealed class UserRepository {
|
|||||||
public async Task<Result<UserEntity, AddUserError>> CreateUser(string username, string password) {
|
public async Task<Result<UserEntity, AddUserError>> CreateUser(string username, string password) {
|
||||||
var usernameRequirementViolation = CheckUsernameRequirements(username);
|
var usernameRequirementViolation = CheckUsernameRequirements(username);
|
||||||
if (usernameRequirementViolation != null) {
|
if (usernameRequirementViolation != null) {
|
||||||
return new AddUserError.NameIsInvalid(usernameRequirementViolation);
|
return new NameIsInvalid(usernameRequirementViolation);
|
||||||
}
|
}
|
||||||
|
|
||||||
var passwordRequirementViolations = CheckPasswordRequirements(password);
|
var passwordRequirementViolations = CheckPasswordRequirements(password);
|
||||||
if (!passwordRequirementViolations.IsEmpty) {
|
if (!passwordRequirementViolations.IsEmpty) {
|
||||||
return new AddUserError.PasswordIsInvalid(passwordRequirementViolations);
|
return new PasswordIsInvalid(passwordRequirementViolations);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await db.Ctx.Users.AnyAsync(user => user.Name == username)) {
|
if (await db.Ctx.Users.AnyAsync(user => user.Name == username)) {
|
||||||
return new AddUserError.NameAlreadyExists();
|
return new NameAlreadyExists();
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = new UserEntity(Guid.NewGuid(), username, UserPasswords.Hash(password));
|
var user = new UserEntity(Guid.NewGuid(), username, UserPasswords.Hash(password));
|
||||||
@ -96,7 +99,7 @@ public sealed class UserRepository {
|
|||||||
public Result<SetUserPasswordError> SetUserPassword(UserEntity user, string password) {
|
public Result<SetUserPasswordError> SetUserPassword(UserEntity user, string password) {
|
||||||
var requirementViolations = CheckPasswordRequirements(password);
|
var requirementViolations = CheckPasswordRequirements(password);
|
||||||
if (!requirementViolations.IsEmpty) {
|
if (!requirementViolations.IsEmpty) {
|
||||||
return new SetUserPasswordError.PasswordIsInvalid(requirementViolations);
|
return new Common.Data.Web.Users.SetUserPasswordErrors.PasswordIsInvalid(requirementViolations);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.PasswordHash = UserPasswords.Hash(password);
|
user.PasswordHash = UserPasswords.Hash(password);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
namespace Phantom.Controller.Rpc;
|
namespace Phantom.Controller.Rpc;
|
||||||
|
|
||||||
sealed class RpcClientConnectionClosedEventArgs : EventArgs {
|
sealed class RpcClientConnectionClosedEventArgs : EventArgs {
|
||||||
public uint RoutingId { get; }
|
public uint RoutingId { get; }
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
using NetMQ;
|
using NetMQ;
|
||||||
using NetMQ.Sockets;
|
using NetMQ.Sockets;
|
||||||
using Phantom.Common.Messages.Agent.BiDirectional;
|
|
||||||
using Phantom.Utils.Rpc.Message;
|
using Phantom.Utils.Rpc.Message;
|
||||||
|
|
||||||
namespace Phantom.Controller.Rpc;
|
namespace Phantom.Controller.Rpc;
|
||||||
|
|
||||||
public sealed class RpcClientConnection<TListener> {
|
public sealed class RpcConnectionToClient<TListener> {
|
||||||
private readonly ServerSocket socket;
|
private readonly ServerSocket socket;
|
||||||
private readonly uint routingId;
|
private readonly uint routingId;
|
||||||
|
|
||||||
@ -15,14 +14,14 @@ public sealed class RpcClientConnection<TListener> {
|
|||||||
internal event EventHandler<RpcClientConnectionClosedEventArgs>? Closed;
|
internal event EventHandler<RpcClientConnectionClosedEventArgs>? Closed;
|
||||||
private bool isClosed;
|
private bool isClosed;
|
||||||
|
|
||||||
internal RpcClientConnection(ServerSocket socket, uint routingId, MessageRegistry<TListener> messageRegistry, MessageReplyTracker messageReplyTracker) {
|
internal RpcConnectionToClient(ServerSocket socket, uint routingId, MessageRegistry<TListener> messageRegistry, MessageReplyTracker messageReplyTracker) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.routingId = routingId;
|
this.routingId = routingId;
|
||||||
this.messageRegistry = messageRegistry;
|
this.messageRegistry = messageRegistry;
|
||||||
this.messageReplyTracker = messageReplyTracker;
|
this.messageReplyTracker = messageReplyTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsSame(RpcClientConnection<TListener> other) {
|
public bool IsSame(RpcConnectionToClient<TListener> other) {
|
||||||
return this.routingId == other.routingId && this.socket == other.socket;
|
return this.routingId == other.routingId && this.socket == other.socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +62,7 @@ public sealed class RpcClientConnection<TListener> {
|
|||||||
return await messageReplyTracker.WaitForReply<TReply>(sequenceId, waitForReplyTime, waitForReplyCancellationToken);
|
return await messageReplyTracker.WaitForReply<TReply>(sequenceId, waitForReplyTime, waitForReplyCancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Receive(ReplyMessage message) {
|
public void Receive(IReply message) {
|
||||||
messageReplyTracker.ReceiveReply(message.SequenceId, message.SerializedReply);
|
messageReplyTracker.ReceiveReply(message.SequenceId, message.SerializedReply);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,14 +8,14 @@ using Serilog.Events;
|
|||||||
namespace Phantom.Controller.Rpc;
|
namespace Phantom.Controller.Rpc;
|
||||||
|
|
||||||
public static class RpcRuntime {
|
public static class RpcRuntime {
|
||||||
public static Task Launch<TOutgoingListener, TIncomingListener>(RpcConfiguration config, IMessageDefinitions<TOutgoingListener, TIncomingListener> messageDefinitions, Func<RpcClientConnection<TOutgoingListener>, TIncomingListener> listenerFactory, CancellationToken cancellationToken) {
|
public static Task Launch<TClientListener, TServerListener>(RpcConfiguration config, IMessageDefinitions<TClientListener, TServerListener> messageDefinitions, Func<RpcConnectionToClient<TClientListener>, TServerListener> listenerFactory, CancellationToken cancellationToken) {
|
||||||
return RpcRuntime<TOutgoingListener, TIncomingListener>.Launch(config, messageDefinitions, listenerFactory, cancellationToken);
|
return RpcRuntime<TClientListener, TServerListener>.Launch(config, messageDefinitions, listenerFactory, cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class RpcRuntime<TOutgoingListener, TIncomingListener> : RpcRuntime<ServerSocket> {
|
internal sealed class RpcRuntime<TClientListener, TServerListener> : RpcRuntime<ServerSocket> {
|
||||||
internal static Task Launch(RpcConfiguration config, IMessageDefinitions<TOutgoingListener, TIncomingListener> messageDefinitions, Func<RpcClientConnection<TOutgoingListener>, TIncomingListener> listenerFactory, CancellationToken cancellationToken) {
|
internal static Task Launch(RpcConfiguration config, IMessageDefinitions<TClientListener, TServerListener> messageDefinitions, Func<RpcConnectionToClient<TClientListener>, TServerListener> listenerFactory, CancellationToken cancellationToken) {
|
||||||
return new RpcRuntime<TOutgoingListener, TIncomingListener>(config, messageDefinitions, listenerFactory, cancellationToken).Launch();
|
return new RpcRuntime<TClientListener, TServerListener>(config, messageDefinitions, listenerFactory, cancellationToken).Launch();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServerSocket CreateSocket(RpcConfiguration config) {
|
private static ServerSocket CreateSocket(RpcConfiguration config) {
|
||||||
@ -29,11 +29,11 @@ internal sealed class RpcRuntime<TOutgoingListener, TIncomingListener> : RpcRunt
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly RpcConfiguration config;
|
private readonly RpcConfiguration config;
|
||||||
private readonly IMessageDefinitions<TOutgoingListener, TIncomingListener> messageDefinitions;
|
private readonly IMessageDefinitions<TClientListener, TServerListener> messageDefinitions;
|
||||||
private readonly Func<RpcClientConnection<TOutgoingListener>, TIncomingListener> listenerFactory;
|
private readonly Func<RpcConnectionToClient<TClientListener>, TServerListener> listenerFactory;
|
||||||
private readonly CancellationToken cancellationToken;
|
private readonly CancellationToken cancellationToken;
|
||||||
|
|
||||||
private RpcRuntime(RpcConfiguration config, IMessageDefinitions<TOutgoingListener, TIncomingListener> messageDefinitions, Func<RpcClientConnection<TOutgoingListener>, TIncomingListener> listenerFactory, CancellationToken cancellationToken) : base(config, CreateSocket(config)) {
|
private RpcRuntime(RpcConfiguration config, IMessageDefinitions<TClientListener, TServerListener> messageDefinitions, Func<RpcConnectionToClient<TClientListener>, TServerListener> listenerFactory, CancellationToken cancellationToken) : base(config, CreateSocket(config)) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.messageDefinitions = messageDefinitions;
|
this.messageDefinitions = messageDefinitions;
|
||||||
this.listenerFactory = listenerFactory;
|
this.listenerFactory = listenerFactory;
|
||||||
@ -71,7 +71,7 @@ internal sealed class RpcRuntime<TOutgoingListener, TIncomingListener> : RpcRunt
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var connection = new RpcClientConnection<TOutgoingListener>(socket, routingId, messageDefinitions.Outgoing, replyTracker);
|
var connection = new RpcConnectionToClient<TClientListener>(socket, routingId, messageDefinitions.ToClient, replyTracker);
|
||||||
connection.Closed += OnConnectionClosed;
|
connection.Closed += OnConnectionClosed;
|
||||||
|
|
||||||
client = new Client(connection, messageDefinitions, listenerFactory(connection), logger, taskManager, cancellationToken);
|
client = new Client(connection, messageDefinitions, listenerFactory(connection), logger, taskManager, cancellationToken);
|
||||||
@ -79,7 +79,7 @@ internal sealed class RpcRuntime<TOutgoingListener, TIncomingListener> : RpcRunt
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogMessageType(logger, routingId, data);
|
LogMessageType(logger, routingId, data);
|
||||||
messageDefinitions.Incoming.Handle(data, client);
|
messageDefinitions.ToServer.Handle(data, client);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var client in clients.Values) {
|
foreach (var client in clients.Values) {
|
||||||
@ -92,7 +92,7 @@ internal sealed class RpcRuntime<TOutgoingListener, TIncomingListener> : RpcRunt
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.Length > 0 && messageDefinitions.Incoming.TryGetType(data, out var type)) {
|
if (data.Length > 0 && messageDefinitions.ToServer.TryGetType(data, out var type)) {
|
||||||
logger.Verbose("Received {MessageType} ({Bytes} B) from {RoutingId}.", type.Name, data.Length, routingId);
|
logger.Verbose("Received {MessageType} ({Bytes} B) from {RoutingId}.", type.Name, data.Length, routingId);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -101,7 +101,7 @@ internal sealed class RpcRuntime<TOutgoingListener, TIncomingListener> : RpcRunt
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckIsRegistrationMessage(ReadOnlyMemory<byte> data, ILogger logger, uint routingId) {
|
private bool CheckIsRegistrationMessage(ReadOnlyMemory<byte> data, ILogger logger, uint routingId) {
|
||||||
if (messageDefinitions.Incoming.TryGetType(data, out var type) && messageDefinitions.IsRegistrationMessage(type)) {
|
if (messageDefinitions.ToServer.TryGetType(data, out var type) && messageDefinitions.IsRegistrationMessage(type)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,18 +109,18 @@ internal sealed class RpcRuntime<TOutgoingListener, TIncomingListener> : RpcRunt
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class Client : MessageHandler<TIncomingListener> {
|
private sealed class Client : MessageHandler<TServerListener> {
|
||||||
public RpcClientConnection<TOutgoingListener> Connection { get; }
|
public RpcConnectionToClient<TClientListener> Connection { get; }
|
||||||
|
|
||||||
private readonly IMessageDefinitions<TOutgoingListener, TIncomingListener> messageDefinitions;
|
private readonly IMessageDefinitions<TClientListener, TServerListener> messageDefinitions;
|
||||||
|
|
||||||
public Client(RpcClientConnection<TOutgoingListener> connection, IMessageDefinitions<TOutgoingListener, TIncomingListener> messageDefinitions, TIncomingListener listener, ILogger logger, TaskManager taskManager, CancellationToken cancellationToken) : base(listener, logger, taskManager, cancellationToken) {
|
public Client(RpcConnectionToClient<TClientListener> connection, IMessageDefinitions<TClientListener, TServerListener> messageDefinitions, TServerListener listener, ILogger logger, TaskManager taskManager, CancellationToken cancellationToken) : base(listener, logger, taskManager, cancellationToken) {
|
||||||
this.Connection = connection;
|
this.Connection = connection;
|
||||||
this.messageDefinitions = messageDefinitions;
|
this.messageDefinitions = messageDefinitions;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Task SendReply(uint sequenceId, byte[] serializedReply) {
|
protected override Task SendReply(uint sequenceId, byte[] serializedReply) {
|
||||||
return Connection.Send(messageDefinitions.CreateReplyMessage(sequenceId, serializedReply));
|
return Connection.Send(messageDefinitions.CreateReplyToServerMessage(sequenceId, serializedReply));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ using Phantom.Controller.Rpc;
|
|||||||
namespace Phantom.Controller.Services.Agents;
|
namespace Phantom.Controller.Services.Agents;
|
||||||
|
|
||||||
sealed class AgentConnection {
|
sealed class AgentConnection {
|
||||||
private readonly RpcClientConnection<IMessageToAgentListener> connection;
|
private readonly RpcConnectionToClient<IMessageToAgentListener> connection;
|
||||||
|
|
||||||
internal AgentConnection(RpcClientConnection<IMessageToAgentListener> connection) {
|
internal AgentConnection(RpcConnectionToClient<IMessageToAgentListener> connection) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsSame(RpcClientConnection<IMessageToAgentListener> connection) {
|
public bool IsSame(RpcConnectionToClient<IMessageToAgentListener> connection) {
|
||||||
return this.connection.IsSame(connection);
|
return this.connection.IsSame(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
using Phantom.Common.Data.Java;
|
using Phantom.Common.Data.Java;
|
||||||
using Phantom.Utils.Collections;
|
using Phantom.Utils.Collections;
|
||||||
|
|
||||||
namespace Phantom.Controller.Services.Agents;
|
namespace Phantom.Controller.Services.Agents;
|
||||||
|
|
||||||
public sealed class AgentJavaRuntimesManager {
|
public sealed class AgentJavaRuntimesManager {
|
||||||
private readonly RwLockedDictionary<Guid, ImmutableArray<TaggedJavaRuntime>> runtimes = new (LockRecursionPolicy.NoRecursion);
|
private readonly RwLockedDictionary<Guid, ImmutableArray<TaggedJavaRuntime>> runtimes = new (LockRecursionPolicy.NoRecursion);
|
||||||
|
@ -52,7 +52,7 @@ public sealed class AgentManager {
|
|||||||
return agents.ByGuid.ToImmutable();
|
return agents.ByGuid.ToImmutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal async Task<bool> RegisterAgent(AuthToken authToken, AgentInfo agentInfo, InstanceManager instanceManager, RpcClientConnection<IMessageToAgentListener> connection) {
|
internal async Task<bool> RegisterAgent(AuthToken authToken, AgentInfo agentInfo, InstanceManager instanceManager, RpcConnectionToClient<IMessageToAgentListener> connection) {
|
||||||
if (!this.authToken.FixedTimeEquals(authToken)) {
|
if (!this.authToken.FixedTimeEquals(authToken)) {
|
||||||
await connection.Send(new RegisterAgentFailureMessage(RegisterAgentFailure.InvalidToken));
|
await connection.Send(new RegisterAgentFailureMessage(RegisterAgentFailure.InvalidToken));
|
||||||
return false;
|
return false;
|
||||||
@ -88,7 +88,7 @@ public sealed class AgentManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal bool UnregisterAgent(Guid agentGuid, RpcClientConnection<IMessageToAgentListener> connection) {
|
internal bool UnregisterAgent(Guid agentGuid, RpcConnectionToClient<IMessageToAgentListener> connection) {
|
||||||
if (agents.ByGuid.TryReplaceIf(agentGuid, static oldAgent => oldAgent.AsOffline(), oldAgent => oldAgent.Connection?.IsSame(connection) == true)) {
|
if (agents.ByGuid.TryReplaceIf(agentGuid, static oldAgent => oldAgent.AsOffline(), oldAgent => oldAgent.Connection?.IsSame(connection) == true)) {
|
||||||
Logger.Information("Unregistered agent with GUID {Guid}.", agentGuid);
|
Logger.Information("Unregistered agent with GUID {Guid}.", agentGuid);
|
||||||
return true;
|
return true;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user