feat: expand cockpit integrations and support workflows
Add Phoenix remote desktop, action connector, documentation engine, and gamification support. Refactor support-case processing and search/action UI, and update installer assets and dependencies.
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
using C4IT.FASD.Cockpit.Communication;
|
||||
using F4SD.Gamification.Services;
|
||||
using FasdCockpitBase.Models.RemoteDesktopConnection;
|
||||
using FasdCockpitCommunication.RemoteDesktopCommunication;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static C4IT.Logging.cLogManager;
|
||||
|
||||
namespace FasdDesktopUi.Basics.Services.RemoteDesktop
|
||||
{
|
||||
internal static class AgentRemoteDesktopService
|
||||
{
|
||||
private static readonly Dictionary<Guid, Process> _viewerProcesses = new Dictionary<Guid, Process>();
|
||||
|
||||
internal static async Task<RemoteDesktopConnectionStatusResult> StartRemoteDesktopConnectionAsync(AgentRemoteClientInfo clientInfo, bool isElevated, CancellationToken token = default)
|
||||
{
|
||||
const int maxRetryCount = 20;
|
||||
TimeSpan baseDelay = TimeSpan.FromSeconds(0.5);
|
||||
|
||||
AgentRemoteDesktopConnecitonDetails connectionDetails = await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.InitiateConnection<AgentRemoteDesktopConnecitonDetails>(clientInfo, isElevated, token);
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Initiated);
|
||||
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Canceled);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Canceled);
|
||||
}
|
||||
|
||||
if (connectionDetails is null)
|
||||
{
|
||||
LogEntry("Could not initiate remote connection.", C4IT.Logging.LogLevels.Warning);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Unknown);
|
||||
}
|
||||
|
||||
if (connectionDetails.Errors != null && connectionDetails.Errors.Count > 0)
|
||||
{
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Error);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Error) { Errors = connectionDetails.Errors.Select(e => e.Message).ToArray() };
|
||||
}
|
||||
|
||||
RemoteDesktopConnectionStatusResult connectionStatus = null;
|
||||
|
||||
for (int i = 0; i < maxRetryCount; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
connectionStatus = await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.GetConnectionStatus(connectionDetails.ConnectionId, token);
|
||||
LogEntry($"Update {i} RemoteDesktop connection status: {connectionStatus}", C4IT.Logging.LogLevels.Debug);
|
||||
|
||||
if (token.IsCancellationRequested || IsRemoteConnectionEstablished(connectionStatus.Status))
|
||||
break;
|
||||
|
||||
await Task.Delay(TimeSpan.FromTicks(baseDelay.Ticks * i));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
if (token.IsCancellationRequested)
|
||||
{
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Canceled);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Canceled);
|
||||
}
|
||||
|
||||
RemoteConnetionStatusChanged?.Invoke(null, connectionStatus.Status);
|
||||
|
||||
if (connectionStatus.Status != RemoteDesktopConnectionStatus.Accepted)
|
||||
{
|
||||
LogEntry($"Could not connect to remote desktop. Status: {connectionStatus}", C4IT.Logging.LogLevels.Warning);
|
||||
return new RemoteDesktopConnectionStatusResult(connectionStatus.Status);
|
||||
}
|
||||
|
||||
StartViewer(connectionDetails);
|
||||
|
||||
GamificationService.TrackAction(F4SD.Gamification.CockpitAction.StartRemoteConnection);
|
||||
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Connected);
|
||||
}
|
||||
|
||||
private static bool IsRemoteConnectionEstablished(RemoteDesktopConnectionStatus status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case RemoteDesktopConnectionStatus.Accepted:
|
||||
case RemoteDesktopConnectionStatus.Connected:
|
||||
case RemoteDesktopConnectionStatus.Finished:
|
||||
case RemoteDesktopConnectionStatus.Canceled:
|
||||
return true;
|
||||
case RemoteDesktopConnectionStatus.Unknown:
|
||||
case RemoteDesktopConnectionStatus.Initiated:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void StartViewer(AgentRemoteDesktopConnecitonDetails connectionDetails)
|
||||
{
|
||||
try
|
||||
{
|
||||
ProcessStartInfo info = new ProcessStartInfo(GetViewerPath())
|
||||
{
|
||||
Arguments = $"-connectionId {connectionDetails.ConnectionId} -phoenixServiceUrl {connectionDetails.PhoenixServiceUrl} -secret {connectionDetails.Secret}"
|
||||
};
|
||||
|
||||
Process process = Process.Start(info);
|
||||
_viewerProcesses.Add(connectionDetails.ConnectionId, process);
|
||||
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Connected);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
internal static async Task StopRemoteDesktopConnection(Guid connectionId, CancellationToken token = default)
|
||||
{
|
||||
await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.StopConnection(connectionId, token);
|
||||
|
||||
if (_viewerProcesses.TryGetValue(connectionId, out var process))
|
||||
process.Close();
|
||||
}
|
||||
|
||||
internal static string GetViewerPath()
|
||||
{
|
||||
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Phoenix\Phoenix.Viewer.exe").ToString();
|
||||
}
|
||||
|
||||
internal static EventHandler<RemoteDesktopConnectionStatus> RemoteConnetionStatusChanged;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user