Separated view request from delta request and respective responses.

This commit is contained in:
Harrison Deng 2021-04-21 01:14:05 -05:00
parent f61bbd3a9e
commit 7438a76bf7
25 changed files with 130 additions and 114 deletions

View File

@ -6,7 +6,8 @@ namespace GameServiceWarden.ClientAPI
{ {
Disconnect, Disconnect,
Connect, Connect,
Service, View,
Delta,
UnexpectedCommunication UnexpectedCommunication
} }
} }

View File

@ -1,9 +0,0 @@
using System;
namespace GameServiceWarden.ClientAPI
{
public interface ICommunicable
{
CommunicableType Type { get; }
}
}

View File

@ -1,13 +1,11 @@
namespace GameServiceWarden.ClientAPI.Requests namespace GameServiceWarden.ClientAPI.Communicable.Requests
{ {
public struct ConnectRequest : ICommunicable public struct ConnectRequest
{ {
public string requestedIdentifier; public string requestedIdentifier;
public string programName; public string programName;
public string programAuthor; public string programAuthor;
public string versionNumber; public string versionNumber;
public string details; public string details;
public CommunicableType Type => CommunicableType.Connect;
} }
} }

View File

@ -0,0 +1,9 @@
using GameServiceWarden.ClientAPI.Module;
namespace GameServiceWarden.ClientAPI.Communicable.Requests
{
public struct ServiceRequest
{
public ServiceManagerAction serviceManagerAction;
}
}

View File

