Files
C4IT-F4SD-Collector/F4SD-Cockpit-ServerCore/DataHistoryConfigClusters.cs
2026-02-05 09:31:26 +01:00

2710 lines
144 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using System.Globalization;
using System.Reflection;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using C4IT.Logging;
using C4IT.XML;
using C4IT.Configuration;
using C4IT.FASD.Base;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public enum eDataHistoryTableCached { Default = 0, Yes = 1, No = 2 };
public enum eDataHistoryQueryType { Query = 0, Static = 1 }
public enum eDataHistoryAggregationType
{
Unknown = 0,
first = 1,
min = 2,
max = 3,
sum = 4,
average = 5,
count = 6,
valuecount = 7,
latestValue = 8,
latestTime = 9
}
public class cDataHistoryConfigClusters : cFasdBaseConfig
{
public static bool confUseBinValuesAsPrimaryKey = true;
public const string constFileNameF4sdConfig = "F4SD-DataClusters-Configuration.xml";
private const string constFileNameF4sdSchema = "F4SD-DataClusters-Configuration.xsd";
private const string constConfigRootElement = "F4SD-DataClusters-Configuration";
public static readonly Guid ConfigId = new Guid("28C26B80-C3E9-43E1-934E-57B7C2DBC374");
public Guid getId() { return ConfigId; }
public Dictionary<string, cDataHistoryConfigCluster> Clusters { get; private set; } = null;
public cDataHistoryConfigCluster MainCluster { get; private set; } = null;
public readonly Dictionary<string, cDataHistoryConfigTable> Tables = new Dictionary<string, cDataHistoryConfigTable>();
public readonly Dictionary<string, string> AlternateTableNames = new Dictionary<string, string>();
internal cDataHistoryConfigClusters() :
base(constFileNameF4sdConfig, constFileNameF4sdSchema, constConfigRootElement)
{
}
public override bool InstantiateProperties(XmlElement XRoot, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
MainCluster = new cDataHistoryConfigClusterMain(XRoot, this, Parser);
if (MainCluster == null)
{
Parser.AddMessage(XRoot, @"No valid main cluster were found in the configuration.", LogLevels.Fatal);
return false;
}
Clusters = cDataHistoryConfigCluster.LoadFromXml(XRoot, this, Parser);
if (Clusters == null)
{
Parser.AddMessage(XRoot, @"No valid clusters were found in the configuration.", LogLevels.Fatal);
return false;
}
Clusters.Add(MainCluster.Name, MainCluster);
// resolve the references
var _IsValid = true;
foreach (var Cluster in Clusters.Values)
foreach (var Table in Cluster.Tables.Values)
IsValid &= Table.ResolveReferences(Tables, Parser);
IsValid = _IsValid;
return true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public override bool DoXmlUpdates(XmlElement XmlRoot, bool withM42Config = false, bool withIntuneConfig = false, bool withMobileDeviceConfig = false, bool withCitrixConfig = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = false;
try
{
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "DataCluster[@Name='Main-ComputerInfo']"
, "<DataCluster Name=\"Main-ComputerInfo\" Origin=\"Main\" InformationClass=\"Computer\"/>"
, "InformationClasses"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='Main-ComputerInfo']"
, "Table[@Name='main-computer-quickaction-details']"
, "<Table Name=\"main-computer-quickaction-details\" SourceName=\"main-computer-quickaction\" Type=\"Events\" Key=\"DeviceId\" EventTimeCol=\"Start\" Cached=\"Yes\" LateDelivery=\"true\"><Table-Columns><Table-Column Name=\"DeviceId\" Type=\"guid\"/><Table-Column Name=\"Start\" Type=\"datetime\"/><Table-Column Name=\"Finish\" Type=\"datetime\"/><Table-Column Name=\"QActionName\" Type=\"string\" Cardinal=\"100\"/><Table-Column Name=\"ResultType\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"ExecutionType\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"Parameters\" Type=\"string\"/><Table-Column Name=\"Result\" Type=\"string\"/><Table-Column Name=\"ErrorCode\" Type=\"int\"/><Table-Column Name=\"ErrorDescription\" Type=\"string\"/></Table-Columns><AutoCreate-Historic-Table Name=\"main-computer-quickaction-history\"/></Table>"
, ""
);
RetVal |= DoXmlInsertTableRow(XmlRoot, "AD-UserInfo", "ad-user", "<Table-Column Name=\"domainDns\" SourceType =\"Static\" Type=\"string\" Cardinal=\"128\"/>", "account");
RetVal |= DoXmlInsertTableRow(XmlRoot, "AD-UserInfo", "ad-user", "<Table-Column Name=\"domainNB\" SourceType =\"Static\" Type=\"string\" Cardinal=\"16\"/>", "account");
RetVal |= DoXmlInsertTableRow(XmlRoot, "AD-ComputerInfo", "ad-computer", "<Table-Column Name=\"domainDns\" SourceType =\"Static\" Type=\"string\" Cardinal=\"128\"/>", "account");
RetVal |= DoXmlInsertTableRow(XmlRoot, "AD-ComputerInfo", "ad-computer", "<Table-Column Name=\"domainNB\" SourceType =\"Static\" Type=\"string\" Cardinal=\"16\"/>", "account");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-DeviceInfo", "agnt-computer-event-numerical", "<Table-Column Name=\"DeviceActivity\" SourceName=\"Device Activity\" Type=\"bigint\" Aggregation=\"sum\"/>");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-DeviceInfo", "agnt-computer-event-numerical", "<Table-Column Name=\"UserActivity\" SourceName=\"User Activity\" Type=\"bigint\" Aggregation=\"sum\"/>");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-DeviceInfo", "agnt-computer-event-numerical", "<Table-Column Name=\"ProcessorTaskManager\" SourceName=\"Task Manager % Score\" Type=\"float\" Aggregation=\"average\" LateDelivery=\"true\" />");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-DeviceInfo", "agnt-computer-event-numerical", "<Table-Column Name=\"CPUSpeed\" SourceName=\"CPU Speed\" Type=\"float\" Aggregation=\"average\" LateDelivery=\"true\" />");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-DeviceInfo", "agnt-computer-event-numerical", "<Table-Column Name=\"CPUBaseSpeed\" SourceName=\"CPU Base Speed\" Type=\"float\" Aggregation=\"average\" LateDelivery=\"true\" />");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-DeviceInfo", "agnt-computer-event-numerical", "<Table-Column Name=\"ProzessorHighEvents\" SourceName=\"Prozessor High Events\" Type=\"datetime\" Aggregation=\"count\" />");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-DeviceInfo", "agnt-computer-event-numerical", "<Table-Column Name=\"LoginDuration\" SourceName=\"Login Duration\" Type=\"bigint\" Aggregation=\"max\" />");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-DeviceInfo", "agnt-computer-event-numerical", "<Table-Column Name=\"ExtendedLoginDuration\" SourceName=\"Extended Login Duration\" Type=\"bigint\" Aggregation=\"max\" />");
RetVal |= DoXmlInsertTableRow(XmlRoot, "Agent-UserInfo", "agnt-user", "<Table-Column Name=\"accountType\" SourceType =\"Static\" Type=\"string\" Cardinal=\"16\"/>");
RetVal |= DoXmlInsertElement(XmlRoot,
"DataCluster[@Name='Agent-DeviceInfo']/Table[@Name='agnt-computer-event-numerical']",
"AdditionalTableName[@Name='agnt-computer-event-numerical-latest']",
"<AdditionalTableName Name =\"agnt-computer-event-numerical-latest\"/>",
"Table-Columns");
RetVal |= DoXmlInsertElement(XmlRoot,
"DataCluster[@Name='Agent-DeviceInfo']/Table[@Name='agnt-computer-event-string']",
"AdditionalTableName[@Name='agnt-computer-event-string-latest']",
"<AdditionalTableName Name =\"agnt-computer-event-string-latest\"/>",
"Table-Columns");
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='Agent-DeviceInfo']"
, "Table[@Name='agnt-computer-event-details-processorTaskManager']"
, "<Table Name=\"agnt-computer-event-details-processorTaskManager\" Type=\"Events\" Key=\"id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"id\" SourceName=\"DEVICECODE\" Type=\"int\" /><Table-Column Name=\"event\" SourceName=\"Task Manager % Score\" Type=\"string\" /><Table-Column Name=\"time\" SourceName=\"EVENTDATE\" Type=\"datetime\" /><Table-Column Name=\"Duration\" SourceName=\"DURATION\" Type=\"bigint\" /><Table-Column Name=\"Value\" SourceName=\"VALUE\" Type=\"float\" /></Table-Columns></Table>"
, "Table[@Name='agnt-computer-event-details-processorUsage']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='Agent-DeviceInfo']"
, "Table[@Name='agnt-computer-event-details-processorTaskManager']"
, "<Table Name=\"agnt-computer-event-details-processorTaskManager\" Type=\"Events\" Key=\"id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"id\" SourceName=\"DEVICECODE\" Type=\"int\" /><Table-Column Name=\"event\" SourceName=\"Task Manager % Score\" Type=\"string\" /><Table-Column Name=\"time\" SourceName=\"EVENTDATE\" Type=\"datetime\" /><Table-Column Name=\"Duration\" SourceName=\"DURATION\" Type=\"bigint\" /><Table-Column Name=\"Value\" SourceName=\"VALUE\" Type=\"float\" /></Table-Columns></Table>"
, "Table[@Name='agnt-computer-event-details-processorUsage']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='Agent-DeviceInfo']"
, "Table[@Name='agnt-computer-event-details-CPUSpeed']"
, "<Table Name=\"agnt-computer-event-details-CPUSpeed\" Type=\"Events\" Key=\"id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"id\" SourceName=\"DEVICECODE\" Type=\"int\" /><Table-Column Name=\"event\" SourceName=\"CPU Speed\" Type=\"string\" /><Table-Column Name=\"time\" SourceName=\"EVENTDATE\" Type=\"datetime\" /><Table-Column Name=\"Duration\" SourceName=\"DURATION\" Type=\"bigint\" /><Table-Column Name=\"Value\" SourceName=\"VALUE\" Type=\"float\" /></Table-Columns></Table>"
, "Table[@Name='agnt-computer-event-details-processorTaskManager']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='Agent-DeviceInfo']"
, "Table[@Name='agnt-computer-event-details-ProzessorHighEvents']"
, "<Table Name=\"agnt-computer-event-details-ProzessorHighEvents\" Type=\"Events\" Key=\"id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"id\" SourceName=\"DEVICECODE\" Type=\"int\" /><Table-Column Name=\"event\" SourceName=\"Prozessor High Events\" Type=\"string\" /><Table-Column Name=\"time\" SourceName=\"EVENTDATE\" Type=\"datetime\" /><Table-Column Name=\"Duration\" SourceName=\"DURATION\" Type=\"bigint\" /><Table-Column Name=\"Value\" SourceName=\"VALUE\" Type=\"float\" /></Table-Columns></Table>"
, "Table[@Name='agnt-computer-event-details-CPUSpeed']"
);
if (withIntuneConfig)
{
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "DataCluster[@Name='IntuneDeviceInfo']"
, "<DataCluster Name=\"IntuneDeviceInfo\" Origin=\"Intune\" InformationClass=\"Computer\"/>"
, "DataCluster[@Name='AD-ComputerInfo']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='IntuneDeviceInfo']"
, "Table[@Name='intune-deviceInfo']"
, "<Table Name=\"intune-deviceInfo\" Type=\"Static\" Key=\"id\"><Table-Columns><Table-Column Name=\"id\" Type=\"guid\"/><Table-Column Name=\"complianceState\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"userPrincipalName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"managementState\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"userDisplayName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"lastSyncDateTime\" Type=\"string\" Cardinal=\"64\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "DataCluster[@Name='IntuneUserInfo']"
, "<DataCluster Name=\"IntuneUserInfo\" Origin=\"Intune\" InformationClass=\"User\"/>"
, "DataCluster[@Name='IntuneDeviceInfo']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='IntuneUserInfo']"
, "Table[@Name='intune-userDeviceCount']"
, "<Table Name=\"intune-userDeviceCount\" Type=\"Static\" Key=\"id\"><Table-Columns><Table-Column Name=\"id\" Type=\"guid\"/><Table-Column Name=\"windows\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"iOS\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"android\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"linux\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"macOs\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"total\" Type=\"int\" Default=\"0\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='IntuneUserInfo']"
, "Table[@Name='intune-userDeviceCount-details']"
, "<Table Name=\"intune-userDeviceCount-details\" Type=\"StaticDetails\" Key=\"id\"><Table-Columns><Table-Column Name=\"id\" Type=\"guid\"/><Table-Column Name=\"deviceName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"model\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"operatingSystem\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"serialNumber\" Type=\"string\" Cardinal=\"64\"/></Table-Columns></Table>"
);
}
if (withIntuneConfig && withMobileDeviceConfig)
{
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "DataCluster[@Name='IntuneMobileDeviceInfo']"
, "<DataCluster Name=\"IntuneMobileDeviceInfo\" Origin=\"Intune\" InformationClass=\"MobileDevice\"/>"
, "DataCluster[@Name='IntuneUserInfo']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='IntuneMobileDeviceInfo']"
, "Table[@Name='intune-mobile-deviceInfo']"
, "<Table Name=\"intune-mobile-deviceInfo\" Type=\"Static\" Key=\"id\"><Table-Columns><Table-Column Name=\"id\" Type=\"guid\"/><Table-Column Name=\"complianceState\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"userPrincipalName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"managementState\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"userDisplayName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"lastSyncDateTime\" Type=\"datetime\"/><Table-Column Name=\"deviceName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"deviceRegistrationState\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"deviceType\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"easDeviceId\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"enrolledDateTime\" Type=\"datetime\"/><Table-Column Name=\"enrollmentProfileName\" Type=\"string\" Cardinal=\"128\"/><Table-Column Name=\"freeStorageSpaceInBytes\" Type=\"bigint\"/><Table-Column Name=\"imei\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"isEncrypted\" Type=\"boolean\"/><Table-Column Name=\"isSupervised\" Type=\"boolean\"/><Table-Column Name=\"jailBroken\" Type=\"boolean\"/><Table-Column Name=\"lostModeState\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"managedDeviceOwnerType\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"managementAgent\" Type=\"string\" Cardinal=\"16\"/><Table-Column Name=\"managementCertificateExpirationDate\" Type=\"datetime\"/><Table-Column Name=\"manufacturer\" Type=\"string\" Cardinal=\"128\"/><Table-Column Name=\"model\" Type=\"string\" Cardinal=\"128\"/><Table-Column Name=\"operatingSystem\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"osVersion\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"ownerType\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"phoneNumber\" Type=\"string\" Cardinal=\"32\"/><Table-Column Name=\"physicalMemoryInBytes\" Type=\"bigint\"/><Table-Column Name=\"serialNumber\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"subscriberCarrier\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"totalStorageSpaceInBytes\" Type=\"bigint\"/><Table-Column Name=\"wiFiMacAddress\" Type=\"string\" Cardinal=\"32\"/></Table-Columns></Table>"
);
}
if (withCitrixConfig)
{
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "DataCluster[@Name='citrixMetrics']"
, "<DataCluster Name=\"citrixMetrics\" Origin=\"Citrix\" InformationClass=\"VirtualSession\"/>"
, "DataCluster[@Name='AD-ComputerInfo']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session']"
, "<Table Name=\"citrix-session\" Type=\"Static\" Key=\"Id\"><Table-Columns><Table-Column Name=\"Id\" SourceName=\"SessionKey\" Type=\"guid\"/><Table-Column Name=\"StartDate\" Type=\"datetime\"/><Table-Column Name=\"EndDate\" Type=\"datetime\"/><Table-Column Name=\"LogOnDuration\" Type=\"int\"/><Table-Column Name=\"ConnectionState\" Type=\"int\" Cardinal=\"64\"/><Table-Column Name=\"EndpointName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"IsAnonymous\" Type=\"boolean\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-metrics']"
, "<Table Name=\"citrix-session-metrics\" Type=\"History\" Key=\"Id\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"CollectedDate\" Type=\"datetime\"/><Table-Column Name=\"IcaRttMS\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"IcaLatency\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"ClientL7Latency\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"ServerL7Latency\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"ConnectionState\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"InputBandwidthUsed\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"OutputBandwidthUsed\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"OutputBandwidthAvailable\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"Fps\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"InputFps\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"OutputFps\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"WanLatency\" Type=\"int\" Aggregation=\"average\"/><Table-Column Name=\"DcLatency\" Type=\"int\" Aggregation=\"average\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-icaRttMS']"
, "<Table Name=\"citrix-session-details-icaRttMS\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"IcaRttMS\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-icaLatency']"
, "<Table Name=\"citrix-session-details-icaLatency\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"IcaLatency\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-clientL7Latency']"
, "<Table Name=\"citrix-session-details-clientL7Latency\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"ClientL7Latency\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-serverL7Latency']"
, "<Table Name=\"citrix-session-details-serverL7Latency\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"ServerL7Latency\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-inputBandwidthUsed']"
, "<Table Name=\"citrix-session-details-inputBandwidthUsed\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"InputBandwidthUsed\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-outputBandwidthAvailable']"
, "<Table Name=\"citrix-session-details-outputBandwidthAvailable\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"OutputBandwidthAvailable\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-fps']"
, "<Table Name=\"citrix-session-details-fps\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"Fps\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-inputFps']"
, "<Table Name=\"citrix-session-details-inputFps\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"InputFps\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-outputFps']"
, "<Table Name=\"citrix-session-details-outputFps\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"OutputFps\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-wanLatency']"
, "<Table Name=\"citrix-session-details-wanLatency\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"WanLatency\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-details-dcLatency']"
, "<Table Name=\"citrix-session-details-dcLatency\" Type=\"Events\" Key=\"Id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"Id\" Type=\"int\"/><Table-Column Name=\"Value\" SourceName=\"DcLatency\" Type=\"int\"/><Table-Column Name=\"time\" SourceName=\"CollectedDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-machine']"
, "<Table Name=\"citrix-session-machine\" Type=\"Static\" Key=\"Id\"><Table-Columns><Table-Column Name=\"Id\" Type=\"guid\"/><Table-Column Name=\"Name\" Type=\"string\"/><Table-Column Name=\"CatalogName\" SourceName=\"Catalog\" SourceJsonField=\"Name\" Type=\"string\" Default=\"0\"/><Table-Column Name=\"AllocationType\" SourceName=\"Catalog\" SourceJsonField=\"AllocationType\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"DesktopGroupName\" SourceName=\"DesktopGroup\" SourceJsonField=\"Name\" Type=\"string\"/><Table-Column Name=\"DnsName\" Type=\"string\"/><Table-Column Name=\"HostedMachine\" SourceName=\"HostedMachineId\" Type=\"string\"/><Table-Column Name=\"IPAddress\" Type=\"string\"/><Table-Column Name=\"WindowsConnectionSetting\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"CurrentRegistrationState\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"AgentVersion\" Type=\"string\"/><Table-Column Name=\"CurrentSessionCount\" Type=\"int\"/><Table-Column Name=\"OSType\" Type=\"string\"/><Table-Column Name=\"IsInMaintenanceMode\" Type=\"boolean\"/><Table-Column Name=\"Cpu\" SourceName=\"CurrentLoadIndex\" SourceJsonField=\"Cpu\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"Memory\" SourceName=\"CurrentLoadIndex\" SourceJsonField=\"Memory\" Type=\"int\" Default=\"0\"/><Table-Column Name=\"Disk\" SourceName=\"CurrentLoadIndex\" SourceJsonField=\"Disk\" Type=\"int\" Default=\"0\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-user']"
, "<Table Name=\"citrix-session-user\" Type=\"Static\" Key=\"Id\"><Table-Columns><Table-Column Name=\"Id\" Type=\"guid\"/><Table-Column Name=\"UserName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"FullName\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"Domain\" Type=\"string\" Cardinal=\"64\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-connection']"
, "<Table Name=\"citrix-session-connection\" Type=\"Static\" Key=\"Id\"><Table-Columns><Table-Column Name=\"Id\" Type=\"guid\"/><Table-Column Name=\"LogOnStartDate\" Type=\"datetime\"/><Table-Column Name=\"LogOnEndDate\" Type=\"datetime\"/><Table-Column Name=\"BrokeringDuration\" Type=\"int\"/><Table-Column Name=\"VMStartStartDate\" Type=\"datetime\"/><Table-Column Name=\"VMStartEndDate\" Type=\"datetime\"/><Table-Column Name=\"HdxStartDate\" Type=\"datetime\"/><Table-Column Name=\"HdxEndDate\" Type=\"datetime\"/><Table-Column Name=\"AuthenticationDuration\" Type=\"int\"/><Table-Column Name=\"GpoStartDate\" Type=\"datetime\"/><Table-Column Name=\"GpoEndDate\" Type=\"datetime\"/><Table-Column Name=\"LogOnScriptsStartDate\" Type=\"datetime\"/><Table-Column Name=\"LogOnScriptsEndDate\" Type=\"datetime\"/><Table-Column Name=\"ProfileLoadStartDate\" Type=\"datetime\"/><Table-Column Name=\"ProfileLoadEndDate\" Type=\"datetime\"/><Table-Column Name=\"InteractiveStartDate\" Type=\"datetime\"/><Table-Column Name=\"InteractiveEndDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='citrixMetrics']"
, "Table[@Name='citrix-session-currentConnection']"
, "<Table Name=\"citrix-session-currentConnection\" Type=\"Static\" Key=\"Id\"><Table-Columns><Table-Column Name=\"Id\" Type=\"guid\"/><Table-Column Name=\"ClientName\" Type=\"string\"/><Table-Column Name=\"ClientAddress\" Type=\"string\"/><Table-Column Name=\"ClientVersion\" Type=\"string\"/><Table-Column Name=\"ClientPlatform\" Type=\"string\"/><Table-Column Name=\"ConnectedViaIPAddress\" Type=\"string\"/><Table-Column Name=\"LaunchedViaHostName\" Type=\"string\"/><Table-Column Name=\"LogOnStartDate\" Type=\"datetime\"/><Table-Column Name=\"LogOnEndDate\" Type=\"datetime\"/><Table-Column Name=\"BrokeringDuration\" Type=\"int\"/><Table-Column Name=\"VMStartStartDate\" Type=\"datetime\"/><Table-Column Name=\"VMStartEndDate\" Type=\"datetime\"/><Table-Column Name=\"HdxStartDate\" Type=\"datetime\"/><Table-Column Name=\"HdxEndDate\" Type=\"datetime\"/><Table-Column Name=\"AuthenticationDuration\" Type=\"int\"/><Table-Column Name=\"GpoStartDate\" Type=\"datetime\"/><Table-Column Name=\"GpoEndDate\" Type=\"datetime\"/><Table-Column Name=\"LogOnScriptsStartDate\" Type=\"datetime\"/><Table-Column Name=\"LogOnScriptsEndDate\" Type=\"datetime\"/><Table-Column Name=\"ProfileLoadStartDate\" Type=\"datetime\"/><Table-Column Name=\"ProfileLoadEndDate\" Type=\"datetime\"/><Table-Column Name=\"InteractiveStartDate\" Type=\"datetime\"/><Table-Column Name=\"InteractiveEndDate\" Type=\"datetime\"/><Table-Column Name=\"UserInitStartDate\" Type=\"datetime\"/><Table-Column Name=\"UserInitEndDate\" Type=\"datetime\"/><Table-Column Name=\"AppxAssociationStartDate\" Type=\"datetime\"/><Table-Column Name=\"AppxAssociationEndDate\" Type=\"datetime\"/><Table-Column Name=\"AppxLoadPackageStartDate\" Type=\"datetime\"/><Table-Column Name=\"AppxLoadPackageEndDate\" Type=\"datetime\"/></Table-Columns></Table>"
);
}
if (withM42Config)
{
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "DataCluster[@Name='M42Tickets']"
, "<DataCluster Name=\"M42Tickets\" Origin=\"M42Wpm\" InformationClass=\"Ticket\" Description=\"Ticket &amp; incident data from Matrix42 Workplace Management\"/>"
, "DataCluster[@Name='AD-ComputerInfo']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Tickets']"
, "<Table Name=\"M42Wpm-Tickets\" Type=\"Static\" Key=\"id\"><Table-Columns><Table-Column Name=\"id\" SourceName=\"TicketObjectId\" Type=\"guid\"/><Table-Column Name=\"name\" SourceName=\"Name\" Type=\"string\" Cardinal =\"10\"/><Table-Column Name=\"Summary\" Type=\"string\" Cardinal =\"1024\"/><Table-Column Name=\"Status\" Type=\"string\" Cardinal =\"64\"/><Table-Column Name=\"StatusId\" Type=\"int\"/><Table-Column Name=\"AssetCIName\" Type=\"string\" Cardinal =\"64\"/><Table-Column Name=\"AssetName\" Type=\"string\" Cardinal =\"64\"/><Table-Column Name=\"AffectedUserId\" Type=\"guid\"/><Table-Column Name=\"AssetId\" Type=\"guid\"/><Table-Column Name=\"CreationDate\" Type=\"datetime\"/><Table-Column Name=\"ClosingDate\" Type=\"datetime\"/><Table-Column Name=\"CreationSourceId\" Type=\"int\"/><Table-Column Name=\"CreationSource\" Type=\"string\" Cardinal =\"256\"/><Table-Column Name=\"Description\" Type=\"string\"/><Table-Column Name=\"DescriptionHtml\" Type=\"string\"/><Table-Column Name=\"Solution\" Type=\"string\"/><Table-Column Name=\"SolutionHtml\" Type=\"string\" IsWritable=\"true\"/><Table-Column Name=\"PriorityId\" Type=\"int\"/><Table-Column Name=\"Priority\" Type=\"string\" Cardinal =\"256\"/><Table-Column Name=\"CategoryId\" Type=\"guid\"/><Table-Column Name=\"Category\" Type=\"string\" Cardinal =\"256\"/><Table-Column Name=\"CategoryHierarchical\" Type=\"string\" Cardinal =\"1024\"/><Table-Column Name=\"CIName\" Type=\"string\" Cardinal =\"64\"/><Table-Column Name=\"DirectLinkEdit\" Type=\"string\" Cardinal =\"1024\"/><Table-Column Name=\"AssetCIId\" Type=\"guid\"/><Table-Column Name=\"AssetSKUAssetGroupId\" Type=\"int\"/><Table-Column Name=\"AssetSKUAssetGroup\" Type=\"string\" Cardinal =\"256\"/><Table-Column Name=\"AssetSKUTypeId\" Type=\"int\"/><Table-Column Name=\"AssetSKUType\" Type=\"string\" Cardinal =\"256\"/><Table-Column Name=\"DirectLinkPreview\" Type=\"string\" Cardinal =\"1024\"/><Table-Column Name=\"DirectLinkClose\" Type=\"string\" Cardinal =\"1024\"/><Table-Column Name=\"AffectedUser\" Type=\"string\" Cardinal =\"256\"/><Table-Column Name=\"Urgency\" Type=\"string\" Cardinal=\"64\" /><Table-Column Name=\"UrgencyId\" Type=\"int\" /><Table-Column Name=\"Impact\" Type=\"string\" Cardinal=\"64\" /><Table-Column Name=\"ImpactId\" Type=\"int\" /></Table-Columns></Table>"
, "-first-"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-History']"
, "<Table Name=\"M42Wpm-Ticket-History\" Type=\"HistoryEvents\" Key=\"id\" EventTimeCol=\"time\"><Table-Columns><Table-Column Name=\"id\" SourceName=\"ActivityObjectId\" Type=\"guid\"/><Table-Column Name=\"time\" SourceName=\"CreationDate\" Type=\"datetime\"/><Table-Column Name=\"CreatedBy\" Type=\"string\" Cardinal=\"64\"/><Table-Column Name=\"Header\" Type=\"string\" Cardinal=\"1024\"/><Table-Column Name=\"Description\" Type=\"string\"/><Table-Column Name=\"DescriptionHtml\" Type=\"string\"/><Table-Column Name=\"IsVisibleForUser\" Type=\"boolean\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Tickets']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-Services']"
, "<Table Name=\"M42Wpm-Ticket-Services\" Type=\"Selection\" Key=\"id\"><Matrix42-DataQueryItems-Template EntityClassName=\"SPSArticleClassBase\" EntityTypeNames=\"SPSArticleTypeService SPSArticleTypeGroup SVCServiceTypeBundle SVCServiceTypeConfigGroup\" OrderBy=\"\" WhereExpression=\"\" /><Table-Columns><Table-Column Name=\"id\" SourceName=\"Id\" Type=\"guid\"/><Table-Column Name=\"SysObjectId\" SourceName=\"Sys-ObjectId\" Type=\"guid\"/><Table-Column Name=\"SysName\" SourceName=\"Sys-Name\" Type=\"string\" Cardinal=\"50\"/><Table-Column Name=\"PortalName\" Type=\"string\" Cardinal =\"300\"/><Table-Column Name=\"Name\" Type=\"string\" Cardinal =\"300\"/><Table-Column Name=\"Status\" Type=\"string\" Cardinal =\"50\"/><Table-Column Name=\"ServiceType\" Type=\"int\"/><Table-Column Name=\"Contact\" Type=\"string\" Cardinal=\"1024\"/><Table-Column Name=\"TechnicalOwner\" Type=\"string\" Cardinal=\"1024\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Ticket-History']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-Assets']"
, "<Table Name=\"M42Wpm-Ticket-Assets\" Type=\"Selection\" Key=\"id\"><Matrix42-DataQueryItems-Template EntityClassName=\"SPSAssetClassBase\" EntityTypeNames=\"SPSComputerType SPSMonitorType SPSPrinterType SPSAssetTypeMobile SPSAssetTypeSIM SPSAssetTypeGenericPeripheralDevice SPSAssetTypeNetworkDevice SPSAssetType\" OrderBy=\"\" WhereExpression=\"\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Id\" Type=\"guid\"/><Table-Column Name=\"SysObjectId\" SourceName=\"Sys-ObjectId\" Type=\"guid\"/><Table-Column Name=\"SysName\" SourceName=\"Sys-Name\" Type=\"string\" Cardinal=\"50\"/><Table-Column Name=\"Asset\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"AssetName\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Host\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"InventoryNumber\" Type=\"string\" Cardinal=\"100\"/><Table-Column Name=\"AssetAssignedUser\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"AssetSKUManName\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"AssetSKUModel\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"SerialNumber\" Type=\"string\" Cardinal=\"100\"/><Table-Column Name=\"CostCenter\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Location\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"OrganizationalUnit\" Type=\"string\" Cardinal=\"300\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Ticket-Services']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-QuickCalls']"
, "<Table Name=\"M42Wpm-Ticket-QuickCalls\" Type=\"Selection\" Key=\"id\"><Matrix42-DataQueryItems-Template EntityClassName=\"SPSQuickCallClassBase\" EntityTypeNames=\"SPSQuickCallType\" OrderBy=\"\" WhereExpression=\"Restricted = 0\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Id\" Type=\"guid\"/><Table-Column Name=\"SysObjectId\" SourceName=\"Sys-ObjectId\" Type=\"guid\"/><Table-Column Name=\"SysName\" SourceName=\"Sys-Name\" Type=\"string\" Cardinal=\"50\"/><Table-Column Name=\"Name\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Subject\" Type=\"string\" Cardinal=\"1024\"/><Table-Column Name=\"Priority\" Type=\"string\" Cardinal=\"100\"/><Table-Column Name=\"Responsible\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"ResponsibleRole\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Category\" SourceName=\"Category_Value\" Type=\"guid\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Ticket-Assets']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-Categories']"
, "<Table Name=\"M42Wpm-Ticket-Categories\" Type=\"Selection\" Key=\"id\"><Matrix42-DataQueryItems-Template EntityClassName=\"SPSScCategoryClassBase\" EntityTypeNames=\"SPSScCategoryType\" OrderBy=\"\" WhereExpression=\"Hidden = 0\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Id\" Type=\"guid\"/><Table-Column Name=\"SysObjectId\" SourceName=\"Sys-ObjectId\" Type=\"guid\"/><Table-Column Name=\"SysName\" SourceName=\"Sys-Name\" Type=\"string\" Cardinal=\"50\"/><Table-Column Name=\"Name\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"parentValue\" SourceName=\"Parent_Value\" Type=\"guid\"/><Table-Column Name=\"parent\" SourceName=\"Parent\" Type=\"string\" Cardinal=\"300\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Ticket-QuickCalls']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-SLAs']"
, "<Table Name=\"M42Wpm-Ticket-SLAs\" Type=\"Selection\" Key=\"id\"><Matrix42-DataQueryItems-Template EntityClassName=\"SVCServiceLevelAgreementClassBase\" EntityTypeNames=\"\" OrderBy=\"\" WhereExpression=\"\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Id\" Type=\"guid\"/><Table-Column Name=\"SysObjectId\" SourceName=\"Sys-ObjectId\" Type=\"guid\"/><Table-Column Name=\"SysName\" SourceName=\"Sys-Name\" Type=\"string\" Cardinal=\"50\"/><Table-Column Name=\"ContractNumber\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Summary\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Responsible\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"EffectiveDate\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"ExpireDate\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"State\" Type=\"string\" Cardinal=\"300\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Ticket-Categories']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-CloseCase-Services']"
, "<Table Name=\"M42Wpm-Ticket-CloseCase-Services\" Type=\"Selection\" Key=\"id\"><Matrix42-DataQueryItems-Template EntityClassName=\"SPSArticleClassBase\" EntityTypeNames=\"SPSArticleTypeService SPSArticleTypeGroup SVCServiceTypeBundle SVCServiceTypeConfigGroup\" OrderBy=\"\" WhereExpression=\"EXISTS(SUBQUERY(SVCServiceBookingClassBase AS B, B.ID, base.ID = B.Service AND B.ProvisioningStatus = 1 AND b.Uninstalled = 0 AND b.OrderType &lt;&gt; 20 AND B.Consumer.Accounts.T(SPSAccountClassAD).ADCn = '{0}'))\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Id\" Type=\"guid\"/><Table-Column Name=\"SysObjectId\" SourceName=\"Sys-ObjectId\" Type=\"guid\"/><Table-Column Name=\"DisplayName\" SourceName=\"Sys-DisplayName\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Name\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"ServiceID\" SourceName=\"ArticleID\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Description\" Type=\"string\" Cardinal=\"300\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Ticket-SLAs']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-Roles']"
, "<Table Name=\"M42Wpm-Ticket-Roles\" Type=\"Selection\" Key=\"id\"><Matrix42-DataQueryItems-Template EntityClassName=\"SPSScRoleClassBase\" EntityTypeNames=\"SPSSecurityTypeRole\" OrderBy=\"\" WhereExpression=\"T(SPSSecurityClassRole).ShowInForwardAction = 1 AND T(SPSSecurityClassRole).Queue.ID IS NULL\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Id\" Type=\"guid\"/><Table-Column Name=\"SysObjectId\" SourceName=\"Sys-ObjectId\" Type=\"guid\"/><Table-Column Name=\"Name\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Description\" Type=\"string\" Cardinal=\"300\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Ticket-CloseCase-Services']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42Tickets']"
, "Table[@Name='M42Wpm-Ticket-Persons']"
, "<Table Name=\"M42Wpm-Ticket-Persons\" Type=\"Selection\" Key=\"id\"><Matrix42-DataQueryItems-Template EntityClassName=\"SPSUserClassBase\" EntityTypeNames=\"\" OrderBy=\"\" WhereExpression=\"(EXISTS(SUBQUERY(SPSSecurityClassRole as Role, Role.ID, Role.ID='6167BCDB-9A7D-4736-B215-4218FB64360D' and Role.ShowInForwardAction = 1)) OR MemberOf.ShowInForwardAction = 1) AND MemberOf.Queue.ID IS NULL AND T(SPSCommonClassBase).State = 2023\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Id\" Type=\"guid\"/><Table-Column Name=\"SysObjectId\" SourceName=\"Sys-ObjectId\" Type=\"guid\"/><Table-Column Name=\"LastName\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"FirstName\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"MailAddress\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"BusinessPhone\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"MobilePhone\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"CostCenter\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Organization\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Location\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Position\" Type=\"string\" Cardinal=\"300\"/><Table-Column Name=\"Status\" Type=\"string\" Cardinal=\"300\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Ticket-Roles']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "DataCluster[@Name='M42UserInfo']"
, "<DataCluster Name=\"M42UserInfo\" Origin=\"M42Wpm\" InformationClass=\"User\" Description=\"User related data from Matrix42 Workplace Management\"/>"
, "DataCluster[@Name='M42Tickets']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-User-NewTicket']"
, "<Table Name=\"M42Wpm-User-NewTicket\" Type=\"Static\" Key=\"id\"><Table-Columns><Table-Column Name=\"id\" Type=\"sid\"/><Table-Column Name=\"Link\" Type=\"string\" Cardinal =\"1024\"/><Table-Column Name=\"SubjectParameter\" Type=\"string\" Cardinal =\"128\"/><Table-Column Name=\"DescriptionParameter\" Type=\"string\" Cardinal =\"128\"/></Table-Columns></Table>"
, "-first-"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-Pickup-TicketStatus']"
, "<Table Name=\"M42Wpm-Pickup-TicketStatus\" Type=\"Static\" Key=\"id\"><Matrix42-Pickup-Template PickupName=\"SPSCommonPickupObjectStatus\" FilteredGroup=\"7\" Sorting=\"byPosition\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Value\" Type=\"int\"/><Table-Column Name=\"name\" SourceName=\"DisplayString\" Type=\"string\" Cardinal =\"150\"/><Table-Column Name=\"hidden\" SourceName =\"Hidden\" Type=\"boolean\"/><Table-Column Name=\"position\" SourceName =\"Position\" Type=\"int\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-User-NewTicket']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-Pickup-IncidentNotificationMode']"
, "<Table Name=\"M42Wpm-Pickup-IncidentNotificationMode\" Type=\"Static\" Key=\"id\"><Matrix42-Pickup-Template PickupName=\"SVMIncidentPickupSendNotifications\" Sorting=\"byName\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Value\" Type=\"int\"/><Table-Column Name=\"name\" SourceName=\"DisplayString\" Type=\"string\" Cardinal =\"150\"/><Table-Column Name=\"hidden\" SourceName =\"Hidden\" Type=\"boolean\"/><Table-Column Name=\"position\" SourceName =\"Position\" Type=\"int\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Pickup-TicketStatus']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-Pickup-TicketTypes']"
, "<Table Name=\"M42Wpm-Pickup-TicketTypes\" Type=\"Static\" Key=\"id\"><Matrix42-Pickup-Template PickupName=\"SPSTicketPickupType\" Sorting=\"byPosition\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Value\" Type=\"int\"/><Table-Column Name=\"name\" SourceName=\"DisplayString\" Type=\"string\" Cardinal =\"150\"/><Table-Column Name=\"hidden\" SourceName =\"Hidden\" Type=\"boolean\"/><Table-Column Name=\"position\" SourceName =\"Position\" Type=\"int\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Pickup-IncidentNotificationMode']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-Pickup-ActivityImpact']"
, "<Table Name=\"M42Wpm-Pickup-ActivityImpact\" Type=\"Static\" Key=\"id\"><Matrix42-Pickup-Template PickupName=\"SVMActivityPickupImpact\" Sorting=\"byPosition\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Value\" Type=\"int\"/><Table-Column Name=\"name\" SourceName=\"DisplayString\" Type=\"string\" Cardinal =\"150\"/><Table-Column Name=\"hidden\" SourceName =\"Hidden\" Type=\"boolean\"/><Table-Column Name=\"position\" SourceName =\"Position\" Type=\"int\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Pickup-TicketTypes']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-Pickup-IncidentEntry']"
, "<Table Name=\"M42Wpm-Pickup-IncidentEntry\" Type=\"Static\" Key=\"id\"><Matrix42-Pickup-Template PickupName=\"SPSActivityIncidentPickupEntry\" Sorting=\"byPosition\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Value\" Type=\"int\"/><Table-Column Name=\"name\" SourceName=\"DisplayString\" Type=\"string\" Cardinal =\"150\"/><Table-Column Name=\"hidden\" SourceName =\"Hidden\" Type=\"boolean\"/><Table-Column Name=\"position\" SourceName =\"Position\" Type=\"int\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Pickup-ActivityImpact']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-Pickup-ActivityUrgency']"
, "<Table Name=\"M42Wpm-Pickup-ActivityUrgency\" Type=\"Static\" Key=\"id\"><Matrix42-Pickup-Template PickupName=\"SVMActivityPickupUrgency\" Sorting=\"byPosition\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Value\" Type=\"int\"/><Table-Column Name=\"name\" SourceName=\"DisplayString\" Type=\"string\" Cardinal =\"150\"/><Table-Column Name=\"hidden\" SourceName =\"Hidden\" Type=\"boolean\"/><Table-Column Name=\"position\" SourceName =\"Position\" Type=\"int\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Pickup-IncidentEntry']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-Pickup-ActivityErrorType']"
, "<Table Name=\"M42Wpm-Pickup-ActivityErrorType\" Type=\"Static\" Key=\"id\"><Matrix42-Pickup-Template PickupName=\"SVMActivityPickupErrorType\" Sorting=\"byPosition\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Value\" Type=\"int\"/><Table-Column Name=\"name\" SourceName=\"DisplayString\" Type=\"string\" Cardinal =\"150\"/><Table-Column Name=\"hidden\" SourceName =\"Hidden\" Type=\"boolean\"/><Table-Column Name=\"position\" SourceName =\"Position\" Type=\"int\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Pickup-ActivityUrgency']"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "DataCluster[@Name='M42UserInfo']"
, "Table[@Name='M42Wpm-Pickup-ObjectStateReason']"
, "<Table Name=\"M42Wpm-Pickup-ObjectStateReason\" Type=\"Static\" Key=\"id\"><Matrix42-Pickup-Template PickupName=\"SPSCommonPickupObjectStateReason\" Sorting=\"byPosition\"/><Table-Columns><Table-Column Name=\"id\" SourceName=\"Value\" Type=\"int\"/><Table-Column Name=\"name\" SourceName=\"DisplayString\" Type=\"string\" Cardinal =\"150\"/><Table-Column Name=\"hidden\" SourceName =\"Hidden\" Type=\"boolean\"/><Table-Column Name=\"position\" SourceName =\"Position\" Type=\"int\"/><Table-Column Name=\"state\" SourceName =\"State\" Type=\"int\"/><Table-Column Name=\"stategroup\" SourceName =\"StateGroup\" Type=\"int\"/></Table-Columns></Table>"
, "Table[@Name='M42Wpm-Pickup-ActivityErrorType']"
);
}
// update table 'M42Wpm-Tickets' columns
RetVal |= DoXmlInsertTableRow(XmlRoot, "M42Tickets", "M42Wpm-Tickets", "<Table-Column Name=\"Urgency\" Type=\"string\" Cardinal=\"64\"/>", "AffectedUser");
RetVal |= DoXmlInsertTableRow(XmlRoot, "M42Tickets", "M42Wpm-Tickets", "<Table-Column Name=\"UrgencyId\" Type=\"int\"/>", "Urgency");
RetVal |= DoXmlInsertTableRow(XmlRoot, "M42Tickets", "M42Wpm-Tickets", "<Table-Column Name=\"Impact\" Type=\"string\" Cardinal=\"64\"/>", "UrgencyId");
RetVal |= DoXmlInsertTableRow(XmlRoot, "M42Tickets", "M42Wpm-Tickets", "<Table-Column Name=\"ImpactId\" Type=\"int\"/>", "Impact");
RetVal |= DoXmlInsertTableRow(XmlRoot, "M42Tickets", "M42Wpm-Ticket-QuickCalls", "<Table-Column Name=\"Category\" SourceName=\"Category_Value\" Type=\"guid\" />", "ResponsibleRole");
var quickCallsCategoryColumn = XmlRoot.SelectSingleNode("DataCluster[@Name='M42Tickets']/Table[@Name='M42Wpm-Ticket-QuickCalls']/Table-Columns/Table-Column[@Name='Category']") as XmlElement;
if (quickCallsCategoryColumn != null)
{
if (!string.Equals(quickCallsCategoryColumn.GetAttribute("SourceName"), "Category_Value", StringComparison.OrdinalIgnoreCase))
{
quickCallsCategoryColumn.SetAttribute("SourceName", "Category_Value");
RetVal = true;
}
if (!string.Equals(quickCallsCategoryColumn.GetAttribute("Type"), "guid", StringComparison.OrdinalIgnoreCase))
{
quickCallsCategoryColumn.SetAttribute("Type", "guid");
RetVal = true;
}
}
var categoriesColumns = XmlRoot.SelectSingleNode("DataCluster[@Name='M42Tickets']/Table[@Name='M42Wpm-Ticket-Categories']/Table-Columns") as XmlElement;
if (categoriesColumns != null)
{
RetVal |= DoXmlInsertTableRow(XmlRoot, "M42Tickets", "M42Wpm-Ticket-Categories", "<Table-Column Name=\"parentValue\" SourceName=\"Parent_Value\" Type=\"guid\" />", "Name");
RetVal |= DoXmlInsertTableRow(XmlRoot, "M42Tickets", "M42Wpm-Ticket-Categories", "<Table-Column Name=\"parent\" SourceName=\"Parent\" Type=\"string\" Cardinal=\"300\" />", "parentValue");
var parentValueColumn = categoriesColumns.SelectSingleNode("Table-Column[@Name='parentValue']") as XmlElement;
if (parentValueColumn != null)
{
if (!string.Equals(parentValueColumn.GetAttribute("SourceName"), "Parent_Value", StringComparison.OrdinalIgnoreCase))
{
parentValueColumn.SetAttribute("SourceName", "Parent_Value");
RetVal = true;
}
if (!string.Equals(parentValueColumn.GetAttribute("Type"), "guid", StringComparison.OrdinalIgnoreCase))
{
parentValueColumn.SetAttribute("Type", "guid");
RetVal = true;
}
}
var parentColumn = categoriesColumns.SelectSingleNode("Table-Column[@Name='parent']") as XmlElement;
if (parentColumn != null)
{
if (!string.Equals(parentColumn.GetAttribute("SourceName"), "Parent", StringComparison.OrdinalIgnoreCase))
{
parentColumn.SetAttribute("SourceName", "Parent");
RetVal = true;
}
if (!string.Equals(parentColumn.GetAttribute("Type"), "string", StringComparison.OrdinalIgnoreCase))
{
parentColumn.SetAttribute("Type", "string");
RetVal = true;
}
if (!string.Equals(parentColumn.GetAttribute("Cardinal"), "300", StringComparison.OrdinalIgnoreCase))
{
parentColumn.SetAttribute("Cardinal", "300");
RetVal = true;
}
}
}
// correct the type attribute for the M42Wpm-Ticket-History table to Events
var M42JournalItemNode = XmlRoot.SelectSingleNode("DataCluster[@Name='M42Tickets']/Table[@Name='M42Wpm-Ticket-History' and @Type!='HistoryEvents']") as XmlElement;
if (M42JournalItemNode != null)
{
M42JournalItemNode.SetAttribute("Type", "HistoryEvents");
RetVal = true;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
public static enumFasdValueType ResultingAggregationType(enumFasdValueType vt, eDataHistoryAggregationType at)
{
switch (at)
{
case eDataHistoryAggregationType.count:
case eDataHistoryAggregationType.valuecount:
return enumFasdValueType.INT;
case eDataHistoryAggregationType.latestTime:
return enumFasdValueType.DATETIME;
case eDataHistoryAggregationType.sum:
if (vt == enumFasdValueType.VERSION)
return enumFasdValueType.STRING;
return vt;
}
return vt;
}
public static string GetSqlDataTypeFromHistoryType(enumFasdValueType type, int Cardinal, bool isBinaryType = false)
{
try
{
if (isBinaryType)
{
switch (type)
{
case enumFasdValueType.VERSION:
return "[varbinary](10)";
case enumFasdValueType.MD5:
return "[binary](16)";
case enumFasdValueType.SID:
return "[varbinary](68)";
case enumFasdValueType.IPV4:
return "[binary](4)";
case enumFasdValueType.IPV6:
return "[binary](16)";
}
return null;
}
switch (type)
{
case enumFasdValueType.STRING:
if (Cardinal <= 0 || Cardinal >= 4000)
return string.Format("[nvarchar](max)", Cardinal);
return string.Format("[nvarchar]({0})", Cardinal);
case enumFasdValueType.GUID:
return "[uniqueidentifier]";
case enumFasdValueType.INT:
return "[int]";
case enumFasdValueType.BIGINT:
return "[bigint]";
case enumFasdValueType.FLOAT:
return "[float]";
case enumFasdValueType.DATETIME:
return "[datetime]";
case enumFasdValueType.VERSION:
return "[nvarchar](50)";
case enumFasdValueType.MD5:
return "[nvarchar](50)";
case enumFasdValueType.SID:
return "[nvarchar](200)";
case enumFasdValueType.IPV4:
return "[nvarchar](50)";
case enumFasdValueType.IPV6:
return "[nvarchar](50)";
case enumFasdValueType.TEXT:
return "[ntext]";
case enumFasdValueType.BOOLEAN:
return "[tinyint]";
}
}
catch (Exception E)
{
LogException(E);
}
return null;
}
public static bool CheckColumnCompatibility(cDataHistoryConfigColumnBase C1, cDataHistoryConfigColumnBase C2)
{
try
{
var strC1 = C1.SqlType;
var strC2 = C2.SqlType;
if (confUseBinValuesAsPrimaryKey && C1.SqlTypeBin != null && C2.SqlTypeBin != null)
{
strC1 = C1.SqlTypeBin;
strC2 = C2.SqlTypeBin;
}
return strC1 == strC2;
}
catch (Exception E)
{
LogException(E);
}
return false;
}
}
public class cDataHistoryConfigCluster : IConfigNodeNamed
{
public bool IsValid { get; protected set; } = false;
public string Name { get; protected set; } = null;
public string Description { get; protected set; } = null;
[JsonIgnore]
public cDataHistoryConfigClusters ParentConfig { get; protected set; } = null;
public enumDataHistoryOrigin Origin { get; protected set; } = enumDataHistoryOrigin.Unknown;
public enumFasdInformationClass InformationClass { get; protected set; } = enumFasdInformationClass.Unknown;
public Dictionary<string, cDataHistoryConfigTable> Tables { get; protected set; } = null;
internal cDataHistoryConfigCluster()
{
}
internal cDataHistoryConfigCluster(XmlElement XNode, cDataHistoryConfigClusters Config, cXmlParser Parser)
{
try
{
if (Config == null)
{
var E = new Exception("No valid configuration");
LogException(E, LogLevels.Fatal);
return;
}
ParentConfig = Config;
Name = cXmlParser.GetStringFromXmlAttribute(XNode, "Name");
if (string.IsNullOrEmpty(Name))
{
Parser.AddMessage(XNode, "The <DataCluster> element has no valid Name attribute.", LogLevels.Warning);
return;
}
Origin = cXmlParser.GetEnumFromAttribute<enumDataHistoryOrigin>(XNode, "Origin", enumDataHistoryOrigin.Unknown);
if (Origin == enumDataHistoryOrigin.Unknown)
{
Parser.AddMessage(XNode, $"The <DataCluster> element with Name='{Name}' has no valid 'Type' attribute.", LogLevels.Error);
return;
}
InformationClass = cXmlParser.GetEnumFromAttribute<enumFasdInformationClass>(XNode, "InformationClass", enumFasdInformationClass.Unknown);
if (InformationClass == enumFasdInformationClass.Unknown)
{
Parser.AddMessage(XNode, $"The <DataCluster> element with Name='{Name}' has no valid 'InformationClass' attribute.", LogLevels.Error);
return;
}
Description = cXmlParser.GetStringFromXmlAttribute(XNode, "Description");
Tables = cDataHistoryConfigTable.LoadFromXml(XNode, this, Parser);
if (Tables == null)
{
Parser.AddMessage(XNode, $"No valid tables found in <DataCluster> element with Name='{Name}'.", LogLevels.Warning);
return;
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
}
internal static Dictionary<string, cDataHistoryConfigCluster> LoadFromXml(XmlElement XNode, cDataHistoryConfigClusters Config, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XDataClusters = XNode.SelectNodes("DataCluster");
if (XDataClusters == null || XDataClusters.Count <= 0)
{
Parser.AddMessage(XNode, "The <DataCluster> element could not be found in the configuration.", LogLevels.Fatal);
return null;
}
Parser.EnterElement("DataCluster");
var RetVal = new Dictionary<string, cDataHistoryConfigCluster>(XDataClusters.Count);
try
{
foreach (XmlNode XNode2 in XDataClusters)
{
if (!(XNode2 is XmlElement XDataCluster))
continue;
var DataCluster = new cDataHistoryConfigCluster(XDataCluster, Config, Parser);
if ((DataCluster != null) && (DataCluster.IsValid))
{
if (!RetVal.ContainsKey(DataCluster.Name))
RetVal.Add(DataCluster.Name, DataCluster);
else
Parser.AddMessage(XDataCluster, $"There's already an <DataCluster> element with Name='{DataCluster.Name}'", LogLevels.Warning);
}
else
{
var strN = "";
if (DataCluster != null)
strN = $" with Name='{DataCluster.Name}'";
Parser.AddMessage(XDataCluster, $"The <DataCluster> element{strN} is not valid.", LogLevels.Error);
}
Parser.SelectElementNext();
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.LeaveElement("DataCluster");
}
if (RetVal.Count > 0)
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
public class cDataHistoryConfigClusterMain : cDataHistoryConfigCluster
{
public readonly Dictionary<enumFasdInformationClass, cDataHistoryConfigMainTable> MainTables = null;
internal cDataHistoryConfigClusterMain(XmlElement XRoot, cDataHistoryConfigClusters Config, cXmlParser Parser)
{
try
{
if (Config == null)
{
var E = new Exception("No valid configuration");
LogException(E, LogLevels.Fatal);
return;
}
IsValid = true;
Name = "Main";
Origin = enumDataHistoryOrigin.Main;
InformationClass = enumFasdInformationClass.Main;
ParentConfig = Config;
var XNode = XRoot.SelectSingleNode("InformationClasses") as XmlElement;
if (XNode == null)
{
Parser.AddMessage(XNode, $"No valid <InformationClasses> element found.", LogLevels.Error);
return;
}
Parser.EnterElement("InformationClasses");
try
{
Tables = cDataHistoryConfigTable.LoadFromXml(XNode, this, Parser);
if (Tables == null)
{
Parser.AddMessage(XNode, $"No valid tables found in <DataCluster> element with Name='{Name}'.", LogLevels.Warning);
return;
}
}
finally
{
Parser.LeaveElement("InformationClasses");
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
}
}
public class cDataHistoryConfigTable : IConfigNodeNamed
{
public bool IsValid { get; protected set; } = false;
public string Name { get; protected set; } = null;
public string SourceName { get; protected set; } = null;
public string Description { get; protected set; } = null;
public bool LateDelivery { get; set; } = false;
public bool HasLateDelivery { get; private set; } = false;
public string AutoCreateHistoryTableName { get; private set; } = null;
public bool IsBuildInTable { get; private set; } = false;
public eDataHistoryTableCached Cached { get; set; } = eDataHistoryTableCached.Default;
public bool IsVirtual { get; set; } = false;
[JsonIgnore]
public cDataHistoryConfigCluster ParentCluster { get; private set; } = null;
public eDataHistoryTableType Type { get; private set; } = eDataHistoryTableType.Unknown;
[JsonIgnore]
public readonly List<cDataHistoryConfigColumnBase> KeyColumns = null;
public readonly List<string> KeyColumnNames = null;
[JsonIgnore]
public cDataHistoryConfigColumnBase EventTimeColumn { get; private set; } = null;
public string EventTimeColumnName { get; private set; } = null;
public readonly Dictionary<string, cDataHistoryConfigSubTable> SubTables = null;
public readonly Dictionary<string, cDataHistoryConfigColumnBase> Columns = new Dictionary<string, cDataHistoryConfigColumnBase>();
public readonly Dictionary<string, cDataHistoryConfigTableIndex> Indexes = new Dictionary<string, cDataHistoryConfigTableIndex>();
public readonly Dictionary<string, cDataHistoryConfigTableReferenceInfo> References = new Dictionary<string, cDataHistoryConfigTableReferenceInfo>();
public readonly bool NoTimeRestriction = false;
public List<string> AlternateNames = null;
[JsonIgnore]
public bool HasScanId = false;
internal cDataHistoryConfigTable()
{
KeyColumns = new List<cDataHistoryConfigColumnBase>();
KeyColumnNames = new List<string>();
SubTables = new Dictionary<string, cDataHistoryConfigSubTable>();
Columns = new Dictionary<string, cDataHistoryConfigColumnBase>();
}
internal cDataHistoryConfigTable(XmlElement XNode, cDataHistoryConfigCluster Cluster, cXmlParser Parser)
{
try
{
if (Cluster == null)
{
LogException(new Exception("no valid Cluster information delivered."));
return;
}
ParentCluster = Cluster;
if (Cluster.Origin == enumDataHistoryOrigin.Main && XNode.Name == "InformationClass")
IsBuildInTable = true;
if (Cluster.Origin == enumDataHistoryOrigin.F4sdAgent || Cluster.Origin == enumDataHistoryOrigin.M42Wpm || Cluster.Origin == enumDataHistoryOrigin.Intune || Cluster.Origin == enumDataHistoryOrigin.Citrix)
IsVirtual = true;
Name = cXmlParser.GetStringFromXmlAttribute(XNode, "Name");
if (string.IsNullOrEmpty(Name))
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> has no valid 'Name' attribute.", LogLevels.Warning);
return;
}
if (IsBuildInTable)
Name = "main-" + Name.ToLowerInvariant();
SourceName = cXmlParser.GetStringFromXmlAttribute(XNode, "SourceName");
if (string.IsNullOrEmpty(SourceName))
SourceName = Name;
Cached = cXmlParser.GetEnumFromAttribute<eDataHistoryTableCached>(XNode, "Cached", eDataHistoryTableCached.Default);
string strKeyColumnNames = cXmlParser.GetStringFromXmlAttribute(XNode, "Key");
if (IsBuildInTable)
strKeyColumnNames = "id";
else
strKeyColumnNames = cXmlParser.GetStringFromXmlAttribute(XNode, "Key");
if (string.IsNullOrEmpty(strKeyColumnNames))
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{Name}' has no valid 'Key' attribute.", LogLevels.Warning);
return;
}
var arrKeyColumnNames = strKeyColumnNames.Split(' ');
KeyColumnNames = new List<string>();
foreach (var Entry in arrKeyColumnNames)
{
var strName = Entry.Trim();
if (!string.IsNullOrEmpty(strName))
KeyColumnNames.Add(strName);
}
if (KeyColumnNames.Count == 0)
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{Name}' is not valid because of an empty 'Key' attribute.", LogLevels.Warning);
return;
}
if (IsBuildInTable)
Type = eDataHistoryTableType.Static;
else
Type = cXmlParser.GetEnumFromAttribute<eDataHistoryTableType>(XNode, "Type", eDataHistoryTableType.Unknown);
if (Type == eDataHistoryTableType.Unknown)
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{Name}' has no valid 'Type' attribute.", LogLevels.Warning);
return;
}
EventTimeColumnName = cXmlParser.GetStringFromXmlAttribute(XNode, "EventTimeCol");
Description = cXmlParser.GetStringFromXmlAttribute(XNode, "Description");
LateDelivery = cXmlParser.GetBoolFromXmlAttribute(XNode, "LateDelivery");
var XNode2 = XNode.SelectSingleNode("AutoCreate-Historic-Table");
if (XNode2 != null)
{
Parser.EnterElement("AutoCreate-Historic-Table");
AutoCreateHistoryTableName = cXmlParser.GetStringFromXmlAttribute(XNode2, "Name");
Parser.LeaveElement("AutoCreate-Historic-Table");
}
if (XNode.Name == "JoinedTable")
{
// we have a table definition with several subtables
var XSubTables = XNode.SelectNodes("SubTable");
if ((XSubTables == null) || XSubTables.Count == 0)
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> has no valid subtables.", LogLevels.Warning);
return;
}
SubTables = new Dictionary<string, cDataHistoryConfigSubTable>(XSubTables.Count);
Parser.EnterElement("SubTable");
try
{
foreach (XmlNode XEntry in XSubTables)
{
if (!(XEntry is XmlElement XSubTable))
continue;
var SubTable = new cDataHistoryConfigSubTable(XSubTable, this, Parser);
if ((SubTable == null) || !SubTable.IsValid || SubTables.ContainsKey(SubTable.Name))
{
Parser.AddMessage(XNode, $"The element <{XSubTable.Name}> is not valid.", LogLevels.Warning);
}
else
SubTables.Add(SubTable.Name, SubTable);
Parser.SelectElementNext();
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.LeaveElement("SubTable");
}
}
else
{
// we have no explicit subtable definitions
var SubTable = new cDataHistoryConfigSubTable(XNode, this, Parser);
if ((SubTable == null) || !SubTable.IsValid)
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> is not valid.", LogLevels.Warning);
return;
}
SubTables = new Dictionary<string, cDataHistoryConfigSubTable>(1)
{
{ SubTable.Name, SubTable }
};
}
if (SubTables.Count == 0)
{
Parser.AddMessage(XNode, $"The table <{XNode.Name}> has no valid subtables.", LogLevels.Warning);
return;
}
// get the key columns
KeyColumns = new List<cDataHistoryConfigColumnBase>();
foreach (var ColName in KeyColumnNames)
{
if (!Columns.TryGetValue(ColName, out var KeyColumn))
{
Parser.AddMessage(XNode, $"The key column name '{ColName}' within the element <{XNode.Name}> could not be found.", LogLevels.Error);
return;
}
KeyColumns.Add(KeyColumn);
}
// check if we have the key columns in each subtable with the same type
foreach (var SubTable in SubTables.Values)
{
HasLateDelivery |= SubTable.HasLateDelivery;
foreach (var KeyColumn in KeyColumns)
{
if (!SubTable.Columns.TryGetValue(KeyColumn.Name, out var Col))
{
Parser.AddMessage(XNode, $"The key column '{KeyColumn.Name}' within the element <{XNode.Name}> could not be found in subtable '{SubTable.Name}'.", LogLevels.Warning);
return;
}
if (Col.ValueType != KeyColumn.ValueType)
{
Parser.AddMessage(XNode, $"The value type of the key column '{KeyColumn.Name}' within the element <{XNode.Name}> is not compatible to the subtable '{SubTable.Name}'.", LogLevels.Warning);
return;
}
if (Col.Cardinal != KeyColumn.Cardinal)
{
Parser.AddMessage(XNode, $"The value cardinal of the key column '{KeyColumn.Name}' within the element <{XNode.Name}> is not compatible to the subtable '{SubTable.Name}'.", LogLevels.Warning);
return;
}
}
}
// get the event time column for event tables
if (!string.IsNullOrEmpty(EventTimeColumnName))
if (Columns.TryGetValue(EventTimeColumnName, out var _ec) && _ec.ValueType == enumFasdValueType.DATETIME)
EventTimeColumn = _ec;
if (Type == eDataHistoryTableType.Events || Type == eDataHistoryTableType.HistoryEvents)
{
if (EventTimeColumn == null)
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{Name}' has no valid 'EventTimeCol' attribute.", LogLevels.Warning);
return;
}
}
// get the alternatetable names
var XAlternates = XNode.SelectNodes("AdditionalTableName");
if (XAlternates != null && XAlternates.Count > 0)
{
Parser.EnterElement("AdditionalTableName");
foreach (XmlNode XEntry in XAlternates)
{
if (!(XEntry is XmlElement XAlternate))
continue;
try
{
var _an = cXmlParser.GetStringFromXmlAttribute(XAlternate, "Name");
if (string.IsNullOrWhiteSpace(_an))
continue;
if (AlternateNames == null)
AlternateNames = new List<string>(XAlternates.Count);
if (!AlternateNames.Contains(_an))
AlternateNames.Add(_an);
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.SelectElementNext();
}
}
Parser.LeaveElement("AdditionalTableName");
}
// get the indexes
var XIndexes = XNode.SelectNodes("Table-Index");
if (XIndexes != null && XIndexes.Count > 0)
{
Parser.EnterElement("Table-Index");
foreach (XmlNode XEntry in XIndexes)
{
if (!(XEntry is XmlElement XIndex))
continue;
try
{
var Index = new cDataHistoryConfigTableIndex
{
Name = XIndex.GetAttribute("Name")
};
if (string.IsNullOrEmpty(Index.Name))
{
Parser.AddMessage(XIndex, $"The element <{XIndex.Name}> has no valid 'Name' attribute.", LogLevels.Warning);
continue;
}
Index.Unique = cXmlParser.GetBoolFromXmlAttribute(XIndex, "Unique");
var strColumns = XIndex.GetAttribute("Columns");
if (string.IsNullOrEmpty(strColumns))
{
Parser.AddMessage(XIndex, $"The element <{XIndex.Name}> with Name='{Index.Name}' has no valid 'Columns' attribute.", LogLevels.Warning);
continue;
}
var arrCols = strColumns.Split(' ');
foreach (var strCol in arrCols)
{
var strCol2 = strCol.Trim();
if (strCol2 == "")
continue;
if (!Columns.TryGetValue(strCol2, out var Col))
{
Parser.AddMessage(XIndex, $"The element <{XIndex.Name}> with Name='{Index.Name}' contains a non existing element '{strCol2}' within the 'Columns' attribute.", LogLevels.Warning);
Index.Columns.Clear();
break;
}
if (Index.Columns.Contains(Col))
{
Parser.AddMessage(XIndex, $"The element <{XIndex.Name}> with Name='{Index.Name}' contains a duplicated element '{strCol2}' within the 'Columns' attribute.", LogLevels.Warning);
Index.Columns.Clear();
break;
}
Index.Columns.Add(Col);
}
if (Columns.Count == 0)
{
Parser.AddMessage(XIndex, $"The element <{XIndex.Name}> with Name='{Index.Name}' has an illegal or no valid entries in the 'Columns' attribute.", LogLevels.Warning);
continue;
}
if (Indexes.ContainsKey(Index.Name))
{
Parser.AddMessage(XIndex, $"The element <{XIndex.Name}> with Name='{Index.Name}' is duplicated.", LogLevels.Warning);
continue;
}
Indexes.Add(Index.Name, Index);
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.SelectElementNext();
}
}
Parser.LeaveElement("Table-Index");
}
// get the table references
var XJoins = XNode.SelectNodes("Table-Reference");
if (XJoins != null && XJoins.Count > 0)
{
Parser.EnterElement("Table-Reference");
foreach (XmlNode XEntry in XJoins)
{
if (!(XEntry is XmlElement XJoin))
continue;
try
{
var Join = new cDataHistoryConfigTableReferenceInfo(XJoin, this, Parser);
if (!Join.IsValid)
{
var strWithName = "";
if (Join.ForeignTableName != null)
strWithName = $"with Name='{Join.ForeignTableName}'";
Parser.AddMessage(XJoin, $"The <Table-Reference> element{strWithName} is not valid.", LogLevels.Warning);
continue;
}
if (References.ContainsKey(Join.ForeignTableName))
{
Parser.AddMessage(XJoin, $"The element <{XJoin.Name}> with Table='{Join.ForeignTableName}' within table '{Name}' is duplicated.", LogLevels.Warning);
continue;
}
References.Add(Join.ForeignTableName, Join);
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.SelectElementNext();
}
}
Parser.LeaveElement("Table-Reference");
}
// resolve the columns of the computations
bool _IsValid = true;
foreach (var Column in Columns.Values)
{
if (!(Column is cDataHistoryConfigColumnComputation CP))
continue;
if (CP.Computation != null)
_IsValid &= CP.Computation.Resolve(Columns, Parser);
}
IsValid = _IsValid;
}
catch (Exception E)
{
IsValid = false;
LogException(E);
}
finally
{
}
}
internal static Dictionary<string, cDataHistoryConfigTable> LoadFromXml(XmlElement XNode, cDataHistoryConfigCluster Cluster, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XTableList = new List<XmlNodeList>(3);
var XList = XNode.SelectNodes("Table");
if (XList != null && XList.Count > 0)
XTableList.Add(XList);
XList = XNode.SelectNodes("JoinedTable");
if (XList != null && XList.Count > 0)
XTableList.Add(XList);
XList = XNode.SelectNodes("InformationClass");
if (XList != null && XList.Count > 0)
XTableList.Add(XList);
if (XTableList.Count == 0)
return null;
var RetVal = new Dictionary<string, cDataHistoryConfigTable>();
foreach (XmlNodeList XTables in XTableList)
{
Parser.EnterElement(XTables[0].Name);
foreach (XmlNode XNode2 in XTables)
{
if (!(XNode2 is XmlElement XTable))
continue;
var Table = new cDataHistoryConfigTable(XTable, Cluster, Parser);
if ((Table != null) && Table.IsValid)
{
if (!RetVal.ContainsKey(Table.Name))
{
if (!Cluster.ParentConfig.Tables.ContainsKey(Table.Name))
{
RetVal.Add(Table.Name, Table);
if (!Cluster.ParentConfig.Tables.ContainsKey(Table.Name))
Cluster.ParentConfig.Tables.Add(Table.Name, Table);
}
else
{
Parser.AddMessage(XTable, $"There's already an <{XTable.Name}> element with Name='{Table.Name}'", LogLevels.Warning);
}
}
else
{
Parser.AddMessage(XTable, $"There's already an <{XTable.Name}> element with Name='{Table.Name}'", LogLevels.Warning);
}
if (Table.AlternateNames != null)
{
foreach (var _an in Table.AlternateNames)
Cluster.ParentConfig.AlternateTableNames[_an] = Table.Name;
}
}
else
{
var strN = "";
if (Table != null)
strN = $" with Name='{Table.Name}'";
Parser.AddMessage(XTable, $"The <{XTable.Name}> element{strN} is not valid.", LogLevels.Error);
}
Parser.SelectElementNext();
}
Parser.LeaveElement(XTables[0].Name);
}
if (RetVal.Count > 0)
{
var _lstAuto = new List<cDataHistoryConfigTable>();
foreach (var Entry in RetVal.Values)
{
if (!string.IsNullOrEmpty(Entry.AutoCreateHistoryTableName))
_lstAuto.Add(Entry);
}
foreach (var Entry in _lstAuto)
{
var _tbl = cDataHistoryConfigTable.CreateHistoricTableFromDetails(Entry);
if (_tbl != null)
{
if (!RetVal.ContainsKey(_tbl.Name))
{
RetVal.Add(_tbl.Name, _tbl);
if (!Cluster.ParentConfig.Tables.ContainsKey(_tbl.Name))
Cluster.ParentConfig.Tables.Add(_tbl.Name, _tbl);
}
}
}
return RetVal;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public override string ToString()
{
return Name;
}
public bool IsUniqueColumn(cDataHistoryConfigColumnBase Column)
{
if (KeyColumns.Contains(Column))
return true;
if (EventTimeColumn == Column)
return true;
foreach (var Index in Indexes.Values)
{
if (!Index.Unique)
continue;
if (Index.Columns.Contains(Column))
return true;
}
return false;
}
public bool IsNullable(cDataHistoryConfigColumnBase Column)
{
return !IsUniqueColumn(Column);
}
internal bool ResolveReferences(Dictionary<string, cDataHistoryConfigTable> Tables, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var RetVal = true;
var delList = new List<cDataHistoryConfigTableReferenceInfo>();
foreach (var Ref in this.References.Values)
{
RetVal &= Ref.Resolve(this, Tables, Parser);
if (!Ref.IsValid)
delList.Add(Ref);
}
foreach (var Ref in delList)
this.References.Remove(Ref.ForeignTableName);
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
internal static cDataHistoryConfigTable CreateHistoricTableFromDetails(cDataHistoryConfigTable SourceTable)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var _newTable = new cDataHistoryConfigTable()
{
IsValid = true,
Name = SourceTable.AutoCreateHistoryTableName,
SourceName = SourceTable.SourceName,
Description = SourceTable.Description,
LateDelivery = SourceTable.LateDelivery,
IsBuildInTable = SourceTable.IsBuildInTable,
Cached = SourceTable.Cached,
IsVirtual = SourceTable.IsVirtual,
ParentCluster = SourceTable.ParentCluster,
Type = eDataHistoryTableType.History
};
var _newSubTable = new cDataHistoryConfigSubTable(_newTable)
{
IsValid = true,
Name = SourceTable.AutoCreateHistoryTableName,
Description = SourceTable.Description
};
_newTable.SubTables.Add(_newSubTable.Name, _newSubTable);
foreach (var Entry in SourceTable.KeyColumns)
{
var _colId = new cDataHistoryConfigColumn(Entry.Name, _newSubTable, Entry.ValueType, Entry.Cardinal)
{
SourceName = Entry.SourceName,
AggregationType = eDataHistoryAggregationType.first
};
_newSubTable.Columns.Add(_colId.Name, _colId);
_newTable.Columns.Add(_colId.Name, _colId);
_newTable.KeyColumns.Add(_colId);
_newTable.KeyColumnNames.Add(_colId.Name);
}
var _colTime = new cDataHistoryConfigColumn(SourceTable.EventTimeColumn.Name, _newSubTable, SourceTable.EventTimeColumn.ValueType, SourceTable.EventTimeColumn.Cardinal)
{
SourceName = SourceTable.EventTimeColumn.SourceName,
AggregationType = eDataHistoryAggregationType.count
};
_newSubTable.Columns.Add(_colTime.Name, _colTime);
_newTable.Columns.Add(_colTime.Name, _colTime);
_newTable.EventTimeColumn = _colTime;
_newTable.EventTimeColumnName = _colTime.Name;
return _newTable;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
public class cDataHistoryConfigSubTable : IConfigNodeNamed
{
public bool IsValid { get; internal set; } = false;
public string Name { get; set; } = null;
public string Description { get; internal set; } = null;
public bool Aggregation { get; private set; } = false;
public bool HasLateDelivery { get; private set; } = false;
[JsonIgnore]
public readonly cDataHistoryConfigTable ParentTable = null;
public readonly cDataHistoryConfigQueryTemplate Template = null;
public readonly Dictionary<string, cDataHistoryConfigColumnBase> Columns = null;
internal cDataHistoryConfigSubTable(cDataHistoryConfigTable Table)
{
ParentTable = Table;
Columns = new Dictionary<string, cDataHistoryConfigColumnBase>();
}
internal cDataHistoryConfigSubTable(XmlElement XNode, cDataHistoryConfigTable Table, cXmlParser Parser)
{
try
{
if (Table == null)
{
LogException(new Exception("No valid Tabel parameter used."), LogLevels.Fatal);
return;
}
ParentTable = Table;
Name = cXmlParser.GetStringFromXmlAttribute(XNode, "Name");
if (string.IsNullOrEmpty(Name))
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> has no valid 'Name' attribute", LogLevels.Warning);
return;
}
Description = cXmlParser.GetStringFromXmlAttribute(XNode, "Description");
Template = cDataHistoryConfigQueryTemplate.LoadFromXml(XNode, Parser);
// ToDo: Check, if we need a template
/*
if (Template == null)
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{Name}' has no valid '<Template>' element", LogLevels.Warning);
return;
}
*/
Columns = cDataHistoryConfigColumnBase.LoadFromXml(XNode, this, Parser);
if (Columns == null || Columns.Count == 0)
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{Name}' has no valid columns", LogLevels.Warning);
return;
}
if (Table.Name == "agnt-computer-event-string")
{
}
foreach (var Col in Columns.Values)
{
HasLateDelivery |= Col.LateDelivery;
if (Col is cDataHistoryConfigColumn _C && _C.AggregationType != eDataHistoryAggregationType.Unknown)
Aggregation = true;
}
if (Table.IsBuildInTable && !Columns.ContainsKey("id"))
{
var _colId = new cDataHistoryConfigColumn("id", this, enumFasdValueType.GUID);
Columns.Add("id", _colId);
if (!Table.Columns.ContainsKey("id"))
Table.Columns.Add("id", _colId);
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
}
}
}
public abstract class cDataHistoryConfigColumnBase : cConfigNodeNamed
{
public readonly enumFasdValueType ValueType = enumFasdValueType.Unknown;
public readonly int Cardinal = -1;
public string SqlType = null;
public string SqlTypeBin = null;
public string NameBin = null;
public string SourceName = null;
public readonly bool LateDelivery = false;
public string SourceTable = null;
public bool IsWritable { get; private set; } = false;
[JsonIgnore]
public readonly cDataHistoryConfigSubTable ParentTable = null;
internal cDataHistoryConfigColumnBase(string Name, cDataHistoryConfigSubTable SubTable, enumFasdValueType Type, int Cardinal = -1) : base(Name)
{
ParentTable = SubTable;
SourceName = Name;
ValueType = Type;
SqlType = cDataHistoryConfigClusters.GetSqlDataTypeFromHistoryType(ValueType, Cardinal, false);
SqlTypeBin = cDataHistoryConfigClusters.GetSqlDataTypeFromHistoryType(ValueType, Cardinal, true);
}
internal cDataHistoryConfigColumnBase(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser) :
base(XNode, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
if (ParentTable == null)
{
LogException(new Exception("No valid ParentTable delivered."));
return;
}
this.ParentTable = ParentTable;
NameBin = Name;
ValueType = cXmlParser.GetEnumFromAttribute<enumFasdValueType>(XNode, "Type", enumFasdValueType.Unknown);
if (ValueType == enumFasdValueType.Unknown)
{
Parser.AddInvalidAttribute(XNode, Name, "Type");
return;
}
Cardinal = cXmlParser.GetIntegerFromXmlAttribute(XNode, "Cardinal", -1);
LateDelivery = cXmlParser.GetBoolFromXmlAttribute(XNode, "LateDelivery");
IsWritable = cXmlParser.GetBoolFromXmlAttribute(XNode, "IsWritable");
SqlType = cDataHistoryConfigClusters.GetSqlDataTypeFromHistoryType(ValueType, Cardinal, false);
if (SqlType == null)
{
Parser.AddMessage(XNode, $"The type '{ValueType}' at element <{XNode.Name}> with Name='{Name}' has no valid corresponding sql type.", LogLevels.Fatal);
return;
}
SqlTypeBin = cDataHistoryConfigClusters.GetSqlDataTypeFromHistoryType(ValueType, Cardinal, true);
if (!string.IsNullOrEmpty(SqlTypeBin))
NameBin = Name + "_bin";
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
static internal Dictionary<string, cDataHistoryConfigColumnBase> LoadFromXml(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
XmlElement XElements = XNode;
if (!ParentTable.ParentTable.IsBuildInTable)
{
var XList2 = XNode.SelectSingleNode("Table-Columns");
if (!(XList2 is XmlElement XList))
{
Parser.AddMessage(XNode, $"Illegal XML node 'Table-Columns' within element <{XNode.Name}> in table '{ParentTable.Name}' found.", LogLevels.Warning);
return null;
}
XElements = XList;
Parser.EnterElement("Table-Columns");
}
var RetVal = new Dictionary<string, cDataHistoryConfigColumnBase>();
try
{
var XColumns = XElements.ChildNodes;
if (XColumns == null || XColumns.Count == 0)
{
Parser.AddMessage(XElements, $"No valid elements found within element <{XElements.Name}> in table '{ParentTable.Name}'.", LogLevels.Warning);
return null;
}
var ColumnGroups = XColumns.Cast<XmlNode>().Where(node => node is XmlElement).GroupBy(node => node.Name);
foreach (var ColGroup in ColumnGroups)
{
Parser.EnterElement(ColGroup.Key);
foreach (XmlElement XColumn in ColGroup)
{
cDataHistoryConfigColumnBase Column = null;
switch (ColGroup.Key)
{
case "Table-Column":
case "InformationClass-Column":
Column = new cDataHistoryConfigColumn(XColumn, ParentTable, Parser);
break;
case "Table-Column-NxtCompute":
Column = new cDataHistoryConfigColumnNxtCompute(XColumn, ParentTable, Parser);
break;
case "Table-Column-NxtCategory":
Column = new cDataHistoryConfigColumnNxtCategory(XColumn, ParentTable, Parser);
break;
case "Table-Column-NxtScore":
Column = new cDataHistoryConfigColumnNxtScore(XColumn, ParentTable, Parser);
break;
case "Table-Column-NxtAction":
Column = new cDataHistoryConfigColumnNxtAction(XColumn, ParentTable, Parser);
break;
case "Table-Column-NxtCampaign":
Column = new cDataHistoryConfigColumnNxtCampaign(XColumn, ParentTable, Parser);
break;
case "Table-Column-Computation":
Column = new cDataHistoryConfigColumnComputation(XColumn, ParentTable, Parser);
break;
default:
continue;
}
var pTable = ParentTable.ParentTable;
if ((Column != null) && Column.IsValid)
{
if (!RetVal.ContainsKey(Column.Name))
{
if (pTable.KeyColumnNames.Contains(Column.Name) || !pTable.Columns.ContainsKey(Column.Name))
{
RetVal.Add(Column.Name, Column);
if (!pTable.Columns.ContainsKey(Column.Name))
pTable.Columns.Add(Column.Name, Column);
}
else
{
Parser.AddMessage(XColumn, $"There's already an <{XColumn.Name}> element with Name='{Column.Name}'", LogLevels.Warning);
}
}
else
{
Parser.AddMessage(XColumn, $"There's already an <{XColumn.Name}> element with Name='{Column.Name}'", LogLevels.Warning);
}
}
else
{
var strN = "";
if (Column != null)
strN = $" with Name='{Column.Name}'";
Parser.AddMessage(XColumn, $"The <{XColumn.Name}> element{strN} is not valid.", LogLevels.Error);
}
Parser.SelectElementNext();
}
Parser.LeaveElement(ColGroup.Key);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (!ParentTable.ParentTable.IsBuildInTable)
Parser.LeaveElement("Table-Columns");
}
if (RetVal.Count > 0)
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
public class cDataHistoryConfigColumn : cDataHistoryConfigColumnBase
{
public eDataHistoryQueryType SourceType = eDataHistoryQueryType.Query;
public string SourceJsonField = null;
public int SourceJsonColumn = -1;
public eDataHistoryAggregationType AggregationType = eDataHistoryAggregationType.Unknown;
public readonly bool FillEmptyEntries = false;
internal cDataHistoryConfigColumn(string Name, cDataHistoryConfigSubTable SubTable, enumFasdValueType Type, int Cardinal = -1) : base(Name, SubTable, Type, Cardinal)
{
}
internal cDataHistoryConfigColumn(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser) :
base(XNode, ParentTable, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
SourceName = cXmlParser.GetStringFromXmlAttribute(XNode, "SourceName", Name);
SourceTable = cXmlParser.GetStringFromXmlAttribute(XNode, "SourceTable", null);
SourceType = cXmlParser.GetEnumFromAttribute<eDataHistoryQueryType>(XNode, "SourceType", eDataHistoryQueryType.Query);
SourceJsonField = cXmlParser.GetStringFromXmlAttribute(XNode, "SourceJsonField", null);
SourceJsonColumn = cXmlParser.GetIntegerFromXmlAttribute(XNode, "SourceJsonColumn", -1);
AggregationType = cXmlParser.GetEnumFromAttribute<eDataHistoryAggregationType>(XNode, "Aggregation", eDataHistoryAggregationType.Unknown);
FillEmptyEntries = cXmlParser.GetBoolFromXmlAttribute(XNode, "FillEmptyEntries");
if (AggregationType != eDataHistoryAggregationType.Unknown)
{
var valType = cDataHistoryConfigClusters.ResultingAggregationType(this.ValueType, this.AggregationType);
SqlType = cDataHistoryConfigClusters.GetSqlDataTypeFromHistoryType(valType, Cardinal, false);
if (SqlType == null)
{
Parser.AddMessage(XNode, $"The type '{ValueType}' at element <{XNode.Name}> with Name='{Name}' has no valid corresponding sql type.", LogLevels.Fatal);
return;
}
SqlTypeBin = cDataHistoryConfigClusters.GetSqlDataTypeFromHistoryType(valType, Cardinal, true);
if (!string.IsNullOrEmpty(SqlTypeBin))
NameBin = Name + "_bin";
}
}
catch (Exception E)
{
IsValid = false;
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cDataHistoryConfigColumnNxtCompute : cDataHistoryConfigColumn
{
internal cDataHistoryConfigColumnNxtCompute(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser) :
base(XNode, ParentTable, Parser)
{
}
}
public class cDataHistoryConfigColumnNxtCategory : cDataHistoryConfigColumn
{
internal cDataHistoryConfigColumnNxtCategory(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser) :
base(XNode, ParentTable, Parser)
{
}
}
public class cDataHistoryConfigColumnNxtScore : cDataHistoryConfigColumnBase
{
public readonly string ScoreName = null;
public readonly string ValueName = null;
public readonly Guid ScoreID = Guid.Empty;
public readonly Guid ValueID = Guid.Empty;
public readonly bool IsPayload = false;
internal cDataHistoryConfigColumnNxtScore(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser) :
base(XNode, ParentTable, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
ScoreName = cXmlParser.GetStringFromXmlAttribute(XNode, "ScoreName");
if (string.IsNullOrEmpty(ScoreName))
{
Parser.AddInvalidAttribute(XNode, Name, "ScoreName");
return;
}
ValueName = cXmlParser.GetStringFromXmlAttribute(XNode, "ValueName");
if (string.IsNullOrEmpty(ValueName))
{
Parser.AddInvalidAttribute(XNode, Name, "ValueName");
return;
}
ScoreID = cXmlParser.GetGuidFromXmlAttribute(XNode, "ScoreID");
ValueID = cXmlParser.GetGuidFromXmlAttribute(XNode, "ValueID");
IsPayload = cXmlParser.GetBoolFromXmlAttribute(XNode, "Payload");
IsValid = true;
}
catch (Exception E)
{
IsValid = false;
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cDataHistoryConfigColumnNxtAction : cDataHistoryConfigColumnBase
{
public readonly string ActionName = null;
public readonly string ValueName = null;
public readonly Guid ActionID = Guid.Empty;
public readonly Guid ValueID = Guid.Empty;
internal cDataHistoryConfigColumnNxtAction(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser) :
base(XNode, ParentTable, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
ActionName = cXmlParser.GetStringFromXmlAttribute(XNode, "ActionName");
if (string.IsNullOrEmpty(ActionName))
{
Parser.AddInvalidAttribute(XNode, Name, "ActionName");
return;
}
ValueName = cXmlParser.GetStringFromXmlAttribute(XNode, "ValueName");
if (string.IsNullOrEmpty(ValueName))
{
Parser.AddInvalidAttribute(XNode, Name, "ValueName");
return;
}
ActionID = cXmlParser.GetGuidFromXmlAttribute(XNode, "ActionID");
ValueID = cXmlParser.GetGuidFromXmlAttribute(XNode, "ValueID");
IsValid = true;
}
catch (Exception E)
{
IsValid = false;
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cDataHistoryConfigColumnNxtCampaign : cDataHistoryConfigColumnBase
{
public readonly string CampaignName = null;
public readonly string ValueName = null;
public readonly Guid CampaignID = Guid.Empty;
public readonly int ValueID = -1;
public readonly bool AsText = false;
internal cDataHistoryConfigColumnNxtCampaign(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser) :
base(XNode, ParentTable, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
CampaignName = cXmlParser.GetStringFromXmlAttribute(XNode, "CampaignName");
if (string.IsNullOrEmpty(CampaignName))
{
Parser.AddInvalidAttribute(XNode, Name, "CampaignName");
return;
}
ValueName = cXmlParser.GetStringFromXmlAttribute(XNode, "ValueName");
if (string.IsNullOrEmpty(ValueName))
{
Parser.AddInvalidAttribute(XNode, Name, "ValueName");
return;
}
CampaignID = cXmlParser.GetGuidFromXmlAttribute(XNode, "CampaignID");
ValueID = cXmlParser.GetIntegerFromXmlAttribute(XNode, "ValueID");
AsText = cXmlParser.GetBoolFromXmlAttribute(XNode, "AsText");
IsValid = true;
}
catch (Exception E)
{
IsValid = false;
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cDataHistoryConfigColumnComputation : cDataHistoryConfigColumnBase
{
public cDataHistoryConfigComputationBase Computation { get; set; } = null;
internal cDataHistoryConfigColumnComputation(XmlElement XNode, cDataHistoryConfigSubTable ParentTable, cXmlParser Parser) :
base(XNode, ParentTable, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
var XList = XNode.SelectNodes("*");
foreach (XmlNode XNode2 in XList)
{
if (!(XNode2 is XmlElement XEntry))
continue;
cDataHistoryConfigComputationBase Co = null;
switch (XNode2.Name)
{
case "Computation-LinearTransform":
Parser.EnterElement("Computation-LinearTransform");
Co = new cDataHistoryConfigComputationLinearTransform(XEntry, Parser);
Parser.LeaveElement("Computation-LinearTransform");
break;
case "Computation-RegEx":
Parser.EnterElement("Computation-RegEx");
Co = new cDataHistoryConfigComputationRegEx(XEntry, Parser);
Parser.LeaveElement("Computation-RegEx");
break;
}
if (Co != null && Co.IsValid)
{
if (Computation != null)
{
Parser.AddMessage(XNode, $"The <{XNode.Name}> element with Name='{Name}' has more than one valid computation sub-node.", LogLevels.Error);
return;
}
Computation = Co;
}
}
if (Computation == null)
{
Parser.AddMessage(XNode, $"The <{XNode.Name}> element with Name='{Name}' has no valid computation sub-node.", LogLevels.Error);
return;
}
IsValid = true;
}
catch (Exception E)
{
IsValid = false;
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public abstract class cDataHistoryConfigComputationBase : IConfigNodeValidation
{
public bool IsValid { get; internal set; } = false;
public List<string> ColumnNames { get; internal set; } = new List<string>();
[JsonIgnore]
public List<cDataHistoryConfigColumnBase> Columns = new List<cDataHistoryConfigColumnBase>();
[JsonIgnore]
private readonly int XLine = 0;
[JsonIgnore]
private readonly int XCol = 0;
[JsonIgnore]
private readonly string NodeName;
internal cDataHistoryConfigComputationBase(XmlElement XNode, cXmlParser Parser)
{
XLine = Parser.currentNode.Line;
XCol = Parser.currentNode.Column;
NodeName = XNode.Name;
}
internal bool Resolve(Dictionary<string, cDataHistoryConfigColumnBase> TableColumns, cXmlParser Parser)
{
try
{
bool _IsValid = true;
foreach (var Entry in ColumnNames)
{
if (!TableColumns.TryGetValue(Entry, out var Column))
{
Parser.AddMessage(XLine, XCol, $"The column name '{Entry}' of the element '<{NodeName}>' could not be resolved.", LogLevels.Error);
_IsValid = false;
continue;
}
Columns.Add(Column);
}
return _IsValid;
}
catch (Exception E)
{
LogException(E);
}
return false;
}
public abstract object Compute(object[] Values);
public static double? GetDouble(object o, double? Default)
{
double? RetVal = Default;
try
{
if (o is int @int)
RetVal = Convert.ToDouble(@int);
else if (o is double @double)
RetVal = @double;
else if (o is string @string)
{
if (double.TryParse(@string, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US").NumberFormat, out double R))
RetVal = R;
else
RetVal = Default;
}
}
catch { }
return RetVal;
}
}
public class cDataHistoryConfigComputationLinearTransform : cDataHistoryConfigComputationBase
{
public double m { get; internal set; } = 1.0f;
public double b { get; internal set; } = 0.0f;
internal cDataHistoryConfigComputationLinearTransform(XmlElement XNode, cXmlParser Parser) :
base(XNode, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
IsValid = false;
try
{
var Column = cXmlParser.GetStringFromXmlAttribute(XNode, "Column");
if (string.IsNullOrWhiteSpace(Column))
{
Parser.AddMessage(XNode, $"The <{XNode.Name}> element has no valid 'column' attribute", LogLevels.Warning);
return;
}
ColumnNames.Add(Column);
m = cXmlParser.GetDoubleFromXmlAttribute(XNode, "m", 1.0);
b = cXmlParser.GetDoubleFromXmlAttribute(XNode, "b", 0.0);
IsValid = true;
}
catch (Exception E)
{
IsValid = false;
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public override object Compute(object[] Values)
{
if (Values.Length != 1)
return null;
double? V = GetDouble(Values[0], null);
if (V == null)
return null;
return m * V + b;
}
}
public class cDataHistoryConfigComputationRegEx : cDataHistoryConfigComputationBase
{
public string RegExFilter { get; internal set; } = null;
public string Replacement { get; internal set; } = null;
public bool AutoTrim { get; internal set; } = false;
internal cDataHistoryConfigComputationRegEx(XmlElement XNode, cXmlParser Parser) :
base(XNode, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
IsValid = false;
try
{
var Column = cXmlParser.GetStringFromXmlAttribute(XNode, "Column");
if (string.IsNullOrWhiteSpace(Column))
{
Parser.AddMessage(XNode, $"The <{XNode.Name}> element has no valid 'column' attribute", LogLevels.Warning);
return;
}
ColumnNames.Add(Column);
RegExFilter = cXmlParser.GetStringFromXmlAttribute(XNode, "RegExFilter");
if (string.IsNullOrWhiteSpace(RegExFilter))
{
Parser.AddInvalidAttribute(XNode, null, "RegExFilter");
return;
}
Replacement = cXmlParser.GetStringFromXmlAttribute(XNode, "Replacement");
AutoTrim = cXmlParser.GetBoolFromXmlAttribute(XNode, "AutoTrim");
IsValid = true;
}
catch (Exception E)
{
IsValid = false;
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public override object Compute(object[] Values)
{
try
{
if (Values.Length != 1)
return null;
if (Values[0] == null)
return null;
var RetVal = Values[0].ToString();
if (string.IsNullOrEmpty(RetVal))
return RetVal;
if (!string.IsNullOrEmpty(RegExFilter))
{
if (!string.IsNullOrEmpty(Replacement))
try
{
RetVal = Regex.Replace(RetVal, RegExFilter, Replacement, RegexOptions.CultureInvariant);
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
else
try
{
var m = Regex.Match(RetVal, RegExFilter, RegexOptions.CultureInvariant);
RetVal = m.Value;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
if (AutoTrim)
RetVal = RetVal.Trim();
return RetVal;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
return null;
}
}
}
public abstract class cDataHistoryConfigQueryTemplate : IConfigNodeValidation
{
public bool IsValid { get; protected set; } = false;
public string Query { get; private set; } = null;
internal cDataHistoryConfigQueryTemplate(XmlElement XNode, bool Compress, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XContent = XNode.SelectSingleNode("text()")?.Value;
if (!string.IsNullOrEmpty(XContent))
{
Query = XContent;
if (Compress)
{
Query = Query.Replace("\r\n", " ");
Query = Query.Replace("\r", " ");
Query = Query.Replace("\n", " ");
Query = Query.Replace("\t", " ");
while (true)
{
var Q = Query.Replace(" ", " ");
if (Q == Query)
break;
Query = Q;
}
Query = Query.Trim();
}
}
IsValid = true;
}
catch (Exception E)
{
Parser.AddMessage(XNode, $"The text content for element <{XNode.Name} is invalid.>", LogLevels.Warning);
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static cDataHistoryConfigQueryTemplate LoadFromXml(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
cDataHistoryConfigQueryTemplate Template = cDataHistoryConfigQueryTemplateNxql.LoadFromXml(XNode, Parser);
if (Template?.IsValid == true)
return Template;
Template = new cDataHistoryConfigQueryTemplateM42Pickup(XNode, Parser);
if (Template?.IsValid == true)
return Template;
Template = new cDataHistoryConfigQueryTemplateM42DataQueryItems(XNode, Parser);
if (Template?.IsValid == true)
return Template;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
public class cDataHistoryConfigQueryTemplateNxql : cDataHistoryConfigQueryTemplate
{
public readonly uint Limit = 4294967295;
internal cDataHistoryConfigQueryTemplateNxql(XmlElement XNode, cXmlParser Parser) :
base(XNode, true, Parser)
{
if (!IsValid)
return;
Limit = cXmlParser.GetUnsignedIntegerFromXmlAttribute(XNode, "Limit", Limit);
IsValid = true;
}
new internal static cDataHistoryConfigQueryTemplateNxql LoadFromXml(XmlElement XNode, cXmlParser Parser)
{
try
{
if (XNode.SelectSingleNode("Nexthink-NXQL-Template") is XmlElement XNode2)
{
Parser.EnterElement("Nexthink-NXQL-Template");
var RetVal = new cDataHistoryConfigQueryTemplateNxql(XNode2, Parser);
Parser.LeaveElement("Nexthink-NXQL-Template");
return RetVal;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
}
return null;
}
}
public class cDataHistoryConfigQueryTemplateM42Pickup : cDataHistoryConfigQueryTemplate
{
public enum enumSorting { unknown = 0, byPosition, byName };
public string PickupName { get; private set; } = null;
public int FilteredGroup { get; private set; } = -1;
public enumSorting Sorting { get; private set; } = enumSorting.unknown;
internal cDataHistoryConfigQueryTemplateM42Pickup(XmlElement XNode, cXmlParser Parser) :
base(XNode, true, Parser)
{
if (!IsValid)
return;
IsValid = false;
if (XNode.SelectSingleNode("Matrix42-Pickup-Template") is XmlElement XNode2)
{
Parser.EnterElement("Matrix42-Pickup-Template");
PickupName = cXmlParser.GetStringFromXmlAttribute(XNode2, "PickupName");
if (string.IsNullOrEmpty(PickupName))
return;
FilteredGroup = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "FilteredGroup", -1);
Sorting = cXmlParser.GetEnumFromAttribute<enumSorting>(XNode2, "Sorting", enumSorting.unknown);
Parser.LeaveElement("Matrix42-Pickup-Template");
IsValid = true;
}
}
}
public class cDataHistoryConfigQueryTemplateM42DataQueryItems : cDataHistoryConfigQueryTemplate
{
public string EntityClassName { get; private set; } = null;
public List<string> EntityTypeNames { get; private set; } = null;
public string OrderBy { get; private set; } = null;
public string WhereExpression { get; private set; } = null;
internal cDataHistoryConfigQueryTemplateM42DataQueryItems(XmlElement XNode, cXmlParser Parser) :
base(XNode, true, Parser)
{
if (!IsValid)
return;
IsValid = false;
if (XNode.SelectSingleNode("Matrix42-DataQueryItems-Template") is XmlElement XNode2)
{
Parser.EnterElement("Matrix42-DataQueryItems-Template");
EntityClassName = cXmlParser.GetStringFromXmlAttribute(XNode2, "EntityClassName");
if (string.IsNullOrEmpty(EntityClassName))
return;
var strEntityTypeNames = cXmlParser.GetStringFromXmlAttribute(XNode2, "EntityTypeNames");
if (string.IsNullOrEmpty(EntityClassName))
return;
var arrEntityTypeNames = strEntityTypeNames.Split(' ');
if (arrEntityTypeNames.Length <= 0)
return;
EntityTypeNames = new List<string>(arrEntityTypeNames.Length);
foreach (var _e in arrEntityTypeNames)
{
var _e2 = _e.Trim();
if (!string.IsNullOrEmpty(_e2))
EntityTypeNames.Add(_e2);
}
OrderBy = cXmlParser.GetStringFromXmlAttribute(XNode2, "OrderBy");
WhereExpression = cXmlParser.GetStringFromXmlAttribute(XNode2, "WhereExpression");
Parser.LeaveElement("Matrix42-DataQueryItems-Template");
IsValid = true;
}
}
}
public class cDataHistoryConfigTableIndex
{
public string Name;
public bool Unique = false;
public List<cDataHistoryConfigColumnBase> Columns = new List<cDataHistoryConfigColumnBase>();
}
public class cDataHistoryConfigTableReferenceInfo : IConfigNodeValidation
{
public bool IsValid { get; private set; } = false;
public string ForeignTableName { get; private set; } = null;
public cDataHistoryConfigTable ForeignTable { get; private set; } = null;
public string ForeignIndexName { get; private set; } = null;
public cDataHistoryConfigTableIndex ReferencedIndex { get; private set; } = null;
[JsonIgnore]
private readonly int XLine = 0;
[JsonIgnore]
private readonly int XCol = 0;
public List<cDataHistoryConfigColumnBase> Columns { get; private set; } = new List<cDataHistoryConfigColumnBase>();
public List<cDataHistoryConfigColumnBase> ReferencedColumns { get; private set; } = new List<cDataHistoryConfigColumnBase>();
internal cDataHistoryConfigTableReferenceInfo(XmlElement XNode, cDataHistoryConfigTable Table, cXmlParser Parser)
{
try
{
XLine = Parser.currentNode.Line;
XCol = Parser.currentNode.Column;
ForeignTableName = XNode.GetAttribute("ForeignTable");
if (string.IsNullOrEmpty(ForeignTableName))
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> has no valid 'Table' attribute.", LogLevels.Warning);
return;
}
var strReference = XNode.GetAttribute("Columns");
if (string.IsNullOrEmpty(strReference))
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{ForeignTableName}' has no valid 'Reference' attribute.", LogLevels.Warning);
return;
}
var arrReference = strReference.Split(' ');
Columns.Clear();
foreach (var Entry in arrReference)
{
var strRef = Entry.Trim();
if (string.IsNullOrWhiteSpace(strRef))
continue;
if (!Table.Columns.TryGetValue(strRef, out var Col))
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{ForeignTableName}' contains a non existing element '{strRef}' within the 'Reference' attribute.", LogLevels.Warning);
Columns.Clear();
break;
}
if (Columns.Contains(Col))
{
Parser.AddMessage(XNode, $"The element <{XNode.Name}> with Name='{ForeignTableName}' contains a duplicated element '{strRef}' within the 'Reference' attribute.", LogLevels.Warning);
Columns.Clear();
break;
}
Columns.Add(Col);
}
ForeignIndexName = XNode.GetAttribute("ForeignIndex");
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
}
}
internal bool Resolve(cDataHistoryConfigTable Table, Dictionary<string, cDataHistoryConfigTable> AllTables, cXmlParser Parser)
{
IsValid = false;
try
{
// get the foreign table
if (!AllTables.TryGetValue(ForeignTableName, out var _ForeignTable))
return false;
// get the foreign table index
cDataHistoryConfigTableIndex _ForeignIndex = null;
if (!string.IsNullOrEmpty(ForeignIndexName))
if (!_ForeignTable.Indexes.TryGetValue(ForeignIndexName, out _ForeignIndex))
return false;
// get the foreign column list
var _ForeignColumns = new List<cDataHistoryConfigColumnBase>();
if (_ForeignIndex == null)
_ForeignColumns.AddRange(_ForeignTable.KeyColumns);
else
_ForeignColumns.AddRange(_ForeignIndex.Columns);
// check for column compatibilty
if (_ForeignColumns.Count != Columns.Count)
{
Parser.AddMessage(this.XLine, this.XCol, string.Format("The number of referenced columns of table '{0}' does not match the number of referenced foreign columns of table '{1}'.", Table.Name, _ForeignTable.Name), LogLevels.Error);
return false;
}
var ColsTo = _ForeignColumns.GetEnumerator();
foreach (var ColFrom in Columns)
{
if (!ColsTo.MoveNext())
return false;
var ColTo = ColsTo.Current;
if (!cDataHistoryConfigClusters.CheckColumnCompatibility(ColFrom, ColTo))
{
Parser.AddMessage(this.XLine, this.XCol, string.Format("The column type or cardinal of column '{0}' in table '{1}' does not match the referenced foreign column '{2}' of table '{3}'.", ColFrom.Name, Table.Name, ColTo.Name, _ForeignTable.Name), LogLevels.Error);
return false;
}
}
ForeignTable = _ForeignTable;
ReferencedIndex = _ForeignIndex;
ReferencedColumns = _ForeignColumns;
this.IsValid = true;
return true;
}
catch (Exception E)
{
LogException(E);
}
return false;
}
}
public class cDataHistoryConfigMainTable : cDataHistoryConfigTable
{
public cDataHistoryConfigMainTable()
{
}
}
}