337 lines
18 KiB
C#
337 lines
18 KiB
C#
using C4IT.F4SD.DisplayFormatting;
|
|
using C4IT.FASD.Base;
|
|
using C4IT.FASD.Cockpit.Communication;
|
|
using C4IT.Logging;
|
|
using C4IT.MultiLanguage;
|
|
using FasdCockpitBase.Models;
|
|
using FasdDesktopUi.Basics.Models;
|
|
using FasdDesktopUi.Basics.Services.ProtocollService;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using static C4IT.Logging.cLogManager;
|
|
|
|
using static FasdDesktopUi.Basics.Models.cQuickActionStatusMonitorModel.cQuickActionStep;
|
|
using static FasdDesktopUi.Basics.UserControls.QuickActionStatusMonitor;
|
|
|
|
namespace FasdDesktopUi.Basics.UiActions
|
|
{
|
|
public class cUiRemoteQuickAction : cUiQuickAction
|
|
{
|
|
public cF4sdQuickActionRemote RemoteQuickAction { get; set; }
|
|
|
|
public cUiRemoteQuickAction(cF4sdQuickActionRemote quickAction) : base(quickAction)
|
|
{
|
|
RemoteQuickAction = quickAction;
|
|
}
|
|
|
|
public async override Task<cQuickActionStatusMonitorModel> GetQuickActionStatusMonitorDataAsync()
|
|
{
|
|
var scriptInfos = await cFasdCockpitCommunicationBase.Instance.GetQuickActionOfAgent(RemoteQuickAction.AgentScriptId);
|
|
|
|
var actionSteps = new List<cQuickActionStatusMonitorModel.cQuickActionStep>() { new cQuickActionStatusMonitorModel.cQuickActionStep(cMultiLanguageSupport.GetItem("QuickAction.Remote.Connect"), RemoteQuickAction.Name, enumActionStepType.connectingToClient) };
|
|
if (scriptInfos.UserPermissionRequired)
|
|
actionSteps.Add(new cQuickActionStatusMonitorModel.cQuickActionStep(cMultiLanguageSupport.GetItem("QuickAction.Remote.UserAcceptance"), RemoteQuickAction.Name, enumActionStepType.waitingForUserAcceptance));
|
|
|
|
actionSteps.Add(new cQuickActionStatusMonitorModel.cQuickActionStep(cMultiLanguageSupport.GetItem("QuickAction.Remote.Running"), RemoteQuickAction.Name, enumActionStepType.running));
|
|
|
|
return new cQuickActionStatusMonitorModel()
|
|
{
|
|
ActionName = RemoteQuickAction.Names.GetValue(),
|
|
QuickActionDefinition = RemoteQuickAction,
|
|
RequiresUserPermission = scriptInfos != null && scriptInfos.UserPermissionRequired,
|
|
ActionSteps = actionSteps,
|
|
QuickActionParameters = RemoteQuickAction.AdjustableParameters,
|
|
RunQuickAction = ProcessActionAsync
|
|
};
|
|
}
|
|
|
|
public override async Task<cDataCanvasDataModel> GetQuickActionDataAsync(cSupportCaseDataProvider dataProvider, bool isDetailedLayout)
|
|
{
|
|
DataProvider = dataProvider;
|
|
|
|
var detailedData = new cDetailedDataModel() { Heading = cMultiLanguageSupport.GetItem("DetailsPage.History") };
|
|
|
|
//Get QuickAciton Data
|
|
if (isDetailedLayout)
|
|
{
|
|
detailedData.FullDetailedData = new List<object>() { new List<object>() { "Status", cMultiLanguageSupport.GetItem("QuickAction.Revision.ExecutionTime") } };
|
|
var quickActionHistory = await dataProvider.QuickActionProtocollHelper.GetQuickActionHistoryAsync(RemoteQuickAction.Name);
|
|
foreach (var quickActionLine in quickActionHistory)
|
|
{
|
|
quickActionLine[1] = _rawValueFormatter.GetDisplayValue(quickActionLine[1], RawValueType.DATETIME);
|
|
detailedData.FullDetailedData.Add(quickActionLine);
|
|
}
|
|
}
|
|
else
|
|
detailedData.FullDetailedData = new List<object>();
|
|
|
|
//Get Process Steps of Action
|
|
var quickActionData = await GetQuickActionStatusMonitorDataAsync();
|
|
|
|
//Get Recommendation
|
|
cRecommendationDataModel recommendationData = QuickActionRecommendation?.Recommendation != null ? QuickActionRecommendation : null;
|
|
|
|
return new cDataCanvasDataModel() { DetailedData = detailedData, QuickActionStatusMonitorData = quickActionData, RecommendationData = recommendationData };
|
|
}
|
|
|
|
public override async Task<List<object>> ProcessActionAsync(CancellationToken token, Dictionary<cAdjustableParameter, object> ParameterDictionary = null)
|
|
{
|
|
try
|
|
{
|
|
int agentDeviceId = int.MinValue;
|
|
int? agentUserIdNullable = null;
|
|
var startTime = DateTime.UtcNow;
|
|
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("AgentDeviceId", out var agentDeviceIdParameter))
|
|
_ = int.TryParse(agentDeviceIdParameter.GetValue(), out agentDeviceId);
|
|
|
|
if (RemoteQuickAction.InformationClasses.Contains(enumFasdInformationClass.User))
|
|
if (DataProvider.NamedParameterEntries.TryGetValue("AgentUserId", out var agentUserIdParameter))
|
|
if (int.TryParse(agentUserIdParameter.GetValue(), out int agentUserId))
|
|
agentUserIdNullable = agentUserId;
|
|
|
|
//todo: task of DataProviderBase?
|
|
var QuickActionResult = new cF4sdQuickActionRevision();
|
|
if (cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode != null)
|
|
{
|
|
var parameters = cExternalToolExecutorEnh.ReplaceParameters(RemoteQuickAction.Parameters, DataProvider.NamedParameterEntries.ToInterfaceDictionary(), false, ParameterDictionary);
|
|
|
|
var scriptInformation = await cFasdCockpitCommunicationBase.Instance.RunAgentScript(RemoteQuickAction, cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode.Value, agentDeviceId, agentUserIdNullable, parameters);
|
|
await UpdateQuickActionStatusAsync(scriptInformation.TaskId, token);
|
|
QuickActionResult = await GetRevisionForStatusMonitorAsync(scriptInformation.RevisionId, scriptInformation.TaskId, token);
|
|
|
|
if (QuickActionResult != null && QuickActionResult.Status is enumQuickActionRevisionStatus.finishedWithError)
|
|
{
|
|
if (QuickActionResult.Output == null)
|
|
QuickActionResult.Output = new cF4sdQuickActionRevision.cOutput() { ErrorCode = 1, ErrorDescription = QuickActionResult.OutputText };
|
|
if (QuickActionResult.Output.ErrorCode == null && QuickActionResult.Output.ResultCode == 0 && QuickActionResult.Output.ErrorDescription == null && !string.IsNullOrEmpty(QuickActionResult.OutputText))
|
|
QuickActionResult.Output.ErrorDescription = QuickActionResult.OutputText;
|
|
}
|
|
}
|
|
|
|
if (QuickActionResult == null)
|
|
QuickActionResult = new cF4sdQuickActionRevision() { Status = enumQuickActionRevisionStatus.finishedWithError, OutputText = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.Canceled") };
|
|
|
|
if (QuickActionResult.Measures?.Count > 0)
|
|
{
|
|
var StatusMonitorMeasureValues = GetStatusMonitorMeasureValues(QuickActionResult.Measures, RemoteQuickAction.QuickActionMeasures);
|
|
|
|
if (StatusMonitorMeasureValues?.Count > 0)
|
|
StatusMonitor.MeasureValues = StatusMonitorMeasureValues;
|
|
}
|
|
|
|
var quickActionOutput = cQuickActionOutput.GetQuickActionOutput(QuickActionResult.Output, DataProvider);
|
|
var protocollOutput = cQuickActionOutput.GetQuickActionOutput(QuickActionResult.Output, DataProvider);
|
|
|
|
if (!token.IsCancellationRequested)
|
|
{
|
|
StatusMonitor.QuickActionOutputs.Add(QuickActionResult.Output);
|
|
var status = quickActionOutput?.IsError == true ? enumQuickActionRevisionStatus.finishedWithError : QuickActionResult.Status;
|
|
|
|
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, RemoteQuickAction.Name, enumActionStepType.running, status);
|
|
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, RemoteQuickAction.Name, enumActionStepType.main, status);
|
|
|
|
cQuickActionCopyData copyData = QuickActionProtocollEntry.GetCopyData(RemoteQuickAction, DataProvider, true, protocollOutput, StatusMonitor.MeasureValues);
|
|
F4SDProtocoll.Instance.Add(new QuickActionProtocollEntry(RemoteQuickAction, copyData));
|
|
|
|
}
|
|
else
|
|
{
|
|
cQuickActionStatusMonitorModel.cQuickActionStep.CancelRemainingQuickActionSteps(StatusMonitor.QuickActionData.ActionSteps);
|
|
|
|
quickActionOutput = new cQuickActionOutputSingle(new cF4sdQuickActionRevision.cOutput() { ResultCode = enumQuickActionSuccess.error, ErrorDescription = cMultiLanguageSupport.GetItem("QuickAction.Copy.Output.Cancel") });
|
|
|
|
if (cF4SDCockpitXmlConfig.Instance.HealthCardConfig.ProtocollLanguage != null)
|
|
{
|
|
string tempLang = cMultiLanguageSupport.CurrentLanguage;
|
|
cMultiLanguageSupport.CurrentLanguage = cF4SDCockpitXmlConfig.Instance.HealthCardConfig.ProtocollLanguage;
|
|
protocollOutput = new cQuickActionOutputSingle(new cF4sdQuickActionRevision.cOutput() { ResultCode = enumQuickActionSuccess.error, ErrorDescription = cMultiLanguageSupport.GetItem("QuickAction.Copy.Output.Cancel") });
|
|
cMultiLanguageSupport.CurrentLanguage = tempLang;
|
|
}
|
|
|
|
cQuickActionCopyData copyData = QuickActionProtocollEntry.GetCopyData(RemoteQuickAction, DataProvider, true, protocollOutput, StatusMonitor.MeasureValues);
|
|
F4SDProtocoll.Instance.Add(new QuickActionProtocollEntry(RemoteQuickAction, copyData));
|
|
return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.Canceled"), _rawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
|
|
}
|
|
|
|
string quickActionStatus;
|
|
switch (QuickActionResult.Status)
|
|
{
|
|
case enumQuickActionRevisionStatus.inProgress:
|
|
quickActionStatus = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.InProgress");
|
|
break;
|
|
case enumQuickActionRevisionStatus.finishedSuccessfull:
|
|
quickActionStatus = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedSuccessfull");
|
|
break;
|
|
case enumQuickActionRevisionStatus.finishedWithError:
|
|
quickActionStatus = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedWithError");
|
|
break;
|
|
case enumQuickActionRevisionStatus.unknown:
|
|
default:
|
|
quickActionStatus = cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.Unknown");
|
|
break;
|
|
}
|
|
|
|
_ = Task.Run(async () =>
|
|
{
|
|
try
|
|
{
|
|
Guid? userId = DataProvider?.Identities?.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.User)?.Id;
|
|
Guid? computerId = DataProvider?.Identities?.FirstOrDefault(identity => identity.Class == enumFasdInformationClass.Computer)?.Id;
|
|
|
|
var reportQuickActionParameter = new cF4SDQuickActionParameters()
|
|
{
|
|
CaseId = DataProvider.CaseId,
|
|
QuickActionId = RemoteQuickAction.Id,
|
|
QuickActionName = RemoteQuickAction.Name,
|
|
Paramaters = ParameterDictionary is null ? null : JsonConvert.SerializeObject(ParameterDictionary, Formatting.None),
|
|
Result = QuickActionResult.Output.Values is null ? null : JsonConvert.SerializeObject(QuickActionResult.Output.Values, Formatting.None),
|
|
ErrorCode = QuickActionResult.Output.ErrorCode,
|
|
ErrorDescription = QuickActionResult.Output.ErrorDescription,
|
|
Start = startTime,
|
|
Finish = DateTime.UtcNow,
|
|
UserId = userId,
|
|
DeviceId = computerId,
|
|
ExecutionType = RemoteQuickAction.ExecutionType,
|
|
ResultType = RemoteQuickAction.ResultType
|
|
};
|
|
|
|
var reportedQuickActionSuccessfully = await cFasdCockpitCommunicationBase.Instance.ReportQuickAction(reportQuickActionParameter);
|
|
|
|
if (reportedQuickActionSuccessfully is false)
|
|
LogEntry($"Failed to report QuickAction '{RemoteQuickAction.Name}' for case '{reportQuickActionParameter.CaseId}' to Analytics.", LogLevels.Warning);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
});
|
|
|
|
return new List<object>() { quickActionStatus, _rawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return new List<object>() { cMultiLanguageSupport.GetItem("QuickAction.Revision.Status.FinishedWithError"), _rawValueFormatter.GetDisplayValue(DateTime.UtcNow, RawValueType.DATETIME) };
|
|
}
|
|
|
|
}
|
|
|
|
public static List<cQuickActionMeasureValue> GetStatusMonitorMeasureValues(List<cF4sdQuickActionRevision.cMeasure> measures, Dictionary<int, cF4sdQuickActionMeasure> QuickActionMeasures)
|
|
{
|
|
try
|
|
{
|
|
var output = new List<cQuickActionMeasureValue>();
|
|
|
|
if (QuickActionMeasures == null || measures == null)
|
|
return null;
|
|
|
|
foreach (var measure in measures)
|
|
{
|
|
if (!QuickActionMeasures.TryGetValue(measure.Id, out var measureDefinition))
|
|
continue;
|
|
|
|
output.Add(new cQuickActionMeasureValue()
|
|
{
|
|
Id = measure.Id,
|
|
Names = measureDefinition.Names,
|
|
Display = cUtility.GetRawValueType(measureDefinition.Display),
|
|
Value = measure.Value,
|
|
PostValue = measure.PostValue
|
|
});
|
|
}
|
|
|
|
return output;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task UpdateQuickActionStatusAsync(int taskId, CancellationToken token)
|
|
{
|
|
try
|
|
{
|
|
const int pollDelayInMilliseconds = 250;
|
|
|
|
while (!token.IsCancellationRequested)
|
|
{
|
|
var quickActionStatus = await cFasdCockpitCommunicationBase.Instance.GetAgentQuickActionStatus(taskId);
|
|
|
|
if (quickActionStatus == enumQuickActionStatus.Unknown)
|
|
break;
|
|
|
|
List<enumActionStepType> actionStepsToUpdate = new List<enumActionStepType>();
|
|
|
|
switch (quickActionStatus)
|
|
{
|
|
case enumQuickActionStatus.ConnectingToClient:
|
|
break;
|
|
case enumQuickActionStatus.WaitingForUserAcceptance:
|
|
actionStepsToUpdate = new List<enumActionStepType>() { enumActionStepType.connectingToClient };
|
|
break;
|
|
case enumQuickActionStatus.Running:
|
|
case enumQuickActionStatus.Finished:
|
|
actionStepsToUpdate = new List<enumActionStepType>() { enumActionStepType.connectingToClient, enumActionStepType.waitingForUserAcceptance };
|
|
break;
|
|
case enumQuickActionStatus.Cancelled:
|
|
var remainingSteps = StatusMonitor.QuickActionData.ActionSteps.Where(step => step.Status != enumQuickActionRevisionStatus.finishedSuccessfull);
|
|
|
|
foreach (var remainingStep in remainingSteps)
|
|
{
|
|
remainingStep.Status = enumQuickActionRevisionStatus.canceled;
|
|
}
|
|
break;
|
|
}
|
|
|
|
foreach (var actionStepToUpdate in actionStepsToUpdate)
|
|
{
|
|
cQuickActionStatusMonitorModel.cQuickActionStep.SetQuickActionStepStatuses(StatusMonitor.QuickActionData.ActionSteps, RemoteQuickAction.Name, actionStepToUpdate, enumQuickActionRevisionStatus.finishedSuccessfull);
|
|
}
|
|
|
|
if (quickActionStatus == enumQuickActionStatus.Finished || quickActionStatus == enumQuickActionStatus.Cancelled)
|
|
break;
|
|
|
|
await Task.Delay(pollDelayInMilliseconds);
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private async Task<cF4sdQuickActionRevision> GetRevisionForStatusMonitorAsync(int revisionId, int taskId, CancellationToken token)
|
|
{
|
|
try
|
|
{
|
|
if (!token.IsCancellationRequested)
|
|
{
|
|
var revision = await cFasdCockpitCommunicationBase.Instance.GetAgentRevision(revisionId, cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode.Value);
|
|
return revision;
|
|
}
|
|
else
|
|
await cFasdCockpitCommunicationBase.Instance.CancelAgentTask(taskId);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|