@ -1,7 +1,7 @@
using System; using System;
using System.IO.Pipes; using System.IO.Pipes;
namespace GameServiceWarden.ClientAPI.Requests namespace GameServiceWarden.ClientAPI.Communicable.Requests
{ {
public static class RequestHeader public static class RequestHeader
{ {

View File

@ -1,11 +0,0 @@
using GameServiceWarden.ClientAPI.Module;
namespace GameServiceWarden.ClientAPI.Requests
{
public struct ServiceRequest : ICommunicable
{
public ServiceManagerAction serviceManagerAction;
public CommunicableType Type => CommunicableType.Service;
}
}

View File

@ -0,0 +1,7 @@
namespace GameServiceWarden.ClientAPI.Communicable.Requests
{
public struct ViewRequest
{
}
}

View File

@ -1,14 +1,12 @@
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
namespace GameServiceWarden.ClientAPI.Responses namespace GameServiceWarden.ClientAPI.Communicable.Responses
{ {
public struct ConnectResponse : ICommunicable public struct ConnectResponse
{ {
public string identifier; public string identifier;
public bool nameTaken; public bool nameTaken;
public bool invalidName; public bool invalidName;
public string errorMsg; public string errorMsg;
public CommunicableType Type => CommunicableType.Connect;
} }
} }

View File

@ -0,0 +1,9 @@
using GameServiceWarden.ClientAPI.Module;
namespace GameServiceWarden.ClientAPI.Communicable.Responses
{
public struct DeltaResponse
{
public ServiceManagerTotal gameServiceDelta;
}
}

View File

@ -1,6 +1,6 @@
using System; using System;
namespace GameServiceWarden.ClientAPI.Responses namespace GameServiceWarden.ClientAPI.Communicable.Responses
{ {
public static class ResponseHeader public static class ResponseHeader
{ {

View File

@ -1,11 +0,0 @@
using GameServiceWarden.ClientAPI.Module;
namespace GameServiceWarden.ClientAPI.Responses
{
public struct ServiceResponse : ICommunicable
{
public ServiceManagerState gameServiceDelta;
public CommunicableType Type => CommunicableType.Service;
}
}

View File

@ -1,10 +1,8 @@
namespace GameServiceWarden.ClientAPI.Responses namespace GameServiceWarden.ClientAPI.Communicable.Responses
{ {
public struct UnexpectedRequestResponse : ICommunicable public struct UnexpectedRequestResponse
{ {
public CommunicableType origin; public CommunicableType origin;
public string message; public string message;
public CommunicableType Type => CommunicableType.UnexpectedCommunication;
} }
} }

View File

@ -0,0 +1,8 @@
using GameServiceWarden.ClientAPI.Module;
namespace GameServiceWarden.ClientAPI.Communicable.Responses
{
public struct ViewResponse {
public ServiceManagerTotal state;
}
}

View File

@ -11,7 +11,6 @@ namespace GameServiceWarden.ClientAPI.Module
DeleteService, DeleteService,
ExecuteCommand, ExecuteCommand,
SetServiceOption, SetServiceOption,
View
} }
public string assemblyName; public string assemblyName;

View File

@ -0,0 +1,15 @@
using System.Collections.Generic;
namespace GameServiceWarden.ClientAPI.Module
{
public struct ServiceManagerDelta
{
public bool subtract;
public string service;
public string running;
public string modules;
public byte[] logs;
public string optionName;
public string optionValue;
}
}

View File

@ -2,10 +2,8 @@ using System.Collections.Generic;
namespace GameServiceWarden.ClientAPI.Module namespace GameServiceWarden.ClientAPI.Module
{ {
public struct ServiceManagerState public struct ServiceManagerTotal
{ {
public bool delta;
public bool subtract;
public ICollection<string> services; public ICollection<string> services;
public ICollection<string> running; public ICollection<string> running;
public ICollection<string> modules; public ICollection<string> modules;

View File

@ -5,5 +5,6 @@ namespace GameServiceWarden.Core.Module
public interface IServiceManagerActionExecuter public interface IServiceManagerActionExecuter
{ {
void ExecuteAction(ServiceManagerAction action); void ExecuteAction(ServiceManagerAction action);
void ViewState();
} }
} }

View File

@ -4,6 +4,7 @@ namespace GameServiceWarden.Core.Module
{ {
public interface IServiceManagerMonitor public interface IServiceManagerMonitor
{ {
void Present(ServiceManagerState state); void Present(ServiceManagerTotal state);
void Present(ServiceManagerDelta delta);
} }
} }

View File

@ -6,6 +6,7 @@ using GameServiceWarden.ClientAPI.Module;
using GameServiceWarden.Core.Persistence; using GameServiceWarden.Core.Persistence;
using GameServiceWarden.ModuleAPI; using GameServiceWarden.ModuleAPI;
using GameServiceWarden.Core.Collection; using GameServiceWarden.Core.Collection;
using System.Text;
namespace GameServiceWarden.Core.Module namespace GameServiceWarden.Core.Module
{ {
@ -35,11 +36,9 @@ namespace GameServiceWarden.Core.Module
data[ServiceDescriptor.ASSEMBLY_PROPERTY] = assemblyName; data[ServiceDescriptor.ASSEMBLY_PROPERTY] = assemblyName;
data[ServiceDescriptor.MODULE_PROPERTY] = moduleName; data[ServiceDescriptor.MODULE_PROPERTY] = moduleName;
services.AddToPersistence(serviceName, data); services.AddToPersistence(serviceName, data);
ServiceManagerState managerState = new ServiceManagerState(); ServiceManagerDelta managerState = new ServiceManagerDelta();
managerState.delta = true;
managerState.subtract = false; managerState.subtract = false;
managerState.services = new List<string>(); managerState.service = serviceName;
managerState.services.Add(serviceName);
managerMonitor.Present(managerState); managerMonitor.Present(managerState);
} }
@ -48,17 +47,15 @@ namespace GameServiceWarden.Core.Module
if (!services.ContainsKey(serviceName)) throw new KeyNotFoundException($"Service under name \"{serviceName}\" not found."); if (!services.ContainsKey(serviceName)) throw new KeyNotFoundException($"Service under name \"{serviceName}\" not found.");
if (running.ContainsKey(serviceName)) running[serviceName].Stop(); if (running.ContainsKey(serviceName)) running[serviceName].Stop();
services.Delete(serviceName); services.Delete(serviceName);
ServiceManagerState managerState = new ServiceManagerState(); ServiceManagerDelta managerState = new ServiceManagerDelta();
managerState.delta = true;
managerState.subtract = true; managerState.subtract = true;
managerState.services = new List<string>(); managerState.service = serviceName;
managerState.services.Add(serviceName);
managerMonitor.Present(managerState); managerMonitor.Present(managerState);
} }
public IEnumerable<string> GetModuleNames() public IEnumerable<string> GetModuleNames()
{ {
ServiceManagerState managerState = new ServiceManagerState(); ServiceManagerTotal managerState = new ServiceManagerTotal();
managerState.modules = modules.Keys.ToImmutableArray(); managerState.modules = modules.Keys.ToImmutableArray();
managerMonitor.Present(managerState); managerMonitor.Present(managerState);
return modules.Keys; return modules.Keys;
@ -66,14 +63,14 @@ namespace GameServiceWarden.Core.Module
public IEnumerable<string> GetServiceNames() public IEnumerable<string> GetServiceNames()
{ {
ServiceManagerState managerState = new ServiceManagerState(); ServiceManagerTotal managerState = new ServiceManagerTotal();
managerState.services = services.Keys.ToImmutableArray(); managerState.services = services.Keys.ToImmutableArray();
managerMonitor.Present(managerState); managerMonitor.Present(managerState);
return services.Keys; return services.Keys;
} }
public IEnumerable<string> GetRunningServiceNames() { public IEnumerable<string> GetRunningServiceNames() {
ServiceManagerState managerState = new ServiceManagerState(); ServiceManagerTotal managerState = new ServiceManagerTotal();
managerState.running = running.Keys.ToImmutableArray(); managerState.running = running.Keys.ToImmutableArray();
managerMonitor.Present(managerState); managerMonitor.Present(managerState);
return running.Keys; return running.Keys;
@ -97,7 +94,7 @@ namespace GameServiceWarden.Core.Module
} }
public IReadOnlyDictionary<string, IReadOnlyDictionary<string, string>> GetOptions() { public IReadOnlyDictionary<string, IReadOnlyDictionary<string, string>> GetOptions() {
ServiceManagerState managerState = new ServiceManagerState(); ServiceManagerTotal managerState = new ServiceManagerTotal();
Dictionary<string, IReadOnlyDictionary<string, string>> serviceOptions = new Dictionary<string, IReadOnlyDictionary<string, string>>(); Dictionary<string, IReadOnlyDictionary<string, string>> serviceOptions = new Dictionary<string, IReadOnlyDictionary<string, string>>();
foreach (string service in GetServiceNames()) foreach (string service in GetServiceNames())
{ {
@ -119,17 +116,14 @@ namespace GameServiceWarden.Core.Module
IReadOnlyDictionary<string, string> info = services[serviceName]; IReadOnlyDictionary<string, string> info = services[serviceName];
ServiceDescriptor service = descriptorCache.Use(serviceName, () => GenerateDescriptor(serviceName, info[ServiceDescriptor.ASSEMBLY_PROPERTY], info[ServiceDescriptor.MODULE_PROPERTY])); ServiceDescriptor service = descriptorCache.Use(serviceName, () => GenerateDescriptor(serviceName, info[ServiceDescriptor.ASSEMBLY_PROPERTY], info[ServiceDescriptor.MODULE_PROPERTY]));
if (!service.GetConfigurableOptions().Contains(optionName)) throw new KeyNotFoundException($"Option \"{optionName}\" for service \"{serviceName}\" not found."); if (!service.GetConfigurableOptions().Contains(optionName)) throw new KeyNotFoundException($"Option \"{optionName}\" for service \"{serviceName}\" not found.");
ServiceManagerState managerState = new ServiceManagerState(); ServiceManagerDelta managerState = new ServiceManagerDelta();
if (service.SetConfigurableValue(optionName, value)) { if (service.SetConfigurableValue(optionName, value)) {
managerState.delta = true; managerState.optionName = optionName;
Dictionary<string, IReadOnlyDictionary<string, string>> changedOption = new Dictionary<string, IReadOnlyDictionary<string, string>>(); managerState.optionValue = GetServiceOptionValue(serviceName, optionName);
Dictionary<string, string> options = new Dictionary<string, string>();
options[optionName] = GetServiceOptionValue(serviceName, optionName);
changedOption[serviceName] = options;
managerState.serviceOptions = changedOption;
}
managerMonitor.Present(managerState); managerMonitor.Present(managerState);
return managerState.delta; return true;
}
return false;
} }
public void StartService(string serviceName) public void StartService(string serviceName)
@ -168,7 +162,7 @@ namespace GameServiceWarden.Core.Module
{ {
logs.Add(service, running[service].GetLogBuffer()); logs.Add(service, running[service].GetLogBuffer());
} }
ServiceManagerState managerState = new ServiceManagerState(); ServiceManagerTotal managerState = new ServiceManagerTotal();
managerState.logs = logs; managerState.logs = logs;
managerMonitor.Present(managerState); managerMonitor.Present(managerState);
return logs; return logs;
@ -180,15 +174,13 @@ namespace GameServiceWarden.Core.Module
private void OnServiceStateChange(object sender, ServiceState state) { private void OnServiceStateChange(object sender, ServiceState state) {
ServiceDescriptor serviceInfo = (ServiceDescriptor)sender; ServiceDescriptor serviceInfo = (ServiceDescriptor)sender;
ServiceManagerState managerChange = new ServiceManagerState(); ServiceManagerDelta managerChange = new ServiceManagerDelta();
switch (state) switch (state)
{ {
case ServiceState.Running: case ServiceState.Running:
if (running.TryAdd(serviceInfo.ServiceName, serviceInfo)) { if (running.TryAdd(serviceInfo.ServiceName, serviceInfo)) {
managerChange.delta = true; managerChange.running = serviceInfo.ServiceName;
managerChange.running = new List<string>();
managerChange.running.Add(serviceInfo.ServiceName);
} }
break; break;
case ServiceState.Stopped: case ServiceState.Stopped:
@ -200,10 +192,8 @@ namespace GameServiceWarden.Core.Module
removedInfo[ServiceDescriptor.ASSEMBLY_PROPERTY] = removed.GetAssemblyName(); removedInfo[ServiceDescriptor.ASSEMBLY_PROPERTY] = removed.GetAssemblyName();
removedInfo[ServiceDescriptor.MODULE_PROPERTY] = removed.GetModuleName(); removedInfo[ServiceDescriptor.MODULE_PROPERTY] = removed.GetModuleName();
services[serviceInfo.ServiceName] = removedInfo; services[serviceInfo.ServiceName] = removedInfo;
managerChange.delta = true;
managerChange.subtract = true; managerChange.subtract = true;
managerChange.running = new List<string>(); managerChange.running = serviceInfo.ServiceName;
managerChange.running.Add(serviceInfo.ServiceName);
} }
break; break;
} }
@ -213,25 +203,15 @@ namespace GameServiceWarden.Core.Module
void OnLogUpdated(object sender, string update) { void OnLogUpdated(object sender, string update) {
ServiceDescriptor service = (ServiceDescriptor)sender; ServiceDescriptor service = (ServiceDescriptor)sender;
ServiceManagerState state = new ServiceManagerState(); ServiceManagerDelta delta = new ServiceManagerDelta();
state.delta = true; delta.logs = Encoding.UTF8.GetBytes(update);
Dictionary<string, string> logUpdate = new Dictionary<string, string>(); managerMonitor.Present(delta);
logUpdate[service.ServiceName] = update;
managerMonitor.Present(state);
} }
public void ExecuteAction(ServiceManagerAction action) public void ExecuteAction(ServiceManagerAction action)
{ {
switch (action.action) switch (action.action)
{ {
case ServiceManagerAction.Type.View:
GetServiceNames();
GetRunningServiceNames();
GetModuleNames();
GetLogBuffer();
GetOptions();
break;
case ServiceManagerAction.Type.CreateService: case ServiceManagerAction.Type.CreateService:
CreateService(action.serviceName, action.assemblyName, action.moduleName); CreateService(action.serviceName, action.assemblyName, action.moduleName);
break; break;
@ -254,5 +234,14 @@ namespace GameServiceWarden.Core.Module
break; break;
} }
} }
public void ViewState()
{
GetServiceNames();
GetRunningServiceNames();
GetModuleNames();
GetLogBuffer();
GetOptions();
}
} }
} }

View File

@ -1,7 +1,7 @@
using System.Diagnostics; using System.Diagnostics;
using System.Text.Json; using System.Text.Json;
using GameServiceWarden.ClientAPI; using GameServiceWarden.ClientAPI;
using GameServiceWarden.ClientAPI.Requests; using GameServiceWarden.ClientAPI.Communicable.Requests;
using GameServiceWarden.Core.Module; using GameServiceWarden.Core.Module;
using GameServiceWarden.Core.Logging; using GameServiceWarden.Core.Logging;
@ -26,9 +26,13 @@ namespace GameServiceWarden.Core.UI
{ {
switch (action.Item2) switch (action.Item2)
{ {
case CommunicableType.Service: case CommunicableType.Delta:
ServiceRequest request = JsonSerializer.Deserialize<ServiceRequest>(action.Item3); ServiceRequest delta = JsonSerializer.Deserialize<ServiceRequest>(action.Item3);
serviceExecutioner.ExecuteAction(request.serviceManagerAction); serviceExecutioner.ExecuteAction(delta.serviceManagerAction);
break;
case CommunicableType.View:
ViewRequest view = JsonSerializer.Deserialize<ViewRequest>(action.Item3);
serviceExecutioner.ViewState();
break; break;
} }
} }

View File

@ -8,8 +8,8 @@ using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using GameServiceWarden.ClientAPI; using GameServiceWarden.ClientAPI;
using GameServiceWarden.ClientAPI.Requests; using GameServiceWarden.ClientAPI.Communicable.Requests;
using GameServiceWarden.ClientAPI.Responses; using GameServiceWarden.ClientAPI.Communicable.Responses;
using GameServiceWarden.Core.Logging; using GameServiceWarden.Core.Logging;
namespace GameServiceWarden.Core.UI namespace GameServiceWarden.Core.UI

View File

@ -15,9 +15,16 @@ namespace GameServiceWarden.Core.UI
this.mediator = mediator; this.mediator = mediator;
} }
public void Present(ServiceManagerState state) public void Present(ServiceManagerTotal state)
{ {
Task replyTask = mediator.ReplyAll(CommunicableType.Service, JsonSerializer.SerializeToUtf8Bytes(state)); Task replyTask = mediator.ReplyAll(CommunicableType.View, JsonSerializer.SerializeToUtf8Bytes(state));
replyTask.Wait();
}
public void Present(ServiceManagerDelta delta)
{
Task replyTask = mediator.ReplyAll(CommunicableType.Delta, JsonSerializer.SerializeToUtf8Bytes(delta));
replyTask.Wait();
} }
} }
} }

