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

2967 lines
149 KiB
C#

using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.SqlTypes;
using System.Dynamic;
using System.Linq;
using System.Reflection;
using System.Security.Principal;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using C4IT.FASD.Base;
using C4IT.FASD.Communication.Citrix;
using C4IT.HTTP;
using C4IT.Logging;
using C4IT_DataHistoryProvider_Base.DataSources;
using Newtonsoft.Json.Linq;
using static C4IT.Logging.cLogManager;
using static C4IT_DataHistoryProvider.cDataHistoryConfigCitrix;
namespace C4IT.DataHistoryProvider
{
public class cDataHistoryCollectorCitrix : cDataHistoryCollectorModule, ISearchResultRelationProvider
{
public const string constConnectorName = "Citrix connector";
public const string constLicenseId = "F2DA5E05-FD3C-4182-9164-9C722140BF85";
public const string constCitrixUserList = "monitorodata/Users?$top={0}&$select=Id,Sid,Upn,Domain&$filter=Domain ne ''";
public const string constCitrixSessionList = "monitorodata/Sessions?$expand=Machine($select=Id,DnsName,Name)&$select=SessionKey,StartDate,EndDate,ConnectionState";
public const string constCitrixSessions = "monitorodata/Sessions?$filter=UserId in ({0})&$expand=Machine($select=Id,DnsName,Name)&$select=SessionKey,StartDate,EndDate,ConnectionState";
public const string constCitrixSession = "monitorodata/Sessions?$filter=SessionKey eq {0}";
public const string constCitrixSessionMetrics = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics";
public const string constCitrixSessionMetricsIcaRTT = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,IcaRttMs)";
public const string constCitrixSessionMetricsIcaLatency = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,IcaLatency)";
public const string constCitrixSessionMetricsClientL7Latency = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,ClientL7Latency)";
public const string constCitrixSessionMetricsServerL7Latency = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,ServerL7Latency)";
public const string constCitrixSessionMetricsInputBandwidthUsed = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,InputBandwidthUsed)";
public const string constCitrixSessionMetricsOutputBandwidthUsed = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,OutputBandwidthUsed)";
public const string constCitrixSessionMetricsOutputBandwidthAvailable = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,OutputBandwidthAvailable)";
public const string constCitrixSessionMetricsFps = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,Fps)";
public const string constCitrixSessionMetricsInputFps = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,InputFps)";
public const string constCitrixSessionMetricsOutputFps = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,OutputFps)";
public const string constCitrixSessionMetricsWanLatency = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,WanLatency)";
public const string constCitrixSessionMetricsDcLatency = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=SessionMetrics($select=Id,CollectedDate,DcLatency)";
public const string constCitrixSessionMachine = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=Machine($expand=CurrentLoadIndex,Catalog,DesktopGroup($select=Name)),Machine";
public const string constCitrixSessionCurrentConnection = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=CurrentConnection,LogOnMetrics";
public const string constCitrixSessionConnections = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=Connection";
public const string constCitrixUserConnections = "monitorodata/Sessions?$filter=UserId in ({0})&$expand=Connection";
public const string constCitrixSessionUser = "monitorodata/Sessions?$select=SessionKey&$filter=SessionKey eq {0}&$expand=User";
public const string constCitrixSessionLogoff = "cvad/manage/Sessions/{0}/$logoff";
public const string constCitrixSessionHide = "cvad/manage/Sessions/{0}/$hide";
public const string constCitrixSessionSendMessage = "cvad/manage/Sessions/{0}/$sendMessage";
public const string constTableNameSession = "citrix-session";
public const string constTableNameSessionMachine = "citrix-session-machine";
public const string constTableNameSessionConnection = "citrix-session-connection";
public const string constTableNameSessionCurrentConnection = "citrix-session-currentConnection";
public const string constTableNameSessionMetrics = "citrix-session-metrics";
public const string constTableNameSessionUser = "citrix-session-user";
public const string constTableNameSessionDetailsIcaRttMS = "citrix-session-details-icaRttMS";
public const string constTableNameSessionDetailsIcaLatency = "citrix-session-details-icaLatency";
public const string constTableNameSessionDetailsClientL7Latency = "citrix-session-details-clientL7Latency";
public const string constTableNameSessionDetailsServerL7Latency = "citrix-session-details-serverL7Latency";
public const string constTableNameSessionDetailsInputBandwidthUsed = "citrix-session-details-inputBandwidthUsed";
public const string constTableNameSessionDetailsOutputBandwidthUsed = "citrix-session-details-outputBandwidthUsed";
public const string constTableNameSessionDetailsOutputBandwidthAvailable = "citrix-session-details-outputBandwidthAvailable";
public const string constTableNameSessionDetailsFps = "citrix-session-details-fps";
public const string constTableNameSessionDetailsInputFps = "citrix-session-details-inputFps";
public const string constTableNameSessionDetailsOutputFps = "citrix-session-details-outputFps";
public const string constTableNameSessionDetailsWanLatency = "citrix-session-details-wanLatency";
public const string constTableNameSessionDetailsDcLatency = "citrix-session-details-dcLatency";
public const int constCitrixUserPaging = 100;
public readonly List<cLdapPropertyInfo> UserMainProperties = new List<cLdapPropertyInfo>() {
new cLdapPropertyInfo() { Name="objectSid", LdapType= enumLdapPropertyType.ldapSid, DbName=null},
new cLdapPropertyInfo() { Name="userPrincipalName", LdapType= enumLdapPropertyType.ldapString, DbName="upn_external"},
};
private Dictionary<string, cCitrixCommunication> tenantCitrixCache = new Dictionary<string, cCitrixCommunication>();
private readonly cDataHistoryCollector _collector;
public cDataHistoryCollectorCitrix(cDataHistoryCollector Collector) : base(Collector, enumDataHistoryOrigin.Citrix, constConnectorName, constLicenseId)
{
_collector = Collector;
}
public async Task<cCitrixCommunication> GetCitrixCommunicationForTenantAsync(string tenant, bool force = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (tenant == null)
return null;
cDataHistoryCitrixTenant _CitrixTenant = null;
var tenants = Collector.InfrastructureConfig.CitrixTenants?.Values;
if (tenants is null)
{
return null;
}
foreach (var Tenant in tenants)
{
if (Tenant.TenantID == tenant)
{
_CitrixTenant = Tenant;
break;
}
}
if (_CitrixTenant != null)
{
if (_CitrixTenant != null && tenantCitrixCache.TryGetValue(_CitrixTenant.TenantID, out var cachedGraph))
return cachedGraph;
var logon = await LogonCitrixTenantAsync(_CitrixTenant, force: force);
if (logon != null)
tenantCitrixCache[_CitrixTenant.TenantID] = logon;
return logon;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cCitrixCommunication> LogonCitrixTenantAsync(cDataHistoryCitrixTenant Tenant, bool force = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var CitrixConn = new cCitrixCommunication();
if (Tenant == null)
{
return null;
}
var LI = new cOAuthLogonInfo()
{
Tenant = Tenant?.TenantID.ToString(),
ClientID = Tenant.Credential?.User,
ClientSecret = Tenant.Credential?.NwCredential.Password,
InstanceId = Tenant?.InstanceID.ToString()
};
var RetVal = await CitrixConn.LogonAsync(LI);
if (RetVal)
return CitrixConn;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cCitrixCommunication> GetCitrixUsersAsync()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var strUrl = string.Format(constCitrixUserList, constCitrixUserPaging);
var tenants = Collector.InfrastructureConfig.CitrixTenants?.Values;
if (tenants is null)
{
Collector.DoProcessUiMessage(2, $" Could not logon to tenant - Tenant is null", LogLevels.Warning);
return null;
}
foreach (var Tenant in tenants)
{
var CitrixConn = await GetCitrixCommunicationForTenantAsync(Tenant.TenantID, true);
if (CitrixConn == null)
{
Collector.DoProcessUiMessage(2, $"error: could not logon to tenat {Tenant.Domain}", LogLevels.Error);
continue;
}
var Result = await CitrixConn.RequestAsync(strUrl, retryForbidden: false);
if (Result != null)
{
var _ty = Result.GetType();
var _props = Result.Result as JObject;
if (_props != null)
{
Collector.DoProcessUiMessage(3, $" properties of selected '{_props}' with {_props.Count} properties could be read.");
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<List<cF4sdApiSearchResultRelation>> GetUserSessionsAsync(List<cF4sdConnectorIds> UserId, CancellationToken Token, cF4sdWebRequestInfo requestInfo)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
string userIds = string.Join(",", UserId.Where(u => !string.IsNullOrWhiteSpace(u?.citrixUserId.ToString())).Select(u => u.citrixUserId));
var strUrl = string.Format(constCitrixSessions, userIds);
var tenantId = UserId?.FirstOrDefault(u => !string.IsNullOrWhiteSpace(u?.citrixTenantId))?.citrixTenantId;
if (tenantId is null)
{
Collector.DoProcessUiMessage(2, $" Could not logon to tenant - Tenant is null", LogLevels.Warning);
return null;
}
var CitrixConn = await GetCitrixCommunicationForTenantAsync(tenantId, true);
if (CitrixConn == null)
{
Collector.DoProcessUiMessage(2, $"error: could not logon to tenat {tenantId}", LogLevels.Error);
return null;
}
// maybe we should think about a concrete implementation of the results instead of a dynamic, what do you think?
var Result = await CitrixConn.RequestListAsync(strUrl, retryForbidden: false);
if (Result != null == Result.Count > 0)
{
var sessionResult = new List<cF4sdApiSearchResultRelation>(Result.Count);
double _sumDuration = 0;
foreach (var Entry in Result)
{
var endDate = DateTime.MinValue;
if (!DateTime.TryParse(Entry.Result.EndDate?.ToString(), out endDate))
endDate = DateTime.UtcNow;
var startDate = DateTime.MinValue;
if (!DateTime.TryParse(Entry.Result.StartDate?.ToString(), out startDate))
startDate = DateTime.UtcNow;
TimeSpan _duration = endDate - startDate;
_sumDuration += _duration.TotalSeconds;
Enum.TryParse(Entry.Result.ConnectionState.ToString(), out enumCitrixSessionStatus connectionState);
var Infos = new Dictionary<string, string>()
{
{ "Status",connectionState.ToString() },
{ "StatusId", Entry.Result.ConnectionState.ToString() },
{ "Domain", Regex.Replace(Entry.Result.Machine.Name?.ToString(), @"\\.*$", "") }
};
var sessionInfo = new cF4sdApiSearchResultRelation()
{
Type = enumF4sdSearchResultClass.VirtualSession,
Name = Regex.Replace(Entry.Result.Machine.Name.ToString(), @"^.*\\", ""),
DisplayName = Regex.Replace(Entry.Result.Machine.Name.ToString(), @"^.*\\", ""),
LastUsed = endDate,
// minor thing due to the fact we did it like that in the Agent before, but:
// Instead of setting the UsingLevel to a temporary value and calculate the actual value later,
// we should maybe calculate the sumvalue beforehand and apply only the calculation here, what do you think?
UsingLevel = _duration.TotalSeconds == 0 ? 1 : _duration.TotalSeconds,
id = Entry.Result.SessionKey,
Status = enumF4sdSearchResultStatus.Active,
Infos = Infos,
Identities = new cF4sdIdentityList()
{
new cF4sdIdentityEntry(){ Class = enumFasdInformationClass.User, Id = UserId[0].Id},
new cF4sdIdentityEntry(){ Class = enumFasdInformationClass.VirtualSession, Id = Entry.Result.SessionKey}
}
};
sessionResult.Add(sessionInfo);
}
if (sessionResult != null && sessionResult.Count > 0)
{
foreach (var Entry in sessionResult)
{
Entry.UsingLevel /= _sumDuration;
}
}
return sessionResult;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetSessionMetricsAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo,int MaxAge, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionMetrics, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetrics, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = constTableNameSessionMetrics,
InformationClass = enumFasdInformationClass.VirtualSession,
Origin = enumDataHistoryOrigin.Citrix,
IsStatic = true,
TableType = eDataHistoryTableType.Static
};
var dicVals = new List<Dictionary<string, object>>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
foreach (var prop in metricsObj.OfType<JObject>())
{
try
{
var metricDict = new Dictionary<string, object>();
foreach (var p in prop.Properties())
{
if (p.Value is JValue v)
metricDict[p.Name] = v.Value ?? null;
else
metricDict[p.Name] = p.Value;
}
dicVals.Add(metricDict);
}
catch (Exception E)
{
LogEntry($"Error getting session property from citrix", LogLevels.Error);
LogException(E);
}
}
}
const string collectDateColumnName = "CollectedDate";
var groupedValues = dicVals.Where(v => v.TryGetValue(collectDateColumnName, out var collectDate) && collectDate is DateTime)
.ToLookup(v => ((DateTime)v[collectDateColumnName]).Date, v => v);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
foreach (var colInfo in SessionTableDetails.Columns.Values)
{
try
{
if (valuesOfDay is null)
{
AddColumnData(retVal, colInfo.SourceName, ConvertToF4sdType(null, colInfo.ValueType));
continue;
}
var valuesOfColumn = valuesOfDay
.Select(v =>
{
if (v.TryGetValue(colInfo.SourceName, out var colValue))
return colValue;
else
return null;
})
.Where(v => v != null);
if (!valuesOfColumn.Any())
{
AddColumnData(retVal, colInfo.SourceName, ConvertToF4sdType(null, colInfo.ValueType));
continue;
}
if (colInfo is cDataHistoryConfigColumn configColumn && configColumn.AggregationType != eDataHistoryAggregationType.Unknown)
{
var aggregatedValue = GetAggregationValue(valuesOfColumn, configColumn.AggregationType, colInfo.ValueType);
AddColumnData(retVal, colInfo.SourceName, ConvertToF4sdType(aggregatedValue, colInfo.ValueType));
}
}
catch (Exception E)
{
LogException(E);
}
}
}
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed sessionmetrics information from citrix with id {Sessionid}. Sessionmetrics content is empty.", 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);
}
return null;
void AddColumnData(cF4SDHealthCardRawData.cHealthCardTable table, string columnName, object value)
{
if (table.Columns.TryGetValue(columnName, out var columnValues))
columnValues.Values.Add(value);
else
table.Columns.Add(columnName, new cF4SDHealthCardRawData.cHealthCardTableColumn(table) { ColumnName = columnName, Values = new List<object>() { value } });
}
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetSessionMetricsDetailsIcaRttMSAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo,int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsIcaRttMS, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsIcaRTT, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsIcaRttMS,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsIcaLatencyAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo,int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsIcaLatency, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsIcaLatency, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsIcaLatency,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsClientL7LatencyAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsClientL7Latency, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsClientL7Latency, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsClientL7Latency,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsServerL7LatencyAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsServerL7Latency, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsServerL7Latency, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsServerL7Latency,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsInputBandwidthUsedAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsInputBandwidthUsed, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsInputBandwidthUsed, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsInputBandwidthUsed,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsOutputBandwidthUsedAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsOutputBandwidthUsed, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsOutputBandwidthUsed, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsOutputBandwidthUsed,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsOutputBandwidthAvailableAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsOutputBandwidthAvailable, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsOutputBandwidthAvailable, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsOutputBandwidthAvailable,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = RefTime.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsFpsAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsFps, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsFps, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsFps,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsInputFpsAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsInputFps, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsInputFps, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsInputFps,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
//var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
// .GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v =>
{
var utc = DateTime.Parse(v[collectDateColumnName].ToString(), null,
System.Globalization.DateTimeStyles.AssumeUniversal | System.Globalization.DateTimeStyles.AdjustToUniversal);
return (utc - RefTime.TimeOfDay).Date.AddDays(1);
});
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = RefTime.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsOutputFpsAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsOutputFps, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsOutputFps, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsOutputFps,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsWanLatencyAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsWanLatency, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsWanLatency, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsWanLatency,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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.cHealthCardDetailsTable>> GetSessionMetricsDetailsDcLatencyAsync(Guid Sessionid, string TenantId, cF4sdWebRequestInfo RequestInfo, int MaxAge, DateTime RefTime, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionDetailsDcLatency, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMetricsDcLatency, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retValList = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
var vals = sessionInfos.Children();
var metricsObj = sessionInfos["SessionMetrics"] as JArray;
if (metricsObj != null)
{
var retVal = new cF4SDHealthCardRawData.cHealthCardDetailsTable()
{
Name = constTableNameSessionDetailsDcLatency,
Columns = SessionTableDetails.Columns.Values.Select(v => v.SourceName).ToList(),
Values = new Dictionary<int, List<object[]>>()
};
const string collectDateColumnName = "CollectedDate";
var groupedValues = metricsObj.Where(v => v[collectDateColumnName] != null && DateTime.TryParse(v[collectDateColumnName]?.ToString(), out _))
.GroupBy(v => DateTime.Parse(v[collectDateColumnName].ToString()).Date);
for (int i = 0; i < MaxAge; i++)
{
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key == referenceDate);
if (valuesOfDay == null)
{
retVal.Values[i] = new List<object[]>();
continue;
}
int index = 0;
foreach (var session in metricsObj)
{
try
{
var dicVals = session.Children<JProperty>().ToDictionary(prop => prop.Name, prop => prop.Value?.ToObject<object>());
var row = retVal.Columns.Select(colName => dicVals.TryGetValue(colName, out var value) ? value : null).ToArray();
if (!retVal.Values.ContainsKey(i))
{
retVal.Values[i] = new List<object[]>();
}
retVal.Values[i].Add(row);
}
catch (Exception e)
{
LogEntry($"Error processing session entry '{session.Path}'", LogLevels.Error);
LogException(e);
}
index++;
}
}
retVal.Columns = SessionTableDetails.Columns.Values.Select(v => v.Name).ToList();
return new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed Session information from citrix with id {Sessionid}. Session content is empty.", LogLevels.Warning);
}
}
return null;
}
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>> GetSessionAsync(Guid Sessionid, string TenantId, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSession, out var SessionTableDetails))
return null;
var strUrl = string.Format(constCitrixSession, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = constTableNameSession,
InformationClass = enumFasdInformationClass.VirtualSession,
Origin = enumDataHistoryOrigin.Citrix,
IsStatic = true,
TableType = eDataHistoryTableType.Static
};
var dicVals = new Dictionary<string, object>();
var vals = sessionInfos.Children();
foreach (var token in vals)
{
try
{
if (token is JProperty prop)
if (prop.Value is JValue val)
dicVals[prop.Name] = val.Value;
}
catch (Exception E)
{
LogEntry($"Error getting session detail property from citrix '{token.Path}'", LogLevels.Error);
LogException(E);
}
}
foreach (var colInfo in SessionTableDetails.Columns.Values)
{
try
{
if (!dicVals.TryGetValue(colInfo.SourceName, out var objVal))
objVal = null;
objVal = ConvertToF4sdType(objVal, colInfo.ValueType);
var _col = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = colInfo.Name, Values = new List<object>(1) { objVal } };
retVal.Columns[colInfo.Name] = _col;
}
catch { }
}
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed session information from citrix with id {Sessionid}. Session content is empty.", 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);
}
return null;
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetSessionUserAsync(Guid Sessionid, string TenantId, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionUser, out var UserTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionUser, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = constTableNameSessionUser,
InformationClass = enumFasdInformationClass.VirtualSession,
Origin = enumDataHistoryOrigin.Citrix,
IsStatic = true,
TableType = eDataHistoryTableType.Static
};
var dicVals = new Dictionary<string, object>();
var vals = sessionInfos.Children();
var userObj = sessionInfos["User"] as JObject;
if (userObj != null)
{
foreach (var prop in userObj.Properties())
{
try
{
if (prop.Value is JValue val)
{
dicVals[prop.Name] = val.Value;
}
else
{
dicVals[prop.Name] = prop.Value.ToString(Newtonsoft.Json.Formatting.None);
}
}
catch (Exception E)
{
LogEntry($"Error getting user property from citrix'{prop.Name}'", LogLevels.Error);
LogException(E);
}
}
}
foreach (var colInfo in UserTableDetails.Columns.Values)
{
try
{
if (!dicVals.TryGetValue(colInfo.SourceName, out var objVal))
objVal = null;
objVal = ConvertToF4sdType(objVal, colInfo.ValueType);
var _col = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = colInfo.Name, Values = new List<object>(1) { objVal } };
retVal.Columns[colInfo.Name] = _col;
}
catch { }
}
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed user information from citrix with id {Sessionid}. Session content is empty.", 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);
}
return null;
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetSessionMachineAsync(Guid Sessionid, string TenantId, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionMachine, out var MachineTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionMachine, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = constTableNameSessionMachine,
InformationClass = enumFasdInformationClass.VirtualSession,
Origin = enumDataHistoryOrigin.Citrix,
IsStatic = true,
TableType = eDataHistoryTableType.Static
};
var dicVals = new Dictionary<string, object>();
var vals = sessionInfos.Children();
var machineObj = sessionInfos["Machine"] as JObject;
if (machineObj != null)
{
foreach (var prop in machineObj.Properties())
{
try
{
if (prop.Value is JValue val)
{
dicVals[prop.Name] = val.Value;
}
else
{
dicVals[prop.Name] = prop.Value.ToString(Newtonsoft.Json.Formatting.None);
}
}
catch (Exception E)
{
LogEntry($"Error getting Machine property from citrix'{prop.Name}'", LogLevels.Error);
LogException(E);
}
}
}
foreach (var colInfo in MachineTableDetails.Columns.Values)
{
try
{
if (!dicVals.TryGetValue(colInfo.SourceName, out var objVal))
objVal = null;
if (colInfo is cDataHistoryConfigColumn configColumn && !string.IsNullOrEmpty(configColumn.SourceJsonField))
{
var _objVal = JObject.Parse(objVal.ToString());
var prop = _objVal.Property(configColumn.SourceJsonField);
objVal = prop?.Value.ToString();
}
objVal = ConvertToF4sdType(objVal, colInfo.ValueType);
var _col = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = colInfo.Name, Values = new List<object>(1) { objVal } };
retVal.Columns[colInfo.Name] = _col;
}
catch { }
}
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed machine information from citrix with id {Sessionid}. Session content is empty.", 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);
}
return null;
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetSessionCurrentConnectionAsync(Guid Sessionid, string TenantId, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionCurrentConnection, out var ConnectionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionCurrentConnection, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = constTableNameSessionCurrentConnection,
InformationClass = enumFasdInformationClass.VirtualSession,
Origin = enumDataHistoryOrigin.Citrix,
IsStatic = true,
TableType = eDataHistoryTableType.Static
};
var dicVals = new Dictionary<string, object>();
var vals = sessionInfos.Children();
var connectionObj = sessionInfos["CurrentConnection"] as JObject;
var logOnMetricsObj = sessionInfos["LogOnMetrics"] as JArray;
if (connectionObj != null)
{
foreach (var prop in connectionObj.Properties())
{
try
{
if (prop.Value is JValue val)
{
dicVals[prop.Name] = val.Value;
}
else
{
dicVals[prop.Name] = prop.Value.ToString(Newtonsoft.Json.Formatting.None);
}
}
catch (Exception E)
{
LogEntry($"Error getting connection property from citrix '{prop.Name}'", LogLevels.Error);
LogException(E);
}
}
}
JObject newestMetric = null;
if (logOnMetricsObj != null && logOnMetricsObj.Count > 0)
{
int maxId = logOnMetricsObj.Max(x => (int)x["Id"]);
newestMetric = logOnMetricsObj.FirstOrDefault(x => (int)x["Id"] == maxId) as JObject;
}
if (newestMetric != null)
{
foreach (var prop in newestMetric.Properties())
{
try
{
if (prop.Value is JValue val)
{
dicVals[prop.Name] = val.Value;
}
else
{
dicVals[prop.Name] = prop.Value.ToString(Newtonsoft.Json.Formatting.None);
}
}
catch (Exception E)
{
LogEntry($"Error getting connection property from citrix '{prop.Name}'", LogLevels.Error);
LogException(E);
}
}
}
foreach (var colInfo in ConnectionTableDetails.Columns.Values)
{
try
{
if (!dicVals.TryGetValue(colInfo.SourceName, out var objVal))
objVal = null;
objVal = ConvertToF4sdType(objVal, colInfo.ValueType);
var _col = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = colInfo.Name, Values = new List<object>(1) { objVal } };
retVal.Columns[colInfo.Name] = _col;
}
catch { }
}
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed connection information from citrix with id {Sessionid}. Session content is empty.", 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);
}
return null;
}
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetSessionConnectionsAsync(Guid Sessionid, string TenantId, 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 (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionConnection, out var ConnectionTableDetails))
return null;
var strUrl = string.Format(constCitrixSessionConnections, Sessionid);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
if (citrixCommunication == null)
return null;
var res = await citrixCommunication.RequestListAsync(strUrl, retryForbidden: false);
if (res != null)
{
JObject sessionInfos = res[0].Result;
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = constTableNameSessionConnection,
InformationClass = enumFasdInformationClass.VirtualSession,
Origin = enumDataHistoryOrigin.Citrix,
IsStatic = true,
TableType = eDataHistoryTableType.Static
};
var dicVals = new Dictionary<string, object>();
var vals = sessionInfos.Children();
var connectionObj = sessionInfos["Connection"] as JObject;
if (connectionObj != null)
{
foreach (var prop in connectionObj.Properties())
{
try
{
if (prop.Value is JValue val)
{
dicVals[prop.Name] = val.Value;
}
else
{
dicVals[prop.Name] = prop.Value.ToString(Newtonsoft.Json.Formatting.None);
}
}
catch (Exception E)
{
LogEntry($"Error getting connection property from citrix '{prop.Name}'", LogLevels.Error);
LogException(E);
}
}
}
foreach (var colInfo in ConnectionTableDetails.Columns.Values)
{
try
{
if (!dicVals.TryGetValue(colInfo.SourceName, out var objVal))
objVal = null;
objVal = ConvertToF4sdType(objVal, colInfo.ValueType);
var _col = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = colInfo.Name, Values = new List<object>(1) { objVal } };
retVal.Columns[colInfo.Name] = _col;
}
catch { }
}
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
}
else
{
LogEntry($"Could not get detailed connection information from citrix with id {Sessionid}. Session content is empty.", 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);
}
return null;
}
public override async Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>> GetDetailsTableResultsVirtualAsync(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 bIcaRttMSDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsIcaRttMS && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bIcaLatencyDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsIcaLatency && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bClientL7LatencyDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsClientL7Latency && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bServerL7LatencyDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsServerL7Latency && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bInputBandwidthUsedDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsInputBandwidthUsed && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bOutputBandwidthUsedDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsOutputBandwidthUsed && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bOutputBandwidthAvailableDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsOutputBandwidthAvailable && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bFpsDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsFps && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bInputFpsDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsInputFps && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bOutputFpsDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsOutputFps && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bWanLatencyDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsWanLatency && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
var bDcLatencyDetailExists = Tables.Exists(v => v.Name == constTableNameSessionDetailsDcLatency && v.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix);
if (!Identities.TryGetValue(enumFasdInformationClass.VirtualSession, out var session) || session?.Id is null)
return null;
if (!Identities.TryGetValue(enumFasdInformationClass.User, out var userIds) || userIds?.citrixTenantId is null)
return null;
var listTasks = new List<Task<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>>(2);
if (bIcaRttMSDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsIcaRttMSAsync(session.Id, userIds.citrixTenantId, requestInfo,MaxAge, RefTime, LogDeep + 1, Token); }));
if (bIcaLatencyDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsIcaLatencyAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime,LogDeep + 1, Token); }));
if (bClientL7LatencyDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsClientL7LatencyAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bServerL7LatencyDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsServerL7LatencyAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bInputBandwidthUsedDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsInputBandwidthUsedAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bOutputBandwidthUsedDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsOutputBandwidthUsedAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bOutputBandwidthAvailableDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsOutputBandwidthAvailableAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bFpsDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsFpsAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bInputFpsDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsInputFpsAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bOutputFpsDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsOutputFpsAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bWanLatencyDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsWanLatencyAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
if (bDcLatencyDetailExists)
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardDetailsTable>>(async () => { return await GetSessionMetricsDetailsDcLatencyAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, RefTime, LogDeep + 1, Token); }));
var arrRes = await Task.WhenAll(listTasks.ToArray());
var retVal = new List<cF4SDHealthCardRawData.cHealthCardDetailsTable>();
foreach (var Entry in arrRes)
if (Entry != null)
retVal.AddRange(Entry);
if (retVal.Count == 0)
return null;
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 override async Task<List<string>> GetQuickActionList()
{
var quickactions = new List<string>{
"Session Logoff",
"Session Hidden",
"Send Message to Session"
};
return await Task.FromResult(quickactions);
}
public async Task<dynamic> QuickActionRun(cF4SDServerQuickActionParameters jsonRequest, cF4sdWebRequestInfo requestInfo, CancellationToken Token)
{
dynamic result = null;
switch (jsonRequest.Action)
{
case "SessionLogoff":
result = await SessionLogoff(jsonRequest.Identities, requestInfo, CancellationToken.None);
break;
case "SessionHidden":
result = await SessionHidden(jsonRequest.Identities, requestInfo, CancellationToken.None);
break;
case "SendMessageToSession":
result = await SendMessageToSession(jsonRequest.Identities, requestInfo, CancellationToken.None);
break;
}
return result;
}
public async Task<dynamic> SessionLogoff(List<cF4sdIdentityEntry> Identities, cF4sdWebRequestInfo requestInfo, CancellationToken Token)
{
var Ids = await Collector.getConntectorIds(Identities, Token, requestInfo, 1);
if (!Ids.TryGetValue(enumFasdInformationClass.VirtualSession, out var session) || session?.Id is null)
return null;
if (!Ids.TryGetValue(enumFasdInformationClass.User, out var userIds) || userIds?.citrixTenantId is null)
return null;
var strUrl = string.Format(constCitrixSessionLogoff, session?.Id);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(userIds?.citrixTenantId, true);
if (citrixCommunication == null)
{
return null;
}
var Result = await citrixCommunication.RequestAsync(strUrl, httpMethod: eHttpMethod.post, retryForbidden: false);
if (Result != null)
{
var ResultJson = Result.Result as JObject;
if (ResultJson != null)
{
Collector.DoProcessUiMessage(3, $" properties of selected '{ResultJson}' with {ResultJson.Count} properties could be read.");
}
return ResultJson;
}
return null;
}
public async Task<dynamic> SessionHidden(List<cF4sdIdentityEntry> Identities, cF4sdWebRequestInfo requestInfo, CancellationToken Token)
{
var Ids = await Collector.getConntectorIds(Identities, Token, requestInfo, 1);
if (!Ids.TryGetValue(enumFasdInformationClass.VirtualSession, out var session) || session?.Id is null)
return null;
if (!Ids.TryGetValue(enumFasdInformationClass.User, out var userIds) || userIds?.citrixTenantId is null)
return null;
var strUrl = string.Format(constCitrixSessionHide, session?.Id);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(userIds?.citrixTenantId, true);
if (citrixCommunication == null)
{
return null;
}
var Result = await citrixCommunication.RequestAsync(strUrl, httpMethod: eHttpMethod.post, retryForbidden: false);
if (Result != null)
{
var ResultJson = Result.Result as JObject;
if (ResultJson != null)
{
Collector.DoProcessUiMessage(3, $" properties of selected '{ResultJson}' with {ResultJson.Count} properties could be read.");
}
return ResultJson;
}
return null;
}
public async Task<dynamic> SendMessageToSession(List<cF4sdIdentityEntry> Identities, cF4sdWebRequestInfo requestInfo, CancellationToken Token)
{
var Ids = await Collector.getConntectorIds(Identities, Token, requestInfo, 1);
if (!Ids.TryGetValue(enumFasdInformationClass.VirtualSession, out var session) || session?.Id is null)
return null;
if (!Ids.TryGetValue(enumFasdInformationClass.User, out var userIds) || userIds?.citrixTenantId is null)
return null;
var strUrl = string.Format(constCitrixSessionSendMessage, session?.Id);
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(userIds?.citrixTenantId, true);
if (citrixCommunication == null)
{
return null;
}
var message = new SessionMessage
{
Style = "Critical",
Title = "Abmeldung bevorstehend!",
Text = "Eine dringende Wartung muss durchgeführt werden. Sie werden in Kürze abgemeldet. Bitte speichern Sie Ihre Daten."
};
var Result = await citrixCommunication.RequestAsync(strUrl, httpMethod: eHttpMethod.post, message, retryForbidden: false);
if (Result != null)
{
var ResultJson = Result.Result as JObject;
if (ResultJson != null)
{
Collector.DoProcessUiMessage(3, $" properties of selected '{ResultJson}' with {ResultJson.Count} properties could be read.");
}
return ResultJson;
}
return null;
}
public override 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)
{
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 (!Identities.TryGetValue(enumFasdInformationClass.VirtualSession, out var session) || session?.Id is null)
return null;
if (!Identities.TryGetValue(enumFasdInformationClass.User, out var userIds) || userIds?.citrixTenantId is null)
return null;
var citrixTableNames = new HashSet<string>(Tables.Where(t => t?.ParentCluster?.Origin == enumDataHistoryOrigin.Citrix).Select(t => t.Name), StringComparer.Ordinal);
bool Has(string tableName) => tableName != null && citrixTableNames.Contains(tableName);
var _userExists = Has(constTableNameSessionUser);
var _sessionExists = Has(constTableNameSession);
var _machineExists = Has(constTableNameSessionMachine);
var _connectionExists = Has(constTableNameSessionConnection);
var _currentConnectionExists = Has(constTableNameSessionCurrentConnection);
var _sessionMetricsExists = Has(constTableNameSessionMetrics);
var retVal = new List<cF4SDHealthCardRawData.cHealthCardTable>();
var listTasks = new List<Task<List<cF4SDHealthCardRawData.cHealthCardTable>>>(2);
if (_sessionExists)
//if (CacheId == null && !instantly)
//{
// retVal.Add(new cF4SDHealthCardRawData.cHealthCardTable()
// {
// Name = constTableNameSessionMetrics,
// InformationClass = enumFasdInformationClass.VirtualSession,
// IsIncomplete = true
// });
//}
//else
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetSessionAsync(session.Id, userIds.citrixTenantId, requestInfo, LogDeep + 1, Token); }));
if (_sessionMetricsExists)
//if (CacheId == null && !instantly)
//{
// retVal.Add(new cF4SDHealthCardRawData.cHealthCardTable()
// {
// Name = constTableNameSessionMetrics,
// InformationClass = enumFasdInformationClass.VirtualSession,
// IsIncomplete = true
// });
//}
//else
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetSessionMetricsAsync(session.Id, userIds.citrixTenantId, requestInfo, MaxAge, LogDeep + 1, Token); }));
if (_machineExists)
//if (CacheId == null && !instantly)
//{
// retVal.Add(new cF4SDHealthCardRawData.cHealthCardTable()
// {
// Name = constTableNameMachineMetrics,
// InformationClass = enumFasdInformationClass.VirtualSession,
// IsIncomplete = true
// });
//}
//else
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetSessionMachineAsync(session.Id, userIds.citrixTenantId, requestInfo, LogDeep + 1, Token); }));
if (_connectionExists)
//if (CacheId == null && !instantly)
//{
// retVal.Add(new cF4SDHealthCardRawData.cHealthCardTable()
// {
// Name = constTableNameMachineMetrics,
// InformationClass = enumFasdInformationClass.VirtualSession,
// IsIncomplete = true
// });
//}
//else
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetSessionConnectionsAsync(session.Id, userIds.citrixTenantId, requestInfo, LogDeep + 1, Token); }));
if (_currentConnectionExists)
//if (CacheId == null && !instantly)
//{
// retVal.Add(new cF4SDHealthCardRawData.cHealthCardTable()
// {
// Name = constTableNameMachineMetrics,
// InformationClass = enumFasdInformationClass.VirtualSession,
// IsIncomplete = true
// });
//}
//else
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetSessionCurrentConnectionAsync(session.Id, userIds.citrixTenantId, requestInfo, LogDeep + 1, Token); }));
if (_userExists)
//if (CacheId == null && !instantly)
//{
// retVal.Add(new cF4SDHealthCardRawData.cHealthCardTable()
// {
// Name = constTableNameMachineMetrics,
// InformationClass = enumFasdInformationClass.VirtualSession,
// IsIncomplete = true
// });
//}
//else
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetSessionUserAsync(session.Id, userIds.citrixTenantId, requestInfo, LogDeep + 1, Token); }));
var arrRes = await Task.WhenAll(listTasks.ToArray());
foreach (var Entry in arrRes)
if (Entry != null)
retVal.AddRange(Entry);
if (retVal.Count == 0)
return null;
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<cCitrixCommunication> GetCitrixSessionsAsync()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var strUrl = string.Format(constCitrixSessionList, constCitrixUserPaging);
var tenants = Collector.InfrastructureConfig.CitrixTenants?.Values;
if (tenants is null)
{
Collector.DoProcessUiMessage(2, $" Could not logon to tenant - Tenant is null", LogLevels.Warning);
return null;
}
foreach (var Tenant in tenants)
{
var CitrixConn = await GetCitrixCommunicationForTenantAsync(Tenant.TenantID, true);
if (CitrixConn == null)
{
Collector.DoProcessUiMessage(2, $"error: could not logon to tenat {Tenant.Domain}", LogLevels.Error);
continue;
}
var Result = await CitrixConn.RequestAsync(strUrl, retryForbidden: false);
if (Result != null)
{
var _ty = Result.GetType();
var _props = Result.Result as JObject;
if (_props != null)
{
Collector.DoProcessUiMessage(3, $" properties of selected '{_props}' with {_props.Count} properties could be read.");
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public override async Task<bool> DoScanAsync(bool Always, bool Rescan, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool EnhancedDebug = 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
{
if (Always)
{
var scanInfo = await Collector.CitrixCollector.GetScanTimeInfoAsync(requestInfo, LogDeep + 1, Token);
if (scanInfo == null)
{
Collector.DoProcessUiMessage(0, "could not get valid scan times info for Citrix connector");
return false;
}
if (scanInfo.NextScan == null)
{
Collector.DoProcessUiMessage(0, "not valid next scan time info for Citrix connector");
return false;
}
var nextScan = (DateTime)scanInfo.NextScan;
if (!(scanInfo.LastScan is DateTime lastScan) || (lastScan >= nextScan))
{
Collector.DoProcessUiMessage(0, $"currently no scan needed for Citrix connector, lastScan={scanInfo.LastScan} (UTC), nextScan={scanInfo.NextScan} (UTC)");
return false;
}
}
Collector.DoProcessUiMessage(0, "");
if (Collector.InfrastructureConfig.CitrixTenants != null)
await DoCitrixScanAsync(requestInfo, LogDeep + 1, Token);
await Collector.SetLastScanTime("CitrixScan-all", DateTime.UtcNow, requestInfo, LogDeep + 1, Token);
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;
}
public async Task<bool> DoCitrixScanAsync(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 tenants = Collector.InfrastructureConfig.CitrixTenants?.Values;
if (tenants is null)
{
Collector.DoProcessUiMessage(2, $" could not logon to tenant - Tenant is null ", LogLevels.Error);
return true;
}
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateUserCitrix", out var QueryInsert))
return false;
using (var Conn = new cDbConnection(Collector.mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main sql database '{Collector.mainDbConnection.Database}', aborting scan...'", LogLevels.Error);
return false;
}
Collector.DoProcessUiMessage(0, string.Format("doing the Citrix cloud scans:"));
foreach (var Tenant in tenants)
{
try
{
Collector.DoProcessUiMessage(1, $"scanning tenat {Tenant.Domain} for users ...");
var CitrixConn = await GetCitrixCommunicationForTenantAsync(Tenant.TenantID, true);
if (CitrixConn == null)
{
Collector.DoProcessUiMessage(2, $"error: could not logon to tenat {Tenant.Domain}", LogLevels.Error);
continue;
}
var strUrl = string.Format(constCitrixUserList, constCitrixUserPaging);
var Result = await CitrixConn.RequestListAsync(strUrl, retryForbidden: false);
var Count = 0;
var Updated = 0;
while (Result != null == Result.Count > 0)
{
foreach (var Entry in Result)
{
Count++;
try
{
var _strId = Entry.Result.Id.ToString();
var _sid = Entry.Result.Sid.ToString();
var sid = new SecurityIdentifier(_sid);
var arrSid = new byte[sid.BinaryLength];
sid.GetBinaryForm(arrSid, 0);
var SqlParams = new Dictionary<string, object>(2)
{
{ "sid_bin", arrSid },
{ "id", _strId },
{ "tenant", Tenant.TenantID }
};
var _res = await DataHistorySqlHelper.ExecuteAsync(Conn, QueryInsert, SqlParams, requestInfo, Token);
if (_res > 0)
Updated++;
else
{
if (DataHistorySqlHelper.GetWellKnownSqlStatement("UpdateUserCitrix2", out var QueryInsert2))
{
string upn = Entry.Result.Upn.ToString();
var SqlParams2 = new Dictionary<string, object>(2)
{
{ "id", _strId },
{ "tenant", Tenant.TenantID },
{ "upn_internal", upn }
};
var _res2 = await DataHistorySqlHelper.ExecuteAsync(Conn, QueryInsert2, SqlParams2, requestInfo, Token);
if (_res2 > 0)
Updated++;
}
}
}
catch (Exception E)
{
LogException(E);
}
}
Collector.DoProcessUiMessage(2, $"{Count} accounts processed, {Updated} updated.");
if (Result.Count < constCitrixUserPaging)
break;
Result.Clear();
if (!await CitrixConn.RequestNextAsync(Result))
break;
}
}
catch (Exception E)
{
LogException(E);
}
Collector.DoProcessUiMessage(1, $"...scanning tenat {Tenant.Domain} finished");
}
Collector.DoProcessUiMessage(0, "... Citrix cloud scans finished.");
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;
}
public override async Task<List<object>> GetIds(cF4sdConnectorIds IdEntry, enumFasdInformationClass InfoClass, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
await Task.CompletedTask;
return new List<object>() { IdEntry.sid };
}
public override async Task<cScanTimeInfo> GetScanTimeInfoAsync(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
{
return await GetScanTimeInfoAsync(Collector.InfrastructureConfig.Citrix.ScanTiming, "CitrixScan", requestInfo, LogDeep, Token);
}
private static void AddToLdapPropertyList(List<cLdapPropertyInfo> list, ref Dictionary<string, cLdapPropertyInfo> dicLdap)
{
foreach (var Entry in list)
{
if (!dicLdap.ContainsKey(Entry.Name))
dicLdap.Add(Entry.Name.ToLowerInvariant(), Entry);
}
}
private Dictionary<string, cLdapPropertyInfo> GetPropertyList(enumFasdInformationClass InformationClass)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var dicLdap = new Dictionary<string, cLdapPropertyInfo>();
try
{
switch (InformationClass)
{
case enumFasdInformationClass.User:
AddToLdapPropertyList(UserMainProperties, ref dicLdap);
break;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return dicLdap;
}
public HashSet<enumFasdInformationClass> GetSupportedInformationClasses() => new HashSet<enumFasdInformationClass>() { enumFasdInformationClass.VirtualSession };
public async Task<cF4sdStagedSearchResultRelations> GetRelationsAsync(IEnumerable<cF4sdIdentityEntry> ids, enumFasdInformationClass informationClass, int age, CancellationToken token = default)
{
try
{
List<cF4sdConnectorIds> sessionsIds = await _collector.getConnectorIdList(ids.ToList(), token, null, 0);
List<cF4sdApiSearchResultRelation> relations = await GetUserSessionsAsync(sessionsIds, token, null);
return new cF4sdStagedSearchResultRelations() { Relations = relations };
}
catch (Exception ex)
{
LogException(ex);
}
return null;
}
private enumCitrixSessionStatus ConvertSessionStatusCode(int sessionStatus)
{
try
{
switch (sessionStatus)
{
case 0:
return enumCitrixSessionStatus.Unknown;
case 1:
return enumCitrixSessionStatus.Connected;
case 2:
return enumCitrixSessionStatus.Disconnected;
case 3:
return enumCitrixSessionStatus.Terminated;
case 4:
return enumCitrixSessionStatus.PreparingSession;
case 5:
return enumCitrixSessionStatus.Active;
case 6:
return enumCitrixSessionStatus.Reconnecting;
case 7:
return enumCitrixSessionStatus.NonBrokeredSession;
case 8:
return enumCitrixSessionStatus.Other;
case 9:
return enumCitrixSessionStatus.Pending;
}
}
catch (Exception E)
{
LogException(E);
}
return enumCitrixSessionStatus.Unknown;
}
private object GetAggregationValue(IEnumerable<object> objVal, eDataHistoryAggregationType AggregationType, enumFasdValueType ValueType)
{
double aggregatedValue;
switch (ValueType)
{
case enumFasdValueType.INT:
case enumFasdValueType.BIGINT:
case enumFasdValueType.FLOAT:
switch (AggregationType)
{
case eDataHistoryAggregationType.average:
return aggregatedValue = objVal.Where(v => v != null)
.Select(v =>Convert.ToDouble(v))
.DefaultIfEmpty(0)
.Average();
case eDataHistoryAggregationType.sum:
return aggregatedValue = objVal.Where(v => v != null)
.Select(v => Convert.ToDouble(v))
.DefaultIfEmpty(0)
.Sum();
case eDataHistoryAggregationType.max:
return aggregatedValue = objVal.Where(v => v != null)
.Select(v => v == DBNull.Value ? 0.0 : Convert.ToDouble(v))
.DefaultIfEmpty(0)
.Max();
case eDataHistoryAggregationType.min:
return aggregatedValue = objVal.Where(v => v != null)
.Select(v => v == DBNull.Value ? 0.0 : Convert.ToDouble(v))
.DefaultIfEmpty(0)
.Min();
case eDataHistoryAggregationType.Unknown:
return null;
}
break;
}
return null;
}
private object ConvertToF4sdType(object objVal, enumFasdValueType ValueType)
{
try
{
if (objVal != null)
{
switch (ValueType)
{
case enumFasdValueType.INT:
return cF4SDHealthCardRawData.GetInteger(objVal);
case enumFasdValueType.GUID:
return XML.cXmlParser.GetGuidFromString(objVal.ToString());
case enumFasdValueType.BOOLEAN:
if (objVal == null) return false;
if (objVal is bool) return (bool)objVal;
if (objVal is int) return (int)objVal != 0;
if (objVal is string) return bool.TryParse((string)objVal, out bool result) ? result : ((string)objVal == "1");
return false; // Standardrückgabewert, falls keine Bedingung zutrifft
case enumFasdValueType.DATETIME:
DateTime? dt = null;
if (objVal is DateTime _dt)
dt = _dt;
else
{
if (DateTime.TryParse(objVal.ToString(), out _dt))
dt = _dt;
}
if (dt is DateTime _dt2)
{
if (_dt2 == new DateTime(1, 1, 1, 0, 0, 0))
dt = null;
}
return dt;
default:
return objVal.ToString();
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
}
return null;
}
public class SessionMessage
{
public string Style { get; set; } = null;
public string Title { get; set; } = null;
public string Text { get; set; } = null;
}
}
public class cF4SDVirtualSession : cF4sdApiSearchResultRelation
{
public Guid SessionId { get; set; }
public string ConnectionState { get; set; }
public string FailureState { get; set; }
public string Startdate { get; set; }
public string Enddate { get; set; }
public string MachineId { get; set; }
public string MachineName { get; set; }
public Guid UserId { get; set; }
}
}