2014 lines
72 KiB
C#
2014 lines
72 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using System.Diagnostics;
|
|
|
|
using C4IT.FASD.Base;
|
|
using C4IT.HTTP;
|
|
using C4IT.Logging;
|
|
using C4IT.MultiLanguage;
|
|
using C4IT.Security;
|
|
using C4IT.FASD.Communication.Agent;
|
|
|
|
using FasdCockpitBase.Models;
|
|
using FasdCockpitCommunication;
|
|
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
using static C4IT.Logging.cLogManager;
|
|
using C4IT.Configuration;
|
|
|
|
namespace C4IT.FASD.Cockpit.Communication
|
|
{
|
|
public class cFasdCockpitCommunicationWeb : cFasdCockpitCommunicationBase
|
|
{
|
|
private cAgentApiHelper agentApiHelper;
|
|
|
|
private string ApiTimingLog = null;
|
|
|
|
public cFasdCockpitCommunicationWeb()
|
|
{
|
|
M42 = new cF4sdCockpitCommunicationM42Web();
|
|
}
|
|
|
|
public override bool IsDemo() => false;
|
|
|
|
public override bool CheckConnectionInfo()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var serverUrl = cFasdCockpitMachineConfiguration.Instance.ServerUrl;
|
|
var url = new Uri(serverUrl);
|
|
return url.IsAbsoluteUri;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public async override Task<cCheckConnectionResult> CheckConnection(Version minServerVersion)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var output = new cCheckConnectionResult() { ConnectionStatus = enumConnectionStatus.unknown };
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var result = await http.GetHttpJson($"api/CheckConnection", 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
output.ConnectionStatus = enumConnectionStatus.serverResponseError;
|
|
return output;
|
|
}
|
|
|
|
SaveApiResultValueJson("CheckConnection", result.Result);
|
|
var connectionResult = JsonConvert.DeserializeObject<cFasdApiConnectionInfo>(result.Result);
|
|
output.ApiConnectionInfo = connectionResult;
|
|
var assembly = Assembly.GetExecutingAssembly();
|
|
var ClientVersion = assembly.GetName().Version;
|
|
|
|
if (!Version.TryParse(connectionResult.MinCockpitVersion, out var minClientVersion))
|
|
{
|
|
LogEntry($"Minimum cockpit version is illegal: {connectionResult.MinCockpitVersion}");
|
|
return output;
|
|
}
|
|
|
|
if (!Version.TryParse(connectionResult.ServerVersion, out var serverVersion))
|
|
{
|
|
LogEntry($"Server version is illegal: {connectionResult.ServerVersion}");
|
|
return output;
|
|
}
|
|
|
|
if (ClientVersion < minClientVersion)
|
|
{
|
|
LogEntry($"Cockpit version ({ClientVersion}) is less than required ({minClientVersion}).");
|
|
output.ConnectionStatus = enumConnectionStatus.incompatibleServerVersion;
|
|
return output;
|
|
}
|
|
|
|
if (serverVersion < minServerVersion)
|
|
{
|
|
LogEntry($"Server version ({serverVersion}) is less than required ({minServerVersion}).");
|
|
output.ConnectionStatus = enumConnectionStatus.incompatibleServerVersion;
|
|
return output;
|
|
}
|
|
|
|
switch (connectionResult.WebServerStatus)
|
|
{
|
|
case enumWebServerStatus.starting:
|
|
output.ConnectionStatus = enumConnectionStatus.serverStarting;
|
|
return output;
|
|
case enumWebServerStatus.notConfigured:
|
|
output.ConnectionStatus = enumConnectionStatus.serverNotConfigured;
|
|
return output;
|
|
}
|
|
|
|
output.ConnectionStatus = enumConnectionStatus.connected;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public static cOneTimePW GetOneTimePw() => new cOneTimePW("OneTimePw", cSecurePassword.Instance);
|
|
|
|
public cHttpHelper GetHttpHelper(bool useToken)
|
|
{
|
|
try
|
|
{
|
|
string Token;
|
|
lock (CockpitUserInfoLock)
|
|
{
|
|
Token = CockpitUserInfo?.Token;
|
|
}
|
|
if (useToken && Token != null)
|
|
return new cHttpHelper(cFasdCockpitMachineConfiguration.Instance.ServerUrl, null, false) { BearerToken = Token };
|
|
|
|
return new cHttpHelper(cFasdCockpitMachineConfiguration.Instance.ServerUrl, GetOneTimePw().GetCredential(), false);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<Guid> GetUserIdByAccount(string userName, string userDomain)
|
|
{
|
|
var output = Guid.Empty;
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var result = await http.GetHttpJson($"api/Logon/GetUserIdByAccount?Account={userName}&Domain={userDomain}", 15000, CancellationToken.None);
|
|
|
|
if (result.IsOk)
|
|
{
|
|
SaveApiResultValue("Logon-GetUserIdByAccount", result.Result, "json");
|
|
output = JsonConvert.DeserializeObject<Guid>(result.Result);
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
public async override Task<cF4sdUserInfo> WinLogon()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = new cHttpHelper(cFasdCockpitMachineConfiguration.Instance.ServerUrl, null, false, UseCookies: true, UseDefaultCredentials: true);
|
|
var _url = "api/Logon/Logon";
|
|
if (!string.IsNullOrEmpty(cMultiLanguageSupport.CurrentLanguage))
|
|
_url = $"api/Logon/Logon?lang={cMultiLanguageSupport.CurrentLanguage}";
|
|
var result = await http.GetHttpJson(_url, 20000, CancellationToken.None);
|
|
|
|
if (result.IsOk)
|
|
{
|
|
if (Debug_apiValues) SaveApiResultValueJson("Logon-Logon", result.Result);
|
|
var _retVal = JsonConvert.DeserializeObject<cF4sdUserInfo>(result.Result);
|
|
return _retVal;
|
|
}
|
|
else
|
|
apiError = (int)result.Status;
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("Logon-Logon", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<cF4SdUserInfoChange> RegisterExternalTokenAsync(cF4SDTokenRegistration Token)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _payLoad = JsonConvert.SerializeObject(Token);
|
|
var http = GetHttpHelper(true);
|
|
var apiAccessInfo = await http.PostJsonAsync($"api/Logon/RegisterExternalToken", _payLoad, 14000, System.Threading.CancellationToken.None);
|
|
if (apiAccessInfo.IsOk)
|
|
{
|
|
var _str = apiAccessInfo.Result;
|
|
if (Debug_apiValues) SaveApiResultValueJson("Logon-RegisterExternalToken", _str);
|
|
var RetVal = JsonConvert.DeserializeObject<cF4SdUserInfoChange>(_str);
|
|
return RetVal;
|
|
}
|
|
else
|
|
apiError = (int)apiAccessInfo.Status;
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("Logon-RegisterExternalToken", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<cF4SDAdditionalUserInfo> GetAdditionalUserInfo(enumAdditionalAuthentication Type)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(true);
|
|
var result = await http.GetHttpJson($"api/Logon/GetAdditionalUserInfo?AccountType={Type}", 5000, CancellationToken.None);
|
|
if (result.IsOk)
|
|
{
|
|
var _retVal = JsonConvert.DeserializeObject<cF4SDAdditionalUserInfo>(result.Result);
|
|
return _retVal;
|
|
}
|
|
else
|
|
apiError = (int)result.Status;
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("Logon-GetAdditionalUserInfo", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<bool> IsAnalyticsModuleActive()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
bool output = false;
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var result = await http.GetHttpJson("api/F4SDAnalytics/GetF4SDAnalyticsState", 2000, CancellationToken.None);
|
|
|
|
if (result.IsOk)
|
|
{
|
|
if (Debug_apiValues) SaveApiResultValueJson("F4SDAnalytics-GetF4SDAnalyticsState", result.Result);
|
|
output = JsonConvert.DeserializeObject<bool>(result.Result);
|
|
}
|
|
else
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
}
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("F4SDAnalytics-GetF4SDAnalyticsState", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public override async Task<bool> CreateUserSession(cF4SDUserSessionParameters sessionParams)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var payload = JsonConvert.SerializeObject(sessionParams);
|
|
|
|
var result = await http.PostJsonAsync("api/F4SDAnalytics/CreateUserSession", payload, 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
}
|
|
|
|
return result.IsOk;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("F4SDAnalytics-CreateUserSession", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task CloseUserSession(Guid sessionId)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var parameter = new cF4SDUserSessionParameters() { SessionId = sessionId, SessionDate = DateTime.UtcNow };
|
|
var payload = JsonConvert.SerializeObject(parameter);
|
|
|
|
var result = await http.PostJsonAsync("api/F4SDAnalytics/CloseUserSession", payload, 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("F4SDAnalytics-CloseUserSession", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
public override async Task<bool> StartCase(cF4SDCaseParameters caseParameters)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var payload = JsonConvert.SerializeObject(caseParameters);
|
|
var result = await http.PostJsonAsync("api/F4SDAnalytics/CreateCase", payload, 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
}
|
|
|
|
return result.IsOk;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("F4SDAnalytics-CreateCase", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task<bool> UpdateCase(cF4SDCaseStatusParameters caseStatusParameters, List<cF4SDCaseTime> caseTimes)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
cF4SDCaseTimeParameters param = new cF4SDCaseTimeParameters
|
|
{
|
|
CaseId = caseStatusParameters.CaseId,
|
|
ActiveTime = caseStatusParameters.ActiveTime,
|
|
StatusId = caseStatusParameters?.StatusId,
|
|
CaseTimes = caseTimes
|
|
};
|
|
|
|
var http = GetHttpHelper(false);
|
|
var payload = JsonConvert.SerializeObject(param);
|
|
|
|
var result = await http.PostJsonAsync("api/F4SDAnalytics/UpdateCaseState", payload, 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
}
|
|
|
|
return result.IsOk;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("F4SDAnalytics-UpdateCaseState", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task<bool> ReportQuickAction(cF4SDQuickActionParameters quickActionParameters)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var payload = JsonConvert.SerializeObject(quickActionParameters);
|
|
var result = await http.PostJsonAsync("api/F4SDAnalytics/ReportQuickActionExecution", payload, 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
}
|
|
|
|
return result.IsOk;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("F4SDAnalytics-ReportQuickActionExecution", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task<bool> KeepAliveCase(Guid caseId)
|
|
{
|
|
try
|
|
{
|
|
Debug.WriteLine($"#############!!!!!!!!!!!!! KeepAliveCase: {caseId}");
|
|
|
|
var http = GetHttpHelper(false);
|
|
var payload = JsonConvert.SerializeObject(caseId);
|
|
var result = await http.PostJsonAsync("api/F4SDAnalytics/KeepAliveCase", payload, 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
await CheckConnectionStatus?.Invoke();
|
|
|
|
return result.IsOk;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task<bool> KeepAliveSession(Guid sessionId)
|
|
{
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var payload = JsonConvert.SerializeObject(sessionId);
|
|
var result = await http.PostJsonAsync("api/F4SDAnalytics/KeepAliveSession", payload, 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
await CheckConnectionStatus?.Invoke();
|
|
|
|
return result.IsOk;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
public override async Task<cFasdBaseConfig> GetConfiguration(enumFasdConfigurationType configType)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var http = GetHttpHelper(true);
|
|
var url = $"api/GetConfiguration?configType={configType}";
|
|
var result = await http.GetHttpJson(url, 20000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
var strXml = JsonConvert.DeserializeObject<string>(result.Result);
|
|
if (Debug_apiValues) SaveApiResultValue("GetConfiguration-" + configType.ToString(), strXml, "xml");
|
|
var output = cFasdBaseConfig.GetConfigByType(configType, strXml);
|
|
return output;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetConfiguration-" + configType.ToString(), timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<Guid?> GetSearchResultsStart(string searchValue, CancellationToken cancellationToken)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var url = $"api/SearchDetailedStart?search={searchValue}";
|
|
|
|
var result = await http.GetHttpJson(url, 20000, cancellationToken, true);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
if (!cancellationToken.IsCancellationRequested)
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("SearchDetailedStart", result.Result, url);
|
|
var deserializedObject = JsonConvert.DeserializeObject<Guid?>(result.Result);
|
|
return deserializedObject;
|
|
}
|
|
catch (TaskCanceledException E) when (cancellationToken.IsCancellationRequested)
|
|
{
|
|
apiError = E.HResult;
|
|
LogEntry("GetSearchResultsStart was cancelled by token.", LogLevels.Debug);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("SearchDetailedStart", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override async Task<cFasdApiSearchResultCollection> GetSearchResultsResult(Guid taskID, CancellationToken cancellationToken)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var url = $"api/SearchDetailedResult?taskID={taskID}";
|
|
|
|
var result = await http.GetHttpJson(url, 20000, cancellationToken, true);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
if (!cancellationToken.IsCancellationRequested)
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("SearchDetailedResult", result.Result, url);
|
|
var deserializedObject = JsonConvert.DeserializeObject<cFasdApiSearchResultCollection>(result.Result);
|
|
return deserializedObject;
|
|
}
|
|
catch (TaskCanceledException E) when (cancellationToken.IsCancellationRequested)
|
|
{
|
|
apiError = E.HResult;
|
|
LogEntry("GetSearchResultsStart was cancelled by token.", LogLevels.Debug);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("SearchDetailedResult", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override async Task GetSearchResultsStop(Guid taskID, CancellationToken cancellationToken)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var url = $"api/SearchDetailedStop?taskID={taskID}";
|
|
|
|
var result = await http.GetHttpJson(url, 20000, cancellationToken);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
if (!cancellationToken.IsCancellationRequested)
|
|
await CheckConnectionStatus?.Invoke();
|
|
return;
|
|
}
|
|
}
|
|
catch (TaskCanceledException E) when (cancellationToken.IsCancellationRequested)
|
|
{
|
|
apiError = E.HResult;
|
|
LogEntry("GetSearchResultsStart was cancelled by token.", LogLevels.Debug);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("SearchDetailedResult", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
|
|
public override async Task<cFasdApiSearchResultCollection> GetPhoneSearchResults(cPhoneSearchParameters searchInfo)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var output = new cFasdApiSearchResultCollection();
|
|
|
|
if (searchInfo == null || searchInfo.phone == null)
|
|
return output;
|
|
|
|
var name = searchInfo.name ?? "";
|
|
name = HttpUtility.UrlEncode(name);
|
|
var phone = HttpUtility.UrlEncode(searchInfo.phone);
|
|
|
|
var http = GetHttpHelper(false);
|
|
|
|
var strUrl = $"api/SearchPhone?searchPhone={phone}&searchName={name}";
|
|
var result = await http.GetHttpJson(strUrl, 10000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("SearchPhone", result.Result, strUrl);
|
|
var deserializedObject = JsonConvert.DeserializeObject<cFasdApiSearchResultCollection>(result.Result);
|
|
output = deserializedObject;
|
|
return output;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("SearchPhone", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
public override async Task<cFasdApiSearchResultCollection> GetComputerSearchResults(string Name, string Domain)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _Name = HttpUtility.UrlEncode(Name);
|
|
var _Domain = "";
|
|
if (string.IsNullOrWhiteSpace(Domain))
|
|
_Domain = HttpUtility.UrlEncode(Domain);
|
|
|
|
var strUrl = $"api/SearchComputerByName?Name={_Name}&Domain={_Domain}";
|
|
|
|
var http = GetHttpHelper(true);
|
|
var result = await http.GetHttpJson(strUrl, 10000, System.Threading.CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("SearchComputerByName", result.Result, strUrl);
|
|
var deserializedObject = JsonConvert.DeserializeObject<cFasdApiSearchResultCollection>(result.Result);
|
|
|
|
return deserializedObject;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("SearchComputerByName", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<cFasdApiSearchResultCollection> GetUserSearchResults(string Name, List<string> SIDs)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _Name = HttpUtility.UrlEncode(Name);
|
|
|
|
var strSids = "";
|
|
foreach (var _sid in SIDs)
|
|
{
|
|
if (strSids != "")
|
|
strSids += ",";
|
|
strSids += _sid;
|
|
}
|
|
|
|
strSids = HttpUtility.UrlEncode(strSids);
|
|
|
|
var strUrl = $"api/SearchUserByNameAndSids?Name={_Name}&SIDs={strSids}";
|
|
|
|
var http = GetHttpHelper(true);
|
|
var result = await http.GetHttpJson(strUrl, 10000, System.Threading.CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("SearchUserByNameAndSids", result.Result, strUrl);
|
|
var deserializedObject = JsonConvert.DeserializeObject<cFasdApiSearchResultCollection>(result.Result);
|
|
|
|
return deserializedObject;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("SearchUserByNameAndSids", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
private void EnrichInfosOfRelationBySearchResult(List<cF4sdApiSearchResultRelation> relations, List<cFasdApiSearchResultEntry> searchResults)
|
|
{
|
|
try
|
|
{
|
|
if (relations is null || searchResults is null)
|
|
return;
|
|
|
|
foreach (var relation in relations)
|
|
{
|
|
var matchingSearchResult = searchResults
|
|
.FirstOrDefault(searchResult => relation.Identities.Any(identity => identity.Id.Equals(searchResult.id)));
|
|
|
|
if (matchingSearchResult?.Infos is null)
|
|
continue;
|
|
|
|
if (relation.Infos is null)
|
|
relation.Infos = new Dictionary<string, string>();
|
|
|
|
foreach (var info in matchingSearchResult.Infos)
|
|
{
|
|
relation.Infos["relation_" + info.Key] = info.Value;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
public override async Task<cF4sdStagedSearchResultRelationTaskId> StartGatheringRelations(IEnumerable<cFasdApiSearchResultEntry> relatedTo, CancellationToken token)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
string url = $"api/StagedSearchRelations?age={cF4SDCockpitXmlConfig.Instance.HealthCardConfig.SearchResultAge}";
|
|
string json = JsonConvert.SerializeObject(relatedTo);
|
|
var http = GetHttpHelper(true);
|
|
var result = await http.PostJsonAsync(url, json, 5_000, token);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
return JsonConvert.DeserializeObject<cF4sdStagedSearchResultRelationTaskId>(result.Result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
apiError = ex.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(ex);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("StagedSearchRelationsStart", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override async Task<cF4sdStagedSearchResultRelations> GetStagedRelations(Guid id, CancellationToken token)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
string url = $"api/StagedSearchRelations/{id}";
|
|
var http = GetHttpHelper(true);
|
|
var result = await http.GetHttpJson(url, 25_000, token, true);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
return JsonConvert.DeserializeObject<cF4sdStagedSearchResultRelations>(result.Result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
apiError = ex.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(ex);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("StagedSearchRelationsStart", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private async Task<cF4sdStagedSearchResultRelations> GetRelationResults(Guid relationTaskId, CancellationToken token)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
string url = $"api/StagedSearchRelations/{relationTaskId}";
|
|
var http = GetHttpHelper(true);
|
|
var result = await http.GetHttpJson(url, 5_000, token, true);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
return null;
|
|
}
|
|
|
|
return JsonConvert.DeserializeObject<cF4sdStagedSearchResultRelations>(result.Result);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
apiError = ex.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(ex);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("StagedSearchRelations", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override async Task<List<cF4sdApiSearchResultRelation>> GetSearchResultRelations(enumF4sdSearchResultClass resultType, List<cFasdApiSearchResultEntry> searchResults)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
var output = new List<cF4sdApiSearchResultRelation>();
|
|
|
|
try
|
|
{
|
|
var resultIds = searchResults.Select(resultData => resultData.id).ToList();
|
|
|
|
if (resultIds?.Count <= 0)
|
|
{
|
|
LogEntry("No valid resultIds where passed.", LogLevels.Error);
|
|
return output;
|
|
}
|
|
|
|
cF4sdStagedSearchResultRelationTaskId relationTaskId = await StartGatheringRelations(searchResults, CancellationToken.None).ConfigureAwait(false);
|
|
|
|
if (relationTaskId is null || relationTaskId?.Id == Guid.Empty)
|
|
{
|
|
LogEntry("Could not start gathering relations.", LogLevels.Warning);
|
|
return output;
|
|
}
|
|
|
|
const int maxRetryCount = 30;
|
|
TimeSpan getRelationsDelay = TimeSpan.FromMilliseconds(500);
|
|
for (int i = 0; i < maxRetryCount; i++)
|
|
{
|
|
var relations = await GetRelationResults(relationTaskId.Id, CancellationToken.None).ConfigureAwait(false);
|
|
output.AddRange(relations?.Relations);
|
|
|
|
if (relations.IsComplete)
|
|
break;
|
|
|
|
await Task.Delay(getRelationsDelay);
|
|
}
|
|
|
|
EnrichInfosOfRelationBySearchResult(output, searchResults);
|
|
|
|
output = output.OrderByDescending(relation => relation.LastUsed)
|
|
.ToList();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetUsageDetailed", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
public override Task<List<cF4sdApiSearchResultRelation>> GetTicketOverviewRelations(string key, bool useRoleScope, int count)
|
|
{
|
|
return Task.FromResult(new List<cF4sdApiSearchResultRelation>());
|
|
}
|
|
public override async Task<cF4SDHealthCardRawData> GetHealthCardData(cF4sdHealthCardRawDataRequest requestData)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var jsonData = JsonConvert.SerializeObject(requestData);
|
|
var urlData = HttpUtility.UrlEncode(jsonData);
|
|
|
|
var http = GetHttpHelper(true);
|
|
var url = $"api/GetRawDataStart?jsonRequest={urlData}";
|
|
var result = await http.GetHttpJson(url, 20000, System.Threading.CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogEntry($"Error on requesting healthcard data: {result.ReasonPhrase}", LogLevels.Error);
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("GetRawDataStart", result.Result, url);
|
|
var output = JsonConvert.DeserializeObject<cF4SDHealthCardRawData>(result.Result);
|
|
return output;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetRawDataStart", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<cF4SDHealthCardRawData> GetHealthCardData(Guid healthCardId)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var urlData = HttpUtility.UrlEncode(healthCardId.ToString());
|
|
|
|
var http = GetHttpHelper(true);
|
|
var url = $"api/GetRawDataNext?RequestId={urlData}";
|
|
var result = await http.GetHttpJson(url, 20000, System.Threading.CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogEntry($"Error on requesting healthcard data: {result.ReasonPhrase}", LogLevels.Error);
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("GetRawDataNext", result.Result, url);
|
|
var output = JsonConvert.DeserializeObject<cF4SDHealthCardRawData>(result.Result);
|
|
|
|
return output;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetRawDataNext", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetDetailsData(cF4sdHealthCardRawDataRequest requestData)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var jsonData = JsonConvert.SerializeObject(requestData);
|
|
var urlData = HttpUtility.UrlEncode(jsonData);
|
|
|
|
var http = GetHttpHelper(true);
|
|
var url = $"api/GetDetailsData?jsonRequest={urlData}";
|
|
var result = await http.GetHttpJson(url, 20000, System.Threading.CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogEntry($"Error on requesting details data: {result.ReasonPhrase}", LogLevels.Error);
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("GetDetailsData", result.Result, url);
|
|
var output = JsonConvert.DeserializeObject<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(result.Result);
|
|
|
|
return output;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetDetailsData", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<int> GetPagedDataCount(cF4sdHealthSelectionDataRequest requestData)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var jsonData = JsonConvert.SerializeObject(requestData);
|
|
var urlData = HttpUtility.UrlEncode(jsonData);
|
|
|
|
var http = GetHttpHelper(true);
|
|
var url = $"api/GetSelectionCount?jsonRequest={urlData}";
|
|
var result = await http.GetHttpJson(url, 20000, System.Threading.CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogEntry($"Error on requesting paged data count: {result.ReasonPhrase}", LogLevels.Error);
|
|
return -1;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("GetSelectionCount", result.Result, url);
|
|
var output = JsonConvert.DeserializeObject<int>(result.Result);
|
|
|
|
return output;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetSelectionCount", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
public override async Task<cF4SDHealthCardRawData.cHealthCardTable> GetPagedData(cF4sdHealthSelectionDataRequest requestData)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var jsonData = JsonConvert.SerializeObject(requestData);
|
|
var urlData = HttpUtility.UrlEncode(jsonData);
|
|
|
|
var http = GetHttpHelper(true);
|
|
var url = $"api/GetSelectionData?jsonRequest={urlData}";
|
|
var result = await http.GetHttpJson(url, 20000, System.Threading.CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogEntry($"Error on requesting paged data: {result.ReasonPhrase}", LogLevels.Error);
|
|
return null;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("GetSelectionData", result.Result, url);
|
|
var output = JsonConvert.DeserializeObject<cF4SDHealthCardRawData.cHealthCardTable>(result.Result);
|
|
|
|
return output;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetSelectionData", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<bool> UpdateHealthcardTableData(cF4SDWriteParameters dataParameter)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
bool output = false;
|
|
try
|
|
{
|
|
var http = GetHttpHelper(true);
|
|
var url = $"api/WriteProperty";
|
|
var payload = JsonConvert.SerializeObject(dataParameter);
|
|
|
|
var result = await http.PostJsonAsync(url, payload, 20000, CancellationToken.None);
|
|
|
|
if (result.IsOk)
|
|
return true;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
public override async Task<bool> Matrix42TicketFinalization(cApiM42Ticket ticketData)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
bool output = false;
|
|
try
|
|
{
|
|
var http = GetHttpHelper(true);
|
|
var url = $"api/Matrix42/TicketFinalization";
|
|
var payload = JsonConvert.SerializeObject(ticketData);
|
|
|
|
var result = await http.PostJsonAsync(url, payload, 20000, CancellationToken.None);
|
|
|
|
if (result.IsOk)
|
|
return true;
|
|
else
|
|
apiError = (int)result.Status;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("Matrix42-TicketFinalization", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public override async Task<bool> GetAgentApiAccessInfo()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var apiAccessInfo = await http.GetHttpJson($"api/GetAgentApiConfiguration", 10000, System.Threading.CancellationToken.None);
|
|
|
|
if (!apiAccessInfo.IsOk)
|
|
{
|
|
apiError = (int)apiAccessInfo.Status;
|
|
return false;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("GetAgentApiConfiguration", apiAccessInfo.Result);
|
|
var apiConfiguration = JsonConvert.DeserializeObject<cAgentApiConfiguration>(apiAccessInfo.Result);
|
|
if (apiConfiguration != null)
|
|
apiConfiguration.ClientSecret = cSecurePassword.Instance.Decode(apiConfiguration.ClientSecret);
|
|
|
|
var cockpitConfiguration = new cCockpitConfiguration() { agentApiConfiguration = apiConfiguration };
|
|
cCockpitConfiguration.Instance = cockpitConfiguration;
|
|
|
|
agentApiHelper = new cAgentApiHelper();
|
|
await agentApiHelper.LogonAsync(apiConfiguration);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetAgentApiConfiguration", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task<bool> GetCockpitConfiguration()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(true);
|
|
var cockpitconfigResult = await http.GetHttpJson($"api/GetCockpitConfiguration", 10000, System.Threading.CancellationToken.None);
|
|
|
|
if (!cockpitconfigResult.IsOk)
|
|
{
|
|
apiError = (int)cockpitconfigResult.Status;
|
|
return false;
|
|
}
|
|
|
|
if (Debug_apiValues) SaveApiResultValueJson("GetCockpitConfiguration", cockpitconfigResult.Result);
|
|
var Configuration = JsonConvert.DeserializeObject<cCockpitConfiguration>(cockpitconfigResult.Result);
|
|
if (Configuration?.agentApiConfiguration?.ClientSecret != null)
|
|
Configuration.agentApiConfiguration.ClientSecret = cSecurePassword.Instance.Decode(Configuration.agentApiConfiguration.ClientSecret);
|
|
|
|
cCockpitConfiguration.Instance = Configuration;
|
|
|
|
agentApiHelper = new cAgentApiHelper();
|
|
await agentApiHelper.LogonAsync(Configuration.agentApiConfiguration);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetCockpitConfiguration", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task<List<string>> GetQuickActionsOfServer()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var apiError = 0;
|
|
var timeStart = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var http = GetHttpHelper(false);
|
|
var result = await http.GetHttpJson("api/QuickAction/GetQuickActionList", 15000, CancellationToken.None);
|
|
|
|
if (!result.IsOk)
|
|
{
|
|
apiError = (int)result.Status;
|
|
if (CheckConnectionStatus != null)
|
|
{
|
|
await CheckConnectionStatus.Invoke();
|
|
}
|
|
return new List<string>();
|
|
}
|
|
if (result.Result is string jsonString && !string.IsNullOrWhiteSpace(jsonString))
|
|
{
|
|
return JsonConvert.DeserializeObject<List<string>>(result.Result);
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
apiError = E.HResult;
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (Debug_apiTiming) SaveApiTimingEntry("GetQuickActionList", timeStart, apiError);
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task<bool> GetAgentOnlineStatus(int AgentDeviceId, int? AgentUserId = null)
|
|
{
|
|
try
|
|
{
|
|
if (cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode == null)
|
|
return false;
|
|
|
|
var onlineStatus = await agentApiHelper.GetOnlineStatusAsync(cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode.Value, AgentDeviceId, AgentUserId);
|
|
|
|
if (onlineStatus != null)
|
|
return onlineStatus.IsOnline;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
public override async Task<cF4sdAgentScript> GetQuickActionOfAgent(int ScriptId)
|
|
{
|
|
var output = new cF4sdAgentScript();
|
|
|
|
try
|
|
{
|
|
var apiResult = await agentApiHelper.GetScript(ScriptId);
|
|
if (apiResult == null)
|
|
{
|
|
await CheckConnectionStatus?.Invoke();
|
|
return output;
|
|
}
|
|
|
|
output.Type = (enumAgentScriptType)(int)apiResult.Type;
|
|
output.UserPermissionRequired = apiResult.PersmissionLevel == 2 || apiResult.PersmissionLevel == 4;
|
|
output.Id = apiResult.Id;
|
|
output.Name = apiResult.Name;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public override async Task<List<cF4sdAgentScript>> GetQuickActionsOfAgent()
|
|
{
|
|
var output = new List<cF4sdAgentScript>();
|
|
|
|
try
|
|
{
|
|
var apiResult = await agentApiHelper.GetScripts();
|
|
if (apiResult == null)
|
|
{
|
|
await CheckConnectionStatus?.Invoke();
|
|
return output;
|
|
}
|
|
|
|
foreach (var script in apiResult)
|
|
{
|
|
var newAgentScript = new cF4sdAgentScript
|
|
{
|
|
Type = (enumAgentScriptType)(int)script.Type,
|
|
UserPermissionRequired = script.PersmissionLevel >= 2,
|
|
Id = script.Id,
|
|
Name = script.Name
|
|
};
|
|
|
|
output.Add(newAgentScript);
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public override async Task<Guid> ActualizeAgentData(int AgentDeviceId, int? AgentUserId = null)
|
|
{
|
|
Guid output = Guid.Empty;
|
|
|
|
try
|
|
{
|
|
if (cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode == null)
|
|
return output;
|
|
|
|
LogEntry($"Actualize Data - Actializing Data for DeviceId: {AgentDeviceId} & UserId {AgentUserId ?? -1}");
|
|
|
|
output = await agentApiHelper.ActualizeData(cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode.Value, AgentDeviceId, AgentUserId);
|
|
|
|
LogEntry($"Actualize Data - Actializing Data ActualizingId: {output}");
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public override async Task<enumActualizeStatus> GetActualizeAgentDataStatus(Guid actualizeId, enumFasdInformationClass informationClass)
|
|
{
|
|
var output = enumActualizeStatus.unknown;
|
|
try
|
|
{
|
|
enumAgentActualizeStatus actualizeStatus = enumAgentActualizeStatus.Unknown;
|
|
|
|
LogEntry($"Actualize Data - Get Actializing Status for Id: {actualizeId}");
|
|
actualizeStatus = await agentApiHelper.GetActualizeStatus(actualizeId, informationClass);
|
|
LogEntry($"Actualize Data - Actializing Status for Id: {actualizeId} = {actualizeStatus}");
|
|
|
|
switch (actualizeStatus)
|
|
{
|
|
case enumAgentActualizeStatus.FinishedByTimeOut:
|
|
output = enumActualizeStatus.failed;
|
|
break;
|
|
case enumAgentActualizeStatus.Finished:
|
|
output = enumActualizeStatus.successfull;
|
|
break;
|
|
default:
|
|
output = enumActualizeStatus.unknown;
|
|
break;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
public override async Task<Guid?> TryActivateDirectConnection(int DeviceId)
|
|
{
|
|
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode == null)
|
|
return null;
|
|
|
|
var connectionId = await agentApiHelper.ActivateDirectConnection(cCockpitConfiguration.Instance.agentApiConfiguration.OrganizationCode.Value, DeviceId);
|
|
|
|
if (connectionId.Equals(Guid.Empty))
|
|
{
|
|
LogEntry($"Couldn't create connection to device with id: {DeviceId}", LogLevels.Error);
|
|
return null;
|
|
}
|
|
|
|
const int retries = 90;
|
|
enumDirectConnectionStatus enumDirectConnectionStatus = enumDirectConnectionStatus.Unknown;
|
|
|
|
for (int i = 0; i < retries; i++)
|
|
{
|
|
await Task.Delay(500);
|
|
enumDirectConnectionStatus = await agentApiHelper.GetDirectConnectionStatus(connectionId);
|
|
|
|
if (enumDirectConnectionStatus == enumDirectConnectionStatus.Connected)
|
|
return connectionId;
|
|
if (enumDirectConnectionStatus == enumDirectConnectionStatus.ClosingConnection)
|
|
{
|
|
LogEntry("Connection is allready closing. Please try again.");
|
|
return null;
|
|
}
|
|
}
|
|
LogEntry("Timeout while waiting for direct connection.", LogLevels.Debug);
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override async Task StopDirectConnection(Guid connectionId) => await agentApiHelper.StopDirectConnection(connectionId);
|
|
|
|
public override async Task<bool> IsDirectConnectionUp(Guid connectionId)
|
|
{
|
|
var connectionStatus = await agentApiHelper.GetDirectConnectionStatus(connectionId);
|
|
return connectionStatus == enumDirectConnectionStatus.Connected;
|
|
}
|
|
|
|
public override async Task<bool> DirectConnectionExtendDuration(Guid connectonId, int timeOutInSeconds) => await agentApiHelper.DirectConnectionExtendDuration(connectonId, timeOutInSeconds);
|
|
|
|
public override async Task<List<List<object>>> GetQuickActionHistory(string QuickActionName, int OrgId, int DeviceId, int? UserId)
|
|
{
|
|
var output = new List<List<object>>();
|
|
|
|
try
|
|
{
|
|
if (!cF4SDCockpitXmlConfig.Instance.QuickActionConfig.F4SDQuickActions.QuickActions.TryGetValue(QuickActionName, out var quickAction))
|
|
return output;
|
|
|
|
if (quickAction is cFasdQuickActionLocal)
|
|
return output;
|
|
|
|
if (quickAction is cF4sdQuickActionRemote remoteQuickAction)
|
|
{
|
|
var revisions = await agentApiHelper.GetRevisions(new DateTime(1900, 01, 01), DateTime.MaxValue, OrgId, DeviceId, UserId);
|
|
revisions = revisions.Where(revision => revision.ScriptName == remoteQuickAction.ScriptName).ToList();
|
|
|
|
foreach (var revision in revisions)
|
|
{
|
|
enumQuickActionRevisionStatus convertedRevisionStatus = enumQuickActionRevisionStatus.unknown;
|
|
|
|
switch (revision.Status)
|
|
{
|
|
case enumRevisionStatus.Success:
|
|
convertedRevisionStatus = enumQuickActionRevisionStatus.finishedSuccessfull;
|
|
break;
|
|
case enumRevisionStatus.Warning:
|
|
case enumRevisionStatus.Error:
|
|
case enumRevisionStatus.Fatal:
|
|
convertedRevisionStatus = enumQuickActionRevisionStatus.finishedWithError;
|
|
break;
|
|
case enumRevisionStatus.Created:
|
|
default:
|
|
convertedRevisionStatus = enumQuickActionRevisionStatus.inProgress;
|
|
break;
|
|
}
|
|
|
|
List<object> revisionLine = new List<object>
|
|
{
|
|
convertedRevisionStatus,
|
|
revision.CreateDate,
|
|
revision.Output
|
|
};
|
|
|
|
output.Add(revisionLine);
|
|
}
|
|
}
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public override async Task<cF4sdAgentScriptInformation> RunAgentScript(cF4sdQuickActionRemote Script, int OrgCode, int DeviceId, int? DeviceAccountId, string Parameters)
|
|
{
|
|
var output = new cF4sdAgentScriptInformation();
|
|
|
|
try
|
|
{
|
|
var agentScriptResult = await agentApiHelper.RunSingleScript(Script.AgentScriptId, OrgCode, DeviceId, DeviceAccountId, Parameters);
|
|
output.ScriptId = agentScriptResult.Id;
|
|
output.RevisionId = agentScriptResult.RevisionId;
|
|
output.TaskId = agentScriptResult.TaskId;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public override async Task<enumQuickActionStatus> GetAgentQuickActionStatus(int TaskId)
|
|
{
|
|
try
|
|
{
|
|
var taskStatus = await agentApiHelper.GetTaskStatus(TaskId);
|
|
|
|
switch (taskStatus)
|
|
{
|
|
case enumAgentTaskStatus.ConnectingToClient:
|
|
return enumQuickActionStatus.ConnectingToClient;
|
|
case enumAgentTaskStatus.WaitingForUserAcceptance:
|
|
return enumQuickActionStatus.WaitingForUserAcceptance;
|
|
case enumAgentTaskStatus.Running:
|
|
case enumAgentTaskStatus.DownloadingScript:
|
|
case enumAgentTaskStatus.Canceling:
|
|
return enumQuickActionStatus.Running;
|
|
case enumAgentTaskStatus.Finished:
|
|
return enumQuickActionStatus.Finished;
|
|
case enumAgentTaskStatus.Canceled:
|
|
return enumQuickActionStatus.Cancelled;
|
|
default:
|
|
return enumQuickActionStatus.Unknown;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return enumQuickActionStatus.Unknown;
|
|
}
|
|
|
|
public override async Task<cF4sdQuickActionRevision> GetAgentRevision(int RevisionId, int OrgId)
|
|
{
|
|
var output = new cF4sdQuickActionRevision();
|
|
|
|
try
|
|
{
|
|
var agentRevision = await agentApiHelper.GetRevision(RevisionId, OrgId);
|
|
|
|
switch (agentRevision?.Status)
|
|
{
|
|
case enumRevisionStatus.Success:
|
|
output.Status = enumQuickActionRevisionStatus.finishedSuccessfull;
|
|
break;
|
|
case enumRevisionStatus.Warning:
|
|
case enumRevisionStatus.Error:
|
|
case enumRevisionStatus.Fatal:
|
|
output.Status = enumQuickActionRevisionStatus.finishedWithError;
|
|
break;
|
|
case enumRevisionStatus.Created:
|
|
output.Status = enumQuickActionRevisionStatus.inProgress;
|
|
break;
|
|
}
|
|
|
|
output.OutputText = agentRevision.Output;
|
|
|
|
if (agentRevision.Measures?.Count > 0)
|
|
{
|
|
output.Measures = new List<cF4sdQuickActionRevision.cMeasure>();
|
|
foreach (var measure in agentRevision.Measures)
|
|
{
|
|
output.Measures.Add(new cF4sdQuickActionRevision.cMeasure()
|
|
{
|
|
Id = measure.Measure.MeasureId,
|
|
Value = measure.Value.Data,
|
|
PostValue = measure.PostValue.Data
|
|
});
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
await CheckConnectionStatus?.Invoke();
|
|
LogException(E);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public override async Task CancelAgentTask(int TaskId)
|
|
{
|
|
try
|
|
{
|
|
var cancelSuccessfull = await agentApiHelper.CancelTask(TaskId);
|
|
|
|
if (!cancelSuccessfull)
|
|
LogEntry($"Failed to cancel task with id: {TaskId}", LogLevels.Warning);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private void SaveApiResultValueJson(string ApiName, string json, string comment = null)
|
|
{
|
|
List<string> comments = null;
|
|
if (comment != null)
|
|
comments = new List<string>() { comment };
|
|
SaveApiResultValueJson(ApiName, json, comments);
|
|
}
|
|
|
|
private void SaveApiResultValueJson(string ApiName, string json, List<string> comment)
|
|
{
|
|
try
|
|
{
|
|
string jsonFormatted = JValue.Parse(json).ToString(Formatting.Indented);
|
|
if (comment != null)
|
|
{
|
|
var _cmm = "";
|
|
foreach (var c in comment)
|
|
{
|
|
_cmm += "//\t" + c + "\r\n";
|
|
}
|
|
jsonFormatted = _cmm + jsonFormatted;
|
|
}
|
|
|
|
SaveApiResultValue(ApiName, jsonFormatted, "json");
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private void SaveApiTimingEntry(string ApiName, DateTime timeStart, int error)
|
|
{
|
|
try
|
|
{
|
|
if (!Debug_apiTiming)
|
|
return;
|
|
|
|
var duration = (DateTime.UtcNow - timeStart).TotalMilliseconds;
|
|
var _now = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-FFFFF");
|
|
|
|
if (ApiTimingLog == null)
|
|
{
|
|
if (!(cLogManager.Instance is cLogManagerFile lf))
|
|
return;
|
|
|
|
if (string.IsNullOrEmpty(lf.LogFolder))
|
|
return;
|
|
|
|
var _fn = Path.GetFileNameWithoutExtension(lf.GetLogFileName());
|
|
ApiTimingLog = Path.Combine(lf.LogFolder, _fn + "-ApiTiming.log");
|
|
}
|
|
|
|
var _line = string.Format("{0}\t{1}\t{2}\t{3}\r\n", _now, ApiName, duration, error);
|
|
System.IO.File.AppendAllText(ApiTimingLog, _line, Encoding.UTF8);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
private void SaveApiResultValue(string ApiName, string Value, string extension)
|
|
{
|
|
try
|
|
{
|
|
if (!Debug_apiValues)
|
|
return;
|
|
|
|
if (!(cLogManager.Instance is cLogManagerFile lf))
|
|
return;
|
|
|
|
if (string.IsNullOrEmpty(lf.LogFolder))
|
|
return;
|
|
|
|
var _now = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-FFFFF");
|
|
var _lf = Path.Combine(lf.LogFolder, "ApiValues");
|
|
|
|
if (!Directory.Exists(_lf))
|
|
Directory.CreateDirectory(_lf);
|
|
|
|
var _fn = Path.Combine(_lf, ApiName + "-" + _now + "." + extension);
|
|
System.IO.File.WriteAllText(_fn, Value, Encoding.UTF8);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
public override async Task InitializeAfterOnlineAsync() { await Task.CompletedTask; }
|
|
|
|
public override async Task TerminateAsync() { await Task.CompletedTask; }
|
|
|
|
public override Uri GetMediaContentUri(string ContentRelPath)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
|
|
try
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(cFasdCockpitMachineConfiguration.Instance.ServerUrl))
|
|
{
|
|
Uri httpsUri = new Uri(cFasdCockpitMachineConfiguration.Instance.ServerUrl + ContentRelPath, UriKind.Absolute);
|
|
UriBuilder uriBuilder = new UriBuilder(httpsUri) { Scheme = "http", Port = -1 };
|
|
return uriBuilder.Uri;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
}
|
|
}
|