View File

@ -7,22 +7,33 @@ namespace GameServiceWarden.Core.Tests.Modules
{ {
public class FakeServiceManagerMonitor : IServiceManagerMonitor public class FakeServiceManagerMonitor : IServiceManagerMonitor
{ {
public List<ServiceManagerState> states = new List<ServiceManagerState>(); public List<ServiceManagerTotal> states = new List<ServiceManagerTotal>();
public ServiceManagerState this[int i] public List<ServiceManagerDelta> deltas = new List<ServiceManagerDelta>();
public ServiceManagerTotal this[int i]
{ {
get get
{ {
return states[i]; return states[i];
} }
} }
public void Present(ServiceManagerState state)
public void Present(ServiceManagerTotal state)
{ {
states.Add(state); states.Add(state);
} }
public ServiceManagerState GetLastState() public void Present(ServiceManagerDelta delta)
{
deltas.Add(delta);
}
public ServiceManagerTotal GetLastState()
{ {
return states[states.Count - 1]; return states[states.Count - 1];
} }
public ServiceManagerDelta GetLastDelta() {
return deltas[deltas.Count - 1];
}
} }
} }

View File

@ -1,15 +1,10 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Threading.Tasks;
using GameServiceWarden.Core.Module; using GameServiceWarden.Core.Module;
using GameServiceWarden.Core.Logging; using GameServiceWarden.Core.Logging;
using GameServiceWarden.ModuleAPI; using GameServiceWarden.ModuleAPI;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
using System.Text;
[assembly: CollectionBehavior(DisableTestParallelization = true)] [assembly: CollectionBehavior(DisableTestParallelization = true)]
namespace GameServiceWarden.Core.Tests.Modules namespace GameServiceWarden.Core.Tests.Modules
@ -39,7 +34,7 @@ namespace GameServiceWarden.Core.Tests.Modules
//When //When
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name); serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
//Then //Then
Assert.Contains<string>(FAKE_SERVICE_NAME, stubMonitor.GetLastState().services); Assert.True(FAKE_SERVICE_NAME.Equals(stubMonitor.GetLastDelta().service));
} }
[Fact] [Fact]
@ -60,9 +55,8 @@ namespace GameServiceWarden.Core.Tests.Modules
serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name); serviceManager.CreateService(FAKE_SERVICE_NAME, ASSEMBLY_NAME, stubServiceModule.Name);
serviceManager.DeleteService(FAKE_SERVICE_NAME); serviceManager.DeleteService(FAKE_SERVICE_NAME);
//Then //Then
Assert.True(stubMonitor.GetLastState().delta); Assert.True(stubMonitor.GetLastDelta().subtract);
Assert.True(stubMonitor.GetLastState().subtract); Assert.True(FAKE_SERVICE_NAME.Equals(stubMonitor.GetLastDelta().service));
Assert.Contains(FAKE_SERVICE_NAME, stubMonitor.GetLastState().services);
} }
[Fact] [Fact]