Files
C4IT-F4SD-Collector/F4SD-Cockpit-ServerCore/DataHistoryCollector.cs
2026-01-28 12:24:39 +01:00

7580 lines
359 KiB
C#

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.IdentityModel.Tokens.Jwt;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices.ActiveDirectory;
using System.IO;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using C4IT.Configuration;
using C4IT.FASD.Base;
using C4IT.FASD.Licensing;
using C4IT.Logging;
using C4IT.Security;
using C4IT.XML;
using C4IT.Matrix42.WebClient;
using C4IT_DataHistoryProvider_Base;
using C4IT_DataHistoryProvider_Base.DataSources;
using C4IT_DataHistoryProvider_Base.Services;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public delegate void DataHistoryUiMessageFunc(cDataHistoryUiStatusMessage Message);
public abstract class cDataHistoryCollectorModule
{
public cDataHistoryCollector Collector { get; protected set; }
public readonly List<enumDataHistoryOrigin> Origins;
public readonly string Name = "";
public readonly Guid LicenseId = Guid.Empty;
public cDataHistoryCollectorModule(cDataHistoryCollector Collector, enumDataHistoryOrigin Origin, string Name, string LicenseId)
{
this.Name = Name;
Guid.TryParse(LicenseId, out this.LicenseId);
this.Collector = Collector;
this.Origins = new List<enumDataHistoryOrigin>() { Origin };
}
public cDataHistoryCollectorModule(cDataHistoryCollector Collector, List<enumDataHistoryOrigin> Origin, string Name, string LicenseId)
{
this.Name = Name;
Guid.TryParse(LicenseId, out this.LicenseId);
this.Collector = Collector;
this.Origins = Origin;
}
public override string ToString()
{
return Name;
}
public abstract Task<cScanTimeInfo> GetScanTimeInfoAsync(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token);
public async Task<cScanTimeInfo> GetScanTimeInfoAsync(cDataHistoryScanTiming ScanTiming, string ScanName, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
var LastScan = await Collector.GetLastScanTime(ScanName, requestInfo, LogDeep + 1, Token);
if (LastScan == null || LastScan == new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc))
return null;
var retVal = new cScanTimeInfo((DateTime)LastScan);
try
{
retVal.NextScan = retVal.GetScanTime(DateTime.UtcNow, ScanTiming);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return retVal;
}
public abstract Task<bool> DoScanAsync(bool Always, bool Rescan, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool EnhancedDebug = false);
public abstract Task<List<object>> GetIds(cF4sdConnectorIds IdEntry, enumFasdInformationClass InfoClass, cF4sdWebRequestInfo requestInfo, int LogDeep);
public virtual List<object> GetFilterValues(List<object> IDs, enumFasdInformationClass InfoClass)
{
return IDs;
}
public virtual async Task<List<string>> GetQuickActionList()
{
await Task.CompletedTask;
var result = new List<string>();
return result;
}
public virtual bool CheckIfLateDelivery(cDataHistoryConfigTable Table)
{
return false;
}
public void AddTableResultVirtualSuccessorTasks(List<cDataHistoryConfigTable> Tables, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, List<Int64> UsageInfo, Guid CacheId, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var lstTables = new List<string>();
var myTables = new List<cDataHistoryConfigTable>();
foreach (var Table in Tables)
{
if (!this.Origins.Contains(Table.ParentCluster.Origin))
continue;
if (!CheckIfLateDelivery(Table))
continue;
myTables.Add(Table);
lstTables.Add(Table.Name);
}
if (lstTables.Count > 0)
{
var ct = new CancellationTokenSource().Token;
var tsk = GetTableResultsVirtualAsync(myTables, Identities, RefTime, MaxAge, false, CacheId, ct, requestInfo, LogDeep + 1);
SuccessorCache.AddTask(CacheId, lstTables, tsk, UsageInfo, ct);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public virtual async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetTableResultsVirtualAsync(List<cDataHistoryConfigTable> Tables, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, bool instantly, Guid? CacheId, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
await Task.CompletedTask;
return null;
}
public virtual async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetDetailsTableResultsVirtualAsync(List<cDataHistoryConfigTable> Tables, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
await Task.CompletedTask;
return null;
}
public virtual async Task<Int64> GetSelectionTableResultCountAsync(cDataHistoryConfigTable Table, List<cF4sdIdentityEntry> Identities, string search, cF4sdWebRequestInfo requestInfo, CancellationToken Token, bool resetFilter = false, List<string> filterParams = null)
{
await Task.CompletedTask;
return -1;
}
public virtual async Task<cF4SDHealthCardRawData.cHealthCardTable> GetSelectionTableResultAsync(cDataHistoryConfigTable Table, List<cF4sdIdentityEntry> Identities, string search, int PageSize, int Page, cF4sdWebRequestInfo requestInfo, CancellationToken Token, bool resetFilter = false, List<string> filterParams = null)
{
await Task.CompletedTask;
return null;
}
public virtual async Task<bool> ValidateMainTablesAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
await Task.CompletedTask;
return true;
}
public virtual async Task<bool> ColumnUpatePostProcessingAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
await Task.CompletedTask;
return false;
}
public virtual void TablePostConfig(cDataHistoryConfigTable Table)
{
}
public virtual async Task<bool> WritePropertyAsync(cF4SDWriteParameters PropertiesToWrite, cF4sdWebRequestInfo requestInfo, CancellationToken Token)
{
await Task.CompletedTask;
return false;
}
public virtual async Task<cF4SdUserInfoChange> ValidateTokenAsync(cF4SDTokenRegistration TokenRegistration, cF4sdWebRequestInfo RequestInfo, int LogDeep, CancellationToken Token)
{
await Task.CompletedTask;
return null;
}
public virtual async Task<cF4SDAdditionalUserInfo> GetAdditionalUserInfo(enumAdditionalAuthentication Type, cF4sdWebRequestInfo RequestInfo, int LogDeep, CancellationToken Token)
{
await Task.CompletedTask;
return null;
}
}
public class cDataHistoryCollector : cDataHistoryCollectorModule, IConfigNodeValidation, ISearchResultRelationProvider
{
public const string constConnectorName = "F4SD collector";
public const string constLicenseId = "00000000-0000-0000-0000-000000000000";
public const int constMinutesUntilTokenIsInvalid = 5;
public static readonly Guid ConfigId = new Guid("0FCE8005-81BD-4F06-82FF-55DD9364FBE5");
public static readonly string JwtTokenIssuer = "https://login.f4sdcockpit.consulting4it.de";
public static readonly string JwtTokenAudience = "urn:Cockpit.F4SD";
public Guid getId() { return ConfigId; }
public const string constFileNameClusterConfig = "F4SD-DataClusters-Configuration.xml";
public const string constFileNameInfrastructureConfig = "F4SD-Infrastructure-Configuration.xml";
public bool IsValid { get; private set; } = false;
public cDataHistoryConfigClusters ClusterConfig { get; private set; } = null;
public cDataHistoryConfigInfrastructure InfrastructureConfig { get; private set; } = null;
private cDataHistoryConfigGolabalParameters GlobalParametersConfigFile = null;
private cF4sdGlobalConfig GlobalConfig { get; set; } = null;
private DateTime GlobalParametersConfigTimestamp = DateTime.MinValue;
private object GlobalParametersConfigLock = new object();
public readonly Dictionary<enumDataHistoryOrigin, cDataHistoryCollectorModule> Connectors = new Dictionary<enumDataHistoryOrigin, cDataHistoryCollectorModule>();
public readonly cDataHistoryCollectorActiveDirectory ActiveDirectory = null;
public readonly cDataHistoryCollectorClientAgent F4sdAgent = null;
public cDataHistoryCollectorM42Wpm M42WpmCollector { get; private set; } = null;
public cDataHistoryCollectorNxql NxqlCollector { get; private set; } = null;
public cDataHistoryCollectorCitrix CitrixCollector { get; private set; } = null;
public bool F4SDAnalyticsValid = false;
public cF4SDAnalyticsConfigDatabase F4SDAnalyticsDb { get; private set; } = null;
public event DataHistoryUiMessageFunc ProcessUiMessage;
public readonly bool autoConnectionCheck = false;
public Dictionary<enumFasdConfigurationType, cFasdBaseConfig> ClientConfigs = null;
public Dictionary<string, string> GlobalConfigValues = new Dictionary<string, string>();
public readonly JwtSecurityTokenHandler JwtTokenHandler = new JwtSecurityTokenHandler();
public SymmetricSecurityKey BearerSecurityKey { get; private set; } = null;
public TokenValidationParameters JwtTokenValidationParameters { get; private set; } = null;
public Dictionary<Guid, DateTime> SessionValues = new Dictionary<Guid, DateTime>();
public Dictionary<Guid, DateTime> CaseValues = new Dictionary<Guid, DateTime>();
public cDataHistoryCollectorTokenCache TokenCache;
public enumWebServerStatus ServerStatus = enumWebServerStatus.starting;
private readonly List<ISearchResultRelationProvider> _searchResultRelationProviders = new List<ISearchResultRelationProvider>();
public bool RunningInIISExpress = false;
#region Services
private IStagedRelationService _stagedRelationService;
public IStagedRelationService GetStagedRelationService()
{
if (_stagedRelationService is null)
_stagedRelationService = new StagedRelationService(_searchResultRelationProviders);
return _stagedRelationService;
}
#endregion
internal class cDetailsComputationInfo
{
internal cDataHistoryConfigComputationBase Computation;
internal int[] ValueIndexes;
}
public cDataHistoryConfigSqlConnection mainDbConnection { get; private set; } = null;
public cDataHistoryCollector(bool autoConnectionCheck, cF4sdWebRequestInfo requestInfo, int LogDeep) : base(null, enumDataHistoryOrigin.Main, constConnectorName, constLicenseId)
{
this.Collector = this;
this.autoConnectionCheck = autoConnectionCheck;
TokenCache = new cDataHistoryCollectorTokenCache(this, requestInfo, LogDeep + 1);
Connectors.Add(enumDataHistoryOrigin.Main, this);
try
{
var _process = Process.GetCurrentProcess();
if (_process?.ProcessName != null && _process.ProcessName.ToLower().StartsWith("iisexpress"))
RunningInIISExpress = true;
}
catch (Exception e1)
{
LogException(e1);
}
var _ActiveDirectory = new cDataHistoryCollectorActiveDirectory(this);
if (cF4SDLicense.Instance?.Modules != null)
{
if (cF4SDLicense.Instance.Modules.ContainsKey(_ActiveDirectory.LicenseId))
{
ActiveDirectory = _ActiveDirectory;
Connectors.Add(enumDataHistoryOrigin.ActiveDirectory, ActiveDirectory);
}
var _F4sdAgent = new cDataHistoryCollectorClientAgent(this);
if (cF4SDLicense.Instance.Modules.ContainsKey(_F4sdAgent.LicenseId))
{
F4sdAgent = _F4sdAgent;
Connectors.Add(enumDataHistoryOrigin.F4sdAgent, F4sdAgent);
}
}
}
public List<cDataHistoryCollectorModule> GetConnectors()
{
var _connectors = Connectors.Values.Distinct().ToList();
return _connectors;
}
public bool RefreshGlobalConfigurationParameters()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
lock (GlobalParametersConfigLock)
{
var _currentTimeStamp = DateTime.MaxValue;
if (GlobalParametersConfigFile != null)
_currentTimeStamp = File.GetLastWriteTimeUtc(GlobalParametersConfigFile.FilePath);
if (_currentTimeStamp <= GlobalParametersConfigTimestamp)
{
DoProcessUiMessage(0, "");
DoProcessUiMessage(1, "Global parameters are already loaded and are up to date...");
return true;
}
DoProcessUiMessage(0, "");
DoProcessUiMessage(1, "loading the global parameters...");
var _cfgGlobalParameters = new cDataHistoryConfigGolabalParameters(this.InfrastructureConfig);
_cfgGlobalParameters.LoadFromFile(out var PMs);
if (PMs != null && PMs.Count > 0)
DoProcessUiMessage(2, PMs);
if (_cfgGlobalParameters == null || !_cfgGlobalParameters.IsValid)
{
DoProcessUiMessage(1, "error on loading the global parameters.");
return false;
}
GlobalParametersConfigFile = _cfgGlobalParameters;
GlobalConfig = new cF4sdGlobalConfig(regPath: null);
if (GlobalParametersConfigFile.Parameters != null)
GlobalConfig.Load(CentralParameters: GlobalParametersConfigFile.Parameters);
}
return true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public async Task<bool> LoadConfigurationAsync(bool checkServerEnvironment, bool checkCurrentUser, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep, Assembly ExecutingAssembly = null)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
IsValid = false;
DoProcessUiMessage(0, "start loading the collector configuration...");
// load the SqlHelper
if (!DataHistorySqlHelper.LoadWellKnownSqlStatements(out var PMs, ExecutingAssembly))
{
if (PMs != null && PMs.Count > 0)
{
DoProcessUiMessage(1, "loading the well defined SQL statements...");
DoProcessUiMessage(2, PMs);
DoProcessUiMessage(1, "error on loading the well defined SQL statement.");
}
return false;
}
// load the infrastructure
DoProcessUiMessage(0, "");
DoProcessUiMessage(1, "loading the the infrastructure definitions...");
var _cfgInfrastructure = new cDataHistoryConfigInfrastructure();
_cfgInfrastructure.LoadFromFile(out PMs);
if (PMs != null && PMs.Count > 0)
DoProcessUiMessage(2, PMs);
if (_cfgInfrastructure == null || !_cfgInfrastructure.IsValid)
{
DoProcessUiMessage(1, "error on loading the infrastructure definitions.");
return false;
}
InfrastructureConfig = _cfgInfrastructure;
DoProcessUiMessage(1, "the infrastructure configuration loaded successful.");
DoProcessUiMessage(0, "");
var HasM42Config = _cfgInfrastructure.M42Wpm != null;
var HasIntuneConfig = (_cfgInfrastructure.AzureTenants?.Values.Any(t => t.ScanIntuneDevices) == true);
var HasMobileDeviceConfig = (_cfgInfrastructure.AzureTenants?.Values.Any(t => t.WithMobileDevices) == true);
var HasCitrixConfig = (InfrastructureConfig.Citrix != null);
DoProcessUiMessage(1, "resolving the ad membership groups");
ActiveDirectory.ResolveWinAuthenticationGroups();
// check the server environment
if (checkServerEnvironment)
await CheckServerEnvironmentAsync(checkCurrentUser, Token, requestInfo, LogDeep + 1);
// load the data clusters
DoProcessUiMessage(0, "");
DoProcessUiMessage(1, "loading the data cluster definitions...");
var _cfgDataClusters = new cDataHistoryConfigClusters();
_cfgDataClusters.LoadFromFile(out PMs, withM42Config: HasM42Config, withIntuneConfig: HasIntuneConfig,withMobileDeviceConfig:HasMobileDeviceConfig,withCitrixConfig:HasCitrixConfig);
if (PMs != null && PMs.Count > 0)
DoProcessUiMessage(2, PMs);
if (_cfgDataClusters == null || !_cfgDataClusters.IsValid)
{
DoProcessUiMessage(1, "error on loading the data cluster definitions.");
return false;
}
ClusterConfig = _cfgDataClusters;
DoProcessUiMessage(1, "the data cluster configuration loaded successful.");
DoProcessUiMessage(0, "");
// load the global parameters
if (!RefreshGlobalConfigurationParameters())
return false;
mainDbConnection = InfrastructureConfig.HistoryDB.Connection;
if (InfrastructureConfig.M42Wpm != null)
{
var _M42WpmCollector = new cDataHistoryCollectorM42Wpm(this);
if (cF4SDLicense.Instance?.Modules != null)
if (cF4SDLicense.Instance.Modules.ContainsKey(_M42WpmCollector.LicenseId))
{
M42WpmCollector = _M42WpmCollector;
Connectors.Add(enumDataHistoryOrigin.M42Wpm, M42WpmCollector);
RegisterSearchRelationProvider(_M42WpmCollector);
}
}
if (InfrastructureConfig.Nexthink != null)
{
var _NxqlCollector = new cDataHistoryCollectorNxql(this);
if (cF4SDLicense.Instance?.Modules != null)
if (cF4SDLicense.Instance.Modules.ContainsKey(_NxqlCollector.LicenseId))
{
NxqlCollector = _NxqlCollector;
Connectors.Add(enumDataHistoryOrigin.NexthinkNxql, NxqlCollector);
}
}
if (HasCitrixConfig)
{
var _CitrixCollector = new cDataHistoryCollectorCitrix(this);
if (cF4SDLicense.Instance?.Modules != null)
//if (cF4SDLicense.Instance.Modules.ContainsKey(_CitrixCollector.LicenseId))
//{
CitrixCollector = _CitrixCollector;
Connectors.Add(enumDataHistoryOrigin.Citrix, _CitrixCollector);
RegisterSearchRelationProvider(_CitrixCollector);
//}
}
if(HasIntuneConfig)
{
Connectors.Add(enumDataHistoryOrigin.Intune, ActiveDirectory);
RegisterSearchRelationProvider(ActiveDirectory);
}
// do the post configuration tasks afer the infrastructure was loaded
DoProcessUiMessage(1, "processing post configuration tasks");
foreach (var Table in _cfgDataClusters.Tables.Values)
{
if (Connectors.TryGetValue(Table.ParentCluster.Origin, out var _module))
_module?.TablePostConfig(Table);
}
RegisterSearchRelationProvider(this);
DoProcessUiMessage(0, "");
DoProcessUiMessage(0, "the collector configuration loaded successful.");
IsValid = true;
return true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private void RegisterSearchRelationProvider(ISearchResultRelationProvider provider)
{
_searchResultRelationProviders.Add(provider);
}
public cF4sdGlobalConfig GetGlobalConfig()
{
RefreshGlobalConfigurationParameters();
cF4sdGlobalConfig _result = null;
lock (GlobalParametersConfigLock)
{
_result = GlobalConfig;
}
return GlobalConfig;
}
private void RegisterSearchRelationProviders(IEnumerable<ISearchResultRelationProvider> providers)
{
_searchResultRelationProviders.AddRange(providers);
}
public async Task CheckServerEnvironmentAsync(bool CheckCurrentUser, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
DoProcessUiMessage(1, "");
DoProcessUiMessage(1, "checking the server environment...");
var _issConfig = IisConfigHelper.CheckIISConfiguration();
if (!_issConfig.IsWebSocketInstalled)
DoProcessUiMessage(2, " Warning: The IIS feature 'WebSocket' is not installed. This is needed for use of direct connections.", LogLevels.Warning);
if (!_issConfig.IsIssWindowsAuthenticationInstalled)
DoProcessUiMessage(2, " Warning: The IIS feature 'WindowsAuthentication' is not installed. This is mandatory for the use of authorization.", LogLevels.Warning);
if (!_issConfig.IsIssWindowsAuthenticationEnabled)
DoProcessUiMessage(2, " Warning: The 'WindowsAuthentication' is not enabled for the WEB application F4SDCockpit. This is mandatory for the use of authorization.", LogLevels.Warning);
await CheckAuthorisationConfigurationAsync(CheckCurrentUser, Token, requestInfo, LogDeep + 1);
DoProcessUiMessage(1, "server environment check finished.");
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task CheckAuthorisationConfigurationAsync(bool CheckCurrentUser, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (InfrastructureConfig?.Authorisation == null || !InfrastructureConfig.Authorisation.IsValid)
{
DoProcessUiMessage(2, " Warning: Authentication is not configured properly in the file 'F4SD-Infrastructure-Configuration.xml'. It is strongly recommended not to use F4SD Cockpit without configured authentication.", LogLevels.Warning);
return;
}
if (CheckCurrentUser)
{
var _userInfo = await GetCurrentUserInfoAsync(Token, requestInfo, LogDeep + 1);
if (_userInfo?.Roles == null || _userInfo.Roles.Count == 0)
{
DoProcessUiMessage(2, $" Warning: The current user {_userInfo?.AdAccount} is not member of any F4SD role. Please check the authentication configuration and the ad group memberships.", LogLevels.Warning);
}
else
{
if (!_userInfo.Roles.Contains("Cockpit.User"))
DoProcessUiMessage(2, $" Warning: The current user {_userInfo.AdAccount} is not member of the F4SD role 'Cockpit.User'. Please check the authentication configuration and the ad group memberships.", LogLevels.Warning);
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public void ValidateClientConfiguration()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
DoProcessUiMessage(0, "start validating the client configuration files...");
DoProcessUiMessage(0, "");
var _Configs = new Dictionary<enumFasdConfigurationType, cFasdBaseConfig>();
var _lst = Enum.GetValues(typeof(enumFasdConfigurationType)).Cast<enumFasdConfigurationType>();
foreach (var _item in _lst)
{
if (_item != enumFasdConfigurationType.unknown)
{
var _msg = new List<cXmlParserNodeMessage>();
var HasM42Config = InfrastructureConfig.M42Wpm != null;
var HasIntuneConfig = (InfrastructureConfig.AzureTenants?.Values.Any(t => t.ScanIntuneDevices) == true);
var HasMobileDeviceConfig = (InfrastructureConfig.AzureTenants?.Values.Any(t => t.WithMobileDevices) == true);
var HasCitrixConfig = (InfrastructureConfig.Citrix != null);
var _cfg = cFasdBaseConfig.GetConfigByType(_item, null, _msg, withM42Config: HasM42Config, withIntuneConfig: HasIntuneConfig, withMobileDeviceConfig: HasMobileDeviceConfig, withCitrixConfig:HasCitrixConfig);
if (_cfg.IsValid)
{
_Configs[_item] = _cfg;
if (_msg.Count == 0)
DoProcessUiMessage(1, $"the {_item} configuration is valid.");
else
DoProcessUiMessage(1, $"the {_item} configuration is valid but has some annotations:");
}
else
DoProcessUiMessage(1, $"the the {_item} configuration is invalid!");
if (_msg.Count > 0)
DoProcessUiMessage(2, _msg);
DoProcessUiMessage(0, "");
}
}
ClientConfigs = _Configs;
DoProcessUiMessage(0, "the validation of the client configuration files finished.");
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public async Task UpdateF4SDAnalyticsConfigInfosAsync(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken _token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (this.F4SDAnalyticsValid && this.F4SDAnalyticsDb?.Connection != null)
{
if (ClientConfigs != null && ClientConfigs.TryGetValue(enumFasdConfigurationType.quickActions, out var _quickActionsBase))
{
if (_quickActionsBase is cFasdQuickActionConfig _quickActions)
{
if (DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateQActionInfo", out var Query))
if (DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateQActionInfoLang", out var Query2))
{
using (var Conn = new cDbConnection(this.F4SDAnalyticsDb.Connection))
{
foreach (var _quickAction in _quickActions.F4SDQuickActions.QuickActions.Values)
{
if (_quickAction.Id == Guid.Empty)
continue;
var _params = new Dictionary<string, object>()
{
{ "Id", _quickAction.Id},
{ "Name", _quickAction.Name},
{ "Type", _quickAction.GetTypeName()}
};
await DataHistorySqlHelper.ExecuteAsync(Conn, Query, _params, requestInfo, _token);
foreach (var _langEntry in _quickAction.Names)
{
_params = new Dictionary<string, object>()
{
{ "Id", _quickAction.Id},
{ "Name", _langEntry.Value},
{ "Lang", _langEntry.Key.ToUpperInvariant()}
};
await DataHistorySqlHelper.ExecuteAsync(Conn, Query2, _params, requestInfo, _token);
}
}
}
}
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
private async Task ValidateDatabaseAsync(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var DbName = InfrastructureConfig.HistoryDB.Connection.Database;
DoProcessUiMessage(0, "");
DoProcessUiMessage(1, $"start validating the data history database '{DbName}' itself...");
using (var DbConn = new cDbConnection(mainDbConnection, Timeout: 10, WithoutDatabase: true))
if (DbConn.IsOpen)
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_Database", out var Query))
return;
var Params = new Dictionary<string, object>() { { "DbName", DbName } };
var n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
DoProcessUiMessage(1, $"the validation of the data history database '{DbName}' itself finished successful.");
}
else
{
DoProcessUiMessage(2, $"the database {DbName} coud not be found.");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Create_Database", out Query))
return;
var Query2 = Query.Clone(string.Format(Query.Query, mainDbConnection.Database));
var n2 = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query2, null, requestInfo, Token);
if (n2 == null)
{
DoProcessUiMessage(2, $"the data history database '{DbName}' could not be created.");
return;
}
DoProcessUiMessage(2, $"the database {DbName} is created successful.");
}
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_DbCollation", out Query))
return;
var strQuery = string.Format(Query.Query, DbName);
var _startTime2 = DateTime.UtcNow;
n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn.Connection, strQuery, null, Token);
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime2, DbName, 0, requestInfo?.requestName);
if (n != 1)
DoProcessUiMessage(2, $"Warning: the collation of database {DbName} is not 'Latin1_General_CI_AI'");
}
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the data history database itself aborted with an exceptional error.");
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public override async Task<bool> ValidateMainTablesAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
// validate if fulltext search is enabled for the server instance
DoProcessUiMessage(1, $"start validating the full text feature...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_Fulltext_Installed", out var Query))
return false;
if (await DataHistorySqlHelper.GetScalarResultAsync<int?>(DbConn, Query, null, requestInfo, Token) != 1)
{
DoProcessUiMessage(1, $"the sql server instance {DbConn.Connection.DataSource} is not enabled for full text.");
return false;
}
// validate if fulltext search is enabled for the database
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_Fulltext", out Query))
return false;
if (!(await DataHistorySqlHelper.GetScalarResultAsync<bool?>(DbConn, Query, null, requestInfo, Token) == true))
{
DoProcessUiMessage(1, $"the database '{DbConn.Connection.Database}' is not enabled for full text.");
return false;
}
DoProcessUiMessage(1, $"the full text feature is activated for the database.");
DoProcessUiMessage(1, "");
// validate the main tables
DoProcessUiMessage(1, $"start validating the main tables...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_MainTables", out Query))
return false;
var n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n > 0)
{
DoProcessUiMessage(1, $"the validation of the main tables finished successful.");
return true;
}
// create the main tables
DoProcessUiMessage(2, $"the main tables are not complete, creating them...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Create_MainTables", out Query))
return false;
var n2 = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, null, requestInfo, Token);
// validate the creates main tables
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_MainTables", out Query))
return false;
n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n > 0)
{
DoProcessUiMessage(2, $"the main tables were created successfull.");
return true;
}
DoProcessUiMessage(2, "An error occurred when creating the main tables.");
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the main tables aborted with an exceptional error.");
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private async Task<bool> ValidateF4SDAnalyticsDatabaseAsync(CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep, bool ForceCreate = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var DbConnection = InfrastructureConfig.F4SDAnalyticsDB?.Connection;
if (DbConnection == null)
return false;
DoProcessUiMessage(0, "");
DoProcessUiMessage(1, $"start validating the data database '{DbConnection.Database}' itself...");
using (var DbConn = new cDbConnection(DbConnection, WithoutDatabase: true))
if (DbConn.IsOpen)
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_Database", out var Query))
return false;
var Params = new Dictionary<string, object>() { { "DbName", DbConnection.Database } };
var n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
DoProcessUiMessage(1, $"the validation of the data F4SDAnalytics database '{DbConnection.Database}' itself finished successful.");
return true;
}
DoProcessUiMessage(2, $"the database {DbConnection.Database} coud not be found.");
if (ForceCreate)
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Create_Database", out Query))
return false;
var Query2 = Query.Clone(string.Format(Query.Query, DbConnection.Database));
var n2 = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query2, null, requestInfo, Token);
if (n2 != null)
{
DoProcessUiMessage(2, $"the database {DbConnection.Database} is created successful.");
return true;
}
DoProcessUiMessage(2, $"Error: the database '{DbConnection.Database}' could not be created.");
return false;
}
}
DoProcessUiMessage(1, $"Error: the connection on the database '{DbConnection.Database}' is not available.");
return false;
}
catch (Exception E)
{
DoProcessUiMessage(0, "");
DoProcessUiMessage(0, $"the validation of the data F4SDAnalytics database itself aborted with an exceptional error.");
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
private async Task<bool> ValidateF4SDAnalyticsMainTablesAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool ForceCreate)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
// validate the main tables
DoProcessUiMessage(1, $"start validating the main tables...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_F4SDAnalyticsMainTables", out var Query))
return false;
var n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n > 0)
{
DoProcessUiMessage(1, $"the validation of the main tables finished successful.");
DoProcessUiMessage(0, "");
return true;
}
if (!ForceCreate && n < 1)
{
DoProcessUiMessage(2, $"the main tables are not complete...");
return false;
}
if (ForceCreate)
{
// create the main tables
DoProcessUiMessage(2, $"the main tables are not complete, creating them...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Create_F4SDAnalyticsMainTables", out Query))
return false;
await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, null, requestInfo, Token);
// validate the creates main tables
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_F4SDAnalyticsMainTables", out Query))
return false;
n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n > 0)
{
DoProcessUiMessage(2, $"the main tables were created successfull.");
DoProcessUiMessage(0, "");
return true;
}
DoProcessUiMessage(2, "An error occurred when creating the main tables.");
}
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the main tables aborted with an exceptional error.");
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private async Task<bool> ValidateF4SDAnalyticsFunctionsAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool ForceCreate)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
// validate the functions
DoProcessUiMessage(1, $"start validating the functions...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_F4SDAnalyticsFunctions", out var Query))
return false;
var n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n > 0)
{
DoProcessUiMessage(1, $"the validation of the functions finished successful.");
DoProcessUiMessage(0, "");
return true;
}
if (!ForceCreate && n < 1)
{
DoProcessUiMessage(2, $"the functions are not complete...");
return false;
}
if (ForceCreate)
{
// create the functions
DoProcessUiMessage(2, $"the functions are not complete, creating them...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Create_F4SDAnalyticsFunctions", out Query))
return false;
await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, null, requestInfo, Token);
// validate the creates functions
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_F4SDAnalyticsFunctions", out Query))
return false;
n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n > 0)
{
DoProcessUiMessage(2, $"the functions were created successfull.");
DoProcessUiMessage(0, "");
return true;
}
DoProcessUiMessage(2, "An error occurred when creating the functions.");
}
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the funtions aborted with an exceptional error.");
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private async Task<bool> ValidateF4SDAnalyticsViewsAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool ForceCreate)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
// validate the view tables
DoProcessUiMessage(1, $"start validating the view tables...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_F4SDAnalyticsViews", out var Query))
return false;
var n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n > 0)
{
DoProcessUiMessage(1, $"the validation of the view tables finished successful.");
DoProcessUiMessage(0, "");
return true;
}
if (!ForceCreate && n < 1)
{
DoProcessUiMessage(2, $"the view tables are not complete...");
return false;
}
if (ForceCreate)
{
// create the view tables
DoProcessUiMessage(2, $"the view tables are not complete, creating them...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Create_F4SDAnalyticsViews", out Query))
return false;
Query.Query = Query.Query.Replace("$DatabaseHistory$", InfrastructureConfig.HistoryDB.Connection.Database);
await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, null, requestInfo, Token);
// validate the creates view tables
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Validate_F4SDAnalyticsViews", out Query))
return false;
n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n > 0)
{
DoProcessUiMessage(2, $"the view tables were created successfull.");
return true;
}
DoProcessUiMessage(2, "An error occurred when creating the view tables.");
}
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the view tables aborted with an exceptional error.");
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private async Task<bool> UpdateF4SDAnalyticsMainTablesAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool ForceCreate)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
// validate the main tables
DoProcessUiMessage(1, $"start update the main tables...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Update_F4SDAnalyticsMainTables", out var Query))
return false;
var n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, Query, null, requestInfo, Token);
if (n == 0)
{
DoProcessUiMessage(1, $"the update of the main tables was successfull, nothing updated.");
return true;
}
if (n > 0)
{
DoProcessUiMessage(1, $"the update of the main tables finished successful.");
DoProcessUiMessage(0, "");
return true;
}
else
{
DoProcessUiMessage(2, $"the main tables could not be updated.");
LogEntry($"the main tables could not be updated.", LogLevels.Fatal);
return false;
}
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the main tables aborted with an exceptional error.");
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private async Task<bool> UpdateF4SDAnalyticsViewsAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool ForceCreate)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
// validate the main tables
DoProcessUiMessage(1, $"start update the views...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("Update_F4SDAnalyticsViews", out var Query))
return false;
Query.Query = Query.Query.Replace("$DatabaseHistory$", InfrastructureConfig.HistoryDB.Connection.Database);
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, null, requestInfo, Token);
if (n != null)
{
DoProcessUiMessage(1, $"the update of the view tables finished successful.");
DoProcessUiMessage(0, "");
return true;
}
DoProcessUiMessage(1, $"the view tables could not be updated.");
return false;
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the update of the views aborted with an exceptional error.");
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private async Task<Version> GetDatabaseTableVersion(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("GetDbTablesVersion", out var Query))
return null;
int apiError = 0;
try
{
using (var Reader = await DataHistorySqlHelper.GetDataReaderAsync(DbConn, Query, null, Token))
{
if (Reader != null)
try
{
if (Reader.HasRows)
{
if (await Reader.ReadAsync())
{
try
{
var iVersion = Reader.GetInt32(0);
var iRevision = Reader.GetInt32(1);
var RetVal = new Version(iVersion, iRevision);
return RetVal;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, "", apiError, requestInfo?.requestName);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task InsertDbVersionAsync(cDbConnection DbConn, Version version, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateDbVersion", out var Query))
return;
var Params = new Dictionary<string, object>(2) { { "version", version.Major }, { "revision", version.Minor } };
await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, Params, requestInfo, Token);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
private async Task<bool> ValidatePostUpdates(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
// get the actual db table version
var currentVersion = await GetDatabaseTableVersion(DbConn, requestInfo, LogDeep + 1, Token);
// get all db table updates not done
var Updates = new SortedList<Version, cDbQuery>();
foreach (var Entry in DataHistorySqlHelper.wellDefinedSqlStatements.Values)
{
const string constUpdateName = "UpdateDbTablesV";
if (Entry.Name.StartsWith(constUpdateName))
{
var strVersion = Entry.Name.Remove(0, constUpdateName.Length);
if (Version.TryParse(strVersion, out var entryVersion))
if (entryVersion > currentVersion)
Updates.Add(entryVersion, Entry);
}
}
// do the updates
var IsOk = true;
foreach (var updateQuery in Updates)
{
var n = await DataHistorySqlHelper.GetScalarResultAsync<int>(DbConn, updateQuery.Value, null, requestInfo, Token);
if (n == 0)
{
DoProcessUiMessage(1, $"the validation of the post update V{updateQuery.Key} was successfull, nothing updated.");
await InsertDbVersionAsync(DbConn, updateQuery.Key, requestInfo, LogDeep + 1, Token);
}
else if (n > 0)
{
DoProcessUiMessage(1, $"{n} updates where processed by post update V{updateQuery.Key}.");
}
else
{
LogEntry($"the post update V01 is not successful.", LogLevels.Fatal);
IsOk = false;
}
}
if (IsOk)
return true;
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the post updates aborted with an exceptional error.");
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
LogEntry($"the post updates could not be validated sucessfull.", LogLevels.Fatal);
return false;
}
private async Task ValidateAgentApiConnection()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
const int maxRetryCount = 3;
TimeSpan delay = TimeSpan.FromSeconds(5);
bool loggedInToAgentApi = false;
for (int i = 0; i < maxRetryCount; i++)
{
loggedInToAgentApi = await F4sdAgent.LogonToAgentApiAsync();
if (loggedInToAgentApi)
break;
LogEntry("Logon to agent API failed.", LogLevels.Warning);
await Task.Delay(delay);
}
if (!loggedInToAgentApi)
{
DoProcessUiMessage(0, $"ERROR: Could not connect to the F4SD Agent API. Maybe there are invalid credentials configured.", LogLevels.Error);
return;
}
var _remoteScript = await F4sdAgent.GetRemoteScriptsAsync();
if (_remoteScript == null)
{
DoProcessUiMessage(0, $"ERROR: Retrieve remote scripts from Agent API.", LogLevels.Error);
return;
}
DoProcessUiMessage(0, $"Successful connection to the F4SD Agent API established. {_remoteScript.Count} remote scripts found.", LogLevels.Info);
}
catch (Exception E)
{
DoProcessUiMessage(0, $"ERROR: Unknown error while validating Agent API.", LogLevels.Error);
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<bool> ValidateHistoryDatabasesAsync(bool isWebservice, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
var RetVal = true;
var DbName = InfrastructureConfig.HistoryDB.Connection.Database;
try
{
DoProcessUiMessage(0, $"start validating the data history database '{DbName}'...");
DoProcessUiMessage(0, "");
await ValidateDatabaseAsync(requestInfo, LogDeep + 1, Token);
if (Token.IsCancellationRequested) return false;
using (var DbConn = new cDbConnection(mainDbConnection, Timeout: 3 * 60 * 60))
{
if (!DbConn.IsOpen)
return false;
//DoProcessUiMessage(0, "");
//RetVal = await ValidateMainTablesAsync(DbConn, requestInfo, LogDeep + 1, Token);
//if (Token.IsCancellationRequested || !RetVal) return false;
DoProcessUiMessage(0, "");
foreach (var Connector in GetConnectors())
{
RetVal = await Connector.ValidateMainTablesAsync(DbConn, requestInfo, LogDeep + 1, Token);
if (Token.IsCancellationRequested || !RetVal) return false;
DoProcessUiMessage(0, "");
}
RetVal = await ValidatePostUpdates(DbConn, requestInfo, LogDeep + 1, Token);
DoProcessUiMessage(0, "");
var _Ok = true;
// check the existance of the tables and create them
foreach (var DbTable in ClusterConfig.Tables.Values)
{
if (DbTable.IsVirtual && DbTable.Cached != eDataHistoryTableCached.Yes)
continue;
_Ok &= await ValidateDbTableAsync(DbConn, DbTable, requestInfo, LogDeep + 1, Token);
}
// check the table references and create them
var lst = "";
foreach (var DbTable in ClusterConfig.Tables.Values)
{
if (DbTable.IsVirtual && DbTable.Cached != eDataHistoryTableCached.Yes)
continue;
var _sqlRefs = await DataHistorySqlHelper.GetTableReferences(DbConn.Connection, DbTable.SourceName, Token);
if (DbTable.HasScanId)
{
lst += DbTable.Name + "\n";
_Ok &= await ValidateDbTableReferenceScanHistoryAsync(DbConn, DbTable, _sqlRefs, requestInfo, LogDeep + 1, Token);
}
foreach (var Ref in DbTable.References.Values)
_Ok &= await ValidateDbTableReferencesAsync(DbConn, DbTable, Ref, _sqlRefs, requestInfo, LogDeep + 1, Token);
}
if (Token.IsCancellationRequested || !RetVal) return false;
await LoadGloablConfigValuesAsync(DbConn, requestInfo, LogDeep + 1, Token);
if (isWebservice)
await TokenCache.LoadAsync(DbConn, Token, requestInfo, LogDeep + 1);
}
DoProcessUiMessage(0, $"the validation of the data history database '{DbName}' finished.");
if (!await F4sdAgent.CheckAndInitializeDbAccess(requestInfo, LogDeep + 1, CancellationToken.None))
{
DoProcessUiMessage(0, $"Could not initialize the F4SD agent database correctly '{InfrastructureConfig.ClientAgent.Organization}'.");
return false;
}
await ValidateAgentApiConnection();
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the data history database '{DbName}' aborted with an exceptional error.");
RetVal = false;
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
private async Task<bool> ValidateDbTableAsync(cDbConnection DbConn, cDataHistoryConfigTable DbTable, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var _TableExist = await DataHistorySqlHelper.CheckIfTableExistAsync(DbConn.Connection, DbTable.SourceName, requestInfo, LogDeep + 1);
if (_TableExist)
LogEntry($"The database '{DbTable.SourceName}' already exist.", LogLevels.Debug);
else
{
LogEntry($"The database '{DbTable.SourceName}' does not exist, creating it...", LogLevels.Debug);
var Query = DataHistorySqlHelper.GetSqlCreateStatement(DbTable, cDataHistoryConfigClusters.confUseBinValuesAsPrimaryKey, true);
var _startTime2 = DateTime.UtcNow;
var CRes = await DataHistorySqlHelper.ExecuteAsync(DbConn.Connection, Query, null, Token);
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry("ValidateDbTableAsync.CreateTable", _startTime2, DbTable.SourceName, 0, requestInfo?.requestName);
}
// validate & create additional table columns
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("CheckAndCreateTableColumn", out var Query2))
return false;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("CheckScanIdTableColumn", out var QueryScanId))
return false;
bool ColumnCreated = false;
foreach (var Column in DbTable.Columns.Values)
{
try
{
var strNull = "NULL";
if (!DbTable.IsNullable(Column))
strNull = "NOT " + strNull;
var strQuery = string.Format(Query2.Query, DbTable.SourceName, Column.Name, Column.SqlType, strNull);
var _startTime2 = DateTime.UtcNow;
var RV = await DataHistorySqlHelper.GetScalarResultAsync<int?>(DbConn.Connection, strQuery, null, Token);
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query2.Name, _startTime2, DbTable.SourceName + "." + Column.Name, 0, requestInfo?.requestName);
if (RV == 1)
ColumnCreated = true;
if (Column.SqlTypeBin != null)
{
strQuery = string.Format(Query2.Query, DbTable.SourceName, Column.Name + DataHistorySqlHelper.constBinValueNameAdd, Column.SqlTypeBin, strNull);
_startTime2 = DateTime.UtcNow;
RV = await DataHistorySqlHelper.GetScalarResultAsync<int?>(DbConn.Connection, strQuery, null, Token);
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query2.Name, _startTime2, DbTable.SourceName + "." + Column.Name + DataHistorySqlHelper.constBinValueNameAdd, 0, requestInfo?.requestName);
if (RV == 1)
ColumnCreated = true;
}
}
catch (Exception E)
{
LogException(E);
}
}
var strQueryScanId = string.Format(QueryScanId.Query, DbTable.SourceName);
var _startTime3 = DateTime.UtcNow;
var _n = await DataHistorySqlHelper.GetScalarResultAsync<int?>(DbConn.Connection, strQueryScanId, null, Token);
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(QueryScanId.Name, _startTime3, DbTable.SourceName, 0, requestInfo?.requestName);
DbTable.HasScanId = _n == 1;
if (ColumnCreated)
{
var isOk = await Connectors[DbTable.ParentCluster.Origin].ColumnUpatePostProcessingAsync(DbConn, requestInfo, LogDeep + 1, Token);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private async Task<bool> ValidateDbTableReferenceScanHistoryAsync(cDbConnection DbConn, cDataHistoryConfigTable DbTable, Dictionary<string, cSqlReferenceInfo> _sqlRefs, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
if (DbTable.Type != eDataHistoryTableType.Events && DbTable.Type != eDataHistoryTableType.History)
return true;
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (_sqlRefs.ContainsKey($"FK_{DbTable.SourceName}_scan-history"))
return true;
var sqlCmd = $"ALTER TABLE [{DbTable.SourceName}] WITH CHECK ADD CONSTRAINT [FK_{DbTable.SourceName}_scan-history] FOREIGN KEY([ScanId]) REFERENCES [main-scan-history] ([ScanId]) ON DELETE CASCADE;";
var _Res = await DataHistorySqlHelper.ExecuteAsync(DbConn.Connection, sqlCmd, null, Token);
return (_Res == -1);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry("ValidateDbTableReferenceScanHistoryAsync", _startTime, "DbTable.SourceName", 0, requestInfo?.requestName);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private async Task<bool> ValidateDbTableReferencesAsync(cDbConnection DbConn, cDataHistoryConfigTable DbTable, cDataHistoryConfigTableReferenceInfo Ref, Dictionary<string, cSqlReferenceInfo> _sqlRefs, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var RetVal = true;
var _RefName = DataHistorySqlHelper.GetReferencingName(DbTable, Ref);
var _exists = false;
foreach (var _refInfo in _sqlRefs.Values)
{
if (_refInfo.Name == _RefName)
{
_exists = true;
break;
}
}
if (!_exists)
{
var _Query = DataHistorySqlHelper.GetReferencingStatements(DbTable, Ref);
var _Res = await DataHistorySqlHelper.ExecuteAsync(DbConn.Connection, _Query, null, Token);
if (_Res != -1)
RetVal = false;
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry("ValidateDbTableReferencesAsync", _startTime, "DbTable.SourceName", 0, requestInfo?.requestName);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public async Task<bool> ValidateAgentDbUpdates(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var cmdList = DataHistorySqlHelper.wellDefinedSqlStatements.Where(v => v.Key.StartsWith("AgentDbUpdate")).ToDictionary(v => v.Key, v => v.Value);
var cmdSorted = new SortedList<string, cDbQuery>(cmdList);
DoProcessUiMessage(0, "");
DoProcessUiMessage(0, "Start validating Agent DB");
using (var DbConn = new cDbConnection(this.InfrastructureConfig.ClientAgent.Connection, Timeout: 3 * 60 * 60))
{
foreach (var DbCmd in cmdSorted.Values)
{
try
{
if (String.IsNullOrWhiteSpace(DbCmd.Description))
DoProcessUiMessage(1, $"Processing SQL query {DbCmd.Name}...");
else
DoProcessUiMessage(1, DbCmd.Description + "...");
var resInt = await DataHistorySqlHelper.ExecuteAsync(DbConn, DbCmd, null, requestInfo, Token, Timeout: 3 * 60 * 60);
DoProcessUiMessage(2, $"...finished.");
}
catch (Exception E)
{
LogException(E);
}
}
}
DoProcessUiMessage(0, "Validating Agent DB finished.");
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public async Task<bool> ValidateF4SDAnalyticsDBAsync(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool ForceCreate = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
var RetVal = true;
F4SDAnalyticsValid = false;
var DbConnection = InfrastructureConfig.F4SDAnalyticsDB?.Connection;
if (DbConnection == null)
return false;
try
{
DoProcessUiMessage(0, "");
DoProcessUiMessage(0, $"start validating the data '{DbConnection.Database}' database...");
var isValid = await ValidateF4SDAnalyticsDatabaseAsync(Token, requestInfo, LogDeep + 1, ForceCreate);
if (!isValid)
{
DoProcessUiMessage(0, "");
DoProcessUiMessage(0, $"the validation of the data database '{DbConnection.Database}' finished.");
return false;
}
if (Token.IsCancellationRequested) return false;
using (var DbConn = new cDbConnection(DbConnection, Timeout: 3 * 60 * 60))
{
if (!DbConn.IsOpen)
{
return false;
}
DoProcessUiMessage(0, "");
RetVal = await ValidateF4SDAnalyticsMainTablesAsync(DbConn, requestInfo, LogDeep + 1, Token, ForceCreate);
if (Token.IsCancellationRequested || !RetVal)
{
return false;
}
RetVal = await ValidateF4SDAnalyticsFunctionsAsync(DbConn, requestInfo, LogDeep + 1, Token, ForceCreate);
if (Token.IsCancellationRequested || !RetVal)
{
return false;
}
RetVal = await ValidateF4SDAnalyticsViewsAsync(DbConn, requestInfo, LogDeep + 1, Token, ForceCreate);
if (Token.IsCancellationRequested || !RetVal)
{
return false;
}
RetVal = await UpdateF4SDAnalyticsViewsAsync(DbConn, requestInfo, LogDeep + 1, Token, ForceCreate);
if (Token.IsCancellationRequested || !RetVal)
{
return false;
}
DoProcessUiMessage(0, "");
F4SDAnalyticsValid = true;
F4SDAnalyticsDb = InfrastructureConfig.F4SDAnalyticsDB;
}
DoProcessUiMessage(0, $"the validation of the data analytics database '{DbConnection.Database}' finished.");
}
catch (Exception E)
{
DoProcessUiMessage(1, $"the validation of the data analytics database '{DbConnection.Database}' aborted with an exceptional error.");
RetVal = false;
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
public async void CheckSessionsAsync(object sender, System.Timers.ElapsedEventArgs e)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var currentTimeStamp = DateTime.UtcNow;
var _toClose = new List<cF4SDUserSessionParameters>();
lock (SessionValues)
{
foreach (var v in SessionValues)
{
var diff = (int)currentTimeStamp.Subtract(SessionValues[v.Key]).TotalMinutes;
if (diff >= F4SDAnalyticsDb.SessionTimeout)
{
var userSessions = new cF4SDUserSessionParameters();
userSessions.SessionId = v.Key;
userSessions.SessionDate = currentTimeStamp;
_toClose.Add(userSessions);
}
}
}
foreach (var s in _toClose)
{
var _requestInfo = new cF4sdWebRequestInfo("CheckSessionsAsync", s.SessionId.ToString());
await CloseUserSessionAsync(s, _requestInfo, 1, CancellationToken.None);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public async void CheckCasesAsync(object sender, System.Timers.ElapsedEventArgs e)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var requestInfo = new cF4sdWebRequestInfo("CheckCasesAsync", null);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceStart(0, requestInfo.requestName, requestInfo.id, requestInfo.created); }
var apiError = 0;
try
{
var currentTimeStamp = DateTime.UtcNow;
var _toClose = new List<cF4SDCaseTimeParameters>();
lock (CaseValues)
{
foreach (var v in CaseValues)
{
var diff = (int)currentTimeStamp.Subtract(CaseValues[v.Key]).TotalMinutes;
if (diff > F4SDAnalyticsDb.CaseTimeout)
{
var caseData = new cF4SDCaseTimeParameters();
caseData.CaseId = v.Key;
caseData.StatusId = CaseStatus.Canceled;
_toClose.Add(caseData);
}
}
}
foreach (var s in _toClose)
{
var requestInfo2 = new cF4sdWebRequestInfo("CheckCasesAsync", s.CaseId?.ToString());
await UpdateCaseStateAsync(s, requestInfo2, 1, CancellationToken.None);
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(0, requestInfo.requestName, requestInfo.id, requestInfo.created, requestInfo.created, ErrorCode: apiError); }
if (CM != null) LogMethodEnd(CM);
}
}
private async Task LoadGloablConfigValuesAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
DoProcessUiMessage(1, $"start loading database config values...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("GetConfigValues", out var Query))
return;
GlobalConfigValues.Clear();
int apiError = 0;
try
{
using (var _reader = await DataHistorySqlHelper.GetDataReaderAsync(DbConn, Query, null, Token))
{
if (_reader != null)
try
{
if (_reader.HasRows)
{
while (await _reader.ReadAsync())
{
try
{
var Key = _reader.GetString(0);
var Value = _reader.GetString(1);
GlobalConfigValues[Key] = Value;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
if (Token.IsCancellationRequested)
return;
}
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, "", apiError, requestInfo?.requestName);
}
await GetSecTokenKeyAsync(DbConn, requestInfo, LogDeep + 1, Token);
DoProcessUiMessage(1, "loading database config values finished.");
DoProcessUiMessage(0, "");
}
catch (Exception E)
{
DoProcessUiMessage(1, $"loading global configuraton aborted with an exceptional error.");
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
private async Task GetSecTokenKeyAsync(cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (GlobalConfigValues.TryGetValue("Security.AccessTokenKey", out var _encKey))
{
var _sec = cSecurePassword.Instance.Decode(_encKey);
BearerSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_sec));
}
else
{
var _sec = Guid.NewGuid().ToString() + Guid.NewGuid().ToString() + Guid.NewGuid().ToString() + Guid.NewGuid().ToString();
_sec = _sec.Replace("-", "");
BearerSecurityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_sec));
_sec = cSecurePassword.Instance.Encode(_sec);
await UpdateConfigValueAsync("Security.AccessTokenKey", _sec, DbConn, requestInfo, LogDeep + 1, Token);
}
JwtTokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = JwtTokenIssuer,
ValidAudience = JwtTokenAudience,
IssuerSigningKey = BearerSecurityKey
};
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public string GenerateJsonWebToken(cF4sdUserInfo UserInfo)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (BearerSecurityKey == null)
return null;
var credentials = new SigningCredentials(BearerSecurityKey, SecurityAlgorithms.HmacSha256);
var claims = new List<Claim> {
new Claim(JwtRegisteredClaimNames.NameId, UserInfo.Id.ToString()),
new Claim(JwtRegisteredClaimNames.UniqueName, UserInfo.Name),
new Claim(JwtRegisteredClaimNames.AuthTime, UserInfo.LogonTime.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'z'")),
new Claim("login_method", UserInfo.AccountType.ToString()),
new Claim("login_account", UserInfo.AdAccount.ToString()),
new Claim("account_sid", UserInfo.AdSid),
new Claim("language", UserInfo.Language ?? "")
};
if (UserInfo.Roles?.Count > 0)
foreach (var _roleEntry in UserInfo.Roles)
claims.Add(new Claim("roles", _roleEntry));
UserInfo.LogonTime = DateTime.UtcNow;
UserInfo.RenewUntil = UserInfo.LogonTime.AddMinutes(90);
UserInfo.ValidUntil = UserInfo.LogonTime.AddMinutes(120);
var token = new JwtSecurityToken(JwtTokenIssuer,
JwtTokenAudience,
claims,
notBefore: UserInfo.LogonTime.AddMinutes(-1),
expires: UserInfo.ValidUntil,
signingCredentials: credentials);
var retVal2 = JwtTokenHandler.WriteToken(token);
return retVal2;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task UpdateConfigValueAsync(string Key, string Value, cDbConnection DbConn, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateConfigValue", out var Query))
return;
var _params = new Dictionary<string, object>()
{
{ "Key", Key},
{ "Value", Value},
};
await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, _params, requestInfo, Token);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<bool> CreateCaseAsync(cF4SDCaseParameters Param, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var anonymous = InfrastructureConfig.F4SDAnalyticsDB?.AnonymousUser;
var DbConnection = InfrastructureConfig.F4SDAnalyticsDB?.Connection;
if (DbConnection == null)
return false;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("CreateCase", out var Query))
return false;
using (var DbConn = new cDbConnection(DbConnection))
if (DbConn.IsOpen)
{
if (anonymous != null && (bool)anonymous)
{
Param.UserId = GetUserHashGuid((Guid)Param.UserId);
}
if (Param.SessionId != null && Param.SessionId != Guid.Empty)
{
if (Param.CaseId != null && Param.CaseId != Guid.Empty)
{
var Params = new Dictionary<string, object>() { { "SessionId", Param.SessionId }, { "CaseId", Param.CaseId }, { "UserId", Param.UserId } };
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
DoProcessUiMessage(2, $"Case is started. CaseId: " + Param.CaseId.ToString(), LogLevels.Debug);
lock (CaseValues)
CaseValues.Add((Guid)Param.CaseId, DateTime.UtcNow);
return true;
}
DoProcessUiMessage(2, $"the insert of the Case-data into F4SDAnalytics database with exception error.", LogLevels.Warning);
return false;
}
DoProcessUiMessage(2, $"API Call - CreateCase Invalid CaseId: 00000000-0000-0000-0000-000000000000 of the Case-data into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
DoProcessUiMessage(2, $"API Call - CreateCase - Invalid SessionId: 00000000-0000-0000-0000-000000000000 of the Case-data into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
return false;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<bool> UpdateCaseStateAsync(cF4SDCaseTimeParameters Param, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var DbConnection = InfrastructureConfig.F4SDAnalyticsDB?.Connection;
if (DbConnection == null)
return false;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateCaseState", out var Query))
return false;
using (var DbConn = new cDbConnection(DbConnection))
if (DbConn.IsOpen)
{
if (Param.CaseId != null && Param.CaseId != Guid.Empty)
{
XElement ParamState = null;
if (Param.CaseTimes != null && Param.CaseTimes.Count > 0)
{
ParamState = new XElement("Root",
from prm in Param.CaseTimes
select new XElement("Item",
new XElement("StatusId", (int)prm.StatusId),
new XElement("TimeStamp", prm.CaseTime)
));
}
var Params = new Dictionary<string, object>() { { "CaseId", Param.CaseId }, { "StatusId", Param.StatusId }, { "ActiveTime", Param.ActiveTime }, { "StatusXML", ParamState?.ToString() ?? String.Empty } };
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
if (Param.StatusId == CaseStatus.Canceled || Param.StatusId == CaseStatus.Finished)
{
DoProcessUiMessage(2, $"Case is closed. CaseId: " + Param.CaseId.ToString(), LogLevels.Debug);
lock (CaseValues)
CaseValues.Remove((Guid)Param.CaseId);
}
return true;
}
DoProcessUiMessage(2, $"Current CaseId: " + Param.CaseId.ToString() + " could not be found", LogLevels.Debug);
return false;
}
DoProcessUiMessage(2, $"API Call UpdateCaseState - Invalid CaseId: 00000000-0000-0000-0000-000000000000 of the Case-data into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
return false;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<bool> ReportQuickActionExecutionAsync(cF4SDQuickActionParameters Param, cDataHistoryConfigSqlConnection DBConnection, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (DBConnection != null && DBConnection.Database == InfrastructureConfig.F4SDAnalyticsDB?.Connection.Database
&& DataHistorySqlHelper.GetWellKnownSqlStatement("AnalyticsReportQuickActionExecution", out var Query))
{
using (var DbConn = new cDbConnection(DBConnection))
if (DbConn.IsOpen)
{
if (Param.CaseId != null && Param.CaseId != Guid.Empty)
{
var Params = new Dictionary<string, object>() { { "CaseId", Param.CaseId }, { "QActionId", Param.QuickActionId },
{ "DeviceId", Param.DeviceId },
{ "Start", Param.Start }, { "Finish", Param.Finish },
{ "Parameters", Param.Paramaters }, { "Result", Param.Result },
{ "ErrorCode", Param.ErrorCode }, { "ErrorDescription", Param.ErrorDescription },
{ "ExecutionType", Param.ExecutionType.ToString() },{ "ResultType", Param.ResultType.ToString() }};
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
return true;
}
DoProcessUiMessage(2, $"the insert of the QuickActionExecution-data into F4SDAnalytics database with exception error.", LogLevels.Warning);
return false;
}
DoProcessUiMessage(2, $"API Call ReportQuickActionExecution - Invalid CaseId: 00000000-0000-0000-0000-000000000000 of the QuickActionExecution-data into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
}
if (DBConnection != null && DBConnection.Database == InfrastructureConfig.HistoryDB.Connection.Database
&& DataHistorySqlHelper.GetWellKnownSqlStatement("ReportQuickActionExecution", out var Query2))
{
using (var DbConn = new cDbConnection(DBConnection))
if (DbConn.IsOpen)
{
var Params = new Dictionary<string, object>() { { "UserId", Param.UserId }, { "QActionId", Param.QuickActionId },
{ "DeviceId", Param.DeviceId },{ "QActionName", Param.QuickActionName },
{ "Start", Param.Start }, { "Finish", Param.Finish },
{ "Parameters", Param.Paramaters }, { "Result", Param.Result },
{ "ErrorCode", Param.ErrorCode }, { "ErrorDescription", Param.ErrorDescription },
{ "ExecutionType", Param.ExecutionType.ToString() },{ "ResultType", Param.ResultType.ToString() }};
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query2, Params, requestInfo, Token);
if (n >= 1)
{
return true;
}
DoProcessUiMessage(2, $"the insert of the QuickActionExecution-data into History database with exception error.");
return false;
}
}
return false;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<bool> CreateUserSessionAsync(cF4SDUserSessionParameters Param, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var anonymous = InfrastructureConfig.F4SDAnalyticsDB?.AnonymousUser;
var DbConnection = InfrastructureConfig.F4SDAnalyticsDB?.Connection;
if (anonymous != null && (bool)anonymous)
{
Param.UserId = GetUserHashGuid((Guid)Param.UserId);
}
if (DbConnection == null)
return false;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("CreateUserSession", out var Query))
return false;
using (var DbConn = new cDbConnection(DbConnection))
if (DbConn.IsOpen)
{
if (Param.SessionId != null && Param.SessionId != Guid.Empty)
{
var Params = new Dictionary<string, object>() { { "SessionId", Param.SessionId }, { "UserId", Param.UserId }, { "SessionDate", Param.SessionDate } };
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
DoProcessUiMessage(2, $"Session is started. SessionId: " + Param.SessionId.ToString(), LogLevels.Debug);
lock (SessionValues)
SessionValues[(Guid)Param.SessionId] = DateTime.UtcNow;
return true;
}
DoProcessUiMessage(2, $"the insert of the Usersession-data into F4SDAnalytics database with exception error.", LogLevels.Warning);
return false;
}
DoProcessUiMessage(2, $"API Call CreateUserSession - Invalid SessionId: 00000000-0000-0000-0000-000000000000 of the Usersession-data into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
return false;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public async Task<bool> CloseUserSessionAsync(cF4SDUserSessionParameters Param, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var DbConnection = InfrastructureConfig.F4SDAnalyticsDB?.Connection;
if (DbConnection == null)
return false;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("CloseUserSession", out var Query))
return false;
using (var DbConn = new cDbConnection(DbConnection))
if (DbConn.IsOpen)
{
if (Param.SessionId != null && Param.SessionId != Guid.Empty)
{
var Params = new Dictionary<string, object>() { { "SessionId", Param.SessionId }, { "SessionDate", Param.SessionDate } };
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
DoProcessUiMessage(2, $"Session is closed. SessionId: " + Param.SessionId.ToString(), LogLevels.Debug);
lock (SessionValues)
SessionValues.Remove((Guid)Param.SessionId);
return true;
}
DoProcessUiMessage(2, $"the update of the Usersession-data into F4SDAnalytics database with exception error.", LogLevels.Warning);
if (cLogManager.DefaultLogger.IsDebug)
{
var _msg = new List<string>()
{
$"query: {Query}",
$"session id: {Param.SessionId}",
$"session date: {Param.SessionDate}",
};
cLogManager.DefaultLogger.LogList(LogLevels.Debug, _msg);
}
return false;
}
DoProcessUiMessage(2, $"API Call CreateUserSession - Invalid SessionId: 00000000-0000-0000-0000-000000000000 of the Usersession-data into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
return false;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<bool> UpdateCaseAsync(Guid CaseId, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var DbConnection = InfrastructureConfig.F4SDAnalyticsDB?.Connection;
if (DbConnection == null)
return false;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateCases", out var Query))
return false;
using (var DbConn = new cDbConnection(DbConnection))
if (DbConn.IsOpen)
{
if (CaseId != null && CaseId != Guid.Empty)
{
var Params = new Dictionary<string, object>() { { "CaseId", CaseId } };
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
DoProcessUiMessage(2, $"Casestatus is updated. CaseId: " + CaseId.ToString(), LogLevels.Debug);
lock (CaseValues)
CaseValues.Add(CaseId, DateTime.UtcNow);
return true;
}
DoProcessUiMessage(2, $"the update of the CaseStatus with CaseId '{CaseId}' into F4SDAnalytics database returned no legal update count ({n}).", LogLevels.Warning);
return false;
}
DoProcessUiMessage(2, $"API Call KeepAliveCase - Invalid CaseId: 00000000-0000-0000-0000-000000000000 to update of the CaseStatus into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
return false;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<bool> ReportTicketAsync(cApiM42Ticket Param, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var anonymous = InfrastructureConfig.F4SDAnalyticsDB?.AnonymousUser;
Guid.TryParse(requestInfo.userInfo?.Id.ToString(), out Guid userGuid);
if (anonymous != null && (bool)anonymous)
Param.User = GetUserHashGuid(userGuid).ToString();
else
Param.User = userGuid.ToString();
var DbConnection = InfrastructureConfig.F4SDAnalyticsDB?.Connection;
if (DbConnection == null)
return false;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("InsertTicket", out var Query))
return false;
using (var DbConn = new cDbConnection(DbConnection))
if (DbConn.IsOpen)
{
if (Param.Ticket != null && Param.Ticket != Guid.Empty)
{
if (Param.CaseId != null && Param.CaseId != Guid.Empty)
{
var startTime = Param.workTimes.FirstOrDefault(x => x.Key == "StartTime").Value;
var endTime = Param.workTimes.FirstOrDefault(x => x.Key == "EndTime").Value;
var workingTime = Param.workTimes.FirstOrDefault(x => x.Key == "NettoWorkingTime").Value;
var Params = new Dictionary<string, object>() { { "TicketId", Param.Ticket }, { "Status", Param.StatusIdValue }, { "CaseId", Param.CaseId }, { "UserId", Param.User }, { "Start", startTime }, { "Finish", endTime }, { "ActiveTime", workingTime } };
var n = await DataHistorySqlHelper.ExecuteAsync(DbConn, Query, Params, requestInfo, Token);
if (n >= 1)
{
DoProcessUiMessage(2, $"Ticket-Data is saved . TicketNumber: " + Param.Ticket, LogLevels.Debug);
lock (CaseValues)
CaseValues.Add((Guid)Param.CaseId, DateTime.UtcNow);
return true;
}
DoProcessUiMessage(2, $"the insert of the Ticket-data into F4SDAnalytics database with exception error.", LogLevels.Warning);
return false;
}
DoProcessUiMessage(2, $"API Call - InsertTicket Invalid CaseId: 00000000-0000-0000-0000-000000000000 of the Ticket-data into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
DoProcessUiMessage(2, $"API Call - InsertTicket - Invalid TicketId: 00000000-0000-0000-0000-000000000000 of the Ticket-data into F4SDAnalytics database.", LogLevels.Warning);
return false;
}
return false;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public bool KeepAliveSession(Guid SessionId, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (SessionId != null && SessionId != Guid.Empty)
{
lock (SessionValues)
SessionValues[SessionId] = DateTime.UtcNow;
return true;
}
if (cLogManager.DefaultLogger.IsDebug) LogEntry($"API Call KeepAliveCase - Invalid CaseId: 00000000-0000-0000-0000-000000000000 ", LogLevels.Warning);
return false;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<bool> KeepAliveCase(Guid CaseId, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (CaseId != null && CaseId != Guid.Empty)
{
if (CaseValues.ContainsKey(CaseId))
{
lock (CaseValues)
CaseValues[CaseId] = DateTime.UtcNow;
}
else
{
await UpdateCaseAsync(CaseId, requestInfo, LogDeep + 1, Token);
}
return true;
}
if (cLogManager.DefaultLogger.IsDebug) LogEntry($"API Call KeepAliveCase - Invalid CaseId: 00000000-0000-0000-0000-000000000000 ", LogLevels.Warning);
return false;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public void DoProcessUiMessage(int Indent, string Message, LogLevels logLevel = LogLevels.Info)
{
try
{
var strIndent = new string(' ', Indent * 2);
cLogManager.DefaultLogger.LogEntry(logLevel, strIndent + Message);
ProcessUiMessage?.Invoke(cDataHistoryUiStatusMessage.Create(Indent, Message));
}
catch { }
}
public void DoProcessUiMessage(int Indent, cXmlParserNodeMessage Message)
{
DoProcessUiMessage(Indent, cXmlParser.GetMessageString(Message));
}
public void DoProcessUiMessage(int Indent, List<cXmlParserNodeMessage> Messages)
{
foreach (var Entry in Messages)
DoProcessUiMessage(Indent, Entry);
}
public void CleanupUiMessageHandler()
{
if (ProcessUiMessage != null)
{
foreach (var Entry in ProcessUiMessage.GetInvocationList())
try
{
ProcessUiMessage -= Entry as DataHistoryUiMessageFunc;
}
catch { }
ProcessUiMessage = null;
}
}
internal class cFasdApiSearchResultExt
{
internal cFasdApiSearchResultEntry Result = new cFasdApiSearchResultEntry();
internal string upn_internal = null;
internal int? IdAgent;
}
public class cUsageData
{
internal Int32 id;
internal Int64 duration;
internal DateTime lastEvent;
}
public async Task<cF4sdUserInfo> GetCurrentUserInfoAsync(CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var _user = WindowsIdentity.GetCurrent();
var _res = await GetWinUserInfoAsync(_user, CultureInfo.CurrentCulture.DisplayName, true, Token, requestInfo, LogDeep + 1);
return _res;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cF4sdUserInfo> GetWinUserInfoAsync(IIdentity Identity, string Language, bool justWinRoles, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (Identity == null)
return null;
if (!(Identity is WindowsIdentity _winUser))
{
LogEntry($"could not logon with specified identity due to incompatible authentication type (name={Identity.Name}, type={Identity.AuthenticationType}");
return null;
}
if (!_winUser.IsAuthenticated)
{
LogEntry($"the specified winuser is not authenticated (name={Identity.Name}, type={Identity.AuthenticationType}");
return null;
}
var _sid = _winUser.User.ToString();
var _retVal = new cF4sdUserInfo()
{
Id = Guid.Empty,
LogonTime = DateTime.UtcNow,
AccountType = cF4sdUserInfo.enumAccountType.AdUser,
AdAccount = _winUser.Name,
Name = _winUser.Name,
AdSid = _sid,
Language = Language
};
LogEntry($"The authenticated user is: name={Identity.Name}, type={Identity.AuthenticationType}");
bool IsEntraIdDevelop = false;
if (!justWinRoles)
{
if (!string.IsNullOrEmpty(_sid))
{
Dictionary<string, List<cFasdApiSearchResultExt>> _ids = null;
if (RunningInIISExpress)
{
// check if we are in EntraID develop mode (running in IIS Express and the user is an Entra ID User)
Guid azureId = Guid.Empty;
azureId = cDataHistoryCollectorActiveDirectory.ConvertAzureSidToGuid(_sid);
if (azureId != Guid.Empty)
_ids = await UserSearchByEntraIdDevelopAsync(azureId, Token, requestInfo, LogDeep + 1);
}
if (_ids == null || _ids.Count == 0)
_ids = await UserSearchBySidsAsync(new List<string> { _sid }, Token, requestInfo, LogDeep + 1);
else
IsEntraIdDevelop = true;
if (Token.IsCancellationRequested)
return null;
if (_ids?.Count > 0)
{
var _entry = _ids?.First().Value;
if (_entry?.Count > 0)
{
var _result = _entry.First().Result;
if (_result != null)
{
_retVal.Name = _result.Name;
_retVal.Id = _result.id;
}
}
}
}
if (_retVal.Id == Guid.Empty)
{
LogEntry($"Could not find user {_winUser.Name} with SID {_sid} for authentication in table 'main-user'.", LogLevels.Warning);
LogEntry($"Please check, if at least one of the defined AD user scan nodes contains this user.", LogLevels.Warning);
return null;
}
}
var _membershipGroups = InfrastructureConfig?.Authorisation?.MembershipGroups?.GroupsAd;
var _resMembershipGroups = new List<cF4SDMembershipGroup>();
if (IsEntraIdDevelop)
{
// if we are in EntraID develop mode, we have fake all ad group memberships
if (_membershipGroups != null)
foreach (var _entryDom in _membershipGroups.Values)
foreach (var _entryGroup in _entryDom.Values)
_resMembershipGroups.Add(_entryGroup);
}
else
{
var _dom = Domain.GetComputerDomain();
var _pc = new PrincipalContext(ContextType.Domain);
var _groups = _winUser.Groups;
var _msgLog = new List<string>();
if (cLogManager.DefaultLogger.IsDebug)
{
_msgLog.Add($"the winuser {_retVal.AdAccount} logged on");
_msgLog.Add($" is member of ad security groups:");
}
foreach (var _group in _groups)
{
if (Token.IsCancellationRequested)
return null;
if (_group is SecurityIdentifier _si)
{
cF4SDMembershipGroupAd _memGrp = null;
if (_membershipGroups != null)
foreach (var _entryDom in _membershipGroups.Values)
{
foreach (var _entryGroup in _entryDom.Values)
{
if (_si.Value == _entryGroup.SID)
{
_resMembershipGroups.Add(_entryGroup);
_memGrp = _entryGroup;
}
}
}
if (DefaultLogger.IsDebug)
{
try
{
var _gp = GroupPrincipal.FindByIdentity(_pc, IdentityType.Sid, _si.Value);
if (_gp != null)
{
if (_memGrp != null)
_msgLog.Add($" {_gp.SamAccountName} ({_gp.DistinguishedName}) is member of '{_memGrp.Name}'");
else
_msgLog.Add($" {_gp.SamAccountName} ({_gp.DistinguishedName})");
}
else
_msgLog.Add($" could not find group {_si.Value}");
}
catch (Exception E)
{
LogException(E);
}
}
}
}
if (cLogManager.DefaultLogger.IsDebug)
cLogManager.DefaultLogger.LogList(LogLevels.Debug, _msgLog);
}
if (_membershipGroups?.Count > 0)
AddRolesByMembership(_retVal, _resMembershipGroups);
if (Token.IsCancellationRequested)
return null;
if (!string.IsNullOrEmpty(_retVal.AdSid) && (M42WpmCollector != null))
await M42WpmCollector.AddM42UserInfosAsync(_retVal, Token, requestInfo, LogDeep + 1);
var _token = GenerateJsonWebToken(_retVal);
_retVal.Token = _token;
return _retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<Dictionary<string, List<cFasdApiSearchResultExt>>> searchSqlAsync(string strQuery, Dictionary<string, object> SqlParam, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep, string QueryName, string PhoneSearch = null, bool SupportCancellation = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
int apiError = 0;
try
{
if (strQuery == null)
return null;
using (var DbConn = new cDbConnection(mainDbConnection, Timeout: 10))
{
if (!DbConn.IsOpen)
return null;
using (var Reader = await DataHistorySqlHelper.GetTableResultAsync(DbConn.Connection, strQuery, SqlParam, Token, SupportCancellation: SupportCancellation))
{
var output = new Dictionary<string, List<cFasdApiSearchResultExt>>();
if (Reader != null)
try
{
if (Reader.HasRows)
{
var maxStateVal = Enum.GetValues(typeof(enumF4sdSearchResultStatus)).Cast<int>().Max<int>();
var minStateVal = Enum.GetValues(typeof(enumF4sdSearchResultStatus)).Cast<int>().Min<int>();
while (await Reader.ReadAsync(Token))
{
try
{
var Entry = new cFasdApiSearchResultExt();
var intType = Reader.GetInt32(0);
Entry.Result.Type = (enumF4sdSearchResultClass)intType;
Entry.upn_internal = Reader.IsDBNull(4) ? null : Reader.GetString(4);
Entry.IdAgent = Reader.IsDBNull(5) ? (int?)null : Reader.GetInt32(5);
var strName = Reader.GetString(1);
if (PhoneSearch != null && Entry.Result.Type == enumF4sdSearchResultClass.Phone) // phone type
{
string strPhone = null;
var strPh = Reader.IsDBNull(8) ? null : Reader.GetString(8);
if (strPh != null)
{
var arrPh = strPh.Split(' ');
foreach (var str in arrPh)
{
if (str.EndsWith(PhoneSearch))
{
strPhone = str;
break;
}
}
}
if (strPhone != null)
{
Entry.Result.Name = strName + " (" + strPhone + ")";
Entry.Result.DisplayName = strName + " (" + strPhone + ")";
}
else
{
Entry.Result.Name = strName;
Entry.Result.DisplayName = strName;
}
}
else
{
Entry.Result.Name = strName;
Entry.Result.DisplayName = strName;
}
Entry.Result.id = Reader.GetFieldValue<Guid>(2);
if (!Reader.IsDBNull(3))
{
var intStatus = Reader.GetInt32(3);
if (intStatus <= maxStateVal && intStatus >= minStateVal)
Entry.Result.Status = (enumF4sdSearchResultStatus)intStatus;
}
var account = Reader.IsDBNull(6) ? null : Reader.GetString(6);
var domain = Reader.IsDBNull(7) ? null : Reader.GetString(7);
Entry.Result.Infos = new Dictionary<string, string>(2)
{
{"account", account },
{"domain", domain },
};
if (output.TryGetValue(strName, out var lst))
{
lst.Add(Entry);
}
else
{
if (output.Count > 11)
break;
lst = new List<cFasdApiSearchResultExt> { Entry };
output.Add(strName, lst);
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
}
catch (Exception E)
{
if (!Token.IsCancellationRequested || !SupportCancellation)
cLogManager.DefaultLogger.LogException(E);
}
return output;
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(QueryName, _startTime, SqlParam, apiError, requestInfo?.requestName);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<Dictionary<string, List<cFasdApiSearchResultExt>>> searchStringAsync(string search, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep, string Field = null, bool Reverse = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var IsPhone = this.InfrastructureConfig.HistoryDB.SearchForPhoneNumbers && isDigits(search);
string strQuery = null;
if (Field == null)
{
if (IsPhone)
{
strQuery = "SearchFulltextRev";
Reverse = true;
}
else
#if SIMULATE_SLOW_SEARCH
strQuery = "SearchFulltextWithDelay";
#else
strQuery = "SearchFulltext";
#endif
}
else
{
if (Reverse)
strQuery = "SearchByFieldRev";
else
strQuery = "SearchByField";
}
var SqlParam = new Dictionary<string, object>();
if (Field == null || !Reverse)
{
var searchMask = $"\"{search}*\"";
SqlParam.Add("SEARCH", searchMask);
}
if (Reverse)
{
char[] arrRev = (search + 'x').ToArray();
Array.Reverse(arrRev);
var strRev = new string(arrRev);
strRev = $"\"{strRev}*\"";
SqlParam.Add("REV", strRev);
}
SqlParam.Add("DAYS", this.InfrastructureConfig.ClientAgent.MaxDeviceAge);
if (strQuery == null)
return null;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement(strQuery, out var Query))
return null;
strQuery = Query.Query;
if (Field != null)
strQuery = string.Format(strQuery, Field);
string strPhoneSearch = null;
if (IsPhone)
strPhoneSearch = search;
return await searchSqlAsync(strQuery, SqlParam, Token, requestInfo, LogDeep + 1, Query.Name, strPhoneSearch, true);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<Dictionary<string, List<cFasdApiSearchResultExt>>> searchComputerNameAsync(string search, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep, string Field = null, bool Reverse = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
string strQuery = "SearchComputerByName";
var SqlParam = new Dictionary<string, object>();
if (Field == null || !Reverse)
{
var searchMask = $"\'{search}%\'";
SqlParam.Add("name", search + "%");
}
if (!DataHistorySqlHelper.GetWellKnownSqlStatement(strQuery, out var Query))
return null;
strQuery = Query.Query;
if (Field != null)
strQuery = string.Format(strQuery, Field);
return await searchSqlAsync(strQuery, SqlParam, Token, requestInfo, LogDeep + 1, Query.Name, SupportCancellation: true);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<List<cFasdApiSearchResultEntry>> DefaultSearchAsync(string search, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
List<Task<bool>> taskList = new List<Task<bool>>();
var RetVal = new List<cFasdApiSearchResultEntry>();
var SearchWithLike = this.InfrastructureConfig.HistoryDB.SearchWithLike;
if (SearchWithLike)
{
var T1 = Task.Run(() => { return searchComputerNameAsync(search, Token, requestInfo, LogDeep + 1); });
var T2 = Task.Run(() => { return searchStringAsync(search, Token, requestInfo, LogDeep + 1); });
var output = await Task.WhenAll(T1, T2);
foreach (var Entry in output[0].Values)
{
if (Entry.Count == 1)
RetVal.Add(Entry[0].Result);
else if (Entry.Count > 1)
{
foreach (var Entry2 in Entry)
{
CompleteSearchEntry(Entry2);
RetVal.Add(Entry2.Result);
}
}
}
foreach (var Entry in output[1].Values)
{
if (RetVal.Count >= 11)
break;
bool alreadyExists = RetVal.Any(x => x.id == Entry[0].Result.id);
if (!alreadyExists)
{
if (Entry.Count == 1)
RetVal.Add(Entry[0].Result);
else if (Entry.Count > 1)
{
foreach (var Entry2 in Entry)
{
CompleteSearchEntry(Entry2);
RetVal.Add(Entry2.Result);
}
}
}
}
}
else
{
var output = await searchStringAsync(search, Token, requestInfo, LogDeep + 1);
foreach (var Entry in output.Values)
{
if (Entry.Count == 1)
RetVal.Add(Entry[0].Result);
else if (Entry.Count > 1)
{
foreach (var Entry2 in Entry)
{
CompleteSearchEntry(Entry2);
RetVal.Add(Entry2.Result);
}
}
}
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
internal cFasdApiSearchResultExt CompleteSearchEntry(cFasdApiSearchResultExt entry)
{
var strDomain = "";
if (entry.upn_internal != null)
{
var arr1 = entry.upn_internal.Split('@');
if (arr1.Length > 1)
{
var arr2 = arr1[1].Split('.');
if (arr2.Length > 0)
strDomain = arr2[0];
}
}
var strDead = "";
if (entry.IdAgent == null)
strDead = "⚠ ";
if (!string.IsNullOrEmpty(strDomain))
{
string c = strDomain[0].ToString().ToUpperInvariant();
strDomain = c + strDomain.Remove(0, 1);
entry.Result.Name += $" (" + strDead + strDomain + ")";
entry.Result.DisplayName += $" (" + strDead + strDomain + ")";
}
return entry;
}
public Guid? DetailedSearchStart(string search, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var cancellationToken = new CancellationTokenSource();
var _task = Task<cFasdApiSearchResultCollection>.Run(async () =>
{
return await DetailedSearchAsync(search, cancellationToken.Token, requestInfo, LogDeep);
});
var RetVal = cDataHistoryCollectorSearchTaskCache.AddTask(cancellationToken, _task);
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cFasdApiSearchResultCollection> DetailedSearchResultAsync(Guid taskID, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var _result = await cDataHistoryCollectorSearchTaskCache.GetResultAsync(taskID);
return _result;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cFasdApiSearchResultCollection> DetailedSearchAsync(string search, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var RetVal = new cFasdApiSearchResultCollection();
var SearchWithLike = this.InfrastructureConfig.HistoryDB.SearchWithLike;
if (SearchWithLike)
{
var T1 = Task.Run(() => { return searchComputerNameAsync(search, Token, requestInfo, LogDeep + 1); });
var T2 = Task.Run(() => { return searchStringAsync(search, Token, requestInfo, LogDeep + 1); });
var output = await Task.WhenAll(T1, T2);
foreach (var Entry in output[0])
{
if (!RetVal.TryGetValue(Entry.Key, out var lst))
{
lst = new List<cFasdApiSearchResultEntry>();
RetVal.Add(Entry.Key, lst);
}
foreach (var Entry2 in Entry.Value)
lst.Add(Entry2.Result);
}
foreach (var Entry in output[1])
{
if (RetVal.Count >= 11)
break;
if (!RetVal.TryGetValue(Entry.Key, out var lst))
{
lst = new List<cFasdApiSearchResultEntry>();
RetVal.Add(Entry.Key, lst);
foreach (var Entry2 in Entry.Value)
lst.Add(Entry2.Result);
}
}
}
else
{
var output = await searchStringAsync(search, Token, requestInfo, LogDeep + 1);
foreach (var Entry in output)
{
if (!RetVal.TryGetValue(Entry.Key, out var lst))
{
lst = new List<cFasdApiSearchResultEntry>();
RetVal.Add(Entry.Key, lst);
}
foreach (var Entry2 in Entry.Value)
lst.Add(Entry2.Result);
}
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cFasdApiSearchResultCollection> PhoneSearchAsync(string searchPhone, string searchName, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
Dictionary<string, List<cFasdApiSearchResultExt>>[] output;
if (string.IsNullOrEmpty(searchName))
{
var res1 = await searchStringAsync(searchPhone, Token, requestInfo, LogDeep + 1, "phone_rev", true);
output = new Dictionary<string, List<cFasdApiSearchResultExt>>[] { res1 };
}
else
{
var T1 = Task.Run(() => { return searchStringAsync(searchPhone, Token, requestInfo, LogDeep + 1, "phone_rev", true); });
var T2 = Task.Run(() => { return searchStringAsync(searchName, Token, requestInfo, LogDeep + 1, "full_name", false); });
output = await Task.WhenAll(T1, T2);
}
var _tmpRetVal = new Dictionary<string, Dictionary<Guid, cFasdApiSearchResultEntry>>();
foreach (var Entry3 in output)
foreach (var Entry in Entry3)
{
if (!_tmpRetVal.TryGetValue(Entry.Key, out var lst))
{
lst = new Dictionary<Guid, cFasdApiSearchResultEntry>();
_tmpRetVal.Add(Entry.Key, lst);
}
foreach (var Entry2 in Entry.Value)
{
bool replace = true;
if (lst.TryGetValue(Entry2.Result.id, out var _e))
{
if (_e.Type > Entry2.Result.Type)
replace = false;
}
if (replace)
lst[Entry2.Result.id] = Entry2.Result;
}
}
var RetVal = new cFasdApiSearchResultCollection();
foreach (var Entry in _tmpRetVal)
{
var lst = Entry.Value.Values.ToList();
RetVal[Entry.Key] = lst;
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<Dictionary<string, List<cFasdApiSearchResultEntry>>> ComputerSearchByNameAsync(string Name, string Domain, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
string strQuery = null;
var SqlParams = new Dictionary<string, object>(2) { { "name", Name } };
if (string.IsNullOrWhiteSpace(Domain))
strQuery = "SearchComputerByName";
else
{
strQuery = "SearchComputerByNameAndDomain";
SqlParams.Add("domain", Domain);
}
if (!DataHistorySqlHelper.GetWellKnownSqlStatement(strQuery, out var Query))
return null;
var output = await searchSqlAsync(Query.Query, SqlParams, Token, requestInfo, LogDeep + 1, Query.Name, SupportCancellation: false);
var RetVal = new Dictionary<string, List<cFasdApiSearchResultEntry>>();
foreach (var Entry in output)
{
if (!RetVal.TryGetValue(Entry.Key, out var lst))
{
lst = new List<cFasdApiSearchResultEntry>();
RetVal.Add(Entry.Key, lst);
}
foreach (var Entry2 in Entry.Value)
lst.Add(Entry2.Result);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
internal async Task<Dictionary<string, List<cFasdApiSearchResultExt>>> UserSearchByEntraIdDevelopAsync(Guid AzureId, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var SqlParams = new Dictionary<string, object> { { "AzureId", AzureId } };
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("SearchUserByAzureIdDevelop", out var Query))
return null;
var res = await searchSqlAsync(Query.Query, SqlParams, Token, requestInfo, LogDeep + 1, Query.Name, SupportCancellation: false);
return res;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
internal async Task<Dictionary<string, List<cFasdApiSearchResultExt>>> UserSearchBySidsAsync(List<string> Sids, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var SqlParams = new Dictionary<string, object>(Sids.Count);
var strIn = "";
int i = 0;
foreach (var Entry in Sids)
{
var objSid = new SecurityIdentifier(Entry);
var arrB = new byte[objSid.BinaryLength];
objSid.GetBinaryForm(arrB, 0);
if (strIn != "")
strIn += ",";
strIn += "@SID" + i.ToString();
SqlParams.Add("SID" + i.ToString(), arrB);
i++;
}
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("SearchUserBySid", out var Query))
return null;
var strQuery = string.Format(Query.Query, strIn);
var res = await searchSqlAsync(strQuery, SqlParams, Token, requestInfo, LogDeep + 1, Query.Name, SupportCancellation: false);
return res;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<Guid?> GetUserIdFromAccountAsync(string Account, string Domain, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (string.IsNullOrEmpty(Account) || string.IsNullOrEmpty(Domain))
return null;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("GetUserIdFromAccount", out var Query))
return null;
var Params = new Dictionary<string, object>()
{
{ "account", Account},
{ "domain", Domain}
};
using (var Conn = new cDbConnection(mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return null;
}
var res = await DataHistorySqlHelper.GetScalarResultAsync<Guid?>(Conn, Query, Params, requestInfo, Token);
return res;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cFasdApiSearchResultCollection> UserSearchByNameAndSidsAsync(string Name, List<string> SIDs, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
Dictionary<string, List<cFasdApiSearchResultExt>> output = null;
if (SIDs != null && SIDs.Count != 0)
output = await UserSearchBySidsAsync(SIDs, Token, requestInfo, LogDeep + 1);
if (output == null || output.Count == 0)
output = await searchStringAsync(Name, Token, requestInfo, LogDeep + 1);
var RetVal = new cFasdApiSearchResultCollection();
foreach (var Entry in output)
{
if (!RetVal.TryGetValue(Entry.Key, out var lst))
{
lst = new List<cFasdApiSearchResultEntry>();
RetVal.Add(Entry.Key, lst);
}
foreach (var Entry2 in Entry.Value)
lst.Add(Entry2.Result);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool isDigits(string s)
{
if (s == null || s == "") return false;
for (int i = 0; i < s.Length; i++)
if ((s[i] ^ '0') > 9)
return false;
return true;
}
public async Task<List<cDataHistoryInfoClassListEntry>> GetInfoClassListTest(enumFasdInformationClass infoClass, bool filtered, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
var IsValid = false;
var RetVal = new List<cDataHistoryInfoClassListEntry>();
try
{
DoProcessUiMessage(0, $"Retrieving the {infoClass} list for testing purposes.");
var queryName = $"Get{infoClass}ListTest";
if (filtered)
queryName += "Filtered";
if (!DataHistorySqlHelper.GetWellKnownSqlStatement(queryName, out var Query))
return RetVal;
using (var Conn = new cDbConnection(mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return RetVal;
}
int apiError = 0;
try
{
using (var Reader = await DataHistorySqlHelper.GetTableResultAsync(Conn, Query, null, Token))
{
if (Reader != null)
try
{
IsValid = true;
if (Reader.HasRows)
{
while (await Reader.ReadAsync())
{
try
{
var Entry = new cDataHistoryInfoClassListEntry
{
Name = Reader.GetString(0),
id = Reader.GetGuid(1)
};
if (!string.IsNullOrWhiteSpace(Entry.Name) && (Entry.id != Guid.Empty))
RetVal.Add(Entry);
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
}
catch (Exception E)
{
IsValid = false;
cLogManager.DefaultLogger.LogException(E);
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, "", apiError, requestInfo?.requestName);
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
if (!IsValid)
DoProcessUiMessage(1, $"Error while retrieving the {infoClass} list for testing purposes.");
else
DoProcessUiMessage(1, $"{RetVal.Count} {infoClass} entries found.");
return RetVal;
}
public async Task<List<cF4sdApiSearchResultRelation>> GetUsageFromAgentData(enumFasdInformationClass infoClass, List<Guid> Ids, int Age, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null;
if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var Age2 = Age;
if (Ids.Count == 1)
Age2 = 365;
var AgentLimit = DateTime.UtcNow + TimeSpan.FromDays(-Age2);
var idInput = Ids.Select(v => new cF4sdIdentityEntry() { Id = v, Class = infoClass }).ToList();
var listIds = await getConnectorIdList(idInput, Token, requestInfo, LogDeep + 1);
if (listIds == null || listIds.Count == 0)
return null;
var lstAgentIds = new Dictionary<int, cDataHistoryUsageIdInfo>(Ids.Count);
var lstTicketIds = new List<cF4sdConnectorIds>(Ids.Count);
foreach (var Entry in listIds)
{
if (M42WpmCollector != null && infoClass == enumFasdInformationClass.User)
{
if (Entry.sid != null)
lstTicketIds.Add(Entry);
}
if (Entry.lastSeenByAgent != null && Entry.lastSeenByAgent >= AgentLimit)
{
if (Entry.agentId2 != null)
lstAgentIds[(int)Entry.agentId2] = new cDataHistoryUsageIdInfo() { Id = Entry.Id, AccountType = enumAccountType.Azure };
if (Entry.agentId != null)
lstAgentIds[(int)Entry.agentId] = new cDataHistoryUsageIdInfo() { Id = Entry.Id, AccountType = enumAccountType.AD };
}
if (Entry.localAgentIds != null)
{
foreach (var entryLocal in Entry.localAgentIds)
{
if (entryLocal.lastSeenByAgent >= AgentLimit)
lstAgentIds[entryLocal.agentId] = new cDataHistoryUsageIdInfo() { Id = Entry.Id, AccountType = enumAccountType.Local, account = entryLocal.account, domain = "" };
}
}
}
if (DefaultLogger.IsDebug)
{
var _msgDebug = new List<string>()
{
$"{lstAgentIds?.Count} agent ids found by usage determination:"
};
foreach (var dbgEntry in lstAgentIds)
_msgDebug.Add($"{dbgEntry.Key}: accountType={dbgEntry.Value.AccountType}, account={dbgEntry.Value.account}, domain={dbgEntry.Value.domain}, id={dbgEntry.Value.Id}");
DefaultLogger.LogList(LogLevels.Debug, _msgDebug);
}
var taskList = new List<Task<List<cF4sdApiSearchResultRelation>>>(2);
if (lstAgentIds.Count > 0)
taskList.Add(Task.Run<List<cF4sdApiSearchResultRelation>>(async () => { return await GetUsedInfoFromAgentData(infoClass, lstAgentIds, Age, Token, requestInfo, LogDeep + 1); }));
if (lstTicketIds.Count > 0)
taskList.Add(Task.Run<List<cF4sdApiSearchResultRelation>>(async () => { return await getTicketUsage(infoClass, lstTicketIds, Age, Token, requestInfo, LogDeep + 1); }));
if (taskList.Count == 0)
return null;
var arrTask = taskList.ToArray();
var RetVal = await Task.WhenAll<List<cF4sdApiSearchResultRelation>>(arrTask);
var RetVal2 = new List<cF4sdApiSearchResultRelation>();
foreach (var Entry in RetVal)
{
if (Entry != null)
RetVal2.AddRange(Entry);
}
if (RetVal2.Count > 0)
return RetVal2;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<List<cF4sdApiSearchResultRelation>> GetUsageFromOnlyAgentData(enumFasdInformationClass infoClass, List<Guid> Ids, int Age, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null;
if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var Age2 = Age;
if (Ids.Count == 1)
Age2 = 365;
var AgentLimit = DateTime.UtcNow + TimeSpan.FromDays(-Age2);
var idInput = Ids.Select(v => new cF4sdIdentityEntry() { Id = v, Class = infoClass }).ToList();
var listIds = await getConnectorIdList(idInput, Token, requestInfo, LogDeep + 1);
if (listIds == null || listIds.Count == 0)
return null;
var lstAgentIds = new Dictionary<int, cDataHistoryUsageIdInfo>(Ids.Count);
foreach (var Entry in listIds)
{
if (Entry.lastSeenByAgent != null && Entry.lastSeenByAgent >= AgentLimit)
{
if (Entry.agentId2 != null)
lstAgentIds[(int)Entry.agentId2] = new cDataHistoryUsageIdInfo() { Id = Entry.Id, AccountType = enumAccountType.Azure };
if (Entry.agentId != null)
lstAgentIds[(int)Entry.agentId] = new cDataHistoryUsageIdInfo() { Id = Entry.Id, AccountType = enumAccountType.AD };
}
if (Entry.localAgentIds != null)
{
foreach (var entryLocal in Entry.localAgentIds)
{
if (entryLocal.lastSeenByAgent >= AgentLimit)
lstAgentIds[entryLocal.agentId] = new cDataHistoryUsageIdInfo() { Id = Entry.Id, AccountType = enumAccountType.Local, account = entryLocal.account, domain = "" };
}
}
}
if (DefaultLogger.IsDebug)
{
var _msgDebug = new List<string>()
{
$"{lstAgentIds?.Count} agent ids found by usage determination:"
};
foreach (var dbgEntry in lstAgentIds)
_msgDebug.Add($"{dbgEntry.Key}: accountType={dbgEntry.Value.AccountType}, account={dbgEntry.Value.account}, domain={dbgEntry.Value.domain}, id={dbgEntry.Value.Id}");
DefaultLogger.LogList(LogLevels.Debug, _msgDebug);
}
var taskList = new List<Task<List<cF4sdApiSearchResultRelation>>>(2);
if (lstAgentIds.Count > 0)
taskList.Add(Task.Run<List<cF4sdApiSearchResultRelation>>(async () => { return await GetUsedInfoFromAgentData(infoClass, lstAgentIds, Age, Token, requestInfo, LogDeep + 1); }));
if (taskList.Count == 0)
return null;
var arrTask = taskList.ToArray();
var RetVal = await Task.WhenAll<List<cF4sdApiSearchResultRelation>>(arrTask);
var RetVal2 = new List<cF4sdApiSearchResultRelation>();
foreach (var Entry in RetVal)
{
if (Entry != null)
RetVal2.AddRange(Entry);
}
if (RetVal2.Count > 0)
return RetVal2;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<List<cF4sdApiSearchResultRelation>> getTicketUsage(enumFasdInformationClass infoClass, List<cF4sdConnectorIds> lstTicketIds, int Age, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
return await M42WpmCollector?.getTicketUsage(lstTicketIds, Token, requestInfo, LogDeep);
}
private enumFasdInformationClass getResultClassForAgentUsage(enumFasdInformationClass infoClass)
{
switch (infoClass)
{
case enumFasdInformationClass.User:
return enumFasdInformationClass.Computer;
case enumFasdInformationClass.Computer:
return enumFasdInformationClass.User;
}
return enumFasdInformationClass.Unknown;
}
private async Task<List<cF4sdApiSearchResultRelation>> GetUsedInfoFromAgentData(enumFasdInformationClass infoClass, Dictionary<int, cDataHistoryUsageIdInfo> AgentIdInfos, int Age, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var lstTasks = new List<Task<List<cF4sdApiSearchResultRelation>>>(AgentIdInfos.Count);
foreach (var AgentId in AgentIdInfos)
lstTasks.Add(GetSingleUsedInfoFromAgentData(infoClass, AgentId.Value, AgentId.Key, Age, Token, requestInfo, LogDeep + 1));
var res = await Task.WhenAll(lstTasks.ToArray());
var RetVal = new List<cF4sdApiSearchResultRelation>();
double _sumDuration = 0;
for (int i = 0; i < res.Length; i++)
{
var Entry = res[i];
if (Entry == null)
continue;
foreach (var Entry2 in Entry)
{
if (Entry2 == null)
continue;
RetVal.Add(Entry2);
_sumDuration += Entry2.UsingLevel;
}
}
if (_sumDuration == 0)
_sumDuration = 1;
foreach (var Entry in RetVal)
Entry.UsingLevel /= _sumDuration;
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<List<cF4sdApiSearchResultRelation>> GetSingleUsedInfoFromAgentData(enumFasdInformationClass infoClass, cDataHistoryUsageIdInfo Id, int AgentId, int Age, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var _usageData = await F4sdAgent.GetSingleUsedInfoFromAgentData(infoClass, AgentId, Age, Token, requestInfo, LogDeep + 1);
if (_usageData == null)
return null;
var _infoClass = getResultClassForAgentUsage(infoClass);
var RetVal = new List<cF4sdApiSearchResultRelation>();
foreach (var _entry in _usageData)
{
var deviceInfo = await GetMainInfoFromAgentId(_infoClass, _entry.id, requestInfo, LogDeep + 1, Token);
if (deviceInfo == null && infoClass == enumFasdInformationClass.Computer && _infoClass == enumFasdInformationClass.User && InfrastructureConfig.ClientAgent?.localAccountAssignments != null)
deviceInfo = await GetLocalUserInfoFromAgentId(_entry.id, requestInfo, LogDeep + 1, Token);
if (deviceInfo != null)
{
var _at = enumAccountType.unknow;
if (infoClass == enumFasdInformationClass.User)
_at = Id.AccountType;
deviceInfo.Identities?.Add(new cF4sdIdentityEntry() { Class = infoClass, Id = Id.Id, agentId = AgentId, AccountType = _at });
deviceInfo.UsingLevel = (double)_entry.duration;
deviceInfo.LastUsed = _entry.lastEvent;
if (deviceInfo.Infos == null)
deviceInfo.Infos = new Dictionary<string, string>();
if (!deviceInfo.Infos.ContainsKey("UserAccountType"))
deviceInfo.Infos.Add("UserAccountType", Id.AccountType.ToString());
if (infoClass == enumFasdInformationClass.User)
{
if (!string.IsNullOrEmpty(Id.account))
deviceInfo.Infos.Add("UserAccount", Id.account);
if (!string.IsNullOrEmpty(Id.domain))
deviceInfo.Infos.Add("UserDommain", Id.domain);
}
RetVal.Add(deviceInfo);
if (DefaultLogger.IsDebug)
deviceInfo.LogIt(LogLevels.Debug);
}
}
if (RetVal.Count > 0)
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<cF4sdApiSearchResultRelation> GetMainInfoFromAgentId(enumFasdInformationClass infoClass, int agentID, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, cF4sdApiSearchResultRelation SearchEntry = null)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement($"Get{infoClass}InfoFromAgentId", out var Query))
return null;
var Params = new Dictionary<string, object>() { { "id", agentID } };
int apiError = 0;
try
{
using (var ConnMain = new cDbConnection(mainDbConnection))
using (var Reader = await DataHistorySqlHelper.GetDataReaderAsync(ConnMain, Query, Params, Token))
{
if (Reader != null)
try
{
if (Reader.HasRows)
{
var maxStateVal = Enum.GetValues(typeof(enumF4sdSearchResultStatus)).Cast<int>().Max<int>();
var minStateVal = Enum.GetValues(typeof(enumF4sdSearchResultStatus)).Cast<int>().Min<int>();
if (await Reader.ReadAsync())
{
try
{
var Id = Reader.GetGuid(0);
var Name = Reader.GetString(1);
var Status = enumF4sdSearchResultStatus.Unknown;
if (!Reader.IsDBNull(2))
{
var intStatus = Reader.GetInt32(2);
if (intStatus <= maxStateVal && intStatus >= minStateVal)
Status = (enumF4sdSearchResultStatus)intStatus;
}
var account = Reader.IsDBNull(3) ? null : Reader.GetString(3);
var domain = Reader.IsDBNull(4) ? null : Reader.GetString(4);
var IsAzure = Reader.GetInt32(5);
var AccountType = enumAccountType.unknow;
if (infoClass == enumFasdInformationClass.User)
{
if (IsAzure == 1)
AccountType = enumAccountType.Azure;
else
AccountType = enumAccountType.AD;
}
var RetVal = new cF4sdApiSearchResultRelation()
{
Type = cFasdApiSearchResultEntry.getSearchClass(infoClass),
id = Id,
Name = Name,
DisplayName = Name,
Status = Status,
LastUsed = DateTime.UtcNow,
UsingLevel = 1.0,
};
RetVal.Identities = new cF4sdIdentityList { new cF4sdIdentityEntry() { Class = infoClass, Id = RetVal.id, agentId = agentID, AccountType = AccountType } };
RetVal.Infos = new Dictionary<string, string>
{
["account"] = account,
["domain"] = domain
};
if (infoClass == enumFasdInformationClass.User)
RetVal.Infos["UserAccountType"] = AccountType.ToString();
if (SearchEntry != null)
{
RetVal.UsingLevel = SearchEntry.UsingLevel;
RetVal.LastUsed = SearchEntry.LastUsed;
if (SearchEntry.Identities != null)
RetVal.Identities?.AddRange(SearchEntry.Identities);
}
return RetVal;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, Params, apiError, requestInfo?.requestName);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<cF4sdApiSearchResultRelation> GetLocalUserInfoFromAgentId(int agentID, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug)
{
CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
LogEntry($"agentId={agentID}", LogLevels.Debug);
}
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement($"GetLocalUserInfoFromAgentId", out var Query))
return null;
var Params = new Dictionary<string, object>() { { "id", agentID } };
int apiError = 0;
try
{
using (var ConnMain = new cDbConnection(mainDbConnection))
using (var Reader = await DataHistorySqlHelper.GetDataReaderAsync(ConnMain, Query, Params, Token))
{
if (Reader != null)
try
{
if (Reader.HasRows)
{
var maxStateVal = Enum.GetValues(typeof(enumF4sdSearchResultStatus)).Cast<int>().Max<int>();
var minStateVal = Enum.GetValues(typeof(enumF4sdSearchResultStatus)).Cast<int>().Min<int>();
if (await Reader.ReadAsync())
{
try
{
var Id = Reader.GetGuid(0);
var Name = Reader.GetString(1);
var Status = enumF4sdSearchResultStatus.Unknown;
if (!Reader.IsDBNull(2))
{
var intStatus = Reader.GetInt32(2);
if (intStatus <= maxStateVal && intStatus >= minStateVal)
Status = (enumF4sdSearchResultStatus)intStatus;
}
var account = Reader.IsDBNull(3) ? null : Reader.GetString(3);
var RetVal = new cF4sdApiSearchResultRelation()
{
Type = enumF4sdSearchResultClass.User,
id = Id,
Name = Name,
DisplayName = Name,
Status = Status,
LastUsed = DateTime.UtcNow,
UsingLevel = 1.0,
};
RetVal.Identities = new cF4sdIdentityList() { new cF4sdIdentityEntry() { Class = enumFasdInformationClass.User, Id = Id, agentId = agentID, AccountType = enumAccountType.Local } };
RetVal.Infos = new Dictionary<string, string>
{
["account"] = account,
["UserAccountType"] = "Local"
};
LogEntry($"Local account info found: id={Id}, account={account} ", LogLevels.Debug);
return RetVal;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, Params, apiError, requestInfo?.requestName);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetTableResultsMainDb(List<cDataHistoryConfigTable> Tables, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, bool instantly, bool IsSecondCall, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
Task<List<cF4SDHealthCardRawData.cHealthCardTable>>[] tasks = new Task<List<cF4SDHealthCardRawData.cHealthCardTable>>[Tables.Count];
for (int i = 0; i < Tables.Count; i++)
{
tasks[i] = getTableRawData(Tables[i], Identities, RefTime, MaxAge, instantly, IsSecondCall, Token, requestInfo, LogDeep + 1);
}
var Results = await Task.WhenAll(tasks).ConfigureAwait(false);
var RetVal = new List<cF4SDHealthCardRawData.cHealthCardTable>();
foreach (var Entry in Results)
{
if (Entry == null)
continue;
RetVal.AddRange(Entry);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cF4SDHealthCardRawData.cHealthCardDetailsTable> GetDetailsTableSingleResultMainDb(cDataHistoryConfigTable Table, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
using (var Conn = new cDbConnection(mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return null;
}
var Cols = new List<string>();
foreach (var col in Table.Columns.Values)
{
Cols.Add(col.Name);
if (col.SqlTypeBin != null)
Cols.Add(col.Name + "_bin");
}
if (!Identities.TryGetValue(Table.ParentCluster.InformationClass, out var _ids))
return null;
var _valId = _ids.Id;
var _rowId = Table.KeyColumns.First()?.SourceName;
var _rowTime = Table.EventTimeColumn?.SourceName;
if (string.IsNullOrEmpty(_rowId) || string.IsNullOrEmpty(_rowTime))
return null;
var Filter = new Dictionary<string, object>(1) { { _rowId, _valId } };
using (var _reader = await DataHistorySqlHelper.getDbReaderDetailTable(Conn, Table.SourceName, Filter, _rowTime, MaxAge, Token))
{
if (_reader == null)
return null;
if (_reader.HasRows)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable
{
Name = Table.Name,
Columns = Table.Columns.Values.Select(v => v.Name).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
var _colInfos = Table.Columns.Values.ToList();
Dictionary<string, int> _dic = new Dictionary<string, int>(Table.Columns.Count);
var _idx = 0;
foreach (var _colInfo in Table.Columns.Values)
{
_dic[_colInfo.SourceName] = _idx;
_idx++;
}
var _arrIdxAssign = Enumerable.Repeat<int>(-1, Table.Columns.Count).ToArray();
for (int i = 0; i < _reader.FieldCount; i++)
{
var _n = _reader.GetName(i);
if (_dic.TryGetValue(_n, out var _ix))
_arrIdxAssign[_ix] = i;
}
while (await _reader.ReadAsync(Token))
{
if (Token.IsCancellationRequested)
return null;
var _row = Enumerable.Repeat<object>(null, Table.Columns.Count).ToArray();
DateTime? EventTime = null;
for (int i = 0; i < Table.Columns.Count; i++)
{
var _n = _arrIdxAssign[i];
if (_n >= 0)
{
var obj = _reader.GetValue(_n);
var _obj2 = DataHistorySqlHelper.GetSqlDataValueFromHistoryType(obj, _colInfos[i].ValueType, _colInfos[i].Cardinal);
_row[i] = _obj2[0];
if (_reader.GetName(_n) == Table.EventTimeColumn.SourceName)
if (_row[i] is DateTime dt)
EventTime = dt;
}
}
if (EventTime != null)
{
var indexDay = cDataHistoryCollector.getDayIndex((DateTime)EventTime, RefTime, MaxAge + 1);
if (!retVal.Values.TryGetValue(indexDay, out var entryDay))
{
entryDay = new List<object[]>();
retVal.Values.Add(indexDay, entryDay);
}
entryDay.Add(_row);
}
}
return retVal;
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetDetailsTableResultsMainDb(List<cDataHistoryConfigTable> Tables, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var _lstTsk = new List<Task<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(Tables.Count);
foreach (var _table in Tables)
_lstTsk.Add(GetDetailsTableSingleResultMainDb(_table, Identities, RefTime, MaxAge, Token));
var arrRet = await Task.WhenAll(_lstTsk);
return arrRet.Where(v => v != null).ToList();
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public static void CorrectUsage(cDataHistoryCollector Collector, cF4SDHealthCardRawData data, List<Int64> Usage)
{
try
{
if (data?.Tables == null || Usage == null)
return;
foreach (var _table in data.Tables.Values)
{
if (_table.IsStatic)
continue;
if (Collector.ClusterConfig.Tables.TryGetValue(_table.Name, out var _configTable) && _configTable.Type != eDataHistoryTableType.History)
continue;
foreach (var _column in _table.Columns.Values)
{
if (_column.Values == null || _column.Values.Count == 0)
continue;
int _l = 0;
if (_table.StartingIndex < 0)
_l = Math.Min(_column.Values.Count + _table.StartingIndex, Usage.Count);
else
_l = Math.Min(_column.Values.Count, Usage.Count - _table.StartingIndex);
for (int i = 0; i < _l; i++)
{
int i1 = 0;
int i2 = 0;
if (_table.StartingIndex < 0)
{
i1 = i;
i2 = i - _table.StartingIndex;
}
else
{
i1 = i + _table.StartingIndex;
i2 = i;
}
if (Usage[i1] <= 0)
_column.Values[i2] = null;
}
}
}
}
catch (Exception E)
{
LogException(E);
}
}
public async Task<cF4SDHealthCardRawData> GetTableResults(List<string> Tables, List<cF4sdIdentityEntry> Identities, DateTime RefTime, int MaxAge, bool instantly, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var _tables = new List<string>();
foreach (var t in Tables)
{
if (!_tables.Contains(t))
_tables.Add(t);
}
var Ids = await getConntectorIds(Identities, Token, requestInfo, LogDeep + 1).ConfigureAwait(false);
var dicVirtualTables = new Dictionary<enumDataHistoryOrigin, List<cDataHistoryConfigTable>>();
var lstDbTables = new List<cDataHistoryConfigTable>();
foreach (var strTable in _tables)
{
var tableConfig = this.GetTableFromName(strTable);
if (tableConfig == null)
{
LogEntry($"The table '{strTable}' could not be found in the data clusters definitions", LogLevels.Warning);
continue;
}
if (lstDbTables.Contains(tableConfig))
continue;
if (tableConfig.Type == eDataHistoryTableType.Events || tableConfig.Type == eDataHistoryTableType.Selection)
continue;
if (tableConfig.IsVirtual)
{
if (Connectors.ContainsKey(tableConfig.ParentCluster.Origin))
{
if (!dicVirtualTables.TryGetValue(tableConfig.ParentCluster.Origin, out var lstTables))
{
lstTables = new List<cDataHistoryConfigTable>();
dicVirtualTables.Add(tableConfig.ParentCluster.Origin, lstTables);
}
if (!lstTables.Contains(tableConfig))
lstTables.Add(tableConfig);
}
}
else
{
lstDbTables.Add(tableConfig);
}
}
var c = dicVirtualTables.Count;
var idx = 0;
if (lstDbTables.Count > 0)
{
c++;
idx = 1;
}
Task<List<cF4SDHealthCardRawData.cHealthCardTable>>[] tasks = new Task<List<cF4SDHealthCardRawData.cHealthCardTable>>[c];
if (lstDbTables.Count > 0)
tasks[0] = GetTableResultsMainDb(lstDbTables, Ids, RefTime, MaxAge, instantly, false, Token, requestInfo, LogDeep + 1);
foreach (var Entry in dicVirtualTables)
{
var C = Connectors[Entry.Key];
tasks[idx] = Task.Run(() => { return C.GetTableResultsVirtualAsync(Entry.Value, Ids, RefTime, MaxAge, instantly, null, Token, requestInfo, LogDeep + 1); });
idx++;
}
var Results = await Task.WhenAll(tasks).ConfigureAwait(false);
var RetVal = new cF4SDHealthCardRawData();
var IsIncompleted = false;
foreach (var Entry in Results)
{
if (Entry == null)
continue;
foreach (var subEntry in Entry)
if (!RetVal.Tables.ContainsKey(subEntry.Name))
{
RetVal.Tables.Add(subEntry.Name, subEntry);
if (instantly)
subEntry.IsIncomplete = false;
else
IsIncompleted |= subEntry.IsIncomplete;
}
}
// detect the usage information
List<Int64> _usage = null;
if (RetVal.Tables.TryGetValue("agnt-computer-event-numerical", out var usageTable))
{
cF4SDHealthCardRawData.cHealthCardTableColumn usageCol1;
if (!usageTable.Columns.TryGetValue("DeviceActivity", out usageCol1))
usageCol1 = null;
cF4SDHealthCardRawData.cHealthCardTableColumn usageCol2;
if (!usageTable.Columns.TryGetValue("UserActivity", out usageCol2))
usageCol2 = null;
if (usageCol1 == null)
{
usageCol1 = usageCol2;
usageCol2 = null;
}
if (usageCol1?.Values != null)
{
var _l = usageCol1.Values.Count;
if (usageCol2?.Values != null)
_l = Math.Max(_l, usageCol2.Values.Count);
_usage = new List<Int64>(_l);
foreach (var _entry in usageCol1.Values)
{
Int64 _v = 0;
try
{
_v = Convert.ToInt64(_entry);
}
catch { }
_usage.Add(_v);
}
if (usageCol2?.Values != null)
{
var _i = 0;
foreach (var _entry in usageCol1.Values)
{
Int64 _v = 0;
try
{
_v = Convert.ToInt64(_entry);
}
catch { }
if (_i < _usage.Count)
_usage[_i] = Math.Max(_usage[_i], _v);
else
_usage.Add(_v);
_i++;
}
}
CorrectUsage(this, RetVal, _usage);
}
}
if (IsIncompleted && !instantly)
{
RetVal.Id = Guid.NewGuid();
foreach (var Entry in dicVirtualTables)
{
var C = Connectors[Entry.Key];
C.AddTableResultVirtualSuccessorTasks(Entry.Value, Ids, RefTime, MaxAge, _usage, RetVal.Id, requestInfo, LogDeep + 1);
}
AddTableResultSuccessorTasks(lstDbTables, Ids, RefTime, MaxAge, _usage, RetVal.Id, requestInfo, LogDeep + 1);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public cDataHistoryConfigTable GetTableFromName(string Name)
{
try
{
if (ClusterConfig.AlternateTableNames.TryGetValue(Name, out var _aln))
Name = _aln;
if (ClusterConfig.Tables.TryGetValue(Name, out var _retVal))
return _retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
}
return null;
}
public async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetDetailsTableResultsAsync(List<string> Tables, List<cF4sdIdentityEntry> Identities, DateTime RefTime, int MaxAge, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var Ids = await getConntectorIds(Identities, Token, requestInfo, LogDeep + 1).ConfigureAwait(false);
var dicVirtualTables = new Dictionary<enumDataHistoryOrigin, List<cDataHistoryConfigTable>>();
var lstDbTables = new List<cDataHistoryConfigTable>();
foreach (var strTable in Tables)
{
var tableConfig = GetTableFromName(strTable);
if (tableConfig == null)
{
LogEntry($"The table '{strTable}' could not be found in the data clusters definitions", LogLevels.Warning);
continue;
}
if (lstDbTables.Contains(tableConfig))
continue;
if (tableConfig.Type != eDataHistoryTableType.Events && tableConfig.Type != eDataHistoryTableType.StaticDetails)
continue;
if (tableConfig.IsVirtual)
{
if (Connectors.ContainsKey(tableConfig.ParentCluster.Origin))
{
if (!dicVirtualTables.TryGetValue(tableConfig.ParentCluster.Origin, out var lstTables))
{
lstTables = new List<cDataHistoryConfigTable>();
dicVirtualTables.Add(tableConfig.ParentCluster.Origin, lstTables);
}
lstTables.Add(tableConfig);
}
}
else
{
lstDbTables.Add(tableConfig);
}
}
var c = dicVirtualTables.Count;
var idx = 0;
if (lstDbTables.Count > 0)
{
c++;
idx = 1;
}
Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>[] tasks = new Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>[c];
if (lstDbTables.Count > 0)
tasks[0] = GetDetailsTableResultsMainDb(lstDbTables, Ids, RefTime, MaxAge, Token, requestInfo, LogDeep + 1);
foreach (var Entry in dicVirtualTables)
{
var C = Connectors[Entry.Key];
tasks[idx] = C.GetDetailsTableResultsVirtualAsync(Entry.Value, Ids, RefTime, MaxAge, Token, requestInfo, LogDeep + 1);
idx++;
}
var Results = await Task.WhenAll(tasks).ConfigureAwait(false);
var RetVal = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
foreach (var Entry in Results)
{
if (Entry == null)
continue;
RetVal.AddRange(Entry);
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<Int64> GetSelectionTableResultCountAsync(string Table, List<cF4sdIdentityEntry> Identities, string search, cF4sdWebRequestInfo requestInfo, CancellationToken Token, bool resetFilter = false, List<string> filterParams = null)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!ClusterConfig.Tables.TryGetValue(Table, out var _table))
{
LogEntry($"Could not find table '{Table}' in table list.", LogLevels.Warning);
return -1;
}
if (!this.Connectors.TryGetValue(_table.ParentCluster.Origin, out var _module))
{
LogEntry($"Could not find module '{_table.ParentCluster.Origin}' in module list.", LogLevels.Warning);
return -1;
}
var _retVal = await _module.GetSelectionTableResultCountAsync(_table, Identities, search, requestInfo, Token, resetFilter, filterParams);
return _retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return -1;
}
public async Task<cF4SDHealthCardRawData.cHealthCardTable> GetSelectionTableResultAsync(string Table, List<cF4sdIdentityEntry> Identities, string search, int PageSize, int Page, cF4sdWebRequestInfo requestInfo, CancellationToken Token, bool resetFilter = false, List<string> filterParams = null)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!ClusterConfig.Tables.TryGetValue(Table, out var _table))
return null;
if (!this.Connectors.TryGetValue(_table.ParentCluster.Origin, out var _module))
return null;
var _retVal = await _module.GetSelectionTableResultAsync(_table, Identities, search, PageSize, Page, requestInfo, Token, resetFilter, filterParams);
return _retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetCachedHistoricTable(cDataHistoryConfigTable tableConfig, Dictionary<string, object> Filter, DateTime RefTime, int MaxAge, cDataHistoryScanTiming Timing, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
using (var Conn = new cDbConnection(mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return null;
}
using (var _reader = await DataHistorySqlHelper.getDbReaderHistoricTable(Conn, tableConfig.SourceName, Filter, RefTime + TimeSpan.FromDays(-MaxAge - 1), Token))
{
if (_reader == null)
return null;
if (_reader.FieldCount > 2)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = tableConfig.Name,
InformationClass = tableConfig.ParentCluster.InformationClass,
Origin = tableConfig.ParentCluster.Origin,
StartingIndex = int.MaxValue,
IsStatic = false,
TableType = tableConfig.Type
};
var maxIndex = int.MinValue;
var Cols = new Dictionary<int, cF4SDHealthCardRawData.cHealthCardTableColumn>(_reader.FieldCount);
for (int i = 0; i < _reader.FieldCount; i++)
{
var _propName = _reader.GetName(i);
if (tableConfig.Columns.TryGetValue(_propName, out var _col))
{
var _ci = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = _col.Name };
Cols[i] = _ci;
retVal.Columns[_col.Name] = _ci;
}
if (tableConfig.Columns.TryGetValue(_propName + "_bin", out var _col2))
{
var _ci = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = _col.Name + "_bin" };
Cols[i] = _ci;
retVal.Columns[_col.Name + "_bin"] = _ci;
}
}
var TimeFrames = new Dictionary<int, KeyValuePair<DateTime, DateTime>>();
if (_reader.HasRows)
{
while (await _reader.ReadAsync())
{
DateTime timeFrom = _reader.GetDateTime(0);
DateTime timeTo = _reader.GetDateTime(1);
var indexTimeFrame = cScanTimeInfo.GetScanIntervalIndex(RefTime, timeFrom, timeTo, Timing);
if (maxIndex == int.MinValue)
{
maxIndex = indexTimeFrame - 1;
}
if (TimeFrames.ContainsKey(indexTimeFrame))
continue;
TimeFrames.Add(indexTimeFrame, new KeyValuePair<DateTime, DateTime>(timeFrom, timeTo));
foreach (var entryCol in Cols)
{
var colInfo = entryCol.Value;
var colIndex = entryCol.Key;
var objValue = _reader[colIndex];
objValue = objValue == DBNull.Value ? null : objValue;
if (Cols.TryGetValue(colIndex, out var _col))
{
if (indexTimeFrame > maxIndex)
{
for (int j = maxIndex + 1; j < indexTimeFrame; j++)
_col.Values.Add(null);
_col.Values.Add(objValue);
}
else if (indexTimeFrame < retVal.StartingIndex)
{
for (int j = indexTimeFrame + 1; j < retVal.StartingIndex; j++)
_col.Values.Insert(0, null);
_col.Values.Insert(0, objValue);
}
else
{
_col.Values[indexTimeFrame - retVal.StartingIndex] = objValue;
}
}
}
retVal.StartingIndex = Math.Min(retVal.StartingIndex, indexTimeFrame);
maxIndex = Math.Max(maxIndex, indexTimeFrame);
}
}
if (maxIndex >= retVal.StartingIndex)
{
retVal.TimeFrames = new DateTime[maxIndex - retVal.StartingIndex + 1, 2];
for (int i = retVal.StartingIndex; i <= maxIndex; i++)
{
if (TimeFrames.TryGetValue(i, out var _tf))
{
retVal.TimeFrames[i - retVal.StartingIndex, 0] = _tf.Key;
retVal.TimeFrames[i - retVal.StartingIndex, 1] = _tf.Value;
}
else
{
retVal.TimeFrames[i - retVal.StartingIndex, 0] = DateTime.MinValue;
retVal.TimeFrames[i - retVal.StartingIndex, 1] = DateTime.MinValue;
}
}
}
return new List<cF4SDHealthCardRawData.cHealthCardTable>() { retVal };
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> getTableRawDataStatic(DbDataReader _reader, cDataHistoryConfigTable tableConfig, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (await _reader.ReadAsync(Token))
{
if (Token.IsCancellationRequested)
return null;
var objValues = new object[_reader.FieldCount];
var n = _reader.GetValues(objValues);
var ColNames = new string[_reader.FieldCount];
if (ColNames.Length == _reader.FieldCount)
{
var RetVal = new cF4SDHealthCardRawData.cHealthCardTable();
for (int i = 0; i < _reader.FieldCount; i++)
{
var objVal = objValues[i] == DBNull.Value ? null : objValues[i];
var strCol = _reader.GetName(i);
RetVal.Columns.Add(strCol, new cF4SDHealthCardRawData.cHealthCardTableColumn(RetVal) { ColumnName = strCol, Values = new List<object>() { objVal } });
}
RetVal.Name = tableConfig.Name;
RetVal.InformationClass = tableConfig.ParentCluster.InformationClass;
RetVal.Origin = tableConfig.ParentCluster.Origin;
RetVal.IsStatic = tableConfig.Type == eDataHistoryTableType.Static;
RetVal.TableType = tableConfig.Type;
return new List<cF4SDHealthCardRawData.cHealthCardTable>() { RetVal };
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> getTableRawDataHistoric(DbDataReader _reader, cDataHistoryConfigTable tableConfig, DateTime RefTime, int MaxAge, bool instantly, bool IsSecondCall, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (tableConfig.EventTimeColumn == null)
return null;
cHistoricAggregationEntry[] arrColAgg = new cHistoricAggregationEntry[tableConfig.Columns.Count];
var i = 0;
foreach (var col in tableConfig.Columns.Values)
{
if (col is cDataHistoryConfigColumn _colInfo)
arrColAgg[i] = new cHistoricAggregationEntry(_colInfo, MaxAge + 1, null);
i++;
}
var _colInfos = tableConfig.Columns.Values.ToList();
Dictionary<string, int> _dic = new Dictionary<string, int>(tableConfig.Columns.Count);
var _idx = 0;
foreach (var _colInfo in tableConfig.Columns.Values)
{
_dic[_colInfo.SourceName] = _idx;
_idx++;
}
var _idxTimeCol = -1;
var _arrIdxAssign = Enumerable.Repeat<int>(-1, tableConfig.Columns.Count).ToArray();
for (i = 0; i < _reader.FieldCount; i++)
{
var _n = _reader.GetName(i);
if (_dic.TryGetValue(_n, out var _ix))
_arrIdxAssign[_ix] = i;
if (_n == tableConfig.EventTimeColumn.SourceName)
_idxTimeCol = i;
}
if (_idxTimeCol < 0)
return null;
while (await _reader.ReadAsync(Token))
{
if (Token.IsCancellationRequested)
return null;
var _eventTime = _reader.GetDateTime(_idxTimeCol);
for (i = 0; i < tableConfig.Columns.Count; i++)
{
var _n = _arrIdxAssign[i];
if (_n >= 0)
{
var obj = _reader.GetValue(_n);
var _obj2 = DataHistorySqlHelper.GetSqlDataValueFromHistoryType(obj, _colInfos[i].ValueType, _colInfos[i].Cardinal);
arrColAgg[i].addValue(_obj2[0], _eventTime, RefTime, 0);
}
}
}
var RetValHistoric = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = tableConfig.Name,
InformationClass = tableConfig.ParentCluster.InformationClass,
Origin = tableConfig.ParentCluster.Origin,
IsStatic = false,
TableType = eDataHistoryTableType.History
};
i = 0;
foreach (var Entry in tableConfig.Columns.Values)
{
var agg = arrColAgg[i];
var col = new cF4SDHealthCardRawData.cHealthCardTableColumn(RetValHistoric)
{
ColumnName = agg.Column.Name,
Values = agg.getValues()
};
RetValHistoric.Columns[agg.Column.Name] = col;
i++;
}
return new List<cF4SDHealthCardRawData.cHealthCardTable>() { RetValHistoric };
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public void AddTableResultSuccessorTasks(List<cDataHistoryConfigTable> Tables, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, List<Int64> UsageInfo, Guid CacheId, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var lstTables = new List<string>();
var myTables = new List<cDataHistoryConfigTable>();
foreach (var Table in Tables)
{
if (Table.ParentCluster.Origin != enumDataHistoryOrigin.Main)
continue;
if (!Table.LateDelivery)
continue;
if (Table.Cached != eDataHistoryTableCached.Yes)
continue;
myTables.Add(Table);
lstTables.Add(Table.Name);
}
if (lstTables.Count > 0)
{
var ct = new CancellationTokenSource().Token;
var tsk = GetTableResultsMainDb(myTables, Identities, RefTime, MaxAge, false, true, ct, requestInfo, LogDeep + 1);
SuccessorCache.AddTask(CacheId, lstTables, tsk, UsageInfo, ct);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> getTableRawData(cDataHistoryConfigTable tableConfig, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, bool instantly, bool IsSecondCall, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (tableConfig.LateDelivery && !instantly && !IsSecondCall)
{
return new List<cF4SDHealthCardRawData.cHealthCardTable>() {
new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = tableConfig.Name,
InformationClass = enumFasdInformationClass.Ticket,
Origin = tableConfig.ParentCluster.Origin,
IsIncomplete = true
}
};
}
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var Cols = new List<string>();
foreach (var col in tableConfig.Columns.Values)
{
Cols.Add(col.Name);
if (col.SqlTypeBin != null)
Cols.Add(col.Name + "_bin");
}
if (Identities.TryGetValue(tableConfig.ParentCluster.InformationClass, out var Identity))
if (Connectors.TryGetValue(tableConfig.ParentCluster.Origin, out var C))
{
var IdValues = await C.GetIds(Identity, tableConfig.ParentCluster.InformationClass, requestInfo, LogDeep + 1);
if (IdValues != null && tableConfig.KeyColumns.Count == IdValues.Count)
{
var Filters = new Dictionary<string, object>();
for (int i = 0; i < IdValues.Count; i++)
{
if (IdValues[i] == null)
{
LogEntry($"Empty filter value used on getting raw data for table {tableConfig.Name}.", LogLevels.Warning);
return null;
}
var Col = tableConfig.KeyColumns[i];
var ColName = Col.Name; if (Col.SqlTypeBin != null)
ColName += "_bin";
Filters.Add(ColName, IdValues[i]);
}
using (var Conn = new cDbConnection(mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return null;
}
using (var _reader = await DataHistorySqlHelper.getDbReaderSelectAsync(Conn, tableConfig.SourceName, Cols, Filters, Token).ConfigureAwait(false))
{
if (_reader.HasRows)
switch (tableConfig.Type)
{
case eDataHistoryTableType.Static:
return await getTableRawDataStatic(_reader, tableConfig, Token);
case eDataHistoryTableType.History:
return await getTableRawDataHistoric(_reader, tableConfig, RefTime, MaxAge, instantly, IsSecondCall, Token);
}
}
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<Dictionary<enumFasdInformationClass, cF4sdConnectorIds>> getConntectorIds(List<cF4sdIdentityEntry> Identities, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var tasks = new Task<cF4sdConnectorIds>[Identities.Count];
for (int i = 0; i < Identities.Count; i++)
{
tasks[i] = getConnectorIds(Identities[i].Class, Identities[i], Token, requestInfo, LogDeep + 1);
}
var Result = await Task.WhenAll(tasks).ConfigureAwait(false);
var RetVal = Result.Where(v => v != null).ToDictionary<cF4sdConnectorIds, enumFasdInformationClass>(x => x.infoClass);
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<List<cF4sdConnectorIds>> getConnectorIdList(List<cF4sdIdentityEntry> Identities, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var tasks = new Task<cF4sdConnectorIds>[Identities.Count];
for (int i = 0; i < Identities.Count; i++)
{
tasks[i] = getConnectorIds(Identities[i].Class, Identities[i], Token, requestInfo, LogDeep + 1, WithLocalAccounts: true);
}
var Result = await Task.WhenAll(tasks).ConfigureAwait(false);
var RetVal = Result.Where(v => v != null).ToList();
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<cF4sdConnectorIds> getConnectorIds(enumFasdInformationClass infoClass, cF4sdIdentityEntry Identity, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep, bool WithLocalAccounts = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
int apiError = 0;
try
{
if (infoClass == enumFasdInformationClass.Ticket)
return new cF4sdConnectorIds() { Id = Identity.Id, infoClass = enumFasdInformationClass.Ticket };
if (infoClass == enumFasdInformationClass.VirtualSession)
return new cF4sdConnectorIds() { Id = Identity.Id, infoClass = enumFasdInformationClass.VirtualSession };
if (infoClass == enumFasdInformationClass.MobileDevice)
return new cF4sdConnectorIds() { Id = Identity.Id, infoClass = enumFasdInformationClass.MobileDevice };
if (!DataHistorySqlHelper.GetWellKnownSqlStatement($"GetConnectorIdsFrom{infoClass}Id", out var Query))
return null;
var Params = new Dictionary<string, object>() { { "id", Identity.Id } };
using (var conn = new cDbConnection(mainDbConnection))
{
if (!conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return null;
}
cF4sdConnectorIds RetVal = null;
try
{
using (var Reader = await DataHistorySqlHelper.GetDataReaderAsync(conn, Query, Params, Token))
{
if (Reader != null)
try
{
if (Reader.HasRows)
{
if (await Reader.ReadAsync())
{
var Entry = new cF4sdConnectorIds()
{
infoClass = infoClass,
Id = Identity.Id
};
Entry.sid = Reader.IsDBNull(0) ? null : (byte[])Reader.GetValue(0);
Entry.agentId = Reader.IsDBNull(1) ? (int?)null : Reader.GetInt32(1);
Entry.agentId2 = Reader.IsDBNull(4) ? (int?)null : Reader.GetInt32(4);
Entry.name = Reader.GetString(2);
Entry.lastSeenByAgent = Reader.IsDBNull(3) ? (DateTime?)null : Reader.GetDateTime(3);
Entry.tenantId = Reader.IsDBNull(5) ? Guid.Empty : Reader.GetGuid(5);
Entry.intuneId = Reader.IsDBNull(6) ? Guid.Empty : Reader.GetGuid(6);
Entry.azureDeviceId = Reader.IsDBNull(7) ? Guid.Empty : Reader.GetGuid(7);
Entry.citrixUserId = Reader.IsDBNull(8) ? (int?)null : Reader.GetInt32(8);
Entry.citrixTenantId = Reader.IsDBNull(9) ? String.Empty : Reader.GetString(9);
if (Identity.agentId != null)
Entry.agentId = Identity.agentId;
Entry.accountType = Identity.AccountType;
RetVal = Entry;
}
}
}
catch (Exception E)
{
LogException(E);
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, Params, apiError, requestInfo?.requestName);
}
var _doLocalAccounts = WithLocalAccounts && RetVal != null && infoClass == enumFasdInformationClass.User && InfrastructureConfig.ClientAgent?.localAccountAssignments != null;
if (DefaultLogger.IsDebug)
{
var _msgDebug = new List<string>() {
"local account lookup infos:",
$"with local accounts: {WithLocalAccounts}",
$"RetVal agent id: {RetVal?.agentId}",
$"info class: {infoClass}",
$"Local account assignments count: {InfrastructureConfig.ClientAgent?.localAccountAssignments?.Count}",
$"do local accounts: {_doLocalAccounts}"
};
DefaultLogger.LogList(LogLevels.Debug, _msgDebug);
}
if (_doLocalAccounts)
{
var lst = new List<int>();
Params = new Dictionary<string, object>() { { "ID", Identity.Id } };
var _count = 0;
var _startTime2 = DateTime.UtcNow;
apiError = 0;
if (DataHistorySqlHelper.GetWellKnownSqlStatement("GetLocalUserFromId", out Query))
try
{
using (var Reader = await DataHistorySqlHelper.GetDataReaderAsync(conn, Query, Params, Token))
{
if (Reader != null)
try
{
if (Reader.HasRows)
{
while (await Reader.ReadAsync())
{
_count++;
var localAgentId = Reader.GetInt32(0);
var lastSeen = Reader.IsDBNull(1) ? (DateTime?)null : Reader.GetDateTime(1);
var localAccount = Reader.GetString(2);
if (lastSeen != null)
{
if (RetVal.localAgentIds == null)
RetVal.localAgentIds = new List<cF4sdConnectorIds.localIdEntry>();
RetVal.localAgentIds.Add(new cF4sdConnectorIds.localIdEntry() { agentId = localAgentId, lastSeenByAgent = (DateTime)lastSeen, account = localAccount });
}
}
}
}
catch (Exception E)
{
LogException(E);
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, Params, apiError, requestInfo?.requestName);
}
LogEntry($"local account assignement for id={Identity.Id} found: {_count}, {RetVal?.localAgentIds?.Count} of them are valid.", LogLevels.Debug);
}
return RetVal;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public static object getJsonValueFromString(string strValue, enumFasdValueType ValueType)
{
try
{
switch (ValueType)
{
default:
string RetVal0 = null;
try
{
RetVal0 = JsonConvert.DeserializeObject<string>(strValue);
}
catch { }
if (RetVal0 == null)
RetVal0 = strValue;
return RetVal0;
case enumFasdValueType.INT:
return JsonConvert.DeserializeObject<Int32>(strValue);
case enumFasdValueType.BIGINT:
return JsonConvert.DeserializeObject<Int64>(strValue);
case enumFasdValueType.FLOAT:
return JsonConvert.DeserializeObject<float>(strValue);
case enumFasdValueType.DATETIME:
var DT = JsonConvert.DeserializeObject<DateTime>(strValue);
return DT;
// ToDo: VERSION deserialization
//case enumFasdValueType.VERSION:
// var strVal1 = JsonConvert.DeserializeObject<string>(strValue);
// if (Version.TryParse(strVal1, out var RetVersion))
// return RetVersion;
// return null;
case enumFasdValueType.BOOLEAN:
var strVal2 = JsonConvert.DeserializeObject<string>(strValue);
return cXmlParser.GetBoolFromString(strVal2);
}
}
catch (Exception E)
{
LogException(E);
}
return null;
}
public static void ComputeEventDetailColumns(cDataHistoryConfigTable TableConfig, cF4SDHealthCardRawData.cHealthCardDetailsTable TableResult)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (TableResult.Columns == null || TableResult.Columns.Count == 0 || TableResult.Values == null)
return;
var lstComputations = new List<cDetailsComputationInfo>();
var index = TableResult.Columns.Count;
foreach (var Entry in TableConfig.Columns.Values)
if (Entry is cDataHistoryConfigColumnComputation comp)
{
var valueIndexes = new int[comp.Computation.Columns.Count];
for (int i = 0; i < comp.Computation.Columns.Count; i++)
{
var compVal = comp.Computation.Columns[i];
var idx = TableResult.Columns.IndexOf(compVal.Name);
if (idx < 0)
{
valueIndexes = null;
break;
}
valueIndexes[i] = idx;
}
if (valueIndexes == null)
continue;
var compInfo = new cDetailsComputationInfo() { Computation = comp.Computation, ValueIndexes = valueIndexes };
lstComputations.Add(compInfo);
TableResult.Columns.Add(comp.Name);
}
foreach (var day in TableResult.Values.Values)
foreach (var Entry in day)
{
var idx = index;
foreach (var compInfo in lstComputations)
{
var vals = new object[compInfo.ValueIndexes.Length];
for (int j = 0; j < vals.Length; j++)
vals[j] = Entry[compInfo.ValueIndexes[j]];
Entry[idx] = compInfo.Computation.Compute(vals);
idx++;
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<DateTime?> GetLastScanTime(string ScanName, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("GetLastScanTime", out var Query))
return null;
var Params = new Dictionary<string, object>() { { "Name", ScanName } };
DateTime? retVal = null;
using (var conn = new cDbConnection(mainDbConnection))
{
if (!conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return null;
}
retVal = await DataHistorySqlHelper.GetScalarResultAsync<DateTime?>(conn, Query, Params, requestInfo, CancellationToken.None);
}
if (retVal == null)
{
retVal = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
await SetLastScanTime(ScanName, (DateTime)retVal, requestInfo, LogDeep + 1, Token);
}
return retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<bool> SetLastScanTime(string ScanName, DateTime LastTime, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("SetLastScanTime", out var Query))
return false;
var Params = new Dictionary<string, object>() { { "Name", ScanName }, { "LastTime", LastTime } };
using (var conn = new cDbConnection(mainDbConnection))
{
if (!conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return false;
}
var retVal = await DataHistorySqlHelper.GetScalarResultAsync<int?>(conn, Query, Params, requestInfo, Token);
return (retVal != null && retVal > 0);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public async Task<Guid> CreateScanHistoryEntry(string ScanName, DateTime TimeFrom, DateTime TimeTo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var RetVal = Guid.Empty;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("CreateScanHistoryEntry", out var Query))
return RetVal;
var RetVal2 = Guid.NewGuid();
var Params = new Dictionary<string, object>() { { "ID", RetVal2 }, { "Name", ScanName }, { "From", TimeFrom }, { "To", TimeTo }, { "Execute", DateTime.UtcNow } };
using (var conn = new cDbConnection(mainDbConnection))
{
if (!conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return RetVal;
}
var rv = await DataHistorySqlHelper.GetScalarResultAsync<int?>(conn, Query, Params, requestInfo, Token);
if (rv == 1)
return RetVal2;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return Guid.Empty;
}
public async Task ConfirmScanHistoryEntry(Guid Id, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("ConfirmScanHistoryEntry", out var Query))
return;
var Params = new Dictionary<string, object>() { { "ID", Id } };
using (var conn = new cDbConnection(mainDbConnection))
{
if (!conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return;
}
var ScanName = await DataHistorySqlHelper.GetScalarResultAsync<string>(conn, Query, Params, requestInfo, Token);
if (!string.IsNullOrEmpty(ScanName))
await SetLastScanTime(ScanName, DateTime.UtcNow, requestInfo, LogDeep + 1, Token);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task RemoveLastScanHistoryEntry(string ScanName, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("RemoveLastScanHistoryEntry", out var Query))
return;
var Params = new Dictionary<string, object>() { { "Name", ScanName } };
using (var conn = new cDbConnection(mainDbConnection))
{
if (!conn.IsOpen)
{
LogEntry($"Could not open main sql database '{mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return;
}
var executionTime = await DataHistorySqlHelper.GetScalarResultAsync<DateTime?>(conn, Query, Params, requestInfo, Token);
if (executionTime == null)
await SetLastScanTime(ScanName, new DateTime(1970, 1, 1, 0, 0, 0), requestInfo, LogDeep + 1, Token);
else
await SetLastScanTime(ScanName, (DateTime)executionTime, requestInfo, LogDeep + 1, Token);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<Dictionary<string, cDataHistoryConfigColumnBase>> GetTableColumnValidationAsync(cDataHistoryConfigTable TableConfig, string Instance, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, cDbConnection MainConn = null)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
var closeDbConnection = false;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("GetTableColumnValidation", out var Query))
return null;
var Params = new Dictionary<string, object>() { { "Table", TableConfig.SourceName }, { "Instance", Instance } };
int apiError = 0;
try
{
if (MainConn == null)
{
closeDbConnection = true;
MainConn = new cDbConnection(mainDbConnection);
if (!MainConn.IsOpen)
return null;
}
var RetVal = new Dictionary<string, cDataHistoryConfigColumnBase>();
DbTransaction trans = MainConn.Connection.BeginTransaction(System.Data.IsolationLevel.Snapshot);
try
{
using (var Reader = await DataHistorySqlHelper.GetDataReaderAsync(MainConn, Query, Params, Token))
{
if (Reader != null)
try
{
if (Reader.HasRows)
{
while (await Reader.ReadAsync() && !Token.IsCancellationRequested)
{
var strColumn = Reader.GetString(0);
if (TableConfig.Columns.TryGetValue(strColumn, out var Col))
RetVal[Col.Name] = Col;
}
}
}
catch (Exception E)
{
LogException(E);
}
}
if (!Token.IsCancellationRequested)
{
trans.Commit();
return RetVal;
}
}
catch (Exception E)
{
LogException(E);
trans.Rollback();
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (closeDbConnection && MainConn != null)
{
MainConn.Dispose();
}
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, Params, apiError, requestInfo?.requestName);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<bool> SetTableColumnValidationAsync(cDataHistoryConfigTable TableConfig, string Instance, HashSet<string> ValidColumns, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, cDbConnection MainConn = null)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
var closeDbConnection = false;
try
{
if (MainConn == null)
{
closeDbConnection = true;
MainConn = new cDbConnection(mainDbConnection);
if (!MainConn.IsOpen)
return false;
}
var RetVal = new Dictionary<string, bool>();
using (DbTransaction trans = MainConn.Connection.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
bool doCommit = false;
try
{
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("GetTableColumnValidationEx", out var Query))
return false;
var Params = new Dictionary<string, object>() { { "Table", TableConfig.SourceName }, { "Instance", Instance } };
int apiError = 0;
var _startTime2 = DateTime.UtcNow;
try
{
using (var Reader = await DataHistorySqlHelper.GetDataReaderAsync(MainConn, Query, Params, Token, Transaction: trans))
{
if (Reader != null)
try
{
if (Reader.HasRows)
{
while (await Reader.ReadAsync() && !Token.IsCancellationRequested)
{
var strColumn = Reader.GetString(0);
var bIsValid = Reader.GetInt16(1);
RetVal[strColumn] = bIsValid == 1;
}
}
}
catch (Exception E)
{
LogException(E);
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, Params, apiError, requestInfo?.requestName);
}
if (Token.IsCancellationRequested)
return false;
var toDelete = new List<string>();
var toUpdate = new Dictionary<string, bool>();
var toInsert = new Dictionary<string, bool>();
foreach (var Column in TableConfig.Columns.Values)
{
var isValid = ValidColumns.Contains(Column.Name);
if (RetVal.TryGetValue(Column.Name, out var ColInfo))
{
if (ColInfo != isValid)
toUpdate[Column.Name] = isValid;
}
else
{
toInsert[Column.Name] = isValid;
}
}
foreach (var ColumnName in ValidColumns)
{
if (!RetVal.ContainsKey(ColumnName))
toDelete.Add(ColumnName);
}
// do the table inserts
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("InsertTableColumnValidation", out Query))
return false;
foreach (var updEntry in toInsert)
{
Params = new Dictionary<string, object>() { { "Table", TableConfig.SourceName }, { "Instance", Instance }, { "Column", updEntry.Key }, { "isValid", updEntry.Value ? 1 : 0 } };
await DataHistorySqlHelper.ExecuteAsync(MainConn, Query, Params, requestInfo, Token, Transaction: trans);
}
// do the table updates
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateTableColumnValidation", out Query))
return false;
foreach (var updEntry in toUpdate)
{
Params = new Dictionary<string, object>() { { "Table", TableConfig.SourceName }, { "Instance", Instance }, { "Column", updEntry.Key }, { "isValid", updEntry.Value ? 1 : 0 } };
await DataHistorySqlHelper.ExecuteAsync(MainConn, Query, Params, requestInfo, Token, Transaction: trans);
}
// do the table deletions
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("DeleteTableColumnValidation", out Query))
return false;
foreach (var updEntry in toDelete)
{
Params = new Dictionary<string, object>() { { "Table", TableConfig.SourceName }, { "Instance", Instance }, { "Column", updEntry } };
await DataHistorySqlHelper.ExecuteAsync(MainConn, Query, Params, requestInfo, Token, Transaction: trans);
}
doCommit = true;
return true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (doCommit)
trans.Commit();
else
trans.Rollback();
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (closeDbConnection && MainConn != null)
{
MainConn.Dispose();
}
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public async Task<List<string>> GetQuickActionAllList()
{
var returnValue = new List<string>();
foreach (var Connector in GetConnectors())
{
var _quickActions = await Connector.GetQuickActionList();
if (_quickActions != null && _quickActions.Count > 0)
returnValue.AddRange(_quickActions);
}
return returnValue;
}
public bool CheckCleanupTimeframes()
{
if (InfrastructureConfig.HistoryDB.CleanupTimeFrames == null)
return true;
if (InfrastructureConfig.HistoryDB.CleanupTimeFrames.Count == 0)
return true;
foreach (var TF in InfrastructureConfig.HistoryDB.CleanupTimeFrames)
{
if (TF.Check())
return true;
}
return false;
}
private async Task<HashSet<Guid>> getCleanupScanIds(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("GetScanHistoryCleanup", out var Query))
return null;
var Params = new Dictionary<string, object>() { { "Age1", InfrastructureConfig.HistoryDB.DaysToCache }, { "Age2", 60 } };
int apiError = 0;
try
{
using (var Conn = new cDbConnection(mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main database '{mainDbConnection.Database}', aborting query'", LogLevels.Error);
return null;
}
using (var Reader = await DataHistorySqlHelper.GetDataReaderAsync(Conn, Query, Params, Token))
{
if (Reader != null)
try
{
var RetVal = new HashSet<Guid>();
if (Reader.HasRows)
{
while (await Reader.ReadAsync() && !Token.IsCancellationRequested)
try
{
var _id = Reader.GetGuid(0);
RetVal.Add(_id);
}
catch (Exception E)
{
LogException(E);
}
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
}
catch (Exception E)
{
apiError = E.HResult;
LogException(E);
}
finally
{
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, _startTime, Params, apiError, requestInfo?.requestName);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<int> CheckCleanup(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var l = await getCleanupScanIds(requestInfo, LogDeep + 1, Token);
if (l != null)
return l.Count;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return 0;
}
public async Task<int> DoCleanup(bool DontUseScanTiming, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (!DontUseScanTiming && !CheckCleanupTimeframes())
{
DoProcessUiMessage(0, "The current time is not within the defined scan time intervals.");
return -2;
}
// get the historic scan ids to cleanup
var lstIds = await getCleanupScanIds(requestInfo, LogDeep + 1, Token);
if (lstIds == null)
return -1;
if (lstIds.Count == 0)
{
DoProcessUiMessage(0, "No outdated scans found. Cleanup is not nescessary.");
return 0;
}
DoProcessUiMessage(0, $"{lstIds.Count} outdated scans found. Starting cleanup...");
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("DeleteScanHistoryEntry", out var Query))
return -1;
Query.TimeoutFactor = 100;
using (var Conn = new cDbConnection(mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main database '{mainDbConnection.Database}', aborting query'", LogLevels.Error);
return -1;
}
var ValidRemoves = 0;
foreach (var _id in lstIds)
{
try
{
if (!DontUseScanTiming && !CheckCleanupTimeframes())
return ValidRemoves;
var Params = new Dictionary<string, object>(1) { { "ID", _id } };
var n = await DataHistorySqlHelper.ExecuteAsync(Conn, Query, Params, requestInfo, Token);
if (n != null && n > 0)
ValidRemoves += (int)n;
}
catch (Exception E)
{
LogException(E);
}
}
DoProcessUiMessage(0, $"{ValidRemoves} history scans removed.");
return ValidRemoves;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return -1;
}
public override async Task<bool> WritePropertyAsync(cF4SDWriteParameters PropertiesToWrite, cF4sdWebRequestInfo requestInfo, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
// check if properties are writable
if (!this.ClusterConfig.Tables.TryGetValue(PropertiesToWrite.TableName, out var tableConfig))
return false;
if (PropertiesToWrite.Values == null)
return false;
var lstIllegal = new List<string>();
foreach (var Entry in PropertiesToWrite.Values)
{
if (!tableConfig.Columns.TryGetValue(Entry.Key, out var colInfo) || !colInfo.IsWritable)
lstIllegal.Add(Entry.Key);
}
foreach (var Entry in lstIllegal)
PropertiesToWrite.Values.Remove(Entry);
if (PropertiesToWrite.Values.Count == 0)
return false;
var result = lstIllegal.Count == 0;
if (this.Connectors.TryGetValue(tableConfig.ParentCluster.Origin, out var _mod))
{
var res = await _mod.WritePropertyAsync(PropertiesToWrite, requestInfo, Token);
if (res)
{
}
return result & res;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private Guid GetUserHashGuid(Guid userId)
{
// check, if we have a GUID
if (!Guid.TryParse(userId.ToString(), out var _guid))
return Guid.Empty;
// convert the GUID into a byte arry and 'salt' it a little bit
var _arr = _guid.ToByteArray();
if (_arr.Length != 16) return Guid.Empty;
var _arrSalt = new byte[3 * 16];
for (byte i = 0; i < 16; i++)
{
byte j = Convert.ToByte(i * 3);
_arrSalt[j] = _arr[i];
_arrSalt[j + 1] = _arr[i];
_arrSalt[j + 2] = j;
}
// get the md5 hash value (128 bit = 16 byte)
var _md5 = MD5.Create();
var _arrHash = _md5.ComputeHash(_arrSalt);
if (_arrHash == null) return Guid.Empty;
if (_arrHash.Length != 16) return Guid.Empty;
// convert the hash value into a GUID
return new Guid(_arrHash);
}
public void AddRolesByMembership(cF4sdUserInfo userInfo, List<cF4SDMembershipGroup> _membershipGroups)
{
if (userInfo.Roles == null)
userInfo.Roles = new List<string>();
AddRolesByMembership(userInfo.Roles, _membershipGroups, userInfo.Name);
}
public void AddRolesByMembership(List<string> Roles, List<cF4SDMembershipGroup> _membershipGroups, string userName)
{
if (_membershipGroups?.Count > 0)
{
var _roles = InfrastructureConfig?.Authorisation?.Roles;
if (_roles != null)
foreach (var _roleEntry in _roles.Values)
{
if (_roleEntry.MembershipGroups != null)
foreach (var _grp in _roleEntry.MembershipGroups)
{
if (_membershipGroups.Contains(_grp))
{
if (Roles?.Contains(_roleEntry.Name) != true)
{
if (Roles == null)
Roles = new List<string>();
Roles.Add(_roleEntry.Name);
Debug.WriteLine($" {userName} is member of '{_roleEntry.Name}'");
}
}
}
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static int getDayIndex(DateTime EventTime, DateTime RefTime, int HistorySize)
{
var deltaTime = (EventTime - RefTime).TotalDays;
int indexDay;
if (deltaTime >= 0)
indexDay = (int)Math.Floor(deltaTime);
else
indexDay = -(int)Math.Ceiling(-deltaTime);
if (indexDay > 0)
indexDay = 0;
indexDay = -indexDay;
if (indexDay >= HistorySize)
indexDay = HistorySize - 1;
return indexDay;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool CheckIfNotEmpty(object _o)
{
if (_o == null) return false;
if (_o is string _s && string.IsNullOrEmpty(_s)) return false;
return true;
}
public override async Task<cScanTimeInfo> GetScanTimeInfoAsync(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
await Task.CompletedTask;
return null;
}
public override async Task<bool> DoScanAsync(bool Always, bool Rescan, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool EnhancedDebug = false)
{
await Task.CompletedTask;
return true;
}
public override async Task<List<object>> GetIds(cF4sdConnectorIds IdEntry, enumFasdInformationClass InfoClass, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
await Task.CompletedTask;
return new List<object>() { IdEntry.Id };
}
public static string getStingList(List<string> L)
{
if (L == null || L.Count == 0)
return null;
var RetVal = "";
foreach (var Entry in L)
{
if (string.IsNullOrEmpty(Entry))
continue;
if (RetVal != "")
RetVal += ',';
RetVal += Entry;
}
return RetVal;
}
public cCockpitConfiguration GetCockpitConfiguration(cF4sdWebRequestInfo requestInfo)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var retVal = new cCockpitConfiguration();
var AgentConfig = InfrastructureConfig?.ClientAgent;
if (AgentConfig != null)
{
retVal.agentApiConfiguration = F4sdAgent.GetAgentApiConfiguration(false);
}
if (InfrastructureConfig?.M42Wpm?.Server != null)
{
var _lang = requestInfo.Culture?.TwoLetterISOLanguageName?.ToUpperInvariant() ?? "";
retVal.m42ServerConfiguration = new cM42ServerConfiguration()
{
Server = InfrastructureConfig.M42Wpm.Server,
DisplayName = InfrastructureConfig.M42Wpm.DisplayNames.GetValue(_lang, null)
};
}
if (RefreshGlobalConfigurationParameters())
lock (GlobalParametersConfigLock)
retVal.GlobalConfig = GlobalParametersConfigFile.Parameters;
return retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public override async Task<cF4SdUserInfoChange> ValidateTokenAsync(cF4SDTokenRegistration TokenRegistration, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (TokenCache == null)
return null;
if (TokenRegistration.UserId != requestInfo.userInfo?.Id)
return null;
cF4SdUserInfoChange _userInfoChange = null;
switch (TokenRegistration?.TokenType)
{
case cF4SDTokenRegistration.enumTokenType.M42Bearer:
_userInfoChange = await this.M42WpmCollector.ValidateTokenAsync(TokenRegistration, requestInfo, LogDeep + 1, Token);
break;
}
if (_userInfoChange == null || _userInfoChange.ValidLogonsUntil == null || _userInfoChange.ValidLogonsUntil.Count == 0)
return null;
var validPeriod = _userInfoChange.ValidLogonsUntil.First().Value;
if (validPeriod.validUntil <= DateTime.UtcNow)
return null;
await TokenCache.SetAsync(TokenRegistration, validPeriod, Token, requestInfo, LogDeep + 1);
return _userInfoChange;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public override async Task<cF4SDAdditionalUserInfo> GetAdditionalUserInfo(enumAdditionalAuthentication Type, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
switch (Type)
{
case enumAdditionalAuthentication.M42WinLogon:
return await M42WpmCollector.GetAdditionalUserInfo(Type, requestInfo, LogDeep + 1, Token);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public HashSet<enumFasdInformationClass> GetSupportedInformationClasses() => new HashSet<enumFasdInformationClass>() { enumFasdInformationClass.User, enumFasdInformationClass.Computer };
public async Task<cF4sdStagedSearchResultRelations> GetRelationsAsync(IEnumerable<cF4sdIdentityEntry> ids, enumFasdInformationClass informationClass, int age, CancellationToken token = default)
{
List<cF4sdApiSearchResultRelation> usageRelations = await GetUsageFromOnlyAgentData(informationClass, ids.Select(id => id.Id).ToList(), age, token, null, 1);
return new cF4sdStagedSearchResultRelations() { Relations = usageRelations };
}
}
public class cScanTimeInfo
{
public readonly DateTime LastScan;
public DateTime? NextScan = null;
public SortedList<DateTime, DateTime> Intervals = new SortedList<DateTime, DateTime>();
public cScanTimeInfo(DateTime LastScan)
{
this.LastScan = LastScan;
}
private DateTime privGetScanTimeIntervals(DateTime time, DateTime LastScan, cDataHistoryScanTiming Timing)
{
try
{
var refTime = TimeZoneInfo.ConvertTimeFromUtc(time, Timing.Timezone);
refTime = refTime.Date + Timing.Offset;
refTime = refTime.ToUniversalTime();
while (refTime > time)
refTime -= TimeSpan.FromDays(1);
var diff = time - refTime;
var nDiff = diff.TotalMilliseconds / Timing.Interval.TotalMilliseconds;
nDiff = Math.Floor(nDiff);
var retVal = refTime + TimeSpan.FromMilliseconds(nDiff * Timing.Interval.TotalMilliseconds);
DateTime intv2 = retVal;
DateTime intv1 = intv2 - Timing.Interval;
while (LastScan < intv2)
{
Intervals.Add(intv1, intv2);
intv2 -= Timing.Interval;
intv1 = intv2 - Timing.Interval;
}
;
return retVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
}
return DateTime.MaxValue;
}
public DateTime GetScanTime(DateTime time, cDataHistoryScanTiming Timing)
{
return privGetScanTimeIntervals(time, LastScan, Timing);
}
public void GetFirstScanTime(cDataHistoryScanTiming Timing)
{
var _now = DateTime.UtcNow;
NextScan = privGetScanTimeIntervals(_now, _now - Timing.Interval, Timing);
}
static public int GetScanIntervalIndex(DateTime time, DateTime timeFrom, DateTime timeTo, cDataHistoryScanTiming Timing)
{
try
{
var refTime = TimeZoneInfo.ConvertTimeFromUtc(time, Timing.Timezone);
refTime = refTime.Date + Timing.Offset;
refTime = refTime.ToUniversalTime();
var Diff = (time - refTime).TotalMilliseconds / Timing.Interval.TotalMilliseconds;
Diff = Math.Round(Diff);
var nDiff = Convert.ToInt32(Diff);
refTime = refTime.AddMilliseconds(nDiff * Timing.Interval.TotalMilliseconds);
var timeCenter = timeFrom.AddTicks((timeTo - timeFrom).Ticks / 2);
Diff = (refTime - timeCenter).TotalMilliseconds / Timing.Interval.TotalMilliseconds;
Diff = Math.Ceiling(Diff);
nDiff = Convert.ToInt32(Diff);
return nDiff;
}
catch (Exception E)
{
LogException(E);
}
return -1;
}
}
public class cDataHistoryInfoClassListEntry
{
public string Name { get; set; }
public Guid id { get; set; }
public override string ToString()
{
return Name;
}
}
public class cF4sdConnectorIds
{
public class localIdEntry
{
public int agentId;
public DateTime lastSeenByAgent;
public string account;
}
public enumFasdInformationClass infoClass { get; set; } = enumFasdInformationClass.Unknown;
public Guid Id { get; set; }
public int? agentId { get; set; } = null;
public int? agentId2 { get; set; } = null;
public List<localIdEntry> localAgentIds { get; set; } = null;
public byte[] sid { get; set; } = null;
public string name { get; set; } = null;
public DateTime? lastSeenByAgent { get; set; } = null;
public enumAccountType accountType { get; set; } = enumAccountType.unknow;
public Guid tenantId { get; set; }
public Guid intuneId { get; set; }
public Guid azureDeviceId { get; set; }
public string citrixTenantId { get; set; }
public int? citrixUserId { get; set; }
}
public class cDataHistoryUiStatusMessage
{
public int Indent = 0;
public string Message;
public static cDataHistoryUiStatusMessage Create(int Indent, string Message)
{
return new cDataHistoryUiStatusMessage()
{
Indent = Indent,
Message = Message
};
}
}
public class cDataHistorySHistoryScanInfo
{
public Guid ID;
public string Scan;
public DateTime TimeFrom;
public DateTime TimeTo;
}
internal class cDataHistoryUsageIdInfo
{
internal Guid Id;
internal enumAccountType AccountType = enumAccountType.unknow;
internal string account = null;
internal string domain = null;
}
public class cF4sdWebRequestInfo
{
public readonly string requestName;
public readonly string id = null;
public readonly DateTime created = DateTime.UtcNow;
public readonly cF4sdUserInfo userInfo = null;
public readonly CultureInfo Culture = null;
public cM42WebClient M42WebClient = null;
public int SqlDuration = 0;
private List<(string, int)> privSqlDurations { get; set; } = null;
public List<(string, int)> SqlDurations
{
get
{
if (privSqlDurations == null)
privSqlDurations = new List<(string, int)>();
return privSqlDurations;
}
}
public cF4sdWebRequestInfo(string requestName, string id, cF4sdUserInfo userInfo = null)
{
try
{
this.requestName = requestName;
this.id = requestName + "-" + id;
this.userInfo = userInfo;
if (!string.IsNullOrEmpty(userInfo?.Language))
{
try
{
this.Culture = CultureInfo.GetCultureInfoByIetfLanguageTag(userInfo.Language);
}
catch { }
}
if (cLogManager.DefaultLogger.IsDebug) LogEntry($"authentication user language: {userInfo?.Language}, user culture: {this.Culture?.Name}", LogLevels.Debug);
}
catch (Exception E)
{
LogException(E);
}
}
}
public class cHistoricAggregationEntry
{
internal cDataHistoryConfigColumn Column;
internal int JsonSubValue = -1;
internal int HistorySize = 0;
internal object LatestValue = null;
internal DateTime? LastestEvent = null;
internal Int64?[] aggInt = null;
internal Double?[] aggDouble = null;
internal Double?[] weightDouble = null;
internal String[] aggString = null;
internal List<string>[] listString = null;
internal Boolean?[] aggBoolean = null;
internal DateTime?[] aggEvent = null;
internal DateTime?[] aggTime = null;
internal Version[] aggVersion = null;
internal Guid?[] aggGuid = null;
private object lockAggregation = new object();
internal cHistoricAggregationEntry(cDataHistoryConfigColumn Column, int HistorySize, Dictionary<string, string[]> JsonSettings)
{
this.Column = Column;
this.HistorySize = HistorySize;
if (Column.SourceJsonColumn >= 0)
JsonSubValue = Column.SourceJsonColumn;
else if (Column.SourceJsonField != null && JsonSettings != null)
{
if (JsonSettings.TryGetValue(Column.SourceName, out var jsonList))
{
for (int i = 0; i < jsonList.Length; i++)
if (jsonList[i] == Column.SourceJsonField)
{
JsonSubValue = i;
break;
}
}
}
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.average:
aggDouble = new Double?[HistorySize];
weightDouble = new Double?[HistorySize];
return;
case eDataHistoryAggregationType.latestTime:
aggEvent = new DateTime?[HistorySize];
return;
case eDataHistoryAggregationType.count:
case eDataHistoryAggregationType.valuecount:
aggInt = new Int64?[HistorySize];
return;
case eDataHistoryAggregationType.Unknown:
return;
case eDataHistoryAggregationType.latestValue:
case eDataHistoryAggregationType.first:
aggEvent = new DateTime?[HistorySize];
break;
}
switch (Column.ValueType)
{
case enumFasdValueType.INT:
case enumFasdValueType.BIGINT:
aggInt = new Int64?[HistorySize];
return;
case enumFasdValueType.FLOAT:
aggDouble = new Double?[HistorySize];
return;
case enumFasdValueType.DATETIME:
aggTime = new DateTime?[HistorySize];
return;
case enumFasdValueType.VERSION:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.sum:
listString = new List<string>[HistorySize];
return;
}
aggVersion = new Version[HistorySize];
return;
case enumFasdValueType.GUID:
aggGuid = new Guid?[HistorySize];
return;
case enumFasdValueType.BOOLEAN:
aggBoolean = new bool?[HistorySize];
return;
case enumFasdValueType.STRING:
case enumFasdValueType.IPV4:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.sum:
listString = new List<string>[HistorySize];
return;
}
aggString = new String[HistorySize];
return;
}
}
internal void addValue(object Value, DateTime EventTime, DateTime RefTime, Int32 EventDuration)
{
try
{
var indexDay = cDataHistoryCollector.getDayIndex(EventTime, RefTime, HistorySize);
if (Value is cDataHistoryCustomJsonMeasure _cm)
{
if (_cm.Values == null)
return;
if (_cm.ErrorCode != null && _cm.ErrorCode != 0)
return;
if (!string.IsNullOrEmpty(_cm.ErrorDescription))
return;
if (_cm.ResultCode != null && _cm.ResultCode != 0)
return;
var _s = _cm.Values.GetType().ToString();
if (_cm.Values is JValue _jVal)
Value = _jVal.Value;
else if (_cm.Values is JArray _jArr)
{
var _res = new object[_jArr.Count];
var i = 0;
foreach (var _jEntry in _jArr)
{
_res[i] = null;
if (_jEntry is JValue _jVal2)
{
_res[i] = _jVal2.Value;
}
i++;
}
Value = _res;
}
}
if ((JsonSubValue >= 0) && (Value is object[] arrVals))
Value = arrVals[JsonSubValue];
lock (lockAggregation)
{
if ((LastestEvent == null || EventTime >= LastestEvent) && !(Value is object[]))
{
LatestValue = Value;
LastestEvent = EventTime;
}
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.average:
if (cDataHistoryCollector.CheckIfNotEmpty(Value))
{
switch (Column.ValueType)
{
case enumFasdValueType.INT:
case enumFasdValueType.BIGINT:
case enumFasdValueType.FLOAT:
var val01 = Convert.ToDouble(Value);
if (weightDouble[indexDay] == null)
weightDouble[indexDay] = 0;
weightDouble[indexDay] += EventDuration;
if (aggDouble[indexDay] == null)
aggDouble[indexDay] = 0;
aggDouble[indexDay] += val01 * EventDuration;
return;
}
}
return;
case eDataHistoryAggregationType.latestTime:
if (aggEvent[indexDay] == null || aggEvent[indexDay] < EventTime)
aggEvent[indexDay] = EventTime;
return;
case eDataHistoryAggregationType.count:
if (aggInt[indexDay] == null)
aggInt[indexDay] = 1;
else
aggInt[indexDay]++;
return;
case eDataHistoryAggregationType.valuecount:
if (cDataHistoryCollector.CheckIfNotEmpty(Value))
{
if (aggInt[indexDay] == null)
aggInt[indexDay] = 1;
else
aggInt[indexDay]++;
}
return;
case eDataHistoryAggregationType.Unknown:
return;
}
switch (Column.ValueType)
{
case enumFasdValueType.INT:
case enumFasdValueType.BIGINT:
if (cDataHistoryCollector.CheckIfNotEmpty(Value))
{
var val02 = Convert.ToInt64(Value);
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
if (aggInt[indexDay] == null)
aggInt[indexDay] = val02;
else
aggInt[indexDay] = Math.Min((Int64)aggInt[indexDay], val02);
return;
case eDataHistoryAggregationType.max:
if (aggInt[indexDay] == null)
aggInt[indexDay] = val02;
else
aggInt[indexDay] = Math.Max((Int64)aggInt[indexDay], val02);
return;
case eDataHistoryAggregationType.sum:
if (aggInt[indexDay] == null)
aggInt[indexDay] = val02;
else
aggInt[indexDay] += val02;
return;
case eDataHistoryAggregationType.first:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggInt[indexDay] = val02;
}
else
{
if (EventTime < aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggInt[indexDay] = val02;
}
}
return;
case eDataHistoryAggregationType.latestValue:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggInt[indexDay] = val02;
}
else
{
if (EventTime > aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggInt[indexDay] = val02;
}
}
return;
}
}
return;
case enumFasdValueType.FLOAT:
if (cDataHistoryCollector.CheckIfNotEmpty(Value))
{
var val03 = Convert.ToDouble(Value);
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
if (aggDouble[indexDay] == null)
aggDouble[indexDay] = val03;
else
aggDouble[indexDay] = Math.Min((Double)aggDouble[indexDay], val03);
return;
case eDataHistoryAggregationType.max:
if (aggDouble[indexDay] == null)
aggDouble[indexDay] = val03;
else
aggDouble[indexDay] = Math.Max((Double)aggDouble[indexDay], val03);
return;
case eDataHistoryAggregationType.sum:
if (aggDouble[indexDay] == null)
aggDouble[indexDay] = val03;
else
aggDouble[indexDay] += val03;
return;
case eDataHistoryAggregationType.first:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggDouble[indexDay] = val03;
}
else
{
if (EventTime < aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggDouble[indexDay] = val03;
}
}
return;
case eDataHistoryAggregationType.latestValue:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggDouble[indexDay] = val03;
}
else
{
if (EventTime > aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggDouble[indexDay] = val03;
}
}
return;
}
}
return;
case enumFasdValueType.DATETIME:
if (cDataHistoryCollector.CheckIfNotEmpty(Value))
{
var val04 = Convert.ToDateTime(Value);
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
if (aggTime[indexDay] == null)
aggTime[indexDay] = val04;
else if (val04 < aggTime[indexDay])
aggTime[indexDay] = val04;
return;
case eDataHistoryAggregationType.max:
if (aggTime[indexDay] == null)
aggTime[indexDay] = val04;
else if (val04 > aggTime[indexDay])
aggTime[indexDay] = val04;
return;
case eDataHistoryAggregationType.sum:
return;
case eDataHistoryAggregationType.first:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggTime[indexDay] = val04;
}
else
{
if (EventTime < aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggTime[indexDay] = val04;
}
}
return;
case eDataHistoryAggregationType.latestValue:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggTime[indexDay] = val04;
}
else
{
if (EventTime > aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggTime[indexDay] = val04;
}
}
return;
}
}
return;
case enumFasdValueType.VERSION:
if (Value != null && Version.TryParse(Value.ToString(), out var val05))
{
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
if (aggVersion[indexDay] == null)
aggVersion[indexDay] = val05;
else if (val05 < aggVersion[indexDay])
aggVersion[indexDay] = val05;
return;
case eDataHistoryAggregationType.max:
if (aggVersion[indexDay] == null)
aggVersion[indexDay] = val05;
else if (val05 > aggVersion[indexDay])
aggVersion[indexDay] = val05;
return;
case eDataHistoryAggregationType.sum:
var strVal05 = val05.ToString();
if (listString[indexDay] == null)
listString[indexDay] = new List<string>() { strVal05 };
else if (listString[indexDay].Count < 32 && !listString[indexDay].Contains(strVal05))
listString[indexDay].Add(strVal05);
return;
case eDataHistoryAggregationType.first:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggVersion[indexDay] = val05;
}
else
{
if (EventTime < aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggVersion[indexDay] = val05;
}
}
return;
case eDataHistoryAggregationType.latestValue:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggVersion[indexDay] = val05;
}
else
{
if (EventTime > aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggVersion[indexDay] = val05;
}
}
return;
}
}
return;
case enumFasdValueType.GUID:
if (Value == null)
return;
Guid _guid = Guid.Empty;
if (Value is Guid _guid2)
_guid = _guid2;
else
{
if (Guid.TryParse(Value.ToString(), out var _guid3))
_guid = _guid3;
else
return;
}
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.first:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggGuid[indexDay] = _guid;
}
else
{
if (EventTime < aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggGuid[indexDay] = _guid;
}
}
return;
case eDataHistoryAggregationType.latestValue:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggGuid[indexDay] = _guid;
}
else
{
if (EventTime > aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggGuid[indexDay] = _guid;
}
}
return;
}
return;
case enumFasdValueType.BOOLEAN:
if (!cDataHistoryCollector.CheckIfNotEmpty(Value))
return;
bool val06 = false;
if (Value is bool v)
val06 = v;
else if (Value is string val06Str)
{
switch (val06Str.Trim().ToLower())
{
case "1":
case "true":
case "yes":
val06 = true;
break;
case "0":
case "false":
case "no":
break;
default:
return;
}
}
else if (Value is sbyte
|| Value is byte
|| Value is short
|| Value is ushort
|| Value is int
|| Value is uint
|| Value is long
|| Value is ulong)
{
var val06Int = Convert.ToInt64(Value);
if (val06Int == 0) { }
else if (val06Int == 1)
val06 = true;
return;
}
else if (Value is float
|| Value is double
|| Value is decimal)
{
var val06Double = Convert.ToDouble(Value);
if (val06Double == 0) { }
else if (val06Double == 1)
val06 = true;
else
return;
}
else
return;
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
if (aggBoolean[indexDay] == null)
aggBoolean[indexDay] = val06;
else
aggBoolean[indexDay] &= val06;
return;
case eDataHistoryAggregationType.max:
if (aggBoolean[indexDay] == null)
aggBoolean[indexDay] = val06;
else
aggBoolean[indexDay] |= val06;
return;
case eDataHistoryAggregationType.sum:
return;
case eDataHistoryAggregationType.first:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggBoolean[indexDay] = val06;
}
else
{
if (EventTime < aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggBoolean[indexDay] = val06;
}
}
return;
case eDataHistoryAggregationType.latestValue:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggBoolean[indexDay] = val06;
}
else
{
if (EventTime > aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggBoolean[indexDay] = val06;
}
}
return;
}
return;
default:
if (Value == null)
return;
var val07 = Value.ToString();
if (val07 == "")
return;
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.sum:
if (listString[indexDay] == null)
listString[indexDay] = new List<string>() { val07 };
else if (listString[indexDay].Count < 32 && !listString[indexDay].Contains(val07))
listString[indexDay].Add(val07);
return;
case eDataHistoryAggregationType.first:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggString[indexDay] = val07;
}
else
{
if (EventTime < aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggString[indexDay] = val07;
}
}
return;
case eDataHistoryAggregationType.latestValue:
if (aggEvent[indexDay] == null)
{
aggEvent[indexDay] = EventTime;
aggString[indexDay] = val07;
}
else
{
if (EventTime > aggEvent[indexDay])
{
aggEvent[indexDay] = EventTime;
aggString[indexDay] = val07;
}
}
return;
}
return;
}
}
}
catch (Exception E)
{
LogException(E);
LogEntry($"error while processing historical value from {Column.ParentTable.Name}/{Column.Name}: {Value}", LogLevels.Error);
}
}
internal List<object> getValues()
{
try
{
var RetVal = getValuesRaw();
if (RetVal == null || !Column.FillEmptyEntries)
return RetVal;
object LastVal = null;
for (int i = RetVal.Count - 1; i >= 0; i--)
{
if (RetVal[i] == null)
RetVal[i] = LastVal;
else
LastVal = RetVal[i];
}
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
return null;
}
internal List<object> getValuesRaw()
{
try
{
List<object> retVal;
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.average:
switch (Column.ValueType)
{
case enumFasdValueType.INT:
case enumFasdValueType.BIGINT:
case enumFasdValueType.FLOAT:
retVal = new List<object>(HistorySize);
for (int i = 0; i < HistorySize; i++)
{
if (weightDouble[i] == 0 || aggDouble[i] == null)
retVal.Add(null);
else
retVal.Add(aggDouble[i] / weightDouble[i]);
}
return retVal;
}
return null;
case eDataHistoryAggregationType.latestTime:
retVal = aggEvent?.Select(x => (object)x).ToList();
return retVal;
case eDataHistoryAggregationType.count:
case eDataHistoryAggregationType.valuecount:
retVal = aggInt.Select(x => (object)x).ToList();
return retVal;
case eDataHistoryAggregationType.Unknown:
return null;
}
switch (Column.ValueType)
{
case enumFasdValueType.INT:
case enumFasdValueType.BIGINT:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
case eDataHistoryAggregationType.max:
case eDataHistoryAggregationType.sum:
case eDataHistoryAggregationType.first:
case eDataHistoryAggregationType.latestValue:
retVal = aggInt.Select(x => (object)x).ToList();
return retVal;
}
return null;
case enumFasdValueType.FLOAT:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
case eDataHistoryAggregationType.max:
case eDataHistoryAggregationType.sum:
case eDataHistoryAggregationType.first:
case eDataHistoryAggregationType.latestValue:
retVal = aggDouble.Select(x => (object)x).ToList();
return retVal;
}
return null;
case enumFasdValueType.DATETIME:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
case eDataHistoryAggregationType.max:
case eDataHistoryAggregationType.first:
case eDataHistoryAggregationType.latestValue:
retVal = aggTime.Select(x => (object)x).ToList();
return retVal;
}
return null;
case enumFasdValueType.VERSION:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
case eDataHistoryAggregationType.max:
case eDataHistoryAggregationType.first:
case eDataHistoryAggregationType.latestValue:
retVal = aggVersion.Select(x => (object)x).ToList();
return retVal;
case eDataHistoryAggregationType.sum:
retVal = listString.Select(x => (object)cDataHistoryCollector.getStingList(x)).ToList();
return retVal;
}
return null;
case enumFasdValueType.GUID:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.first:
case eDataHistoryAggregationType.latestValue:
retVal = aggGuid.Select(x => (object)x).ToList();
return retVal;
}
return null;
case enumFasdValueType.BOOLEAN:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.min:
case eDataHistoryAggregationType.max:
case eDataHistoryAggregationType.first:
case eDataHistoryAggregationType.latestValue:
retVal = aggBoolean.Select(x => (object)x).ToList();
return retVal;
}
return null;
default:
switch (Column.AggregationType)
{
case eDataHistoryAggregationType.first:
case eDataHistoryAggregationType.latestValue:
retVal = aggString.Select(x => (object)x).ToList();
return retVal;
case eDataHistoryAggregationType.sum:
retVal = listString.Select(x => (object)cDataHistoryCollector.getStingList(x)).ToList();
return retVal;
}
return null;
}
}
catch (Exception E)
{
LogException(E);
}
return null;
}
}
public class cDataHistoryCustomJsonMeasure
{
public int? ResultCode = null;
public int? ErrorCode = null;
public string ErrorDescription = null;
public object Values;
}
}