3147 lines
158 KiB
C#
3147 lines
158 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 constCitrixSessionLogInSummaries = "monitorodata/Sessions?$filter=UserId in ({0})$select=Id,StartDate&$expand=User($select=UserName),LogOnSummaries($select=LogOnDuration,AuthenticationDuration,BrokingDuration,ProfileLoadDuration,GpoProcessingDuration,InteractiveSessionDuration)";
|
|
public const string constCitrixSessionLogInSummaries2 = "monitorodata/LogOnSummaries?$expand=Session($expand=User)&$filter=UserId eq {0}";
|
|
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 constTableNameSessionStateMetrics = "citrix-connectionState-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 == res.Count > 0)
|
|
{
|
|
JObject sessionInfos = res[0].Result;
|
|
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = constTableNameSessionMetrics,
|
|
InformationClass = enumFasdInformationClass.VirtualSession,
|
|
Origin = enumDataHistoryOrigin.Citrix,
|
|
IsStatic = true,
|
|
TableType = eDataHistoryTableType.Static
|
|
};
|
|
|
|
foreach (var Entry in res) {
|
|
|
|
|
|
|
|
}
|
|
|
|
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.cHealthCardTable>> GetSessionStateMetricsAsync(cF4sdConnectorIds UserIds, 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
|
|
{
|
|
|
|
var strUrl = string.Format(constCitrixSessions, UserIds.citrixUserId.ToString());
|
|
|
|
if (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameSessionStateMetrics, out var SessionTableDetails))
|
|
return null;
|
|
|
|
var citrixCommunication = await GetCitrixCommunicationForTenantAsync(TenantId, true);
|
|
if (citrixCommunication == null)
|
|
return null;
|
|
|
|
var res = await citrixCommunication.RequestAsync(strUrl, retryForbidden: false);
|
|
if (res != null)
|
|
{
|
|
JObject sessionInfos = res.Result;
|
|
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = constTableNameSessionStateMetrics,
|
|
InformationClass = enumFasdInformationClass.VirtualSession,
|
|
IsStatic = true,
|
|
TableType = eDataHistoryTableType.Static
|
|
};
|
|
|
|
var dicVals = new List<Dictionary<string, object>>();
|
|
var vals = sessionInfos.Children();
|
|
var metricsObj = sessionInfos["value"] as JArray;
|
|
|
|
if (metricsObj != null)
|
|
{
|
|
dicVals = metricsObj
|
|
.OfType<JObject>()
|
|
.Where(o =>
|
|
o["StartDate"] != null &&
|
|
o["ConnectionState"] != null &&
|
|
DateTime.TryParse(o["StartDate"].ToString(), out _)
|
|
)
|
|
.GroupBy(o => new
|
|
{
|
|
Date = DateTime.Parse(o["StartDate"].ToString()).Date,
|
|
ConnectionState = (int)o["ConnectionState"]
|
|
})
|
|
.OrderBy(g => g.Key.Date)
|
|
.Select(g => new Dictionary<string, object>
|
|
{
|
|
{ "StartDate", g.Key.Date }, // ✅ DateTime
|
|
{ "ConnectionState", g.Key.ConnectionState },
|
|
{ "ConnectionCount", g.Count() }
|
|
})
|
|
.ToList();
|
|
|
|
|
|
|
|
|
|
const string startDateColumnName = "StartDate";
|
|
const string connectionStatusColumnName = "ConnectionState";
|
|
|
|
var groupedValues = dicVals
|
|
.Where(v =>
|
|
v.TryGetValue(startDateColumnName, out var collectDate) &&
|
|
collectDate is DateTime &&
|
|
v.TryGetValue(connectionStatusColumnName, out _))
|
|
.GroupBy(v => new
|
|
{
|
|
StartDate = ((DateTime)v[startDateColumnName]).Date,
|
|
ConnectionStatus = v[connectionStatusColumnName]
|
|
})
|
|
.Select(g => new Dictionary<string, object>
|
|
{
|
|
{ startDateColumnName, g.Key.StartDate },
|
|
{ connectionStatusColumnName, g.Key.ConnectionStatus },
|
|
{ "ConnectionCount", g.Count() }
|
|
})
|
|
.ToLookup(d => new
|
|
{
|
|
StartDate = (DateTime)d[startDateColumnName],
|
|
ConnectionStatus = d[connectionStatusColumnName],
|
|
ConnectionCount = d["ConnectionCount"]
|
|
});
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < MaxAge; i++)
|
|
{
|
|
DateTime referenceDate = DateTime.Now.AddDays(-i).Date;
|
|
|
|
//var valuesOfDay = groupedValues.FirstOrDefault(v => v.Key.Date == referenceDate);
|
|
var valuesOfDay = groupedValues.Where(g => g.Key.StartDate == referenceDate).SelectMany(g => g).ToList();
|
|
|
|
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));
|
|
}
|
|
else
|
|
{
|
|
var value = valuesOfColumn.FirstOrDefault();
|
|
AddColumnData(retVal, colInfo.SourceName, ConvertToF4sdType(value, 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 {UserIds}. 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); }));
|
|
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetSessionStateMetricsAsync(userIds, 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; }
|
|
}
|
|
|
|
|
|
}
|