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 FasdCockpitCommunication.TicketOverview; 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 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(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 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(result.Result); } } catch (Exception E) { LogException(E); } return output; } public async override Task 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(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 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(_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 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(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 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(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 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 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 UpdateCase(cF4SDCaseStatusParameters caseStatusParameters, List 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 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 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 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 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(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 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(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 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(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 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(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 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(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 GetUserSearchResults(string Name, List 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(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 relations, List 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(); foreach (var info in matchingSearchResult.Infos) { relation.Infos["relation_" + info.Key] = info.Value; } } } catch (Exception E) { LogException(E); } } public override async Task StartGatheringRelations(IEnumerable 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(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 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(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 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(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> GetSearchResultRelations(enumF4sdSearchResultClass resultType, List searchResults) { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); var apiError = 0; var timeStart = DateTime.UtcNow; var output = new List(); 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; } #region Ticketübersicht public override async Task> GetTicketOverviewCounts(IEnumerable keys, bool useRoleScope) { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); var apiError = 0; var timeStart = DateTime.UtcNow; try { var normalizedKeys = (keys ?? Enumerable.Empty()) .Where(k => !string.IsNullOrWhiteSpace(k)) .Distinct(StringComparer.OrdinalIgnoreCase) .ToList(); var http = GetHttpHelper(true); var scope = useRoleScope ? "role" : "personal"; var urlBuilder = new StringBuilder($"api/TicketOverview/GetCounts?scope={scope}"); if (normalizedKeys.Count > 0) { var joinedKeys = HttpUtility.UrlEncode(string.Join(",", normalizedKeys)); urlBuilder.Append($"&keys={joinedKeys}"); } var url = urlBuilder.ToString(); var result = await http.GetHttpJson(url, 15000, CancellationToken.None); if (!result.IsOk) { apiError = (int)result.Status; if (CheckConnectionStatus != null) await CheckConnectionStatus.Invoke(); LogEntry($"Error on requesting ticket overview counts ({scope}). Status: {result.Status}", LogLevels.Warning); return new Dictionary(StringComparer.OrdinalIgnoreCase); } if (Debug_apiValues) SaveApiResultValueJson("TicketOverview.GetCounts", result.Result, url); var response = JsonConvert.DeserializeObject(result.Result); return response?.ToDictionary(normalizedKeys) ?? new Dictionary(StringComparer.OrdinalIgnoreCase); } catch (Exception E) { apiError = E.HResult; if (CheckConnectionStatus != null) await CheckConnectionStatus.Invoke(); LogException(E); } finally { if (Debug_apiTiming) SaveApiTimingEntry("TicketOverview.GetCounts", timeStart, apiError); LogMethodEnd(CM); } return new Dictionary(StringComparer.OrdinalIgnoreCase); } public override async Task> GetTicketOverviewRelations(string key, bool useRoleScope, int count) { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); var apiError = 0; var timeStart = DateTime.UtcNow; var output = new List(); try { if (string.IsNullOrWhiteSpace(key)) return output; var http = GetHttpHelper(true); var scope = useRoleScope ? "role" : "personal"; var safeKey = HttpUtility.UrlEncode(key); var url = $"api/TicketOverview/GetRelations?key={safeKey}&scope={scope}&count={Math.Max(0, count)}"; var result = await http.GetHttpJson(url, 20000, CancellationToken.None); if (!result.IsOk) { apiError = (int)result.Status; if (CheckConnectionStatus != null) await CheckConnectionStatus.Invoke(); LogEntry($"Error on requesting ticket overview relations for '{key}' ({scope}). Status: {result.Status}", LogLevels.Warning); return output; } if (Debug_apiValues) SaveApiResultValueJson("TicketOverview.GetRelations", result.Result, url); var relations = JsonConvert.DeserializeObject>(result.Result); if (relations != null) output = relations; } catch (Exception E) { apiError = E.HResult; if (CheckConnectionStatus != null) await CheckConnectionStatus.Invoke(); LogException(E); } finally { if (Debug_apiTiming) SaveApiTimingEntry("TicketOverview.GetRelations", timeStart, apiError); LogMethodEnd(CM); } return output; } #endregion public override async Task 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(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 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(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> 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>(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 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(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 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(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 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 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 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(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 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(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> 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(); } if (result.Result is string jsonString && !string.IsNullOrWhiteSpace(jsonString)) { return JsonConvert.DeserializeObject>(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 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 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> GetQuickActionsOfAgent() { var output = new List(); 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 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 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 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 IsDirectConnectionUp(Guid connectionId) { var connectionStatus = await agentApiHelper.GetDirectConnectionStatus(connectionId); return connectionStatus == enumDirectConnectionStatus.Connected; } public override async Task DirectConnectionExtendDuration(Guid connectonId, int timeOutInSeconds) => await agentApiHelper.DirectConnectionExtendDuration(connectonId, timeOutInSeconds); public override async Task>> GetQuickActionHistory(string QuickActionName, int OrgId, int DeviceId, int? UserId) { var output = new List>(); 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 revisionLine = new List { convertedRevisionStatus, revision.CreateDate, revision.Output }; output.Add(revisionLine); } } } catch (Exception E) { await CheckConnectionStatus?.Invoke(); LogException(E); } return output; } public override async Task 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 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 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(); 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 comments = null; if (comment != null) comments = new List() { comment }; SaveApiResultValueJson(ApiName, json, comments); } private void SaveApiResultValueJson(string ApiName, string json, List 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; } } }