diff --git a/C4IT_DataHistoryProvider_Base/F4SD-Cockpit-Server.csproj b/C4IT_DataHistoryProvider_Base/F4SD-Cockpit-Server.csproj
index 0c6f115..cfb5a2a 100644
--- a/C4IT_DataHistoryProvider_Base/F4SD-Cockpit-Server.csproj
+++ b/C4IT_DataHistoryProvider_Base/F4SD-Cockpit-Server.csproj
@@ -302,9 +302,12 @@
DataSources\IRemoteDesktopManager.cs
-
- DataSources\ISearchResultRelationProvider.cs
-
+
+ DataSources\ISearchResultRelationProvider.cs
+
+
+ DataSources\ITicketActivityProvider.cs
+
F4SDConfigGlobalParametersXml.cs
@@ -381,4 +384,4 @@
-
\ No newline at end of file
+
diff --git a/C4IT_DataHistoryProvider_Test/Config/F4SD-Global-Configuration.xml b/C4IT_DataHistoryProvider_Test/Config/F4SD-Global-Configuration.xml
index 5b3fbaa..437d50f 100644
--- a/C4IT_DataHistoryProvider_Test/Config/F4SD-Global-Configuration.xml
+++ b/C4IT_DataHistoryProvider_Test/Config/F4SD-Global-Configuration.xml
@@ -24,6 +24,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/C4IT_DataHistoryProvider_Test/Config/F4SD-Global-Configuration.xsd b/C4IT_DataHistoryProvider_Test/Config/F4SD-Global-Configuration.xsd
index 3d01823..dda5729 100644
--- a/C4IT_DataHistoryProvider_Test/Config/F4SD-Global-Configuration.xsd
+++ b/C4IT_DataHistoryProvider_Test/Config/F4SD-Global-Configuration.xsd
@@ -132,6 +132,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -182,6 +197,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/C4IT_DataHistoryProvider_Test/Config/F4SD-Infrastructure-Configuration.xml b/C4IT_DataHistoryProvider_Test/Config/F4SD-Infrastructure-Configuration.xml
index 3bb761d..eed8339 100644
--- a/C4IT_DataHistoryProvider_Test/Config/F4SD-Infrastructure-Configuration.xml
+++ b/C4IT_DataHistoryProvider_Test/Config/F4SD-Infrastructure-Configuration.xml
@@ -82,15 +82,11 @@
-
+
M42 Demo Server (Imagoverum)
-
-
-
-
-
+
diff --git a/F4SD-Cockpit-ServerCore/DataHistoryCollector.cs b/F4SD-Cockpit-ServerCore/DataHistoryCollector.cs
index 3b1fe00..1b5c25f 100644
--- a/F4SD-Cockpit-ServerCore/DataHistoryCollector.cs
+++ b/F4SD-Cockpit-ServerCore/DataHistoryCollector.cs
@@ -276,7 +276,8 @@ namespace C4IT.DataHistoryProvider
public readonly Dictionary Connectors = new Dictionary();
public readonly cDataHistoryCollectorActiveDirectory ActiveDirectory = null;
public readonly cDataHistoryCollectorClientAgent F4sdAgent = null;
- public cDataHistoryCollectorM42Wpm M42WpmCollector { get; private set; } = null;
+ public cDataHistoryCollectorM42Wpm M42WpmCollector { get; private set; } = null;
+ public ITicketActivityProvider TicketActivityProvider { get; private set; } = null;
public cDataHistoryCollectorNxql NxqlCollector { get; private set; } = null;
public cDataHistoryCollectorCitrix CitrixCollector { get; private set; } = null;
//public cDataHistoryCollectorEmpirum EmpirumCollector { get; private set; } = null;
@@ -409,10 +410,12 @@ namespace C4IT.DataHistoryProvider
GlobalParametersConfigFile = _cfgGlobalParameters;
- GlobalConfig = new cF4sdGlobalConfig(regPath: null);
- if (GlobalParametersConfigFile.Parameters != null)
- GlobalConfig.Load(CentralParameters: GlobalParametersConfigFile.Parameters);
- }
+ GlobalConfig = new cF4sdGlobalConfig(regPath: null);
+ if (GlobalParametersConfigFile.Parameters != null)
+ GlobalConfig.Load(CentralParameters: GlobalParametersConfigFile.Parameters);
+ GlobalConfig.TicketConfiguration.ActivityFilters =
+ GlobalParametersConfigFile.ActivityFilters ?? new cActivityFilterPolicy();
+ }
return true;
}
@@ -514,8 +517,9 @@ namespace C4IT.DataHistoryProvider
if (cF4SDLicense.Instance?.Modules != null)
if (cF4SDLicense.Instance.Modules.ContainsKey(_M42WpmCollector.LicenseId))
{
- M42WpmCollector = _M42WpmCollector;
- Connectors.Add(enumDataHistoryOrigin.M42Wpm, M42WpmCollector);
+ M42WpmCollector = _M42WpmCollector;
+ TicketActivityProvider = _M42WpmCollector;
+ Connectors.Add(enumDataHistoryOrigin.M42Wpm, M42WpmCollector);
RegisterSearchRelationProvider(_M42WpmCollector);
}
}
diff --git a/F4SD-Cockpit-ServerCore/DataHistoryCollectorM42Wpm.cs b/F4SD-Cockpit-ServerCore/DataHistoryCollectorM42Wpm.cs
index 19aa0db..b9462b5 100644
--- a/F4SD-Cockpit-ServerCore/DataHistoryCollectorM42Wpm.cs
+++ b/F4SD-Cockpit-ServerCore/DataHistoryCollectorM42Wpm.cs
@@ -2,8 +2,9 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
-using System.Net.Http;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
using System.Numerics;
using System.Reflection;
using System.Security.Principal;
@@ -31,14 +32,17 @@ using static C4IT.Matrix42.WebClient.cM42WebClient;
namespace C4IT.DataHistoryProvider
{
- public class cDataHistoryCollectorM42Wpm : cDataHistoryCollectorModule, ISearchResultRelationProvider
+ public class cDataHistoryCollectorM42Wpm : cDataHistoryCollectorModule, ISearchResultRelationProvider, ITicketActivityProvider
{
public const string constConnectorName = "Matrix42 WPM conntector";
public const string constLicenseId = "9CE1A6BE-6A0C-4A27-94A5-44AB997B8E62";
private const string constUrlIsAlive = "m42Services/api/c4itf4sdwebapi/isalive";
- private const string constUrlGetTickets = "m42Services/api/c4itf4sdwebapi/getticketlist?sid={0}&hours={1}&queueoption={2}";
- private const string constUrlGetTicketsQueuesParam = "&queues={0}";
+ private const string constUrlGetTickets = "m42Services/api/c4itf4sdwebapi/getticketlist?sid={0}&hours={1}&queueoption={2}";
+ private const string constUrlGetTicketsQueuesParam = "&queues={0}";
+ private const string constUrlGetTicketsV2 = "m42Services/api/c4itf4sdwebapi/v2/getticketlist";
+ private const string constUrlGetTicketOverviewCountsV2 = "m42Services/api/c4itf4sdwebapi/v2/getticketoverviewcounts";
+ private const string constUrlGetTicketOverviewRelationsV2 = "m42Services/api/c4itf4sdwebapi/v2/getticketoverviewrelations";
private const string constUrlGetTicketDetails = "m42Services/api/c4itf4sdwebapi/getticketdetails?objectid={0}";
private const string constUrlGetTicketHistory = "m42Services/api/c4itf4sdwebapi/gettickethistory?objectid={0}";
private const string constUrlGetCreateTicket = "m42Services/api/c4itf4sdwebapi/getdirectlinkcreateticket?sid={0}{1}";
@@ -687,24 +691,33 @@ namespace C4IT.DataHistoryProvider
if (!await CheckOnline())
return null;
- var objSid = new SecurityIdentifier(UserId.sid, 0);
- var strSid = objSid.ToString();
- var queueOption = (int)Collector.InfrastructureConfig.M42Wpm.ActivityQueueFilterOption;
- var strUrl = string.Format(constUrlGetTickets,
- strSid,
- Collector.InfrastructureConfig.M42Wpm.ClosedTicketHistory,
- queueOption);
-
- if (queueOption != 0)
- {
- var encodedQueues = GetEncodedActivityQueues();
- if (!string.IsNullOrWhiteSpace(encodedQueues))
- strUrl += string.Format(constUrlGetTicketsQueuesParam, encodedQueues);
- }
-
- var _wc = await GetWebClient(requestInfo, Token);
- var res = await _wc.HttpEnh.GetAsync(strUrl);
- if (res.IsSuccessStatusCode)
+ var objSid = new SecurityIdentifier(UserId.sid, 0);
+ var strSid = objSid.ToString();
+ var _wc = await GetWebClient(requestInfo, Token);
+ var request = new cTicketActivityListRequest
+ {
+ Sid = strSid,
+ Hours = Collector.InfrastructureConfig.M42Wpm.ClosedTicketHistory,
+ Filters = GetActivityFilters()
+ };
+ var res = await PostJsonAsync(_wc, constUrlGetTicketsV2, request, Token);
+ if (res?.StatusCode == HttpStatusCode.NotFound)
+ {
+ if (!TryGetLegacyQueueFilter(out var queueOption, out var encodedQueues))
+ {
+ LogEntry("The activity filter policy requires the v2 ticket API; legacy fallback was rejected (fail closed).", LogLevels.Warning);
+ return null;
+ }
+ var strUrl = string.Format(
+ constUrlGetTickets,
+ strSid,
+ Collector.InfrastructureConfig.M42Wpm.ClosedTicketHistory,
+ queueOption);
+ if (!string.IsNullOrWhiteSpace(encodedQueues))
+ strUrl += string.Format(constUrlGetTicketsQueuesParam, encodedQueues);
+ res = await _wc.HttpEnh.GetAsync(strUrl);
+ }
+ if (res?.IsSuccessStatusCode == true)
{
var strJson = await res.Content.ReadAsStringAsync();
if (!string.IsNullOrEmpty(strJson))
@@ -1093,12 +1106,76 @@ namespace C4IT.DataHistoryProvider
return filtered;
}
- private int GetActivityQueueOption()
- {
- return (int)Collector.InfrastructureConfig.M42Wpm.ActivityQueueFilterOption;
- }
-
- private string GetEncodedActivityQueues()
+ private int GetActivityQueueOption()
+ {
+ return (int)Collector.InfrastructureConfig.M42Wpm.ActivityQueueFilterOption;
+ }
+
+ private cActivityFilterPolicy GetActivityFilters()
+ {
+ return Collector?.GetGlobalConfig()?.TicketConfiguration?.ActivityFilters
+ ?? new cActivityFilterPolicy();
+ }
+
+ private bool TryGetLegacyQueueFilter(out int queueOption, out string encodedQueues)
+ {
+ queueOption = 0;
+ encodedQueues = null;
+ var activeFilters = (GetActivityFilters()?.Filters ?? new List())
+ .Where(entry => entry?.Enabled == true)
+ .ToList();
+ if (activeFilters.Count == 0)
+ return true;
+ if (activeFilters.Count != 1)
+ return false;
+
+ var activityFilter = activeFilters[0];
+ if (!string.Equals(activityFilter.Provider, "Matrix42", StringComparison.OrdinalIgnoreCase)
+ || !string.Equals(activityFilter.Field, "Queue", StringComparison.OrdinalIgnoreCase)
+ || activityFilter.Match != enumActivityFilterMatch.include
+ || activityFilter.EmptyHandling == enumActivityFilterEmptyHandling.only)
+ {
+ return false;
+ }
+
+ queueOption = activityFilter.EmptyHandling == enumActivityFilterEmptyHandling.include ? 1 : 2;
+ var values = (activityFilter.Values ?? new List())
+ .Where(value => value != null)
+ .Select(value =>
+ {
+ if (Guid.TryParse(value.ID, out var id) && id != Guid.Empty)
+ return ":" + HttpUtility.UrlEncode(id.ToString("D"));
+ return string.IsNullOrWhiteSpace(value.Name)
+ ? null
+ : HttpUtility.UrlEncode(value.Name.Trim());
+ })
+ .Where(value => !string.IsNullOrWhiteSpace(value))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+ if (values.Count == 0)
+ return false;
+
+ encodedQueues = string.Join("|", values);
+ return true;
+ }
+
+ private static Task PostJsonAsync(
+ cM42WebClient webClient,
+ string url,
+ object request,
+ CancellationToken token)
+ {
+ var json = JsonConvert.SerializeObject(
+ request,
+ Formatting.None,
+ new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
+ return webClient.HttpEnh.PostAsync(
+ url,
+ new StringContent(json, Encoding.UTF8, "application/json"),
+ token);
+ }
+
+ private string GetEncodedActivityQueues()
{
var queues = Collector.InfrastructureConfig.M42Wpm.ActivityQueues;
if (queues == null || queues.Count == 0)
@@ -1140,28 +1217,36 @@ namespace C4IT.DataHistoryProvider
string scope,
IReadOnlyCollection requestedKeys,
cF4sdWebRequestInfo requestInfo,
- CancellationToken token)
- {
- try
- {
- var urlBuilder = new StringBuilder(constUrlGetTicketOverviewCounts);
- urlBuilder.Append("?sid=").Append(HttpUtility.UrlEncode(sid));
- urlBuilder.Append("&scope=").Append(HttpUtility.UrlEncode(scope ?? string.Empty));
-
- if (requestedKeys != null && requestedKeys.Count > 0)
- {
- urlBuilder.Append("&keys=").Append(HttpUtility.UrlEncode(string.Join(",", requestedKeys)));
- }
-
- var queueOption = GetActivityQueueOption();
- var encodedQueues = queueOption != 0 ? GetEncodedActivityQueues() : null;
- AppendQueueFilterQuery(urlBuilder, queueOption, encodedQueues);
-
- var url = urlBuilder.ToString();
- var wc = await GetWebClient(requestInfo, token);
- var res = await wc.HttpEnh.GetAsync(url, token);
- if (token.IsCancellationRequested)
- return new Dictionary(StringComparer.OrdinalIgnoreCase);
+ CancellationToken token)
+ {
+ try
+ {
+ var wc = await GetWebClient(requestInfo, token);
+ var request = new cTicketOverviewFilterRequest
+ {
+ Sid = sid,
+ Scope = scope,
+ Keys = requestedKeys?.ToList() ?? new List(),
+ Filters = GetActivityFilters()
+ };
+ var res = await PostJsonAsync(wc, constUrlGetTicketOverviewCountsV2, request, token);
+ if (res?.StatusCode == HttpStatusCode.NotFound)
+ {
+ if (!TryGetLegacyQueueFilter(out var queueOption, out var encodedQueues))
+ {
+ LogEntry("The activity filter policy requires the v2 overview API; legacy fallback was rejected (fail closed).", LogLevels.Warning);
+ return new Dictionary(StringComparer.OrdinalIgnoreCase);
+ }
+ var urlBuilder = new StringBuilder(constUrlGetTicketOverviewCounts);
+ urlBuilder.Append("?sid=").Append(HttpUtility.UrlEncode(sid));
+ urlBuilder.Append("&scope=").Append(HttpUtility.UrlEncode(scope ?? string.Empty));
+ if (requestedKeys != null && requestedKeys.Count > 0)
+ urlBuilder.Append("&keys=").Append(HttpUtility.UrlEncode(string.Join(",", requestedKeys)));
+ AppendQueueFilterQuery(urlBuilder, queueOption, encodedQueues);
+ res = await wc.HttpEnh.GetAsync(urlBuilder.ToString(), token);
+ }
+ if (token.IsCancellationRequested)
+ return new Dictionary(StringComparer.OrdinalIgnoreCase);
if (res?.IsSuccessStatusCode == true)
{
@@ -1227,64 +1312,12 @@ namespace C4IT.DataHistoryProvider
if (string.IsNullOrWhiteSpace(sid))
return new Dictionary(StringComparer.OrdinalIgnoreCase);
- var normalizedKeys = (keys ?? Enumerable.Empty())
- .Where(k => !string.IsNullOrWhiteSpace(k))
- .Distinct(StringComparer.OrdinalIgnoreCase)
- .ToList();
- var now = DateTime.UtcNow;
- var ttl = GetTicketOverviewCacheDuration(useRoleScope);
-
- if (!useRoleScope)
- {
- // process thr personal scope
- if (TryGetTicketOverviewPersonalCache(sid, now, out var cachedPersonal))
- return FilterTicketOverviewCounts(cachedPersonal, normalizedKeys);
-
- var counts = await FetchTicketOverviewCountsAsync(sid, "personal", normalizedKeys, requestInfo, Token);
- if (Token.IsCancellationRequested)
- return new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- SetTicketOverviewPersonalCache(sid, counts, now.Add(ttl));
- return FilterTicketOverviewCounts(counts, normalizedKeys);
- }
-
- // process the role scope
- var roleIds = await GetTicketOverviewRoleIdsAsync(sid, now, ttl, Token);
- if (roleIds == null || roleIds.Count == 0)
- return new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- var countsByRole = new Dictionary>();
- var missingRoles = new List();
-
- foreach (var roleId in roleIds)
- {
- if (TryGetTicketOverviewRoleCache(roleId, now, out var cachedRole))
- {
- countsByRole[roleId] = cachedRole;
- }
- else
- {
- missingRoles.Add(roleId);
- }
- }
-
- if (missingRoles.Count > 0)
- {
- var fetched = await FetchTicketOverviewCountsByRolesAsync(missingRoles, normalizedKeys, requestInfo, LogDeep + 1, Token);
- var expiresAt = DateTime.UtcNow.Add(ttl);
-
- foreach (var roleId in missingRoles)
- {
- if (!fetched.TryGetValue(roleId, out var roleCounts))
- roleCounts = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- SetTicketOverviewRoleCache(roleId, roleCounts, expiresAt);
- countsByRole[roleId] = roleCounts;
- }
- }
-
- var summed = SumTicketOverviewCounts(countsByRole.Values);
- return FilterTicketOverviewCounts(summed, normalizedKeys);
+ var normalizedKeys = (keys ?? Enumerable.Empty())
+ .Where(k => !string.IsNullOrWhiteSpace(k))
+ .Distinct(StringComparer.OrdinalIgnoreCase)
+ .ToList();
+ var scope = useRoleScope ? "role" : "personal";
+ return await FetchTicketOverviewCountsAsync(sid, scope, normalizedKeys, requestInfo, Token);
}
catch (Exception E)
{
@@ -1314,26 +1347,37 @@ namespace C4IT.DataHistoryProvider
return new List();
var sid = requestInfo?.userInfo?.AdSid;
- if (string.IsNullOrWhiteSpace(sid))
- return new List();
-
- var scope = useRoleScope ? "role" : "personal";
- var urlBuilder = new StringBuilder(constUrlGetTicketOverviewRelations);
- urlBuilder.Append("?sid=").Append(HttpUtility.UrlEncode(sid));
- urlBuilder.Append("&scope=").Append(HttpUtility.UrlEncode(scope));
- urlBuilder.Append("&key=").Append(HttpUtility.UrlEncode(key));
- urlBuilder.Append("&count=").Append(Math.Max(0, count));
-
- var queueOption = GetActivityQueueOption();
- var encodedQueues = queueOption != 0 ? GetEncodedActivityQueues() : null;
- AppendQueueFilterQuery(urlBuilder, queueOption, encodedQueues);
-
- var url = urlBuilder.ToString();
-
- var wc = await GetWebClient(requestInfo, Token);
- var res = await wc.HttpEnh.GetAsync(url, Token);
- if (Token.IsCancellationRequested)
- return new List();
+ if (string.IsNullOrWhiteSpace(sid))
+ return new List();
+
+ var scope = useRoleScope ? "role" : "personal";
+ var wc = await GetWebClient(requestInfo, Token);
+ var request = new cTicketOverviewFilterRequest
+ {
+ Sid = sid,
+ Scope = scope,
+ Key = key,
+ Count = Math.Max(0, count),
+ Filters = GetActivityFilters()
+ };
+ var res = await PostJsonAsync(wc, constUrlGetTicketOverviewRelationsV2, request, Token);
+ if (res?.StatusCode == HttpStatusCode.NotFound)
+ {
+ if (!TryGetLegacyQueueFilter(out var queueOption, out var encodedQueues))
+ {
+ LogEntry("The activity filter policy requires the v2 relation API; legacy fallback was rejected (fail closed).", LogLevels.Warning);
+ return new List();
+ }
+ var urlBuilder = new StringBuilder(constUrlGetTicketOverviewRelations);
+ urlBuilder.Append("?sid=").Append(HttpUtility.UrlEncode(sid));
+ urlBuilder.Append("&scope=").Append(HttpUtility.UrlEncode(scope));
+ urlBuilder.Append("&key=").Append(HttpUtility.UrlEncode(key));
+ urlBuilder.Append("&count=").Append(Math.Max(0, count));
+ AppendQueueFilterQuery(urlBuilder, queueOption, encodedQueues);
+ res = await wc.HttpEnh.GetAsync(urlBuilder.ToString(), Token);
+ }
+ if (Token.IsCancellationRequested)
+ return new List();
if (res?.IsSuccessStatusCode == true)
{
diff --git a/F4SD-Cockpit-ServerCore/DataHistoryConfigGolabalParameters.cs b/F4SD-Cockpit-ServerCore/DataHistoryConfigGolabalParameters.cs
index 0151aa4..d4252ef 100644
--- a/F4SD-Cockpit-ServerCore/DataHistoryConfigGolabalParameters.cs
+++ b/F4SD-Cockpit-ServerCore/DataHistoryConfigGolabalParameters.cs
@@ -1,7 +1,10 @@
using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Xml;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Security;
+using System.Text;
+using System.Xml;
using Newtonsoft.Json;
@@ -21,7 +24,8 @@ namespace C4IT.DataHistoryProvider
private const string constFileNameF4sdSchema = "F4SD-Global-Configuration.xsd";
private const string constConfigRootElement = "F4SD-Global-Configuration";
- public cConfigHelperParameterList Parameters { get; private set; } = null;
+ public cConfigHelperParameterList Parameters { get; private set; } = null;
+ public cActivityFilterPolicy ActivityFilters { get; private set; } = new cActivityFilterPolicy();
private cDataHistoryConfigInfrastructure InfrastructureConfig = null;
@@ -102,12 +106,15 @@ namespace C4IT.DataHistoryProvider
if (_overrideValues != null && _overrideValues.ValueList != null && _overrideValues.ValueList.Count > 0)
_result.Items[_overrideValues.Name] = _overrideValues;
continue;
- case "TicketProcessing":
- var _ticketProcessingEntry = getTicketProcessingEntry(_item, Parser);
- if (_ticketProcessingEntry != null)
- _result.Items[_ticketProcessingEntry.Name] = _ticketProcessingEntry;
- continue;
- }
+ case "TicketProcessing":
+ var _ticketProcessingEntry = getTicketProcessingEntry(_item, Parser);
+ if (_ticketProcessingEntry != null)
+ _result.Items[_ticketProcessingEntry.Name] = _ticketProcessingEntry;
+ continue;
+ case "ActivityFilters":
+ ActivityFilters = getActivityFilters(_item, Parser);
+ continue;
+ }
if (_attPolicy != null && _attValue != null && _ElementCount == 0)
{
@@ -156,8 +163,89 @@ namespace C4IT.DataHistoryProvider
if (CM != null) LogMethodEnd(CM);
}
- return _result;
- }
+ return _result;
+ }
+
+ private static cActivityFilterPolicy getActivityFilters(XmlElement node, cXmlParser parser)
+ {
+ var result = new cActivityFilterPolicy();
+ foreach (XmlElement filterNode in node.SelectNodes("Filter").OfType())
+ {
+ parser.EnterElement(filterNode.Name);
+ try
+ {
+ if (!Enum.TryParse(filterNode.GetAttribute("Match"), true, out enumActivityFilterMatch match))
+ match = enumActivityFilterMatch.exclude;
+ if (!Enum.TryParse(filterNode.GetAttribute("EmptyHandling"), true, out enumActivityFilterEmptyHandling emptyHandling))
+ emptyHandling = enumActivityFilterEmptyHandling.include;
+
+ var filter = new cActivityFilter
+ {
+ Provider = filterNode.GetAttribute("Provider"),
+ Field = filterNode.GetAttribute("Field"),
+ Enabled = bool.TryParse(filterNode.GetAttribute("Enabled"), out var enabled) && enabled,
+ Match = match,
+ EmptyHandling = emptyHandling
+ };
+
+ foreach (XmlElement valueNode in filterNode.SelectNodes("Value").OfType())
+ {
+ filter.Values.Add(new cActivityFilterValue
+ {
+ ID = valueNode.GetAttribute("ID"),
+ Name = valueNode.GetAttribute("Name")
+ });
+ }
+
+ result.Filters.Add(filter);
+ }
+ finally
+ {
+ parser.LeaveElement(filterNode.Name);
+ }
+ }
+
+ return result;
+ }
+
+ private string getDefaultActivityFiltersXml()
+ {
+ var queueOption = InfrastructureConfig?.M42Wpm?.ActivityQueueFilterOption
+ ?? enumActivityQueueFilterOptions.showAll;
+ var queues = InfrastructureConfig?.M42Wpm?.ActivityQueues
+ ?? new List();
+ var enableQueueFilter = queueOption != enumActivityQueueFilterOptions.showAll && queues.Count > 0;
+ var emptyHandling = queueOption == enumActivityQueueFilterOptions.onlyListedQueues
+ ? enumActivityFilterEmptyHandling.exclude
+ : enumActivityFilterEmptyHandling.include;
+
+ var xml = new StringBuilder();
+ xml.Append("");
+ xml.AppendFormat(
+ "",
+ enableQueueFilter.ToString().ToLowerInvariant(),
+ emptyHandling);
+ foreach (var queue in queues.Where(queue => queue != null))
+ {
+ xml.AppendFormat(
+ "",
+ queue.QueueID == Guid.Empty ? string.Empty : queue.QueueID.ToString("D"),
+ SecurityElement.Escape(queue.QueueName ?? string.Empty));
+ }
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ xml.Append("");
+ return xml.ToString();
+ }
private cConfigHelperParameterEntry getInformationClassSearchPriority(XmlElement XNode, cXmlParser Parser)
{
@@ -487,11 +575,16 @@ namespace C4IT.DataHistoryProvider
, "ShowOverview"
, ""
);
- RetVal |= DoXmlInsertElement(XmlRoot
- , "TicketConfiguration"
- , "TicketProcessing"
- , ""
- );
+ RetVal |= DoXmlInsertElement(XmlRoot
+ , "TicketConfiguration"
+ , "TicketProcessing"
+ , ""
+ );
+ RetVal |= DoXmlInsertElement(XmlRoot
+ , "TicketConfiguration"
+ , "ActivityFilters"
+ , getDefaultActivityFiltersXml()
+ );
RetVal |= DoXmlRemoveElement(XmlRoot
, "TicketConfiguration"
, "OpenActivitiesExternally"
diff --git a/F4SD-Cockpit-ServerCore/DataHistoryConfigInfrastructure.cs b/F4SD-Cockpit-ServerCore/DataHistoryConfigInfrastructure.cs
index b0c910b..32a039e 100644
--- a/F4SD-Cockpit-ServerCore/DataHistoryConfigInfrastructure.cs
+++ b/F4SD-Cockpit-ServerCore/DataHistoryConfigInfrastructure.cs
@@ -49,7 +49,7 @@ namespace C4IT.DataHistoryProvider
{
}
- public override bool InstantiateProperties(XmlElement XRoot, cXmlParser Parser)
+ public override bool InstantiateProperties(XmlElement XRoot, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
@@ -118,9 +118,34 @@ namespace C4IT.DataHistoryProvider
if (CM != null) LogMethodEnd(CM);
}
- return false;
- }
- }
+ return false;
+ }
+
+ public override bool DoXmlUpdates(XmlElement xmlRoot, bool withM42Config = false, bool withIntuneConfig = false, bool withMobileDeviceConfig = false, bool withCitrixConfig = false)
+ {
+ // Queue filtering moved to the provider-neutral global ActivityFilters policy.
+ // InstantiateProperties runs first, so the values remain available for the
+ // one-time migration while the obsolete XML is removed.
+ if (!(xmlRoot.SelectSingleNode("Matrix42-WPM") is XmlElement matrix42))
+ return false;
+
+ var changed = false;
+ if (matrix42.HasAttribute("ActivityQueueFilter"))
+ {
+ matrix42.RemoveAttribute("ActivityQueueFilter");
+ changed = true;
+ }
+
+ var queues = matrix42.SelectSingleNode("Queues");
+ if (queues != null)
+ {
+ matrix42.RemoveChild(queues);
+ changed = true;
+ }
+
+ return changed;
+ }
+ }
public class cDataHistoryConfigDatabase : IConfigNodeValidation
{
diff --git a/F4SD-Cockpit-ServerCore/DataSources/ITicketActivityProvider.cs b/F4SD-Cockpit-ServerCore/DataSources/ITicketActivityProvider.cs
new file mode 100644
index 0000000..d530aa2
--- /dev/null
+++ b/F4SD-Cockpit-ServerCore/DataSources/ITicketActivityProvider.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+using C4IT.DataHistoryProvider;
+using C4IT.FASD.Base;
+
+namespace C4IT_DataHistoryProvider_Base.DataSources
+{
+ ///
+ /// Provider-neutral access to ticket-system activities used by search and overview.
+ /// Provider-specific filter fields remain opaque configuration values.
+ ///
+ public interface ITicketActivityProvider
+ {
+ bool TicketAndServiceRequestsEnabled { get; }
+
+ Task> GetTicketsFromSid(
+ cF4sdConnectorIds userId,
+ CancellationToken token,
+ cF4sdWebRequestInfo requestInfo);
+
+ Task> GetTicketOverviewCountsAsync(
+ IEnumerable keys,
+ bool useRoleScope,
+ cF4sdWebRequestInfo requestInfo,
+ int logDeep,
+ CancellationToken token);
+
+ Task> GetTicketOverviewRelationsAsync(
+ string key,
+ bool useRoleScope,
+ int count,
+ cF4sdWebRequestInfo requestInfo,
+ int logDeep,
+ CancellationToken token);
+ }
+}
diff --git a/F4SDwebService/Config/F4SD-Global-Configuration.xml b/F4SDwebService/Config/F4SD-Global-Configuration.xml
index 5b3fbaa..437d50f 100644
--- a/F4SDwebService/Config/F4SD-Global-Configuration.xml
+++ b/F4SDwebService/Config/F4SD-Global-Configuration.xml
@@ -24,6 +24,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/F4SDwebService/Config/F4SD-Infrastructure-Configuration.xml b/F4SDwebService/Config/F4SD-Infrastructure-Configuration.xml
index 3bb761d..eed8339 100644
--- a/F4SDwebService/Config/F4SD-Infrastructure-Configuration.xml
+++ b/F4SDwebService/Config/F4SD-Infrastructure-Configuration.xml
@@ -82,15 +82,11 @@
-
+
M42 Demo Server (Imagoverum)
-
-
-
-
-
+
diff --git a/F4SDwebService/Controllers/TicketOverviewController.cs b/F4SDwebService/Controllers/TicketOverviewController.cs
index 8ea78b4..898a0ac 100644
--- a/F4SDwebService/Controllers/TicketOverviewController.cs
+++ b/F4SDwebService/Controllers/TicketOverviewController.cs
@@ -39,7 +39,7 @@ namespace FasdWebService.Controllers
return Ok(new TicketOverviewCountsResult());
}
- var collector = WebApiApplication.Collector?.M42WpmCollector;
+ var collector = WebApiApplication.Collector?.TicketActivityProvider;
if (collector == null)
{
return Ok(new TicketOverviewCountsResult());
@@ -95,7 +95,7 @@ namespace FasdWebService.Controllers
return Ok(new List());
}
- var collector = WebApiApplication.Collector?.M42WpmCollector;
+ var collector = WebApiApplication.Collector?.TicketActivityProvider;
if (collector == null)
{
return Ok(new List());
diff --git a/F4SDwebService/Publish/Config/F4SD-Global-Configuration.xml b/F4SDwebService/Publish/Config/F4SD-Global-Configuration.xml
index 5b3fbaa..437d50f 100644
--- a/F4SDwebService/Publish/Config/F4SD-Global-Configuration.xml
+++ b/F4SDwebService/Publish/Config/F4SD-Global-Configuration.xml
@@ -24,6 +24,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/F4SDwebService/Publish/Config/F4SD-Global-Configuration.xsd b/F4SDwebService/Publish/Config/F4SD-Global-Configuration.xsd
index 3d01823..dda5729 100644
--- a/F4SDwebService/Publish/Config/F4SD-Global-Configuration.xsd
+++ b/F4SDwebService/Publish/Config/F4SD-Global-Configuration.xsd
@@ -132,6 +132,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -182,6 +197,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/F4SDwebService/Publish/Config/F4SD-Infrastructure-Configuration.xml b/F4SDwebService/Publish/Config/F4SD-Infrastructure-Configuration.xml
index 3bb761d..eed8339 100644
--- a/F4SDwebService/Publish/Config/F4SD-Infrastructure-Configuration.xml
+++ b/F4SDwebService/Publish/Config/F4SD-Infrastructure-Configuration.xml
@@ -82,15 +82,11 @@
-
+
M42 Demo Server (Imagoverum)
-
-
-
-
-
+