Changed pipe names to end with ".pipe".
Added timeouts to closing.
This commit is contained in:
parent
526e657f59
commit
78e9e185c2
@ -18,27 +18,28 @@ namespace GameServiceWarden.Core.Games
|
|||||||
{
|
{
|
||||||
public class ServiceDescriptor //entity
|
public class ServiceDescriptor //entity
|
||||||
{
|
{
|
||||||
private const string DISTRIBUTOR_SUFFIX = "_dist";
|
private const string LOG_DISTRIBUTOR_PREFIX = "log_dist_";
|
||||||
private const int INIT_TIMEOUT = 1000;
|
private const int TIMEOUT = 1000;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The name of the service itself, independent of the name of the module this service is using.
|
/// The name of the service itself, independent of the name of the module this service is using.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ServiceName { get { return serviceName; } }
|
public string ServiceName { get { return serviceName; } }
|
||||||
private readonly string serviceName;
|
private readonly string serviceName;
|
||||||
private bool running;
|
private readonly Guid runningUID;
|
||||||
|
private volatile bool running;
|
||||||
private readonly IService service;
|
private readonly IService service;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The services log output pipe name.
|
/// The services log output pipe name.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ServiceLogPipeName { get { return (serviceName); } }
|
public string ServiceLogPipeName { get { return (runningUID.ToString() + ".pipe"); } }
|
||||||
private string moduleName;
|
private string moduleName;
|
||||||
private readonly string assemblyName;
|
private readonly string assemblyName;
|
||||||
private NamedPipeServerStream logReceiver;
|
private volatile NamedPipeServerStream logReceiver;
|
||||||
private NamedPipeClientStream logSender;
|
private volatile NamedPipeClientStream logSender;
|
||||||
private ConcurrentStack<NamedPipeServerStream> logStreamListeners;
|
private ConcurrentStack<NamedPipeServerStream> logStreamListeners;
|
||||||
private Task logUpdateTask;
|
private Task logUpdateTask;
|
||||||
private Task acceptingTask;
|
private Task acceptingTask;
|
||||||
private CancellationTokenSource stopToken;
|
private volatile CancellationTokenSource stopToken;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Name of module this service uses.
|
/// Name of module this service uses.
|
||||||
@ -52,6 +53,8 @@ namespace GameServiceWarden.Core.Games
|
|||||||
this.assemblyName = assemblyName ?? throw new ArgumentNullException("assemblyName");
|
this.assemblyName = assemblyName ?? throw new ArgumentNullException("assemblyName");
|
||||||
this.serviceName = serviceName ?? throw new ArgumentNullException("serviceName");
|
this.serviceName = serviceName ?? throw new ArgumentNullException("serviceName");
|
||||||
this.service.StateChangeEvent += OnServiceStateChange;
|
this.service.StateChangeEvent += OnServiceStateChange;
|
||||||
|
runningUID = Guid.NewGuid();
|
||||||
|
|
||||||
|
|
||||||
Dictionary<string, IServiceConfigurable> tempConfigurables = new Dictionary<string, IServiceConfigurable>();
|
Dictionary<string, IServiceConfigurable> tempConfigurables = new Dictionary<string, IServiceConfigurable>();
|
||||||
foreach (IServiceConfigurable configurable in service.Configurables)
|
foreach (IServiceConfigurable configurable in service.Configurables)
|
||||||
@ -71,23 +74,25 @@ namespace GameServiceWarden.Core.Games
|
|||||||
{
|
{
|
||||||
Logger.Log($"\"{ServiceName}\" is starting.");
|
Logger.Log($"\"{ServiceName}\" is starting.");
|
||||||
if (running) throw new InvalidOperationException("Service instance already running.");
|
if (running) throw new InvalidOperationException("Service instance already running.");
|
||||||
logReceiver = new NamedPipeServerStream(ServiceLogPipeName + DISTRIBUTOR_SUFFIX, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
logReceiver = new NamedPipeServerStream(LOG_DISTRIBUTOR_PREFIX + ServiceLogPipeName, PipeDirection.In, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
||||||
Task waitForConnection = logReceiver.WaitForConnectionAsync();
|
Task waitForConnection = logReceiver.WaitForConnectionAsync();
|
||||||
logSender = new NamedPipeClientStream(".", ServiceLogPipeName + DISTRIBUTOR_SUFFIX, PipeDirection.Out);
|
logSender = new NamedPipeClientStream(".", LOG_DISTRIBUTOR_PREFIX + ServiceLogPipeName, PipeDirection.Out);
|
||||||
logSender.Connect();
|
logSender.Connect();
|
||||||
waitForConnection.Wait();
|
waitForConnection.Wait();
|
||||||
byte[] idToken = Guid.NewGuid().ToByteArray();
|
byte[] idToken = Guid.NewGuid().ToByteArray();
|
||||||
ValueTask sendTokenTask = logSender.WriteAsync(idToken);
|
ValueTask sendTokenTask = logSender.WriteAsync(idToken);
|
||||||
byte[] receivedToken = new byte[idToken.Length];
|
byte[] receivedToken = new byte[idToken.Length];
|
||||||
logReceiver.Read(receivedToken);
|
logReceiver.Read(receivedToken);
|
||||||
|
|
||||||
if (!sendTokenTask.AsTask().Wait(500) || !sendTokenTask.IsCompletedSuccessfully) {
|
if (!sendTokenTask.AsTask().Wait(500) || !sendTokenTask.IsCompletedSuccessfully)
|
||||||
|
{
|
||||||
throw new ServiceInitializationException("Error while sending identification token.");
|
throw new ServiceInitializationException("Error while sending identification token.");
|
||||||
}
|
}
|
||||||
if (!idToken.SequenceEqual(receivedToken)) {
|
if (!idToken.SequenceEqual(receivedToken))
|
||||||
|
{
|
||||||
throw new ServiceInitializationException("Wrong distributor identification token.");
|
throw new ServiceInitializationException("Wrong distributor identification token.");
|
||||||
}
|
}
|
||||||
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(INIT_TIMEOUT);
|
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TIMEOUT);
|
||||||
Task initializationTask = Task.Run(() => service.InitializeService(logSender), cancellationTokenSource.Token);
|
Task initializationTask = Task.Run(() => service.InitializeService(logSender), cancellationTokenSource.Token);
|
||||||
initializationTask.Wait();
|
initializationTask.Wait();
|
||||||
cancellationTokenSource.Dispose();
|
cancellationTokenSource.Dispose();
|
||||||
@ -102,18 +107,27 @@ namespace GameServiceWarden.Core.Games
|
|||||||
/// <exception cref="InvalidOperationException">Is thrown when the is not running.</exception>
|
/// <exception cref="InvalidOperationException">Is thrown when the is not running.</exception>
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
Logger.Log("\"{ServiceName}\" is stopping.");
|
|
||||||
if (!running) throw new InvalidOperationException("Service instance not running.");
|
if (!running) throw new InvalidOperationException("Service instance not running.");
|
||||||
|
Logger.Log($"\"{ServiceName}\" is stopping.");
|
||||||
service.ElegantShutdown();
|
service.ElegantShutdown();
|
||||||
|
logSender.Close();
|
||||||
|
logReceiver.Close();
|
||||||
stopToken.Cancel();
|
stopToken.Cancel();
|
||||||
try {
|
try
|
||||||
acceptingTask.Wait();
|
{
|
||||||
} catch (AggregateException e) {
|
if (!acceptingTask.Wait(TIMEOUT)) {
|
||||||
|
throw new TimeoutException($"Could not stop \"{ServiceName}\" accepting task within {TIMEOUT}ms.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (AggregateException e)
|
||||||
|
{
|
||||||
e.Handle((exception) => exception is TaskCanceledException);
|
e.Handle((exception) => exception is TaskCanceledException);
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logUpdateTask.Wait();
|
if (!logUpdateTask.Wait(TIMEOUT)) {
|
||||||
|
throw new TimeoutException($"Could not stop \"{ServiceName}\" broadcast within{TIMEOUT}ms.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (AggregateException e)
|
catch (AggregateException e)
|
||||||
{
|
{
|
||||||
@ -163,11 +177,13 @@ namespace GameServiceWarden.Core.Games
|
|||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetServiceName() {
|
public string GetServiceName()
|
||||||
|
{
|
||||||
return serviceName;
|
return serviceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetModuleName() {
|
public string GetModuleName()
|
||||||
|
{
|
||||||
return moduleName;
|
return moduleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,7 +196,7 @@ namespace GameServiceWarden.Core.Games
|
|||||||
private void OnServiceStateChange(object sender, bool running)
|
private void OnServiceStateChange(object sender, bool running)
|
||||||
{
|
{
|
||||||
this.running = running;
|
this.running = running;
|
||||||
Logger.Log($"{ServiceName}'s state changed to {(running ? "running" : "stopped")}.", LogLevel.DEBUG);
|
Logger.Log($"The service \"{ServiceName}\" is changing states to {(running ? "running" : "stopped")}.", LogLevel.DEBUG);
|
||||||
ServiceStateChangeEvent?.Invoke(this, running);
|
ServiceStateChangeEvent?.Invoke(this, running);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,22 +213,26 @@ namespace GameServiceWarden.Core.Games
|
|||||||
Logger.Log($"\"{ServiceName}\" stopped accepting log listeners.");
|
Logger.Log($"\"{ServiceName}\" stopped accepting log listeners.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task BroadcastLog() {
|
private async Task BroadcastLog()
|
||||||
|
{
|
||||||
Stack<NamedPipeServerStream> completeStack = new Stack<NamedPipeServerStream>();
|
Stack<NamedPipeServerStream> completeStack = new Stack<NamedPipeServerStream>();
|
||||||
Stack<(Task, CancellationTokenSource)> writeTasks = new Stack<(Task, CancellationTokenSource)>();
|
Stack<(Task, CancellationTokenSource)> writeTasks = new Stack<(Task, CancellationTokenSource)>();
|
||||||
byte[] buffer = new byte[1024 * 8];
|
byte[] buffer = new byte[1024 * 8];
|
||||||
int fill;
|
int fill;
|
||||||
Logger.Log($"\"{ServiceName}\" is now listening to the service log and broadcasting.");
|
Logger.Log($"\"{ServiceName}\" is now listening to the service log and broadcasting.");
|
||||||
while ((fill = await logReceiver.ReadAsync(buffer, 0, buffer.Length, stopToken.Token)) > 0)
|
while (running && (fill = await logReceiver.ReadAsync(buffer, 0, buffer.Length, stopToken.Token)) > 0)
|
||||||
{
|
{
|
||||||
Logger.Log($"Broadcasting {fill} bytes.", LogLevel.DEBUG);
|
Logger.Log($"Broadcasting {fill} bytes.", LogLevel.DEBUG);
|
||||||
NamedPipeServerStream pipe;
|
NamedPipeServerStream pipe;
|
||||||
while (logStreamListeners.TryPop(out pipe))
|
while (logStreamListeners.TryPop(out pipe))
|
||||||
{
|
{
|
||||||
if (!pipe.IsConnected) {
|
if (!pipe.IsConnected)
|
||||||
|
{
|
||||||
pipe.Dispose();
|
pipe.Dispose();
|
||||||
Logger.Log($"\"{ServiceName}\" detected a disconnected log listener. Removing from list of listener(s).", LogLevel.DEBUG);
|
Logger.Log($"\"{ServiceName}\" detected a disconnected log listener. Removing from list of listener(s).", LogLevel.DEBUG);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
CancellationTokenSource cancelToken = new CancellationTokenSource(1000);
|
CancellationTokenSource cancelToken = new CancellationTokenSource(1000);
|
||||||
writeTasks.Push((pipe.WriteAsync(buffer, 0, fill, cancelToken.Token), cancelToken));
|
writeTasks.Push((pipe.WriteAsync(buffer, 0, fill, cancelToken.Token), cancelToken));
|
||||||
completeStack.Push(pipe);
|
completeStack.Push(pipe);
|
||||||
@ -224,7 +244,8 @@ namespace GameServiceWarden.Core.Games
|
|||||||
logStreamListeners.Push(completePipe);
|
logStreamListeners.Push(completePipe);
|
||||||
}
|
}
|
||||||
(Task, CancellationTokenSource) taskAndCancel;
|
(Task, CancellationTokenSource) taskAndCancel;
|
||||||
while (writeTasks.TryPop(out taskAndCancel)) {
|
while (writeTasks.TryPop(out taskAndCancel))
|
||||||
|
{
|
||||||
await taskAndCancel.Item1;
|
await taskAndCancel.Item1;
|
||||||
taskAndCancel.Item2.Dispose();
|
taskAndCancel.Item2.Dispose();
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,6 @@ namespace GameServiceWarden.Core.Games
|
|||||||
{
|
{
|
||||||
switch (action.action)
|
switch (action.action)
|
||||||
{
|
{
|
||||||
//TODO FINISH MOVING THIS!!!!
|
|
||||||
case ServiceManagerAction.Type.View:
|
case ServiceManagerAction.Type.View:
|
||||||
GetServiceNames();
|
GetServiceNames();
|
||||||
GetRunningServiceNames();
|
GetRunningServiceNames();
|
||||||
|
@ -15,7 +15,8 @@ namespace GameServiceWarden.Core.UI
|
|||||||
{
|
{
|
||||||
public class IPCMediator
|
public class IPCMediator
|
||||||
{
|
{
|
||||||
private const int CONNECT_TIMEOUT = 1000;
|
private const int TIMEOUT = 1000;
|
||||||
|
public string PipeName {get { return name + ".pipe"; } }
|
||||||
private readonly string name;
|
private readonly string name;
|
||||||
private readonly ConcurrentDictionary<string, (NamedPipeServerStream, Task)> pipes;
|
private readonly ConcurrentDictionary<string, (NamedPipeServerStream, Task)> pipes;
|
||||||
public BlockingCollection<(string, CommunicableType, byte[])> RequestQueue { get; private set; }
|
public BlockingCollection<(string, CommunicableType, byte[])> RequestQueue { get; private set; }
|
||||||
@ -48,7 +49,7 @@ namespace GameServiceWarden.Core.UI
|
|||||||
stopAcceptingToken.Cancel();
|
stopAcceptingToken.Cancel();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
acceptTask.Wait();
|
if (!acceptTask.Wait(TIMEOUT)) throw new TimeoutException($"IPCMediator \"{name}\" was unable to stop accepting task within {TIMEOUT}ms.");
|
||||||
}
|
}
|
||||||
catch (AggregateException e)
|
catch (AggregateException e)
|
||||||
{
|
{
|
||||||
@ -109,7 +110,7 @@ namespace GameServiceWarden.Core.UI
|
|||||||
Logger.Log("Accepting Interface connections.");
|
Logger.Log("Accepting Interface connections.");
|
||||||
while (active)
|
while (active)
|
||||||
{
|
{
|
||||||
NamedPipeServerStream pipe = new NamedPipeServerStream(name, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
NamedPipeServerStream pipe = new NamedPipeServerStream(PipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);
|
||||||
Logger.Log("Waiting for connection.", LogLevel.DEBUG);
|
Logger.Log("Waiting for connection.", LogLevel.DEBUG);
|
||||||
await pipe.WaitForConnectionAsync(stopAcceptingToken.Token);
|
await pipe.WaitForConnectionAsync(stopAcceptingToken.Token);
|
||||||
connectionTasks.Add(OnConnection(pipe));
|
connectionTasks.Add(OnConnection(pipe));
|
||||||
@ -135,7 +136,7 @@ namespace GameServiceWarden.Core.UI
|
|||||||
Logger.Log("Interface attempting to connect.", LogLevel.DEBUG);
|
Logger.Log("Interface attempting to connect.", LogLevel.DEBUG);
|
||||||
byte[] headerBuffer = new byte[sizeof(uint) * 2];
|
byte[] headerBuffer = new byte[sizeof(uint) * 2];
|
||||||
int headerFill = 0;
|
int headerFill = 0;
|
||||||
CancellationTokenSource headerCancel = new CancellationTokenSource(CONNECT_TIMEOUT);
|
CancellationTokenSource headerCancel = new CancellationTokenSource(TIMEOUT);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int readLength;
|
int readLength;
|
||||||
@ -148,7 +149,7 @@ namespace GameServiceWarden.Core.UI
|
|||||||
catch (AggregateException e)
|
catch (AggregateException e)
|
||||||
{
|
{
|
||||||
e.Handle((exception) => exception is TaskCanceledException);
|
e.Handle((exception) => exception is TaskCanceledException);
|
||||||
Logger.Log($"Interface did not send header data within {CONNECT_TIMEOUT}ms.", LogLevel.DEBUG);
|
Logger.Log($"Interface did not send header data within {TIMEOUT}ms.", LogLevel.DEBUG);
|
||||||
} finally {
|
} finally {
|
||||||
await pipe.DisposeAsync();
|
await pipe.DisposeAsync();
|
||||||
headerCancel.Dispose();
|
headerCancel.Dispose();
|
||||||
@ -164,7 +165,7 @@ namespace GameServiceWarden.Core.UI
|
|||||||
|
|
||||||
byte[] bodyBuffer = new byte[bodyLength];
|
byte[] bodyBuffer = new byte[bodyLength];
|
||||||
int bodyFill = 0;
|
int bodyFill = 0;
|
||||||
CancellationTokenSource bodyCancel = new CancellationTokenSource(CONNECT_TIMEOUT);
|
CancellationTokenSource bodyCancel = new CancellationTokenSource(TIMEOUT);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int readLength = 0;
|
int readLength = 0;
|
||||||
@ -177,7 +178,7 @@ namespace GameServiceWarden.Core.UI
|
|||||||
catch (AggregateException e)
|
catch (AggregateException e)
|
||||||
{
|
{
|
||||||
e.Handle((exception) => exception is TaskCanceledException);
|
e.Handle((exception) => exception is TaskCanceledException);
|
||||||
Logger.Log($"Interface failed to send body data within {CONNECT_TIMEOUT}.", LogLevel.DEBUG);
|
Logger.Log($"Interface failed to send body data within {TIMEOUT}.", LogLevel.DEBUG);
|
||||||
} finally {
|
} finally {
|
||||||
await pipe.DisposeAsync();
|
await pipe.DisposeAsync();
|
||||||
bodyCancel.Dispose();
|
bodyCancel.Dispose();
|
||||||
@ -204,7 +205,7 @@ namespace GameServiceWarden.Core.UI
|
|||||||
requestAccepted = true;
|
requestAccepted = true;
|
||||||
response.identifier = request.requestedIdentifier;
|
response.identifier = request.requestedIdentifier;
|
||||||
}
|
}
|
||||||
CancellationTokenSource cancelResponse = new CancellationTokenSource(CONNECT_TIMEOUT);
|
CancellationTokenSource cancelResponse = new CancellationTokenSource(TIMEOUT);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await pipe.WriteAsync(JsonSerializer.SerializeToUtf8Bytes(response), cancelResponse.Token);
|
await pipe.WriteAsync(JsonSerializer.SerializeToUtf8Bytes(response), cancelResponse.Token);
|
||||||
@ -212,7 +213,7 @@ namespace GameServiceWarden.Core.UI
|
|||||||
catch (AggregateException e)
|
catch (AggregateException e)
|
||||||
{
|
{
|
||||||
e.Handle((exception) => exception is TaskCanceledException);
|
e.Handle((exception) => exception is TaskCanceledException);
|
||||||
Logger.Log($"Interface did not receive response within {CONNECT_TIMEOUT}ms.", LogLevel.DEBUG);
|
Logger.Log($"Interface did not receive response within {TIMEOUT}ms.", LogLevel.DEBUG);
|
||||||
}
|
}
|
||||||
if (!requestAccepted) {
|
if (!requestAccepted) {
|
||||||
cancelResponse.Dispose();
|
cancelResponse.Dispose();
|
||||||
|
@ -5,18 +5,18 @@
|
|||||||
<mxCell id="0"/>
|
<mxCell id="0"/>
|
||||||
<mxCell id="1" parent="0"/>
|
<mxCell id="1" parent="0"/>
|
||||||
<mxCell id="dmd0HlDYcxYugIlahWj0-5" value="ServiceDescriptor" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;" parent="1" vertex="1">
|
<mxCell id="dmd0HlDYcxYugIlahWj0-5" value="ServiceDescriptor" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;" parent="1" vertex="1">
|
||||||
<mxGeometry x="695" y="1100" width="510" height="410" as="geometry">
|
<mxGeometry x="695" y="1100" width="510" height="420" as="geometry">
|
||||||
<mxRectangle x="762" y="1030" width="130" height="26" as="alternateBounds"/>
|
<mxRectangle x="762" y="1030" width="130" height="26" as="alternateBounds"/>
|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="dmd0HlDYcxYugIlahWj0-6" value="+ ServiceName: string property - serviceName: string - running: bool - service: IService - ServiceLogPipeName: string property - moduleName: string - assemblyName: string - logStreamListeners: ConcurrentStack<NamedPipeServerStream> - logUpdateTask: Task - acceptingTask: Task - stopToken: CancellationTokenSource - configurables: IReadOnlyDictionary<string, IServiceConfigurable> + ServiceStateChangeEvent: event EventHandler<bool>" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;" parent="dmd0HlDYcxYugIlahWj0-5" vertex="1">
|
<mxCell id="dmd0HlDYcxYugIlahWj0-6" value="+ ServiceName: string property - serviceName: string - runningUID: Guid - running: bool - service: IService - ServiceLogPipeName: string property - moduleName: string - assemblyName: string - logStreamListeners: ConcurrentStack<NamedPipeServerStream> - logUpdateTask: Task - acceptingTask: Task - stopToken: CancellationTokenSource - configurables: IReadOnlyDictionary<string, IServiceConfigurable> + ServiceStateChangeEvent: event EventHandler<bool>" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;" parent="dmd0HlDYcxYugIlahWj0-5" vertex="1">
|
||||||
<mxGeometry y="26" width="510" height="194" as="geometry"/>
|
<mxGeometry y="26" width="510" height="204" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="dmd0HlDYcxYugIlahWj0-7" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;" parent="dmd0HlDYcxYugIlahWj0-5" vertex="1">
|
<mxCell id="dmd0HlDYcxYugIlahWj0-7" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;" parent="dmd0HlDYcxYugIlahWj0-5" vertex="1">
|
||||||
<mxGeometry y="220" width="510" height="8" as="geometry"/>
|
<mxGeometry y="230" width="510" height="8" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="dmd0HlDYcxYugIlahWj0-8" value="+ Start(): void + Stop(): void + ExecuteCommand(command: string): void + GetConfigurableOptions(): ISet<string> + SetConfigurableValue(configurationName: string, value: string): bool + GetConfigurableValue(configurationName: string): string + GetServiceState(): bool + GetModuleName(): string + GetassemblyName(): string - OnServiceStateChange(sender: object, running: bool): void - AcceptLogConnections(): Task - BroadcastLog(): Task" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;" parent="dmd0HlDYcxYugIlahWj0-5" vertex="1">
|
<mxCell id="dmd0HlDYcxYugIlahWj0-8" value="+ Start(): void + Stop(): void + ExecuteCommand(command: string): void + GetConfigurableOptions(): ISet<string> + SetConfigurableValue(configurationName: string, value: string): bool + GetConfigurableValue(configurationName: string): string + GetServiceState(): bool + GetModuleName(): string + GetassemblyName(): string - OnServiceStateChange(sender: object, running: bool): void - AcceptLogConnections(): Task - BroadcastLog(): Task" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;" parent="dmd0HlDYcxYugIlahWj0-5" vertex="1">
|
||||||
<mxGeometry y="228" width="510" height="182" as="geometry"/>
|
<mxGeometry y="238" width="510" height="182" as="geometry"/>
|
||||||
</mxCell>
|
</mxCell>
|
||||||
<mxCell id="dmd0HlDYcxYugIlahWj0-15" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="1" source="dmd0HlDYcxYugIlahWj0-11" target="dmd0HlDYcxYugIlahWj0-5" edge="1">
|
<mxCell id="dmd0HlDYcxYugIlahWj0-15" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="1" source="dmd0HlDYcxYugIlahWj0-11" target="dmd0HlDYcxYugIlahWj0-5" edge="1">
|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||
@ -193,348 +193,348 @@
|
|||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||
</diagram>
|
</diagram>
|
||||||
<diagram id="gj0qHRc3eh050ABAey3g" name="Data-Flow">
|
<diagram id="gj0qHRc3eh050ABAey3g" name="Data-Flow">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGraphModel dx="1024" dy="592" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
<mxGraphModel dx="1024" dy="592" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||||

 
 



|

 
 
 
 





|
||||||
<root>
|
<root>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-0"/>
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-0"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-1" parent="jVG6p58vlRYGO9X4wXeX-0"/>
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-1" parent="jVG6p58vlRYGO9X4wXeX-0"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="28FAlPysTx9DMYvLwa-2-21" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-2" target="jVG6p58vlRYGO9X4wXeX-3" edge="1">
|
<mxCell id="28FAlPysTx9DMYvLwa-2-21" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.3333333333333333;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-2" target="jVG6p58vlRYGO9X4wXeX-3" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-2" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-2" value="Actor" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="10" y="300" width="30" height="60" as="geometry"/>
|
<mxGeometry x="10" y="300" width="30" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-12" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-4" edge="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-12" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-4" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="28FAlPysTx9DMYvLwa-2-22" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=0.75;entryY=0.1;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-2" edge="1">
|
<mxCell id="28FAlPysTx9DMYvLwa-2-22" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.25;exitDx=0;exitDy=0;entryX=0.75;entryY=0.1;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-2" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="345FJoVc2gbAayMsQlD7-0" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-4" edge="1">
|
<mxCell id="345FJoVc2gbAayMsQlD7-0" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="jVG6p58vlRYGO9X4wXeX-4" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="345FJoVc2gbAayMsQlD7-6" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="28FAlPysTx9DMYvLwa-2-7" edge="1">
|
<mxCell id="345FJoVc2gbAayMsQlD7-6" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-3" target="28FAlPysTx9DMYvLwa-2-7" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-3" value="Console View" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-3" value="Console View" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="80" y="300" width="120" height="60" as="geometry"/>
|
<mxGeometry x="80" y="300" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-13" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-4" target="jVG6p58vlRYGO9X4wXeX-5" edge="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-13" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-4" target="jVG6p58vlRYGO9X4wXeX-5" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="345FJoVc2gbAayMsQlD7-2" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-4" target="jVG6p58vlRYGO9X4wXeX-5" edge="1">
|
<mxCell id="345FJoVc2gbAayMsQlD7-2" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-4" target="jVG6p58vlRYGO9X4wXeX-5" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-4" value="string command (request)" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-4" value="string command (request)" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="260" y="482.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="260" y="482.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-8" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-8" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="28FAlPysTx9DMYvLwa-2-3" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
|
<mxCell id="28FAlPysTx9DMYvLwa-2-3" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-18" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-9" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-18" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-5" target="jVG6p58vlRYGO9X4wXeX-9" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-5" value="MainController" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-5" value="MainController" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="420" y="482.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="420" y="482.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-6" value="http://www.plainionist.net/Implementing-Clean-Architecture-Controller-Presenter/" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-6" value="http://www.plainionist.net/Implementing-Clean-Architecture-Controller-Presenter/" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry y="840" width="480" height="20" as="geometry"/>
|
<mxGeometry y="840" width="480" height="20" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-7" value="&lt;&lt;Interface&gt;&gt;<br>ICommand" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-7" value="&lt;&lt;Interface&gt;&gt;<br>ICommand" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="420" y="372.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="420" y="372.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-10" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-10" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="jVG6p58vlRYGO9X4wXeX-7" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-8" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-8" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxPoint x="809.9999999999998" y="512.5000000000002" as="sourcePoint"/>
|
<mxPoint x="809.9999999999998" y="512.5000000000002" as="sourcePoint"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="345FJoVc2gbAayMsQlD7-3" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
|
<mxCell id="345FJoVc2gbAayMsQlD7-3" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="345FJoVc2gbAayMsQlD7-4" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
|
<mxCell id="345FJoVc2gbAayMsQlD7-4" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="jVG6p58vlRYGO9X4wXeX-9" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="jVG6p58vlRYGO9X4wXeX-9" value="ServiceController" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="jVG6p58vlRYGO9X4wXeX-9" value="ServiceController" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="575" y="482.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="575" y="482.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-4" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-4" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;endArrow=block;endFill=1;strokeColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-5" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;strokeColor=#f0f0f0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-5" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;strokeColor=#f0f0f0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-2" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-7" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1.008;entryY=0.625;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-7" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1.008;entryY=0.625;entryDx=0;entryDy=0;entryPerimeter=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry">
|
||||||

 
 



|

 
 
 
 





|
||||||
<Array as="points">
|
<Array as="points">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxPoint x="960" y="338"/>
|
<mxPoint x="960" y="338"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxPoint x="960" y="580"/>
|
<mxPoint x="960" y="580"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</Array>
|
</Array>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-16" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-11" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-16" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-11" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="345FJoVc2gbAayMsQlD7-7" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
|
<mxCell id="345FJoVc2gbAayMsQlD7-7" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry">
|
<mxGeometry relative="1" as="geometry">
|
||||||

 
 



|

 
 
 
 





|
||||||
<Array as="points">
|
<Array as="points">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxPoint x="960" y="338"/>
|
<mxPoint x="960" y="338"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxPoint x="960" y="83"/>
|
<mxPoint x="960" y="83"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</Array>
|
</Array>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxGeometry>
|
</mxGeometry>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="28FAlPysTx9DMYvLwa-2-1" value="ServiceManager" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="28FAlPysTx9DMYvLwa-2-1" value="ServiceManager" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="800" y="307.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="800" y="307.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="28FAlPysTx9DMYvLwa-2-9" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="tM_Gde3HH8YiZ2frBV5J-0" edge="1">
|
<mxCell id="28FAlPysTx9DMYvLwa-2-9" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="tM_Gde3HH8YiZ2frBV5J-0" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-12" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=block;endFill=0;strokeColor=#f0f0f0;dashed=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="UY-EM7-1ECCvWtENr50b-11" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-12" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=block;endFill=0;strokeColor=#f0f0f0;dashed=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="UY-EM7-1ECCvWtENr50b-11" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-13" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-13" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="tM_Gde3HH8YiZ2frBV5J-3" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
|
<mxCell id="tM_Gde3HH8YiZ2frBV5J-3" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-5" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="28FAlPysTx9DMYvLwa-2-5" value="ServicePresenter" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="28FAlPysTx9DMYvLwa-2-5" value="ServicePresenter" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="575" y="122.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="575" y="122.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="28FAlPysTx9DMYvLwa-2-8" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-7" target="jVG6p58vlRYGO9X4wXeX-3" edge="1">
|
<mxCell id="28FAlPysTx9DMYvLwa-2-8" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=open;endFill=0;fillColor=#1ba1e2;strokeColor=#006EAF;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-7" target="jVG6p58vlRYGO9X4wXeX-3" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="tM_Gde3HH8YiZ2frBV5J-5" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-7" target="tM_Gde3HH8YiZ2frBV5J-0" edge="1">
|
<mxCell id="tM_Gde3HH8YiZ2frBV5J-5" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-7" target="tM_Gde3HH8YiZ2frBV5J-0" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="28FAlPysTx9DMYvLwa-2-7" value="String Output" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="28FAlPysTx9DMYvLwa-2-7" value="String Output" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="260" y="122.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="260" y="122.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-1" value="ServiceAction &lt;DS&gt;" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-1" value="ServiceAction &lt;DS&gt;" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="800" y="542.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="800" y="542.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-6" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-2" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-6" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-2" target="UY-EM7-1ECCvWtENr50b-1" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-20" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-1" target="28FAlPysTx9DMYvLwa-2-1" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-20" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-1" target="28FAlPysTx9DMYvLwa-2-1" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-2" value="&lt;&lt;Interface&gt;&gt;<br>IServiceManipulator" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-2" value="&lt;&lt;Interface&gt;&gt;<br>IServiceManipulator" style="whiteSpace=wrap;html=1;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="800" y="432.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="800" y="432.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-22" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-10" target="28FAlPysTx9DMYvLwa-2-5" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-22" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.25;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-10" target="28FAlPysTx9DMYvLwa-2-5" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-10" value="ServicesResult &lt;DS&gt;" style="whiteSpace=wrap;html=1;fillColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-10" value="ServicesResult &lt;DS&gt;" style="whiteSpace=wrap;html=1;fillColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="800" y="67.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="800" y="67.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-14" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-11" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-14" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#f0f0f0;dashed=1;" parent="jVG6p58vlRYGO9X4wXeX-1" source="UY-EM7-1ECCvWtENr50b-11" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-21" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-21" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;endArrow=open;endFill=0;strokeColor=#006EAF;fillColor=#1ba1e2;" parent="jVG6p58vlRYGO9X4wXeX-1" source="28FAlPysTx9DMYvLwa-2-1" target="UY-EM7-1ECCvWtENr50b-10" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-11" value="&lt;&lt;Interface&gt;&gt;<br>IServicesMonitor" style="whiteSpace=wrap;html=1;fillColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-11" value="&lt;&lt;Interface&gt;&gt;<br>IServicesMonitor" style="whiteSpace=wrap;html=1;fillColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="800" y="167.5" width="120" height="60" as="geometry"/>
|
<mxGeometry x="800" y="167.5" width="120" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-70" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-70" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="220" y="50" width="10" height="570" as="geometry"/>
|
<mxGeometry x="220" y="50" width="10" height="570" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-71" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-71" value="" style="line;strokeWidth=2;direction=south;html=1;fillColor=none;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="760" y="50" width="10" height="570" as="geometry"/>
|
<mxGeometry x="760" y="50" width="10" height="570" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="UY-EM7-1ECCvWtENr50b-73" value="Page 191 (Chapter 22) of Clean Architecture" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="UY-EM7-1ECCvWtENr50b-73" value="Page 191 (Chapter 22) of Clean Architecture" style="text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry y="870" width="480" height="20" as="geometry"/>
|
<mxGeometry y="870" width="480" height="20" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="tM_Gde3HH8YiZ2frBV5J-2" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="tM_Gde3HH8YiZ2frBV5J-0" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
|
<mxCell id="tM_Gde3HH8YiZ2frBV5J-2" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=block;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="tM_Gde3HH8YiZ2frBV5J-0" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="tM_Gde3HH8YiZ2frBV5J-4" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="tM_Gde3HH8YiZ2frBV5J-0" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
|
<mxCell id="tM_Gde3HH8YiZ2frBV5J-4" value="Use" style="edgeStyle=orthogonalEdgeStyle;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;dashed=1;endArrow=open;endFill=0;" parent="jVG6p58vlRYGO9X4wXeX-1" source="tM_Gde3HH8YiZ2frBV5J-0" target="tM_Gde3HH8YiZ2frBV5J-1" edge="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry relative="1" as="geometry"/>
|
<mxGeometry relative="1" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="tM_Gde3HH8YiZ2frBV5J-0" value="MainPresenter" style="html=1;dashed=0;whitespace=wrap;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="tM_Gde3HH8YiZ2frBV5J-0" value="MainPresenter" style="html=1;dashed=0;whitespace=wrap;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="420" y="122.5" width="110" height="60" as="geometry"/>
|
<mxGeometry x="420" y="122.5" width="110" height="60" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxCell id="tM_Gde3HH8YiZ2frBV5J-1" value="&lt;&lt;Interface&gt;&gt;<br>IConsoleOutput" style="html=1;dashed=0;whitespace=wrap;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
<mxCell id="tM_Gde3HH8YiZ2frBV5J-1" value="&lt;&lt;Interface&gt;&gt;<br>IConsoleOutput" style="html=1;dashed=0;whitespace=wrap;" parent="jVG6p58vlRYGO9X4wXeX-1" vertex="1">
|
||||||

 
 



|

 
 
 
 





|
||||||
<mxGeometry x="420" y="20" width="110" height="50" as="geometry"/>
|
<mxGeometry x="420" y="20" width="110" height="50" as="geometry"/>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxCell>
|
</mxCell>
|
||||||

 
 



|

 
 
 
 





|
||||||
</root>
|
</root>
|
||||||

 
 



|

 
 
 
 





|
||||||
</mxGraphModel>
|
</mxGraphModel>
|
||||||

 
 



|

 
 
 
 





|
||||||
</diagram>
|
</diagram>
|
||||||
</mxfile>
|
</mxfile>
|
@ -302,15 +302,14 @@ namespace GameServiceWarden.Core.Tests.Modules.Games
|
|||||||
{
|
{
|
||||||
using (StreamReader reader = new StreamReader(clientStreams[i]))
|
using (StreamReader reader = new StreamReader(clientStreams[i]))
|
||||||
{
|
{
|
||||||
CancellationTokenSource cancelToken = new CancellationTokenSource(15000);
|
|
||||||
string message = null;
|
string message = null;
|
||||||
Task task = Task.Run(() => message = reader.ReadLine(), cancelToken.Token);
|
Task clientTask = Task.Run(() => message = reader.ReadLine());
|
||||||
Assert.True(task.Wait(10000));
|
Assert.True(clientTask.Wait(1000));
|
||||||
Assert.True(COMMAND.Equals(message), $"Received message \"{message}\" when expecting \"{COMMAND}\"");
|
Assert.True(COMMAND.Equals(message), $"Received message \"{message}\" when expecting \"{COMMAND}\"");
|
||||||
cancelToken.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
serviceManager.StopService(FAKE_SERVICE_NAME);
|
Task task = Task.Run(() => serviceManager.StopService(FAKE_SERVICE_NAME));
|
||||||
|
Assert.True(task.Wait(5000)); //TODO FIX WHY THIS IS HAPPENING!!!!!
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
Reference in New Issue
Block a user