4177 lines
190 KiB
C#
4177 lines
190 KiB
C#
using C4IT.F4SD.SupportCaseProtocoll.Models;
|
|
using C4IT.FASD.Base;
|
|
using C4IT.Logging;
|
|
using C4IT.Matrix42.WebClient;
|
|
using C4IT.XML;
|
|
using C4IT_DataHistoryProvider_Base.DataSources;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Reflection;
|
|
using System.Security.Principal;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using static C4IT.FASD.Base.cF4SDHealthCardRawData;
|
|
using static C4IT.Logging.cLogManager;
|
|
using static C4IT.Matrix42.WebClient.cM42WebClient;
|
|
|
|
namespace C4IT.DataHistoryProvider
|
|
{
|
|
public class cDataHistoryCollectorM42Wpm : cDataHistoryCollectorModule, ISearchResultRelationProvider
|
|
{
|
|
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 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}";
|
|
private const string constUrlGetCreateTicketAssetParam = "&assetname={0}";
|
|
private const string constUrlUpdateSolution = "m42Services/api/c4itf4sdwebapi/updateactivitysolution/{0}/";
|
|
private const string constUrlGetPickupValues = "m42Services/api/c4itf4sdwebapi/getpickup/{0}?group={1}";
|
|
private const string constUrlGetRoleMeberships = "m42services/api/c4itf4sdwebapi/getrolememberships/?sid={0}";
|
|
private const string constUrlGetTicketOverviewCounts = "m42Services/api/c4itf4sdwebapi/getticketoverviewcounts";
|
|
private const string constUrlGetTicketOverviewCountsByRoles = "m42Services/api/c4itf4sdwebapi/getticketoverviewcountsbyroles";
|
|
private const string constUrlGetTicketOverviewRelations = "m42Services/api/c4itf4sdwebapi/getticketoverviewrelations";
|
|
private const string constUrlGetDataQueryRelationItems = "m42Services/api/dataquery/relationitems";
|
|
private const string constUrlGetDataQueryRelationItemsCount = "m42Services/api/dataquery/relationitems/count";
|
|
private const string constUrlCreateTicket = "m42Services/api/ticket/create?activitytype={0}";
|
|
private const string constUrlActivityGetQuickCallTemplateInfo = "m42Services/api/activity/quickcalltemplateinfo/{0}";
|
|
private const string constUrlCreateJournalEntry = "m42Services/api/journal/Add";
|
|
private const string constUrlFragmentsGetList = "m42Services/api/data/fragments/{0}?where={1}&columns={2}&pagesize={3}&pagenumber={4}&sort={5}";
|
|
private const string constUrlObjectsGetObject = "m42Services/api/data/objects/{0}/{1}?full={2}";
|
|
private const string constUrlObjectsUpdateObject = "m42Services/api/data/objects/{0}?full={1}";
|
|
private const string constUrlTicketClose = "m42Services/api/ticket/close";
|
|
private const string constUrlActivityPause = "m42Services/api/activity/Pause";
|
|
private const string constUrlActivityForward = "m42Services/api/activity/Forward";
|
|
private const string constUrlActivityTrackWorkingTime = "m42Services/api/activity/trackworkingtime";
|
|
private const string constUrlTicketTransform = "m42Services/api/ticket/transform";
|
|
private const string constUrlActivityReopen = "m42Services/api/activity/reopen";
|
|
private const string constUrlGenerateApiTokenForMe = "m42Services/api/apitoken/generateapitokenforme";
|
|
private const string constUrlGenerateAccessTokenFromApiToken = "m42Services/api/apitoken/generateaccesstokenfromapitoken";
|
|
|
|
|
|
public const string constTableNameTicketDetails = "M42Wpm-Tickets";
|
|
public const string constTableNameTicketHistory = "M42Wpm-Ticket-History";
|
|
public const string constTableNameUserTicket = "M42Wpm-User-NewTicket";
|
|
|
|
private readonly cM42WebClient WebClient = null;
|
|
private Dictionary<string, cM42WebClient> dicWebClients = new Dictionary<string, cM42WebClient>();
|
|
|
|
private readonly Timer onlineTimer = null;
|
|
|
|
private bool IsOnline = false;
|
|
|
|
private Dictionary<WebClientCacheIndex, WebClientCacheEntry> UserWebClientCache = new Dictionary<WebClientCacheIndex, WebClientCacheEntry>();
|
|
|
|
private readonly object _ticketOverviewCacheLock = new object();
|
|
private readonly Dictionary<string, TicketOverviewCountCacheEntry> _ticketOverviewPersonalCache = new Dictionary<string, TicketOverviewCountCacheEntry>(StringComparer.OrdinalIgnoreCase);
|
|
private readonly Dictionary<Guid, TicketOverviewCountCacheEntry> _ticketOverviewRoleCache = new Dictionary<Guid, TicketOverviewCountCacheEntry>();
|
|
private readonly Dictionary<string, TicketOverviewRoleListCacheEntry> _ticketOverviewRoleListCache = new Dictionary<string, TicketOverviewRoleListCacheEntry>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
private readonly cDataHistoryCollector _collector;
|
|
|
|
private static class _OnlineCheckCriticalSection
|
|
{
|
|
public static SemaphoreSlim Semaphore = new SemaphoreSlim(1, 1);
|
|
}
|
|
|
|
private static class _LanguageDicWebClientCriticalSection
|
|
{
|
|
public static SemaphoreSlim Semaphore = new SemaphoreSlim(1, 1);
|
|
}
|
|
|
|
private struct WebClientCacheIndex
|
|
{
|
|
public Guid Id;
|
|
public string Language;
|
|
}
|
|
|
|
private class WebClientCacheEntry
|
|
{
|
|
public cM42WebClient WebClient;
|
|
public DateTime LastUsed;
|
|
public DateTime ValidUntil;
|
|
}
|
|
|
|
private sealed class TicketOverviewCountCacheEntry
|
|
{
|
|
public Dictionary<string, int> Counts { get; set; } = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
public DateTime ExpiresAtUtc { get; set; }
|
|
}
|
|
|
|
private sealed class TicketOverviewRoleListCacheEntry
|
|
{
|
|
public List<Guid> RoleIds { get; set; } = new List<Guid>();
|
|
public DateTime ExpiresAtUtc { get; set; }
|
|
}
|
|
|
|
private sealed class TicketOverviewCountsByRolesRequest
|
|
{
|
|
public string Sid { get; set; }
|
|
public List<Guid> RoleGuids { get; set; } = new List<Guid>();
|
|
public List<string> Keys { get; set; } = new List<string>();
|
|
public int QueueOption { get; set; }
|
|
public string Queues { get; set; }
|
|
}
|
|
|
|
private sealed class TicketOverviewCountsByRolesResponse
|
|
{
|
|
[JsonProperty("countsByRole")]
|
|
public Dictionary<string, Dictionary<string, int>> CountsByRole { get; set; }
|
|
= new Dictionary<string, Dictionary<string, int>>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
public class cM42ApiTokenModel
|
|
{
|
|
public string ApiToken { get; set; }
|
|
public string Name { get; set; }
|
|
public bool? Enabled { get; set; }
|
|
public DateTime? ValidUntil { get; set; }
|
|
public string UserId { get; set; }
|
|
}
|
|
|
|
private class cApiTokenRequestModelBase
|
|
{
|
|
public string Name { get; set; }
|
|
public int ExpirationDays { get; set; }
|
|
}
|
|
|
|
public cDataHistoryCollectorM42Wpm(cDataHistoryCollector Collector) : base(Collector, enumDataHistoryOrigin.M42Wpm, constConnectorName, constLicenseId)
|
|
{
|
|
if (Collector.InfrastructureConfig.M42Wpm.Server == null)
|
|
return;
|
|
|
|
_collector = Collector;
|
|
|
|
WebClient = new cM42WebClient(Collector.InfrastructureConfig.M42Wpm.Server);
|
|
|
|
if (Collector.autoConnectionCheck)
|
|
onlineTimer = new Timer(onlineTimerCallback, null, 0, 30000);
|
|
|
|
}
|
|
|
|
private async Task<cM42WebClient> GetWebClient(cF4sdWebRequestInfo requestInfo, CancellationToken Token)
|
|
{
|
|
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
if (cLogManager.DefaultLogger.IsDebug)
|
|
LogEntry($"M42 webclient culture: {requestInfo?.Culture?.TextInfo?.CultureName}", LogLevels.Debug);
|
|
|
|
if (requestInfo?.Culture == null)
|
|
{
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry($"M42 webclient requested with no culture", LogLevels.Debug);
|
|
return WebClient;
|
|
}
|
|
|
|
await _LanguageDicWebClientCriticalSection.Semaphore.WaitAsync(Token);
|
|
try
|
|
{
|
|
var _lang = requestInfo.Culture.TextInfo.CultureName;
|
|
if (dicWebClients.TryGetValue(_lang, out var client))
|
|
{
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry($"M42 webclient request returned with culture: {client?.UserLanguage}", LogLevels.Debug);
|
|
return client;
|
|
}
|
|
|
|
|
|
client = new cM42WebClient(Collector.InfrastructureConfig.M42Wpm.Server, _lang);
|
|
var resLogon = await client.LogonWithApiKeyAsync(Collector.InfrastructureConfig.M42Wpm.Credential.NwCredential.Password);
|
|
if (resLogon == cM42WebClient.eReason.ok)
|
|
{
|
|
dicWebClients[_lang] = client;
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry($"M42 webclient request returned with culture: {client?.UserLanguage}", LogLevels.Debug);
|
|
return client;
|
|
}
|
|
else
|
|
{
|
|
LogEntry($"Could not logon to M42 server with culture {_lang}. Reason: {resLogon}", LogLevels.Warning);
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
_LanguageDicWebClientCriticalSection.Semaphore.Release();
|
|
}
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry($"M42 webclient requested return with no culture.", LogLevels.Debug);
|
|
return WebClient;
|
|
}
|
|
|
|
private async Task<cM42WebClient> GetUserWebClient(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
lock (requestInfo)
|
|
if (requestInfo?.M42WebClient != null)
|
|
return requestInfo.M42WebClient;
|
|
|
|
if (requestInfo?.userInfo?.Id is null)
|
|
return null;
|
|
|
|
var _lang = requestInfo.Culture?.TextInfo?.CultureName;
|
|
if (_lang == null)
|
|
_lang = "en-Us";
|
|
|
|
var _index = new WebClientCacheIndex() { Id = requestInfo.userInfo.Id, Language = _lang };
|
|
lock (UserWebClientCache)
|
|
{
|
|
if (UserWebClientCache.TryGetValue(_index, out var _cacheEntry) && _cacheEntry.ValidUntil < DateTime.UtcNow + TimeSpan.FromMinutes(cDataHistoryCollector.constMinutesUntilTokenIsInvalid))
|
|
{
|
|
_cacheEntry.LastUsed = DateTime.UtcNow;
|
|
lock (requestInfo)
|
|
requestInfo.M42WebClient = _cacheEntry.WebClient;
|
|
return _cacheEntry.WebClient;
|
|
}
|
|
}
|
|
|
|
if (Collector.TokenCache == null)
|
|
return null;
|
|
|
|
var _tokenInfo = await Collector.TokenCache.GetAsync(requestInfo.userInfo.Id, cF4SDTokenRegistration.enumTokenType.M42Bearer, requestInfo, LogDeep + 1);
|
|
|
|
if (_tokenInfo == null || !_tokenInfo.IsValid())
|
|
return null;
|
|
|
|
var client = new cM42WebClient(Collector.InfrastructureConfig.M42Wpm.Server, _lang);
|
|
client.SetBearerToken(_tokenInfo.secret);
|
|
var _reason = await client.Open();
|
|
if (_reason == eReason.ok)
|
|
{
|
|
lock (UserWebClientCache)
|
|
{
|
|
UserWebClientCache[_index] = new WebClientCacheEntry() { WebClient = client, LastUsed = DateTime.UtcNow, ValidUntil = _tokenInfo.validUntil };
|
|
}
|
|
|
|
lock (requestInfo)
|
|
requestInfo.M42WebClient = client;
|
|
|
|
return client;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private void CleanupUserWebCache()
|
|
{
|
|
lock (UserWebClientCache)
|
|
{
|
|
var _del = new List<WebClientCacheIndex>();
|
|
foreach (var _entry in UserWebClientCache)
|
|
if (_entry.Value.LastUsed < DateTime.UtcNow - TimeSpan.FromMinutes(10) || _entry.Value.ValidUntil < DateTime.UtcNow)
|
|
_del.Add(_entry.Key);
|
|
foreach (var entry in _del)
|
|
UserWebClientCache.Remove(entry);
|
|
}
|
|
}
|
|
|
|
public override async Task<bool> DoScanAsync(bool Always, bool Rescan, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token, bool EnhancedDebug = false)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (Collector.M42WpmCollector is null)
|
|
return false;
|
|
|
|
Collector.DoProcessUiMessage(0, "");
|
|
if (!Always)
|
|
{
|
|
var scanInfo = await Collector.M42WpmCollector.GetScanTimeInfoAsync(requestInfo, LogDeep + 1, Token);
|
|
if (scanInfo?.LastScan is DateTime _lastScan && scanInfo?.NextScan is DateTime _nextScan)
|
|
{
|
|
if (_lastScan >= _nextScan)
|
|
{
|
|
Collector.DoProcessUiMessage(0, $"currently no scan needed for M42 api token cleanup, lastScan={_lastScan} (UTC), nextScan={_nextScan} (UTC)");
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
await CleanupApiTokensAsync(Token);
|
|
if (Token.IsCancellationRequested)
|
|
return false;
|
|
|
|
await Collector.SetLastScanTime("M42Scan-CleanupToken", DateTime.UtcNow, requestInfo, LogDeep + 1, Token);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public override async Task<List<object>> GetIds(cF4sdConnectorIds IdEntry, enumFasdInformationClass InfoClass, cF4sdWebRequestInfo requestInfo, int LogDeep)
|
|
{
|
|
await Task.CompletedTask;
|
|
return new List<object>() { IdEntry.Id };
|
|
}
|
|
|
|
public override async Task<cScanTimeInfo> GetScanTimeInfoAsync(cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var scanTiming = new cDataHistoryScanTiming()
|
|
{
|
|
IsValid = true,
|
|
Interval = TimeSpan.FromDays(1),
|
|
Offset = TimeSpan.FromHours(1),
|
|
Timezone = TimeZoneInfo.Local
|
|
};
|
|
return await GetScanTimeInfoAsync(scanTiming, "M42Scan-CleanupToken", requestInfo, LogDeep + 1, Token);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
private async Task<bool> CheckLogonAsync(bool force, CancellationToken Token)
|
|
{
|
|
if (!force && WebClient.BearerToken != null)
|
|
return true;
|
|
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
if (Collector.InfrastructureConfig.M42Wpm == null)
|
|
return false;
|
|
|
|
Collector.DoProcessUiMessage(0, "");
|
|
Collector.DoProcessUiMessage(0, $"Start estabishing M42 WPM connection to server {Collector.InfrastructureConfig.M42Wpm.Server}...");
|
|
var resLogon = await WebClient.LogonWithApiKeyAsync(Collector.InfrastructureConfig.M42Wpm.Credential.NwCredential.Password);
|
|
if (resLogon == cM42WebClient.eReason.ok)
|
|
{
|
|
Collector.DoProcessUiMessage(0, "...M42 WPM connection established successful.");
|
|
StartOnlineValidation();
|
|
return true;
|
|
}
|
|
|
|
Collector.DoProcessUiMessage(1, $"Logon failed: {resLogon}");
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
Collector.DoProcessUiMessage(0, "");
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
Collector.DoProcessUiMessage(0, "Error: Could not connect to M42 WPM.");
|
|
return false;
|
|
}
|
|
|
|
public async Task<bool> ValidateConnectionAsync(bool forceLogon, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
|
|
try
|
|
{
|
|
await _OnlineCheckCriticalSection.Semaphore.WaitAsync(Token);
|
|
try
|
|
{
|
|
var CheckResult = true;
|
|
if (!IsOnline || forceLogon)
|
|
CheckResult = await CheckLogonAsync(true, Token);
|
|
if (CheckResult)
|
|
{
|
|
var resWeb = await WebClient.HttpEnh.GetAsync(constUrlIsAlive, Token);
|
|
CheckResult = resWeb != null && resWeb.IsSuccessStatusCode;
|
|
if (forceLogon)
|
|
{
|
|
if (CheckResult)
|
|
Collector.DoProcessUiMessage(0, "...F4SD web api 'is alive' is reachable.");
|
|
else
|
|
Collector.DoProcessUiMessage(0, "Error: F4SD web api 'is alive' is not reachable. Maybe F4SD support is not installed or wrong version.", LogLevels.Error);
|
|
}
|
|
}
|
|
|
|
IsOnline = CheckResult;
|
|
|
|
if (onlineTimer != null)
|
|
onlineTimer.Change(30000, 60000);
|
|
|
|
return IsOnline;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
_OnlineCheckCriticalSection.Semaphore.Release();
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private enumTicketStatus ConvertM42TicketCode(int M42TicketStatus)
|
|
{
|
|
try
|
|
{
|
|
switch (M42TicketStatus)
|
|
{
|
|
case 200:
|
|
return enumTicketStatus.New;
|
|
case 201:
|
|
case 202:
|
|
return enumTicketStatus.InProgress;
|
|
case 203:
|
|
return enumTicketStatus.OnHold;
|
|
case 204:
|
|
return enumTicketStatus.Closed;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
return enumTicketStatus.Unknown;
|
|
}
|
|
|
|
public async Task<List<cF4SDTicketSummary>> GetTicketsFromSid(cF4sdConnectorIds UserId, CancellationToken Token, cF4sdWebRequestInfo requestInfo)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
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 = string.Join("|",
|
|
Collector.InfrastructureConfig.M42Wpm.ActivityQueues.Select(q =>
|
|
string.Format("{0}:{1}",
|
|
HttpUtility.UrlEncode(q.QueueName),
|
|
HttpUtility.UrlEncode(q.QueueID.ToString())
|
|
)
|
|
)
|
|
);
|
|
strUrl += string.Format(constUrlGetTicketsQueuesParam, encodedQueues);
|
|
}
|
|
|
|
var _wc = await GetWebClient(requestInfo, Token);
|
|
var res = await _wc.HttpEnh.GetAsync(strUrl);
|
|
if (res.IsSuccessStatusCode)
|
|
{
|
|
var strJson = await res.Content.ReadAsStringAsync();
|
|
if (!string.IsNullOrEmpty(strJson))
|
|
{
|
|
var ticketInfoList = JsonConvert.DeserializeObject<List<cF4SDTicketSummary>>(strJson);
|
|
if (!(ticketInfoList?.Count > 0))
|
|
return null;
|
|
|
|
foreach (var Entry in ticketInfoList)
|
|
Entry.UserId = UserId.Id;
|
|
|
|
return ticketInfoList;
|
|
}
|
|
}
|
|
|
|
StartOnlineValidation();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public async Task<List<cF4sdApiSearchResultRelation>> getTicketUsage(List<cF4sdConnectorIds> lstTicketIds, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var lstTasks = new List<Task<List<cF4SDTicketSummary>>>();
|
|
foreach (var Entry in lstTicketIds)
|
|
lstTasks.Add(GetTicketsFromSid(Entry, Token, requestInfo));
|
|
|
|
var result = await Task.WhenAll(lstTasks);
|
|
|
|
if (result == null)
|
|
return null;
|
|
|
|
var retVal = new Dictionary<string, cF4SDTicketSummary>();
|
|
foreach (var Entry in result)
|
|
if (Entry != null)
|
|
{
|
|
foreach (var Entry2 in Entry)
|
|
{
|
|
if (Entry2.IsPrimaryAccount)
|
|
retVal[Entry2.Name] = Entry2;
|
|
else if (!retVal.ContainsKey(Entry2.Name))
|
|
retVal.Add(Entry2.Name, Entry2);
|
|
}
|
|
}
|
|
|
|
if (retVal.Count > 0)
|
|
{
|
|
var ticketResult = new List<cF4sdApiSearchResultRelation>(retVal.Count);
|
|
foreach (var Entry in retVal.Values)
|
|
{
|
|
var Infos = new Dictionary<string, string>()
|
|
{
|
|
{ "Summary", Entry.Summary },
|
|
{ "ActivityType", Entry.ActivityType },
|
|
{ "Status", Entry.Status },
|
|
{ "StatusId", ConvertM42TicketCode(Entry.StatusId).ToString() },
|
|
{ "Asset", Entry.AssetName },
|
|
{ "ServiceName", Entry.ServiceName },
|
|
{ "ServiceId", Entry.ServiceId.ToString() },
|
|
{ "AssetType", Entry.AssetCIName }
|
|
};
|
|
|
|
var ticketInfo = new cF4sdApiSearchResultRelation()
|
|
{
|
|
Type = enumF4sdSearchResultClass.Ticket,
|
|
Name = Entry.Name,
|
|
DisplayName = Entry.Name,
|
|
id = Entry.TicketObjectId,
|
|
Status = enumF4sdSearchResultStatus.Active,
|
|
Infos = Infos,
|
|
Identities = new cF4sdIdentityList()
|
|
{
|
|
new cF4sdIdentityEntry(){ Class = enumFasdInformationClass.User, Id = Entry.UserId},
|
|
new cF4sdIdentityEntry(){ Class = enumFasdInformationClass.Ticket, Id = Entry.TicketObjectId}
|
|
}
|
|
};
|
|
ticketResult.Add(ticketInfo);
|
|
}
|
|
|
|
return ticketResult;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private TimeSpan GetTicketOverviewCacheDuration(bool useRoleScope)
|
|
{
|
|
var ticketConfig = Collector?.GetGlobalConfig()?.TicketConfiguration;
|
|
var minutes = useRoleScope
|
|
? ticketConfig?.OverviewPollingRole ?? cF4sdTicketConfig.DefaultOverviewPollingRole
|
|
: ticketConfig?.OverviewPollingPersonal ?? cF4sdTicketConfig.DefaultOverviewPollingPersonal;
|
|
|
|
if (minutes < 1)
|
|
minutes = 1;
|
|
|
|
return TimeSpan.FromMinutes(minutes);
|
|
}
|
|
|
|
private bool TryGetTicketOverviewPersonalCache(string sid, DateTime now, out Dictionary<string, int> counts)
|
|
{
|
|
counts = null;
|
|
if (string.IsNullOrWhiteSpace(sid))
|
|
return false;
|
|
|
|
lock (_ticketOverviewCacheLock)
|
|
{
|
|
if (_ticketOverviewPersonalCache.TryGetValue(sid, out var entry))
|
|
{
|
|
if (entry.ExpiresAtUtc > now)
|
|
{
|
|
counts = new Dictionary<string, int>(entry.Counts, StringComparer.OrdinalIgnoreCase);
|
|
return true;
|
|
}
|
|
|
|
_ticketOverviewPersonalCache.Remove(sid);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private bool TryGetTicketOverviewRoleCache(Guid roleId, DateTime now, out Dictionary<string, int> counts)
|
|
{
|
|
counts = null;
|
|
if (roleId == Guid.Empty)
|
|
return false;
|
|
|
|
lock (_ticketOverviewCacheLock)
|
|
{
|
|
if (_ticketOverviewRoleCache.TryGetValue(roleId, out var entry))
|
|
{
|
|
if (entry.ExpiresAtUtc > now)
|
|
{
|
|
counts = new Dictionary<string, int>(entry.Counts, StringComparer.OrdinalIgnoreCase);
|
|
return true;
|
|
}
|
|
|
|
_ticketOverviewRoleCache.Remove(roleId);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void SetTicketOverviewPersonalCache(string sid, Dictionary<string, int> counts, DateTime expiresAtUtc)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(sid))
|
|
return;
|
|
|
|
lock (_ticketOverviewCacheLock)
|
|
{
|
|
_ticketOverviewPersonalCache[sid] = new TicketOverviewCountCacheEntry
|
|
{
|
|
Counts = new Dictionary<string, int>(counts ?? new Dictionary<string, int>(), StringComparer.OrdinalIgnoreCase),
|
|
ExpiresAtUtc = expiresAtUtc
|
|
};
|
|
}
|
|
}
|
|
|
|
private void SetTicketOverviewRoleCache(Guid roleId, Dictionary<string, int> counts, DateTime expiresAtUtc)
|
|
{
|
|
if (roleId == Guid.Empty)
|
|
return;
|
|
|
|
lock (_ticketOverviewCacheLock)
|
|
{
|
|
_ticketOverviewRoleCache[roleId] = new TicketOverviewCountCacheEntry
|
|
{
|
|
Counts = new Dictionary<string, int>(counts ?? new Dictionary<string, int>(), StringComparer.OrdinalIgnoreCase),
|
|
ExpiresAtUtc = expiresAtUtc
|
|
};
|
|
}
|
|
}
|
|
|
|
private bool TryGetTicketOverviewRoleIdsFromCache(string sid, DateTime now, out List<Guid> roleIds)
|
|
{
|
|
roleIds = null;
|
|
if (string.IsNullOrWhiteSpace(sid))
|
|
return false;
|
|
|
|
lock (_ticketOverviewCacheLock)
|
|
{
|
|
if (_ticketOverviewRoleListCache.TryGetValue(sid, out var entry))
|
|
{
|
|
if (entry.ExpiresAtUtc > now)
|
|
{
|
|
roleIds = new List<Guid>(entry.RoleIds);
|
|
return true;
|
|
}
|
|
|
|
_ticketOverviewRoleListCache.Remove(sid);
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private void SetTicketOverviewRoleIdsCache(string sid, IEnumerable<Guid> roleIds, DateTime expiresAtUtc)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(sid))
|
|
return;
|
|
|
|
var normalized = (roleIds ?? Enumerable.Empty<Guid>())
|
|
.Where(id => id != Guid.Empty)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
lock (_ticketOverviewCacheLock)
|
|
{
|
|
_ticketOverviewRoleListCache[sid] = new TicketOverviewRoleListCacheEntry
|
|
{
|
|
RoleIds = normalized,
|
|
ExpiresAtUtc = expiresAtUtc
|
|
};
|
|
}
|
|
}
|
|
|
|
private async Task<List<Guid>> GetTicketOverviewRoleIdsAsync(string sid, DateTime now, TimeSpan ttl, CancellationToken token)
|
|
{
|
|
if (TryGetTicketOverviewRoleIdsFromCache(sid, now, out var cached))
|
|
return cached;
|
|
|
|
var userInfo = await GetM42UserInfoAsync(sid, token);
|
|
var roles = userInfo?.Roles ?? new List<M42UserUserInfo.M42Role>();
|
|
var roleIds = roles
|
|
.Where(r => r != null && r.Id != Guid.Empty)
|
|
.Select(r => r.Id)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
SetTicketOverviewRoleIdsCache(sid, roleIds, now.Add(ttl));
|
|
return roleIds;
|
|
}
|
|
|
|
private async Task<Dictionary<Guid, Dictionary<string, int>>> FetchTicketOverviewCountsByRolesAsync(
|
|
IEnumerable<Guid> roleIds,
|
|
IReadOnlyCollection<string> requestedKeys,
|
|
cF4sdWebRequestInfo requestInfo,
|
|
int logDeep,
|
|
CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(logDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var roleList = (roleIds ?? Enumerable.Empty<Guid>())
|
|
.Where(id => id != Guid.Empty)
|
|
.Distinct()
|
|
.ToList();
|
|
|
|
if (roleList.Count == 0)
|
|
return new Dictionary<Guid, Dictionary<string, int>>();
|
|
|
|
var queueOption = GetActivityQueueOption();
|
|
var encodedQueues = queueOption != 0 ? GetEncodedActivityQueues() : null;
|
|
|
|
var request = new TicketOverviewCountsByRolesRequest
|
|
{
|
|
Sid = requestInfo?.userInfo?.AdSid,
|
|
RoleGuids = roleList,
|
|
Keys = requestedKeys?.Where(k => !string.IsNullOrWhiteSpace(k)).ToList() ?? new List<string>(),
|
|
QueueOption = queueOption,
|
|
Queues = encodedQueues
|
|
};
|
|
|
|
var jsonBody = JsonConvert.SerializeObject(request, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
|
|
|
|
var wc = await GetWebClient(requestInfo, token);
|
|
var res = await wc.HttpEnh.PostAsync(constUrlGetTicketOverviewCountsByRoles, content, token);
|
|
if (token.IsCancellationRequested)
|
|
return new Dictionary<Guid, Dictionary<string, int>>();
|
|
|
|
if (res?.IsSuccessStatusCode == true)
|
|
{
|
|
var json = await res.Content.ReadAsStringAsync();
|
|
if (!string.IsNullOrWhiteSpace(json))
|
|
{
|
|
var response = JsonConvert.DeserializeObject<TicketOverviewCountsByRolesResponse>(json);
|
|
if (response?.CountsByRole != null)
|
|
{
|
|
var result = new Dictionary<Guid, Dictionary<string, int>>();
|
|
foreach (var entry in response.CountsByRole)
|
|
{
|
|
if (!Guid.TryParse(entry.Key, out var roleId) || roleId == Guid.Empty)
|
|
continue;
|
|
|
|
var counts = entry.Value ?? new Dictionary<string, int>();
|
|
result[roleId] = new Dictionary<string, int>(counts, StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
|
|
StartOnlineValidation();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(logDeep, CM, requestInfo.id, requestInfo.created, startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return new Dictionary<Guid, Dictionary<string, int>>();
|
|
}
|
|
|
|
private Dictionary<string, int> SumTicketOverviewCounts(IEnumerable<Dictionary<string, int>> sources)
|
|
{
|
|
var result = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
if (sources == null)
|
|
return result;
|
|
|
|
foreach (var counts in sources)
|
|
{
|
|
if (counts == null)
|
|
continue;
|
|
|
|
foreach (var kvp in counts)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(kvp.Key))
|
|
continue;
|
|
|
|
result[kvp.Key] = result.TryGetValue(kvp.Key, out var existing)
|
|
? existing + kvp.Value
|
|
: kvp.Value;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
private Dictionary<string, int> FilterTicketOverviewCounts(Dictionary<string, int> counts, IReadOnlyCollection<string> requestedKeys)
|
|
{
|
|
if (counts == null)
|
|
return new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
if (requestedKeys == null || requestedKeys.Count == 0)
|
|
return new Dictionary<string, int>(counts, StringComparer.OrdinalIgnoreCase);
|
|
|
|
var filtered = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
foreach (var key in requestedKeys)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(key))
|
|
continue;
|
|
|
|
filtered[key] = counts.TryGetValue(key, out var value) ? value : 0;
|
|
}
|
|
|
|
return filtered;
|
|
}
|
|
|
|
private int GetActivityQueueOption()
|
|
{
|
|
return (int)Collector.InfrastructureConfig.M42Wpm.ActivityQueueFilterOption;
|
|
}
|
|
|
|
private string GetEncodedActivityQueues()
|
|
{
|
|
var queues = Collector.InfrastructureConfig.M42Wpm.ActivityQueues;
|
|
if (queues == null || queues.Count == 0)
|
|
return null;
|
|
|
|
return string.Join("|",
|
|
queues.Select(q =>
|
|
string.Format("{0}:{1}",
|
|
HttpUtility.UrlEncode(q.QueueName),
|
|
HttpUtility.UrlEncode(q.QueueID.ToString())
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
private static void AppendQueueFilterQuery(StringBuilder urlBuilder, int queueOption, string encodedQueues)
|
|
{
|
|
if (queueOption != 0)
|
|
urlBuilder.Append("&queueoption=").Append(queueOption);
|
|
|
|
if (!string.IsNullOrWhiteSpace(encodedQueues))
|
|
urlBuilder.Append("&queues=").Append(encodedQueues);
|
|
}
|
|
|
|
private async Task<Dictionary<string, int>> FetchTicketOverviewCountsAsync(
|
|
string sid,
|
|
string scope,
|
|
IReadOnlyCollection<string> 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<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
if (res?.IsSuccessStatusCode == true)
|
|
{
|
|
var json = await res.Content.ReadAsStringAsync();
|
|
if (!string.IsNullOrWhiteSpace(json))
|
|
{
|
|
var root = JsonConvert.DeserializeObject<JObject>(json);
|
|
var countsToken = root?["counts"] as JObject;
|
|
var counts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
if (countsToken != null)
|
|
{
|
|
foreach (var prop in countsToken.Properties())
|
|
{
|
|
if (prop?.Name == null)
|
|
continue;
|
|
var value = prop.Value?.Type == JTokenType.Integer
|
|
? prop.Value.Value<int>()
|
|
: int.TryParse(prop.Value?.ToString(), out var parsed) ? parsed : 0;
|
|
counts[prop.Name] = value;
|
|
}
|
|
}
|
|
return counts;
|
|
}
|
|
}
|
|
|
|
StartOnlineValidation();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
|
|
return new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
public async Task<Dictionary<string, int>> GetTicketOverviewCountsAsync(IEnumerable<string> keys, bool useRoleScope, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (!await CheckOnline())
|
|
return new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
var sid = requestInfo?.userInfo?.AdSid;
|
|
if (string.IsNullOrWhiteSpace(sid))
|
|
return new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
var normalizedKeys = (keys ?? Enumerable.Empty<string>())
|
|
.Where(k => !string.IsNullOrWhiteSpace(k))
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
.ToList();
|
|
var now = DateTime.UtcNow;
|
|
var ttl = GetTicketOverviewCacheDuration(useRoleScope);
|
|
|
|
if (!useRoleScope)
|
|
{
|
|
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<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
SetTicketOverviewPersonalCache(sid, counts, now.Add(ttl));
|
|
return FilterTicketOverviewCounts(counts, normalizedKeys);
|
|
}
|
|
|
|
var roleIds = await GetTicketOverviewRoleIdsAsync(sid, now, ttl, Token);
|
|
if (roleIds == null || roleIds.Count == 0)
|
|
return new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
var countsByRole = new Dictionary<Guid, Dictionary<string, int>>();
|
|
var missingRoles = new List<Guid>();
|
|
|
|
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<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
SetTicketOverviewRoleCache(roleId, roleCounts, expiresAt);
|
|
countsByRole[roleId] = roleCounts;
|
|
}
|
|
}
|
|
|
|
var summed = SumTicketOverviewCounts(countsByRole.Values);
|
|
return FilterTicketOverviewCounts(summed, normalizedKeys);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
public async Task<List<cF4sdApiSearchResultRelation>> GetTicketOverviewRelationsAsync(string key, bool useRoleScope, int count, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (!await CheckOnline())
|
|
return new List<cF4sdApiSearchResultRelation>();
|
|
|
|
if (string.IsNullOrWhiteSpace(key))
|
|
return new List<cF4sdApiSearchResultRelation>();
|
|
|
|
var sid = requestInfo?.userInfo?.AdSid;
|
|
if (string.IsNullOrWhiteSpace(sid))
|
|
return new List<cF4sdApiSearchResultRelation>();
|
|
|
|
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<cF4sdApiSearchResultRelation>();
|
|
|
|
if (res?.IsSuccessStatusCode == true)
|
|
{
|
|
var json = await res.Content.ReadAsStringAsync();
|
|
if (!string.IsNullOrWhiteSpace(json))
|
|
{
|
|
var relations = JsonConvert.DeserializeObject<List<cF4sdApiSearchResultRelation>>(json);
|
|
if (relations != null)
|
|
{
|
|
await EnsureTicketOverviewRelationIdentitiesAsync(relations, requestInfo, LogDeep + 1, Token);
|
|
return relations;
|
|
}
|
|
}
|
|
}
|
|
|
|
StartOnlineValidation();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return new List<cF4sdApiSearchResultRelation>();
|
|
}
|
|
|
|
private async Task EnsureTicketOverviewRelationIdentitiesAsync(
|
|
List<cF4sdApiSearchResultRelation> relations,
|
|
cF4sdWebRequestInfo requestInfo,
|
|
int logDeep,
|
|
CancellationToken token)
|
|
{
|
|
if (relations == null)
|
|
return;
|
|
|
|
foreach (var relation in relations)
|
|
{
|
|
if (token.IsCancellationRequested || relation == null)
|
|
return;
|
|
|
|
var identities = relation.Identities ?? new cF4sdIdentityList();
|
|
relation.Identities = identities;
|
|
|
|
if (!identities.Any(i => i.Class == enumFasdInformationClass.Ticket) && relation.id != Guid.Empty)
|
|
{
|
|
identities.Add(new cF4sdIdentityEntry
|
|
{
|
|
Class = enumFasdInformationClass.Ticket,
|
|
Id = relation.id
|
|
});
|
|
}
|
|
|
|
if (relation.Infos == null)
|
|
relation.Infos = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
if (!relation.Infos.ContainsKey("Sids") && relation.Infos.TryGetValue("UserSid", out var userSid) && !string.IsNullOrWhiteSpace(userSid))
|
|
relation.Infos["Sids"] = userSid;
|
|
|
|
Guid userId = Guid.Empty;
|
|
if (relation.Infos.Count > 0)
|
|
{
|
|
if (relation.Infos.TryGetValue("Sids", out var sidsValue))
|
|
{
|
|
var sids = sidsValue?.Split(',')
|
|
.Select(v => v.Trim())
|
|
.Where(v => !string.IsNullOrWhiteSpace(v))
|
|
.ToList();
|
|
|
|
if (sids != null && sids.Count > 0)
|
|
{
|
|
var resolved = await Collector.UserSearchBySidsAsync(sids, token, requestInfo, logDeep + 1);
|
|
var user = resolved?.Values?.FirstOrDefault()?.FirstOrDefault();
|
|
if (user?.Result != null)
|
|
userId = user.Result.id;
|
|
}
|
|
}
|
|
|
|
if (userId == Guid.Empty && relation.Infos.TryGetValue("UserAccount", out var userAccount))
|
|
{
|
|
relation.Infos.TryGetValue("UserDomain", out var userDomain);
|
|
if (!string.IsNullOrWhiteSpace(userAccount))
|
|
{
|
|
var resolved = await Collector.GetUserIdFromAccountAsync(userAccount, userDomain, requestInfo, logDeep + 1, token);
|
|
if (resolved.HasValue)
|
|
userId = resolved.Value;
|
|
}
|
|
}
|
|
|
|
if (userId == Guid.Empty)
|
|
{
|
|
if (relation.Infos.TryGetValue("UserId", out var userIdString) ||
|
|
relation.Infos.TryGetValue("UserGuid", out userIdString) ||
|
|
relation.Infos.TryGetValue("UserIdentityId", out userIdString))
|
|
{
|
|
Guid.TryParse(userIdString, out userId);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (userId == Guid.Empty)
|
|
continue;
|
|
|
|
identities.RemoveAll(i => i.Class == enumFasdInformationClass.User);
|
|
identities.Add(new cF4sdIdentityEntry
|
|
{
|
|
Class = enumFasdInformationClass.User,
|
|
Id = userId
|
|
});
|
|
|
|
relation.Infos["UserId"] = userId.ToString();
|
|
relation.Infos["UserGuid"] = userId.ToString();
|
|
}
|
|
}
|
|
|
|
public override async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetTableResultsVirtualAsync(List<cDataHistoryConfigTable> Tables, Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, DateTime RefTime, int MaxAge, bool instantly, Guid? CacheId, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (!await CheckOnline())
|
|
return null;
|
|
|
|
var bMainExists = Tables.Exists(v => v.Name == constTableNameTicketDetails && v.ParentCluster?.Origin == enumDataHistoryOrigin.M42Wpm);
|
|
var bHistoryExists = Tables.Exists(v => v.Name == constTableNameTicketHistory && v.ParentCluster?.Origin == enumDataHistoryOrigin.M42Wpm);
|
|
var bUserInfoExists = Tables.Exists(v => v.Name == constTableNameUserTicket && v.ParentCluster?.Origin == enumDataHistoryOrigin.M42Wpm);
|
|
var bPickupsExists = Tables.Exists(v => v.ParentCluster?.Origin == enumDataHistoryOrigin.M42Wpm && v.SubTables?.Count == 1 && v.SubTables.Values.First().Template is cDataHistoryConfigQueryTemplateM42Pickup);
|
|
|
|
if (!bMainExists && !bHistoryExists && !bUserInfoExists && !bPickupsExists)
|
|
return null;
|
|
|
|
|
|
if (!Identities.TryGetValue(enumFasdInformationClass.Ticket, out var idTicket))
|
|
{
|
|
bMainExists = false;
|
|
bHistoryExists = false;
|
|
}
|
|
|
|
if (!bMainExists && !bHistoryExists && !bUserInfoExists && !bPickupsExists)
|
|
return null;
|
|
|
|
var listTasks = new List<Task<List<cF4SDHealthCardRawData.cHealthCardTable>>>(2);
|
|
if (bMainExists && CacheId == null)
|
|
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetTicketMainTableAsync(idTicket.Id, requestInfo, LogDeep + 1, Token); }));
|
|
if (bHistoryExists && (instantly || CacheId != null))
|
|
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetTicketHistoryTableAsync(idTicket.Id, requestInfo, LogDeep + 1, Token); }));
|
|
if (bUserInfoExists && (CacheId == null))
|
|
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetUserTicketAsync(Identities, Token, requestInfo, LogDeep + 1); }));
|
|
if (bPickupsExists && (instantly || CacheId != null))
|
|
{
|
|
foreach (var _table in Tables)
|
|
{
|
|
if (_table.ParentCluster?.Origin != enumDataHistoryOrigin.M42Wpm)
|
|
continue;
|
|
if (!(_table.SubTables.Values.First()?.Template is cDataHistoryConfigQueryTemplateM42Pickup))
|
|
continue;
|
|
|
|
listTasks.Add(Task.Run<List<cF4SDHealthCardRawData.cHealthCardTable>>(async () => { return await GetUserPickupValuesAsync(_table, requestInfo, LogDeep + 1, Token); }));
|
|
}
|
|
}
|
|
|
|
var arrRes = await Task.WhenAll(listTasks.ToArray());
|
|
var retVal = new List<cF4SDHealthCardRawData.cHealthCardTable>();
|
|
foreach (var Entry in arrRes)
|
|
if (Entry != null)
|
|
retVal.AddRange(Entry);
|
|
|
|
|
|
// add the incomplete tables
|
|
if (CacheId == null)
|
|
{
|
|
if (bHistoryExists)
|
|
retVal.Add(new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = constTableNameTicketHistory,
|
|
InformationClass = enumFasdInformationClass.Ticket,
|
|
Origin = enumDataHistoryOrigin.M42Wpm,
|
|
IsIncomplete = true
|
|
});
|
|
|
|
foreach (var _table in Tables)
|
|
{
|
|
if (_table.ParentCluster?.Origin != enumDataHistoryOrigin.M42Wpm)
|
|
continue;
|
|
if (!(_table.SubTables.Values.First()?.Template is cDataHistoryConfigQueryTemplateM42Pickup))
|
|
continue;
|
|
|
|
retVal.Add(new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = _table.Name,
|
|
InformationClass = _table.ParentCluster.InformationClass,
|
|
Origin = _table.ParentCluster.Origin,
|
|
IsIncomplete = true
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
if (retVal.Count == 0)
|
|
return null;
|
|
|
|
return retVal;
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetTicketMainTableAsync(Guid TicketId, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameTicketDetails, out var M42TableDetails))
|
|
return null;
|
|
|
|
var strUrl = string.Format(constUrlGetTicketDetails, TicketId);
|
|
var _wc = await GetWebClient(requestInfo, Token);
|
|
var res = await _wc.HttpEnh.GetAsync(strUrl);
|
|
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry("SpecialDebug GetTicketMainTableAsync #1");
|
|
if (res?.IsSuccessStatusCode == true)
|
|
{
|
|
var strJson = await res.Content.ReadAsStringAsync();
|
|
|
|
if (!string.IsNullOrEmpty(strJson))
|
|
{
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry("SpecialDebug GetTicketMainTableAsync #2");
|
|
|
|
JObject ticketInfos = JsonConvert.DeserializeObject<JObject>(strJson);
|
|
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = constTableNameTicketDetails,
|
|
InformationClass = enumFasdInformationClass.Ticket,
|
|
Origin = enumDataHistoryOrigin.M42Wpm,
|
|
IsStatic = true,
|
|
TableType = eDataHistoryTableType.Static
|
|
};
|
|
|
|
var dicVals = new Dictionary<string, object>();
|
|
var vals = ticketInfos.Children();
|
|
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry("SpecialDebug GetTicketMainTableAsync #3");
|
|
|
|
foreach (var token in vals)
|
|
{
|
|
try
|
|
{
|
|
if (token is JProperty prop)
|
|
if (prop.Value is JValue val)
|
|
dicVals[prop.Name] = val.Value;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogEntry($"Error getting M42 ticket detail property '{token.Path}'", LogLevels.Error);
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry("SpecialDebug GetTicketMainTableAsync #4");
|
|
|
|
foreach (var colInfo in M42TableDetails.Columns.Values)
|
|
{
|
|
try
|
|
{
|
|
if (!dicVals.TryGetValue(colInfo.SourceName, out var objVal))
|
|
objVal = null;
|
|
|
|
objVal = ConvertToF4sdType(objVal, colInfo.ValueType);
|
|
|
|
var _col = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = colInfo.Name, Values = new List<object>(1) { objVal } };
|
|
if (colInfo.IsWritable && colInfo.SourceName == "SolutionHtml")
|
|
_col.IsWritable = true;
|
|
|
|
retVal.Columns[colInfo.Name] = _col;
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry("SpecialDebug GetTicketMainTableAsync #5");
|
|
|
|
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
|
|
}
|
|
else
|
|
{
|
|
LogEntry($"Could not get detailed ticket information for ticket wit id {TicketId}. Ticket content is empty.", LogLevels.Warning);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cLogManager.DefaultLogger.LogHttpResponseMessage(res, $"Could not get detailed ticket information for ticket wit id {TicketId}.", LogLevels.Warning);
|
|
}
|
|
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry("SpecialDebug GetTicketMainTableAsync #6");
|
|
|
|
StartOnlineValidation();
|
|
|
|
if (cLogManager.DefaultLogger.IsDebug) LogEntry("SpecialDebug GetTicketMainTableAsync #7");
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private object ConvertToF4sdType(object objVal, enumFasdValueType ValueType)
|
|
{
|
|
try
|
|
{
|
|
if (objVal != null)
|
|
{
|
|
switch (ValueType)
|
|
{
|
|
case enumFasdValueType.INT:
|
|
return cF4SDHealthCardRawData.GetInteger(objVal);
|
|
case enumFasdValueType.GUID:
|
|
return cXmlParser.GetGuidFromString(objVal.ToString());
|
|
case enumFasdValueType.BOOLEAN:
|
|
|
|
if (objVal == null) return false;
|
|
if (objVal is bool) return (bool)objVal;
|
|
if (objVal is int) return (int)objVal != 0;
|
|
if (objVal is string) return bool.TryParse((string)objVal, out bool result) ? result : ((string)objVal == "1");
|
|
return false; // Standardrückgabewert, falls keine Bedingung zutrifft
|
|
case enumFasdValueType.DATETIME:
|
|
DateTime? dt = null;
|
|
if (objVal is DateTime _dt)
|
|
dt = _dt;
|
|
else
|
|
{
|
|
if (DateTime.TryParse(objVal.ToString(), out _dt))
|
|
dt = _dt;
|
|
}
|
|
if (dt is DateTime _dt2)
|
|
{
|
|
if (_dt2 == new DateTime(1, 1, 1, 0, 0, 0))
|
|
dt = null;
|
|
}
|
|
return dt;
|
|
default:
|
|
return objVal.ToString();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetTicketHistoryTableAsync(Guid TicketId, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameTicketHistory, out var M42TableDetails))
|
|
return null;
|
|
|
|
var strUrl = string.Format(constUrlGetTicketHistory, TicketId);
|
|
var _wc = await GetWebClient(requestInfo, Token);
|
|
var res = await _wc.HttpEnh.GetAsync(strUrl);
|
|
|
|
if (res?.IsSuccessStatusCode == true)
|
|
{
|
|
var strJson = await res.Content.ReadAsStringAsync();
|
|
|
|
if (!string.IsNullOrEmpty(strJson))
|
|
{
|
|
JContainer ticketInfos = JsonConvert.DeserializeObject<JContainer>(strJson);
|
|
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = constTableNameTicketHistory,
|
|
InformationClass = enumFasdInformationClass.Ticket,
|
|
Origin = enumDataHistoryOrigin.M42Wpm,
|
|
IsStatic = false,
|
|
TableType = eDataHistoryTableType.HistoryEvents
|
|
};
|
|
|
|
var hLength = ticketInfos.Count;
|
|
retVal.Columns = new Dictionary<string, cF4SDHealthCardRawData.cHealthCardTableColumn>(M42TableDetails.Columns.Count);
|
|
|
|
foreach (var colInfo in M42TableDetails.Columns.Values)
|
|
{
|
|
retVal.Columns[colInfo.Name] = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal)
|
|
{
|
|
ColumnName = colInfo.Name,
|
|
Values = new List<object>(hLength)
|
|
};
|
|
}
|
|
|
|
foreach (var Entry in ticketInfos)
|
|
{
|
|
var dicVals = new Dictionary<string, object>();
|
|
var vals = Entry.Children();
|
|
foreach (var token in vals)
|
|
{
|
|
try
|
|
{
|
|
|
|
if (token is JProperty prop)
|
|
if (prop.Value is JValue val)
|
|
dicVals[prop.Name] = val.Value;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogEntry($"Error getting M42 ticket detail property '{token.Path}'", LogLevels.Error);
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
foreach (var col in M42TableDetails.Columns.Values)
|
|
{
|
|
if (!retVal.Columns.TryGetValue(col.Name, out var dataCol))
|
|
continue;
|
|
if (dicVals.TryGetValue(col.SourceName, out var _val))
|
|
{
|
|
_val = ConvertToF4sdType(_val, col.ValueType);
|
|
dataCol.Values.Add(_val);
|
|
}
|
|
else
|
|
dataCol.Values.Add(null);
|
|
}
|
|
}
|
|
|
|
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
|
|
}
|
|
}
|
|
|
|
StartOnlineValidation();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetUserTicketAsync(Dictionary<enumFasdInformationClass, cF4sdConnectorIds> Identities, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
// get table definition
|
|
if (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameUserTicket, out var tableConfig))
|
|
return null;
|
|
|
|
// get the user sid
|
|
if (!Identities.TryGetValue(enumFasdInformationClass.User, out var idUser))
|
|
return null;
|
|
var strSid = new SecurityIdentifier(idUser.sid, 0).ToString();
|
|
|
|
// get the asset name, if computer is in Identities
|
|
if (!Identities.TryGetValue(enumFasdInformationClass.Computer, out var idComuter))
|
|
idComuter = null;
|
|
|
|
// create the api url
|
|
var strOpt = "";
|
|
if (idComuter != null && !string.IsNullOrEmpty(idComuter.name))
|
|
strOpt = string.Format(constUrlGetCreateTicketAssetParam, HttpUtility.UrlEncode(idComuter.name));
|
|
var strUrl = string.Format(constUrlGetCreateTicket, HttpUtility.UrlEncode(strSid), strOpt);
|
|
|
|
// call the api
|
|
var _wc = await GetWebClient(requestInfo, Token);
|
|
var res = await _wc.HttpEnh.GetAsync(strUrl);
|
|
|
|
if (res?.IsSuccessStatusCode == true)
|
|
{
|
|
var strJson = await res.Content.ReadAsStringAsync();
|
|
|
|
if (!string.IsNullOrEmpty(strJson))
|
|
{
|
|
// construct the result
|
|
JObject ticketInfos = JsonConvert.DeserializeObject<JObject>(strJson);
|
|
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = constTableNameUserTicket,
|
|
InformationClass = enumFasdInformationClass.User,
|
|
Origin = enumDataHistoryOrigin.M42Wpm,
|
|
IsStatic = true,
|
|
TableType = eDataHistoryTableType.Static
|
|
};
|
|
|
|
var dicVals = new Dictionary<string, object>();
|
|
var vals = ticketInfos.Children();
|
|
foreach (var token in vals)
|
|
{
|
|
try
|
|
{
|
|
if (token is JProperty prop)
|
|
if (prop.Value is JValue val)
|
|
dicVals[prop.Name] = val.Value;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogEntry($"Error getting M42 ticket detail property '{token.Path}'", LogLevels.Error);
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
foreach (var colInfo in tableConfig.Columns.Values)
|
|
{
|
|
try
|
|
{
|
|
object objVal = null;
|
|
if (colInfo.Name == "id")
|
|
objVal = idUser.sid;
|
|
else if (!dicVals.TryGetValue(colInfo.SourceName, out objVal))
|
|
objVal = null;
|
|
|
|
objVal = ConvertToF4sdType(objVal, colInfo.ValueType);
|
|
|
|
retVal.Columns[colInfo.Name] = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = colInfo.Name, Values = new List<object>(1) { objVal } };
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
|
|
}
|
|
}
|
|
|
|
StartOnlineValidation();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task<List<cF4SDHealthCardRawData.cHealthCardTable>> GetUserPickupValuesAsync(cDataHistoryConfigTable TableConfig, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (!(TableConfig?.SubTables.Count > 0))
|
|
return null;
|
|
if (!(TableConfig.SubTables.Values.First().Template is cDataHistoryConfigQueryTemplateM42Pickup _template))
|
|
return null;
|
|
|
|
// create the api url
|
|
var colInfo = new List<string>();
|
|
foreach (var _colInfo in TableConfig.Columns.Values)
|
|
{
|
|
colInfo.Add(_colInfo.SourceName);
|
|
}
|
|
var columns = string.Join(",", colInfo);
|
|
var where = _template.FilteredGroup == -1 ? "" : string.Format("StateGroup = '{0}'", _template.FilteredGroup);
|
|
var _strUrl = string.Format(constUrlFragmentsGetList, _template.PickupName, where, columns, string.Empty, string.Empty, string.Empty);
|
|
_strUrl = RemoveEmptyQueryParameters(_strUrl);
|
|
|
|
|
|
// call the api
|
|
var _wc = await GetWebClient(requestInfo, Token);
|
|
var res = await _wc.HttpEnh.GetAsync(_strUrl);
|
|
|
|
if (res?.IsSuccessStatusCode == true)
|
|
{
|
|
var strJson = await res.Content.ReadAsStringAsync();
|
|
|
|
if (!string.IsNullOrEmpty(strJson))
|
|
{
|
|
// construct the result
|
|
JArray PickupResult = JsonConvert.DeserializeObject<JArray>(strJson);
|
|
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = TableConfig.Name,
|
|
InformationClass = enumFasdInformationClass.User,
|
|
Origin = enumDataHistoryOrigin.M42Wpm,
|
|
IsStatic = true,
|
|
TableType = eDataHistoryTableType.Static
|
|
};
|
|
|
|
var _dicColInfo = new Dictionary<string, cDataHistoryConfigColumnBase>(TableConfig.Columns.Count);
|
|
var _dicIndex = new Dictionary<string, int>(TableConfig.Columns.Count);
|
|
var _lstResultCols = new List<cHealthCardTableColumn>(TableConfig.Columns.Count);
|
|
var _idxPosition = -1;
|
|
var _idxName = -1;
|
|
var _i = 0;
|
|
foreach (var _colInfo in TableConfig.Columns.Values)
|
|
{
|
|
var _col = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = _colInfo.Name };
|
|
retVal.Columns[_colInfo.Name] = _col;
|
|
_dicColInfo[_colInfo.SourceName] = _colInfo;
|
|
_dicIndex[_colInfo.SourceName] = _i;
|
|
_lstResultCols.Add(_col);
|
|
if (_colInfo.SourceName == "Position")
|
|
_idxPosition = _i;
|
|
if (_colInfo.SourceName == "DisplayString")
|
|
_idxName = _i;
|
|
_i++;
|
|
}
|
|
|
|
var _result = new List<object[]>();
|
|
foreach (var _row in PickupResult)
|
|
{
|
|
var _s = _row.ToString();
|
|
try
|
|
{
|
|
// get the row values from JSON result
|
|
var IdsValid = true;
|
|
var _resultRow = new object[TableConfig.Columns.Count];
|
|
_resultRow.Initialize();
|
|
foreach (var _col in _row)
|
|
{
|
|
if (_col is JProperty prop)
|
|
if (prop.Value is JValue val)
|
|
{
|
|
if (_dicColInfo.TryGetValue(prop.Name, out var _colInfo))
|
|
if (_dicIndex.TryGetValue(prop.Name, out var _idx))
|
|
{
|
|
var objVal = ConvertToF4sdType(val.Value, _colInfo.ValueType);
|
|
if (TableConfig.KeyColumns.Contains(_colInfo))
|
|
if (objVal == null || objVal is string _str && _str == string.Empty)
|
|
IdsValid = false;
|
|
|
|
_resultRow[_idx] = objVal;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!IdsValid)
|
|
continue;
|
|
|
|
_result.Add(_resultRow);
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogEntry($"Error getting M42 pickup values for tale {TableConfig.Name} at '{_row}'", LogLevels.Error);
|
|
LogException(E);
|
|
}
|
|
|
|
}
|
|
|
|
// sort the result
|
|
switch (_template.Sorting)
|
|
{
|
|
case cDataHistoryConfigQueryTemplateM42Pickup.enumSorting.byPosition:
|
|
if (_idxPosition >= 0)
|
|
try
|
|
{
|
|
_result.Sort((x, y) =>
|
|
{
|
|
var xVal = x[_idxPosition];
|
|
var yVal = y[_idxPosition];
|
|
|
|
// Wenn x null ist und y nicht, soll y zuerst kommen (x ist also größer)
|
|
if (xVal == null && yVal != null) return 1;
|
|
|
|
// Wenn y null ist und x nicht, soll x zuerst kommen (x ist also kleiner)
|
|
if (xVal != null && yVal == null) return -1;
|
|
|
|
// Wenn beide null sind, sind sie gleich
|
|
if (xVal == null && yVal == null) return 0;
|
|
|
|
// Wenn keines der beiden null ist, normal vergleichen
|
|
return ((Int32)xVal).CompareTo((Int32)yVal);
|
|
});
|
|
}
|
|
catch { }
|
|
break;
|
|
case cDataHistoryConfigQueryTemplateM42Pickup.enumSorting.byName:
|
|
if (_idxName >= 0)
|
|
try
|
|
{
|
|
_result.Sort((x, y) => ((string)(x[_idxName])).CompareTo((string)(y[_idxName])));
|
|
}
|
|
catch { }
|
|
break;
|
|
}
|
|
|
|
// put the result into the result colums
|
|
foreach (var _entry in _result)
|
|
{
|
|
for (int _idx = 0; _idx < TableConfig.Columns.Count; _idx++)
|
|
{
|
|
var _col = _lstResultCols[_idx];
|
|
_col.Values.Add(_entry[_idx]);
|
|
}
|
|
}
|
|
|
|
return new List<cF4SDHealthCardRawData.cHealthCardTable>(1) { retVal };
|
|
}
|
|
}
|
|
|
|
StartOnlineValidation();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public override bool CheckIfLateDelivery(cDataHistoryConfigTable Table)
|
|
{
|
|
if (Table.Name == constTableNameTicketHistory)
|
|
return true;
|
|
if (Table.SubTables?.First().Value?.Template is cDataHistoryConfigQueryTemplateM42Pickup)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
public override async Task<bool> WritePropertyAsync(cF4SDWriteParameters PropertiesToWrite, cF4sdWebRequestInfo requestInfo, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
if (PropertiesToWrite.TableName != constTableNameTicketDetails)
|
|
return false;
|
|
|
|
if (PropertiesToWrite.Values.Count != 1)
|
|
return false;
|
|
|
|
if (!Collector.ClusterConfig.Tables.TryGetValue(constTableNameTicketDetails, out var tableConfig))
|
|
return false;
|
|
|
|
if (!tableConfig.Columns.TryGetValue(PropertiesToWrite.Values.First().Key, out var colInfo))
|
|
return false;
|
|
|
|
if (!colInfo.IsWritable)
|
|
return false;
|
|
|
|
var strSolution = JsonConvert.SerializeObject(PropertiesToWrite.Values.First().Value.ToString());
|
|
var _content = new StringContent(strSolution);
|
|
var _url = string.Format(constUrlUpdateSolution, HttpUtility.UrlEncode(PropertiesToWrite.id.ToString()));
|
|
|
|
var _wc = await GetWebClient(requestInfo, Token);
|
|
var res = await _wc.HttpEnh.PostAsync(_url, _content, Token);
|
|
|
|
if (res?.IsSuccessStatusCode == true)
|
|
return true;
|
|
|
|
StartOnlineValidation();
|
|
|
|
return false;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private async void onlineTimerCallback(object state)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
CleanupUserWebCache();
|
|
await ValidateConnectionAsync(false, CancellationToken.None);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
}
|
|
|
|
private void StartOnlineValidation()
|
|
{
|
|
if (Collector?.autoConnectionCheck == true)
|
|
_ = Task.Run(() => ValidateConnectionAsync(false, CancellationToken.None));
|
|
}
|
|
|
|
public async Task<bool> CheckOnline()
|
|
{
|
|
await _OnlineCheckCriticalSection.Semaphore.WaitAsync();
|
|
try
|
|
{
|
|
return IsOnline;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
_OnlineCheckCriticalSection.Semaphore.Release();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public async Task<M42UserUserInfo> GetM42UserInfoAsync(string userSid, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
var strUrl = string.Format(constUrlGetRoleMeberships, userSid);
|
|
var res = await WebClient.HttpEnh.GetAsync(strUrl, Token);
|
|
if (Token.IsCancellationRequested)
|
|
return null;
|
|
|
|
if (res?.IsSuccessStatusCode == true)
|
|
{
|
|
var strJson = await res.Content.ReadAsStringAsync();
|
|
|
|
if (!string.IsNullOrEmpty(strJson))
|
|
{
|
|
var _userInfo = JsonConvert.DeserializeObject<M42UserUserInfo>(strJson);
|
|
if (_userInfo?.User != null && _userInfo.User.Id != Guid.Empty)
|
|
return _userInfo;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task<List<string>> GetUserRoles(Guid UserId, CancellationToken Token, string ReportTag = null, bool logDetailed = false)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
var _QueryRelationInfo = new cM42DataQueryRelationInfo2()
|
|
{
|
|
EntityClassName = "SPSUserClassBase",
|
|
EntityTypeName = "SPSSecurityTypeRole",
|
|
FragmentId = UserId,
|
|
columns = "Name",
|
|
pageSize = 0,
|
|
RelationName = "MemberOf"
|
|
};
|
|
|
|
var _json = JsonConvert.SerializeObject(_QueryRelationInfo);
|
|
var _content = new StringContent(_json, Encoding.UTF8, "application/json");
|
|
var _res = await WebClient.HttpEnh.PostAsync(constUrlGetDataQueryRelationItems, _content, Token);
|
|
if (_res.IsSuccessStatusCode)
|
|
{
|
|
var _strResult = await _res.Content.ReadAsStringAsync();
|
|
|
|
if (string.IsNullOrEmpty(_strResult))
|
|
return null;
|
|
|
|
List<JObject> _roles = JsonConvert.DeserializeObject<List<JObject>>(_strResult);
|
|
|
|
var _retVal = new List<string>();
|
|
|
|
foreach (var _roleEntry in _roles)
|
|
{
|
|
var _vals = _roleEntry.Children();
|
|
foreach (var _val in _vals)
|
|
{
|
|
try
|
|
{
|
|
if (_val is JProperty prop)
|
|
{
|
|
if (prop.Name == "Name")
|
|
{
|
|
var _propGroupName = prop.Value;
|
|
if (prop.Value is JValue _jVal && _jVal.Value != null)
|
|
{
|
|
var _groupName = _jVal.Value.ToString();
|
|
_retVal.Add(_groupName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (_retVal.Count > 0)
|
|
return _retVal;
|
|
}
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task<List<cF4SDMembershipGroup>> GetF4SDRoles(Guid UserId, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
var _M42UserInfoRoles = await GetUserRoles(UserId, Token);
|
|
|
|
if (_M42UserInfoRoles != null && _M42UserInfoRoles.Count > 0)
|
|
{
|
|
var _M42Memberships = Collector?.InfrastructureConfig?.Authorisation?.MembershipGroups?.GroupsM42;
|
|
|
|
var _resMembershipGroups = new List<cF4SDMembershipGroup>();
|
|
|
|
if (_M42Memberships != null)
|
|
{
|
|
foreach (var _membership in Collector.InfrastructureConfig.Authorisation.MembershipGroups.GroupsM42.Values)
|
|
{
|
|
foreach (var _M42Role in _M42UserInfoRoles)
|
|
{
|
|
|
|
if (_M42Role.ToLowerInvariant() == _membership.RoleName.ToLowerInvariant())
|
|
if (!_resMembershipGroups.Contains(_membership))
|
|
_resMembershipGroups.Add(_membership);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return _resMembershipGroups;
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public async Task AddM42UserInfosAsync(cF4sdUserInfo userInfo, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
// set M42 Logon to possible
|
|
if (userInfo.possibleLogons == null)
|
|
userInfo.possibleLogons = new List<enumAdditionalAuthentication>();
|
|
if (!userInfo.possibleLogons.Contains(enumAdditionalAuthentication.M42WinLogon))
|
|
userInfo.possibleLogons.Add(enumAdditionalAuthentication.M42WinLogon);
|
|
|
|
// check, if the ad sid can be found in M42
|
|
var _M42UserInfo = await GetM42UserInfoAsync(userInfo.AdSid, Token);
|
|
|
|
if (Token.IsCancellationRequested)
|
|
return;
|
|
|
|
// if yes, set M42 for an addidional automatic logon possibility
|
|
if (_M42UserInfo?.User != null)
|
|
{
|
|
if (userInfo.additionalLogons == null)
|
|
userInfo.additionalLogons = new List<enumAdditionalAuthentication>();
|
|
if (!userInfo.additionalLogons.Contains(enumAdditionalAuthentication.M42WinLogon))
|
|
userInfo.additionalLogons.Add(enumAdditionalAuthentication.M42WinLogon);
|
|
|
|
}
|
|
|
|
// check, if we have already a valid token for the user
|
|
if (Collector.TokenCache != null)
|
|
{
|
|
// get the api token from token cache
|
|
cM42UserInfoResult m42UserInfo = null;
|
|
var _res = await Collector.TokenCache.GetAsync(userInfo.Id, cF4SDTokenRegistration.enumTokenType.M42Api, requestInfo, LogDeep + 1);
|
|
if (_res != null && _res.IsValid())
|
|
{
|
|
// check the api token, if it's still valid
|
|
var _m42 = new cM42WebClient(Collector.InfrastructureConfig.M42Wpm.Server, UseSSL: true);
|
|
var _m42Reason = await _m42.LogonWithApiKeyAsync(_res.secret, Token);
|
|
if (_m42Reason == eReason.ok && _m42.BearerToken != null)
|
|
{
|
|
// get the user info
|
|
m42UserInfo = await _m42.GetUserInfoAsync();
|
|
|
|
// save the new bearer token to token cache
|
|
var TokenRegistration = new cF4SDTokenRegistration()
|
|
{
|
|
TokenType = cF4SDTokenRegistration.enumTokenType.M42Bearer,
|
|
UserId = userInfo.Id,
|
|
Secret = _m42.BearerToken
|
|
};
|
|
|
|
// set the new bearer token into the token cache
|
|
await Collector.TokenCache.SetAsync(TokenRegistration, GetTokenValidityPeriod(_m42.BearerLifeTime), Token, requestInfo, LogDeep + 1);
|
|
if (Token.IsCancellationRequested)
|
|
return;
|
|
|
|
// set the valid until info
|
|
if (userInfo.ValidLogonsUntil == null)
|
|
userInfo.ValidLogonsUntil = new Dictionary<enumAdditionalAuthentication, cF4SDTokenValidityPeriod>();
|
|
userInfo.ValidLogonsUntil[enumAdditionalAuthentication.M42WinLogon] = cF4SDTokenValidityPeriod.Create(_res.validUntil, _res.renewUntil);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
// check, if there is a valid bearer token for M42
|
|
_res = await Collector.TokenCache.GetAsync(userInfo.Id, cF4SDTokenRegistration.enumTokenType.M42Bearer, requestInfo, LogDeep + 1);
|
|
if (_res != null && _res.IsValid())
|
|
{
|
|
// if yes, get the user info
|
|
var _m42 = new cM42WebClient(Collector.InfrastructureConfig.M42Wpm.Server, UseSSL: true);
|
|
_m42.SetBearerToken(_res.secret);
|
|
|
|
var _res2 = await _m42.Open();
|
|
if (_res2 == eReason.ok)
|
|
{
|
|
m42UserInfo = await _m42.GetUserInfoAsync();
|
|
|
|
// set the valid until info
|
|
if (userInfo.ValidLogonsUntil == null)
|
|
userInfo.ValidLogonsUntil = new Dictionary<enumAdditionalAuthentication, cF4SDTokenValidityPeriod>();
|
|
userInfo.ValidLogonsUntil[enumAdditionalAuthentication.M42WinLogon] = cF4SDTokenValidityPeriod.Create(_res.validUntil, _res.renewUntil);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// get the role memberships relatet to the M42 roles
|
|
if (m42UserInfo?.User?.Id != null)
|
|
{
|
|
var _F4SDRoles = await GetF4SDRoles((Guid)m42UserInfo.User.Id, Token);
|
|
|
|
if (_F4SDRoles?.Count > 0)
|
|
Collector.AddRolesByMembership(userInfo, _F4SDRoles);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
public override async Task<Int64> GetSelectionTableResultCountAsync(cDataHistoryConfigTable Table, List<cF4sdIdentityEntry> Identities, string search, cF4sdWebRequestInfo requestInfo, CancellationToken Token, bool resetFilter = false, List<string> filterParams = null)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
if (!(Table.SubTables.Values.First().Template is cDataHistoryConfigQueryTemplateM42DataQueryItems _template))
|
|
return -1;
|
|
|
|
if (string.IsNullOrEmpty(search))
|
|
search = "";
|
|
string _whereExpr = null;
|
|
if (!resetFilter && !string.IsNullOrEmpty(_template.WhereExpression))
|
|
{
|
|
if (filterParams != null && filterParams.Count > 0)
|
|
_whereExpr = string.Format(_template.WhereExpression, filterParams.ToArray());
|
|
else
|
|
_whereExpr = _template.WhereExpression;
|
|
}
|
|
var _cols = Table.KeyColumns.First().SourceName;
|
|
|
|
var _QueryRelationInfo = new cM42DataQueryRelationInfo()
|
|
{
|
|
EntityClassName = _template.EntityClassName,
|
|
EntityTypeName = string.Join(",", _template.EntityTypeNames),
|
|
DataQueryName = string.IsNullOrWhiteSpace(_template.DataQueryName) ? null : _template.DataQueryName,
|
|
search = search,
|
|
WhereExpression = _whereExpr,
|
|
pageSize = 0,
|
|
page = 0,
|
|
totalCounted = true,
|
|
columns = _cols
|
|
};
|
|
|
|
var _json = JsonConvert.SerializeObject(_QueryRelationInfo);
|
|
var _content = new StringContent(_json, Encoding.UTF8, "application/json");
|
|
var _wc = await GetWebClient(requestInfo, Token);
|
|
var res = await _wc.HttpEnh.PostAsync(constUrlGetDataQueryRelationItemsCount, _content);
|
|
if (res.IsSuccessStatusCode)
|
|
{
|
|
var _strResult = await res.Content.ReadAsStringAsync();
|
|
if (Int64.TryParse(_strResult, out var count))
|
|
{
|
|
return count;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
public override async Task<cF4SDHealthCardRawData.cHealthCardTable> GetSelectionTableResultAsync(cDataHistoryConfigTable Table, List<cF4sdIdentityEntry> Identities, string search, int PageSize, int Page, cF4sdWebRequestInfo requestInfo, CancellationToken Token, bool resetFilter = false, List<string> filterParams = null)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
if (!(Table.SubTables.Values.First().Template is cDataHistoryConfigQueryTemplateM42DataQueryItems _template))
|
|
return null;
|
|
|
|
if (string.IsNullOrEmpty(search))
|
|
search = "";
|
|
string _whereExpr = null;
|
|
if (!resetFilter && !string.IsNullOrEmpty(_template.WhereExpression))
|
|
{
|
|
if (filterParams != null && filterParams.Count > 0)
|
|
_whereExpr = string.Format(_template.WhereExpression, filterParams.ToArray());
|
|
else
|
|
_whereExpr = _template.WhereExpression;
|
|
}
|
|
|
|
var _cols = Table.KeyColumns.First().SourceName;
|
|
|
|
var _QueryRelationInfo = new cM42DataQueryRelationInfo()
|
|
{
|
|
EntityClassName = _template.EntityClassName,
|
|
EntityTypeName = string.Join(",", _template.EntityTypeNames),
|
|
DataQueryName = string.IsNullOrWhiteSpace(_template.DataQueryName) ? null : _template.DataQueryName,
|
|
WhereExpression = _whereExpr,
|
|
search = search,
|
|
pageSize = PageSize,
|
|
page = Page,
|
|
columns = _cols
|
|
};
|
|
|
|
var _json = JsonConvert.SerializeObject(_QueryRelationInfo);
|
|
var _content = new StringContent(_json, Encoding.UTF8, "application/json");
|
|
var _wc = await GetWebClient(requestInfo, Token);
|
|
var res = await _wc.HttpEnh.PostAsync(constUrlGetDataQueryRelationItems, _content, Token);
|
|
if (res.IsSuccessStatusCode)
|
|
{
|
|
var _strResult = await res.Content.ReadAsStringAsync();
|
|
|
|
if (string.IsNullOrEmpty(_strResult))
|
|
return null;
|
|
|
|
List<JObject> ticketInfos = JsonConvert.DeserializeObject<List<JObject>>(_strResult);
|
|
var _valueCount = ticketInfos.Count;
|
|
var retVal = new cF4SDHealthCardRawData.cHealthCardTable()
|
|
{
|
|
Name = Table.Name,
|
|
InformationClass = Table.ParentCluster.InformationClass,
|
|
Origin = Table.ParentCluster.Origin,
|
|
IsStatic = false,
|
|
TableType = Table.Type
|
|
};
|
|
|
|
var _dicColInfo = Table.Columns.ToDictionary(v => v.Value.SourceName, v => v.Value);
|
|
foreach (var colInfo in Table.Columns.Values)
|
|
{
|
|
retVal.Columns[colInfo.Name] = new cF4SDHealthCardRawData.cHealthCardTableColumn(retVal) { ColumnName = colInfo.Name, Values = new List<object>(_valueCount) };
|
|
}
|
|
|
|
foreach (var _entry in ticketInfos)
|
|
{
|
|
var _vals = _entry.Children();
|
|
var _maxCount = 0;
|
|
foreach (var _token in _vals)
|
|
{
|
|
try
|
|
{
|
|
if (_token is JProperty prop)
|
|
if (!string.IsNullOrEmpty(prop.Name) && prop.Value is JValue _val)
|
|
{
|
|
var _value = _val.Value;
|
|
|
|
if (!_dicColInfo.TryGetValue(prop.Name, out var _colInfo))
|
|
continue;
|
|
if (!retVal.Columns.TryGetValue(_colInfo.Name, out var _colData))
|
|
continue;
|
|
|
|
_value = ConvertToF4sdType(_value, _colInfo.ValueType);
|
|
|
|
_colData.Values.Add(_value);
|
|
_maxCount = Math.Max(_maxCount, _colData.Values.Count);
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogEntry($"Error getting M42 ticket detail property '{_token?.Path}'", LogLevels.Error);
|
|
LogException(E);
|
|
}
|
|
}
|
|
|
|
foreach (var _colData in retVal.Columns.Values)
|
|
{
|
|
while (_colData.Values.Count < _maxCount)
|
|
_colData.Values.Add(null);
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private cF4SDTokenValidityPeriod GetTokenValidityPeriod(DateTime validUntil)
|
|
{
|
|
var _renew = validUntil - TimeSpan.FromSeconds(Math.Max(0, (validUntil - DateTime.UtcNow).TotalSeconds * 2 / 10));
|
|
return cF4SDTokenValidityPeriod.Create(validUntil, _renew);
|
|
}
|
|
|
|
public override async Task<cF4SdUserInfoChange> ValidateTokenAsync(cF4SDTokenRegistration TokenRegistration, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (TokenRegistration?.TokenType is cF4SDTokenRegistration.enumTokenType.M42Bearer &&
|
|
!string.IsNullOrEmpty(Collector?.InfrastructureConfig?.M42Wpm.Server) &&
|
|
!string.IsNullOrEmpty(TokenRegistration?.Secret)
|
|
)
|
|
{
|
|
var _M42UserInfo = await cM42WebClient.LogonBearer(Collector.InfrastructureConfig.M42Wpm.Server, TokenRegistration.Secret, Token, UseSSL: true, LogDetailed: true);
|
|
if (Token.IsCancellationRequested)
|
|
return null;
|
|
|
|
if (_M42UserInfo != null)
|
|
{
|
|
if (_M42UserInfo.BearerValidUntil > DateTime.UtcNow && TokenRegistration.AutoCreatePermanent && _M42UserInfo.User?.Id != null)
|
|
{
|
|
var _res2 = await CreateApiToken(TokenRegistration, _M42UserInfo, Token, requestInfo, LogDeep + 1);
|
|
if (Token.IsCancellationRequested)
|
|
return null;
|
|
|
|
if (_res2 < DateTime.UtcNow)
|
|
return null;
|
|
}
|
|
|
|
// user info & f4sd token aktualisieren
|
|
var _validityPeriod = GetTokenValidityPeriod(_M42UserInfo.BearerValidUntil);
|
|
|
|
|
|
var Roles = new List<string>();
|
|
if (_M42UserInfo?.User?.Id != null)
|
|
{
|
|
var _F4SDRoles = await GetF4SDRoles((Guid)_M42UserInfo.User.Id, Token);
|
|
if (_F4SDRoles?.Count > 0)
|
|
Collector.AddRolesByMembership(Roles, _F4SDRoles, requestInfo?.userInfo?.Name);
|
|
|
|
}
|
|
var _retVal = new cF4SdUserInfoChange()
|
|
{
|
|
ValidLogonsUntil = new Dictionary<enumAdditionalAuthentication, cF4SDTokenValidityPeriod> { { enumAdditionalAuthentication.M42WinLogon, _validityPeriod } },
|
|
Roles = Roles
|
|
};
|
|
|
|
|
|
return _retVal;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private class cM42IdResult
|
|
{
|
|
public Guid Id { get; set; }
|
|
public string Name { get; set; }
|
|
}
|
|
|
|
private async Task<DateTime> CreateApiToken(cF4SDTokenRegistration TokenRegistration, cM42UserInfoResult UserInfo, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
// obtain token name
|
|
var tokenName = $"F4SD_{UserInfo.User.LastName ?? ""}_{UserInfo.User.FirstName ?? ""}_{UserInfo.User.Id}";
|
|
|
|
// create M42 web client
|
|
var _m42 = new cM42WebClient(Collector.InfrastructureConfig.M42Wpm.Server, UseSSL: true);
|
|
_m42.SetBearerToken(UserInfo.BearerToken);
|
|
var _resOpen = await _m42.Open();
|
|
if (_resOpen != eReason.ok)
|
|
return DateTime.MinValue;
|
|
|
|
// check if token alsready exist
|
|
var _strListToken = await _m42.GetFragmentListAsync("PLSTSApiTokenBase", Token, $"Name='{tokenName}'");
|
|
if (!string.IsNullOrEmpty(_strListToken))
|
|
{
|
|
// remove all existing tokens with corresponding name
|
|
var lstIds = JsonConvert.DeserializeObject<List<cM42IdResult>>(_strListToken);
|
|
foreach (var objId in lstIds)
|
|
{
|
|
var _delRequest = new Dictionary<Guid, string>()
|
|
{
|
|
{ objId.Id, "PLSTSApiTokenType" }
|
|
};
|
|
await _m42.DeleteObjectsAsync("F4SD Cockpit", _delRequest, Token);
|
|
if (Token.IsCancellationRequested)
|
|
return DateTime.MinValue;
|
|
}
|
|
}
|
|
|
|
// create token generation request
|
|
var tokenRequest = new cApiTokenRequestModelBase()
|
|
{
|
|
Name = tokenName,
|
|
ExpirationDays = (int)(Collector?.InfrastructureConfig?.M42Wpm?.ApiLifetime ?? cDataHistoryConfigM42Wpm.enumApiTokenLifetime.days30)
|
|
};
|
|
|
|
// generate token
|
|
var strJson = JsonConvert.SerializeObject(tokenRequest);
|
|
var CO = new StringContent(strJson, Encoding.UTF8, "application/json");
|
|
var _resPost = await _m42.Http.PostAsync(constUrlGenerateApiTokenForMe, CO);
|
|
if (Token.IsCancellationRequested)
|
|
return DateTime.MinValue;
|
|
|
|
var _content = await _resPost.Content.ReadAsStringAsync();
|
|
if (Token.IsCancellationRequested)
|
|
return DateTime.MinValue;
|
|
|
|
if (_resPost.IsSuccessStatusCode)
|
|
{
|
|
var _tokenModel = JsonConvert.DeserializeObject<cM42ApiTokenModel>(_content);
|
|
if (!string.IsNullOrEmpty(_tokenModel?.ApiToken) && _tokenModel?.ValidUntil >= DateTime.UtcNow)
|
|
{
|
|
var _validUntil = (DateTime)_tokenModel.ValidUntil;
|
|
var _renewUntil = _validUntil - TimeSpan.FromDays(1);
|
|
var _tr = new cF4SDTokenRegistration()
|
|
{
|
|
TokenType = cF4SDTokenRegistration.enumTokenType.M42Api,
|
|
UserId = TokenRegistration.UserId,
|
|
Name = _tokenModel?.Name,
|
|
Secret = _tokenModel.ApiToken,
|
|
AutoCreatePermanent = false
|
|
};
|
|
|
|
await Collector.TokenCache.SetAsync(_tr, cF4SDTokenValidityPeriod.Create(_validUntil, _renewUntil), Token, requestInfo, LogDeep + 1);
|
|
if (Token.IsCancellationRequested)
|
|
return DateTime.MinValue;
|
|
|
|
return _validUntil;
|
|
}
|
|
}
|
|
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return DateTime.MinValue;
|
|
}
|
|
|
|
public async Task<string> CreateM42TicketAsync(cApiM42Ticket ticketInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
|
|
|
|
var userFragmentListTask = GetFragmentListAsync(new cDataFragmentsParams
|
|
{
|
|
Columns = "ID",
|
|
Ddname = "SPSUserClassBase",
|
|
Pagenumber = 0,
|
|
Pagesize = 10,
|
|
Where = string.Format("T(SPSCommonClassbase).State = 2023 AND Accounts.T(SPSAccountClassAD).ADCn = '{0}'", ticketInfo.User)
|
|
}, requestInfo, LogDeep + 1, token);
|
|
|
|
List<Task> tasksToAwait = new List<Task> { userFragmentListTask };
|
|
|
|
Task<dynamic> assetFragmentListTask = null;
|
|
if (!ticketInfo.AffectedAsset.Equals("RemoveAffectedAssetEntry", StringComparison.InvariantCultureIgnoreCase) && !string.IsNullOrEmpty(ticketInfo.AffectedAsset))
|
|
{
|
|
assetFragmentListTask = GetFragmentListAsync(new cDataFragmentsParams
|
|
{
|
|
Columns = "ID",
|
|
Ddname = "SPSAssetClassBase",
|
|
Pagenumber = 0,
|
|
Pagesize = 10,
|
|
Where = string.Format("T(SPSCommonClassbase).State = 710 AND T(SPSComputerClassBase).Name = '{0}'", ticketInfo.AffectedAsset)
|
|
}, requestInfo, LogDeep + 1, token);
|
|
tasksToAwait.Add(assetFragmentListTask);
|
|
}
|
|
|
|
Task<dynamic> quickCallFragmentListTask = null;
|
|
if (ticketInfo.Quickcall.HasValue && ticketInfo.Quickcall.Value != Guid.Empty)
|
|
{
|
|
quickCallFragmentListTask = GetQuickCallTemplateInfoAsync(ticketInfo.Quickcall.Value, requestInfo, LogDeep + 1, token);
|
|
tasksToAwait.Add(quickCallFragmentListTask);
|
|
}
|
|
else
|
|
{
|
|
LogEntry($"No quick call set to create new ticket.", LogLevels.Error);
|
|
return null;
|
|
}
|
|
|
|
// Warte auf alle gestarteten Tasks
|
|
await Task.WhenAll(tasksToAwait);
|
|
|
|
var fragments = userFragmentListTask.Result;
|
|
var idAsString = "";
|
|
Guid? assetId = null;
|
|
var assetNotFound = false;
|
|
if (assetFragmentListTask != null)
|
|
{
|
|
var assetFragments = assetFragmentListTask.Result;
|
|
if (token.IsCancellationRequested) return null;
|
|
if (assetFragments == null || assetFragments.Count == 0)
|
|
{
|
|
assetNotFound = true;
|
|
}
|
|
else
|
|
{
|
|
idAsString = (string)assetFragments?[0]?.ID;
|
|
if (Guid.TryParse(idAsString, out Guid assetIdTemp))
|
|
{
|
|
assetId = assetIdTemp;
|
|
}
|
|
else
|
|
assetNotFound = true;
|
|
}
|
|
}
|
|
|
|
idAsString = (string)fragments?[0]?.ID;
|
|
if (!Guid.TryParse(idAsString, out Guid userID))
|
|
{
|
|
LogEntry($"No initiating user found with state active (710) and AD Common Name: {ticketInfo.User}", LogLevels.Error);
|
|
return null;
|
|
}
|
|
Guid? requestCategoryId = ticketInfo.Category;
|
|
if (requestCategoryId.HasValue && requestCategoryId.Value == Guid.Empty)
|
|
{
|
|
requestCategoryId = null;
|
|
}
|
|
|
|
var ticketInfo2 = new cM42TicketInfo()
|
|
{
|
|
Subject = ticketInfo.Summary,
|
|
DescriptionHTML = ticketInfo.DescriptionHtml,
|
|
SolutionHTML = ticketInfo.SolutionHtml,
|
|
User = userID,
|
|
Asset = assetId,
|
|
Service = ticketInfo.AffectedService,
|
|
Template = ticketInfo.Quickcall,
|
|
Category = requestCategoryId,
|
|
EntryBy = 20500
|
|
};
|
|
|
|
var quickCallFragments = quickCallFragmentListTask?.Result;
|
|
if (quickCallFragments != null)
|
|
{
|
|
var quickCallData = quickCallFragments;
|
|
|
|
if (int.TryParse((string)quickCallData?.Impact, out int impact))
|
|
ticketInfo2.Impact = impact;
|
|
|
|
if (int.TryParse((string)quickCallData?.Urgency, out int urgency))
|
|
ticketInfo2.Urgency = urgency;
|
|
|
|
if (int.TryParse((string)quickCallData?.EntryBy, out int entryBy))
|
|
ticketInfo2.EntryBy = entryBy;
|
|
|
|
if (int.TryParse((string)quickCallData?.ErrorType, out int errorType))
|
|
ticketInfo2.ErrorType = errorType;
|
|
|
|
if (int.TryParse((string)quickCallData?.Priority, out int priority))
|
|
ticketInfo2.Priority = priority;
|
|
|
|
if (Guid.TryParse((string)quickCallData?.RecipientRole, out Guid recipientRole))
|
|
ticketInfo2.ResponsibleRole = recipientRole;
|
|
|
|
if (Guid.TryParse((string)quickCallData?.RecipientID, out Guid recipient))
|
|
ticketInfo2.ResponsibleUser = recipient;
|
|
|
|
if (Guid.TryParse((string)quickCallData?.Asset, out Guid asset))
|
|
ticketInfo2.Asset = ticketInfo2.Asset ?? asset;
|
|
|
|
if (Guid.TryParse((string)quickCallData?.Service, out Guid service))
|
|
ticketInfo2.Service = ticketInfo2.Service ?? service;
|
|
|
|
if (!ticketInfo2.Category.HasValue && Guid.TryParse((string)quickCallData?.Category, out Guid category))
|
|
ticketInfo2.Category = category;
|
|
|
|
if (bool.TryParse((string)quickCallData?.NotifyResponsible, out bool notifyResponsible))
|
|
ticketInfo2.NotifyResponsible = notifyResponsible;
|
|
|
|
if (int.TryParse((string)quickCallData?.Classification, out int Classification))
|
|
ticketInfo2.Classification = Classification;
|
|
}
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(ticketInfo2, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
|
|
var url = string.Format(constUrlCreateTicket, ticketInfo2.Classification);
|
|
|
|
|
|
var response = await _webClient.HttpEnh.PostAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var json = await response.Content.ReadAsStringAsync();
|
|
Guid TicketId = Guid.TryParse(json?.Trim('"'), out TicketId) ? TicketId : Guid.Empty;
|
|
|
|
await AddWorkingTimesAsync(TicketId, ticketInfo.workTimes, requestInfo, LogDeep + 1, token);
|
|
|
|
cCreateJournalEntryInfo journalEntry = null;
|
|
if (assetNotFound)
|
|
{
|
|
string assetNotFoundText = "";
|
|
if (ticketInfo.AdditionalValues.TryGetValue("Dialog.CloseCase.AssetNotFoundInMatrix42", out object valueObj))
|
|
{
|
|
assetNotFoundText = valueObj as string;
|
|
}
|
|
if (!string.IsNullOrEmpty(assetNotFoundText))
|
|
{
|
|
journalEntry = new cCreateJournalEntryInfo()
|
|
{
|
|
Comments = string.Format(assetNotFoundText, ticketInfo.AffectedAsset),
|
|
ObjectId = TicketId,
|
|
EntryType = 0
|
|
};
|
|
await CreateM42JournalAsync(journalEntry, requestInfo, LogDeep + 1, token);
|
|
}
|
|
}
|
|
journalEntry = new cCreateJournalEntryInfo()
|
|
{
|
|
Comments = ticketInfo.CopyTemplates,
|
|
ObjectId = TicketId,
|
|
EntryType = 20600
|
|
};
|
|
await CreateM42JournalAsync(journalEntry, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
try
|
|
{
|
|
if (ticketInfo.SupportCaseProtocollEntries != null)
|
|
{
|
|
await ProtocollSupportCaseProtocollEntries(ticketInfo.SupportCaseProtocollEntries, TicketId, requestInfo, LogDeep, token);
|
|
}
|
|
else if (ticketInfo.QuickActionHistory != null)
|
|
{
|
|
await ProtocollSupportCaseQuickActionHistory(ticketInfo.QuickActionHistory, TicketId, requestInfo, LogDeep, token);
|
|
}
|
|
|
|
if (token.IsCancellationRequested)
|
|
return null;
|
|
}
|
|
catch (TaskCanceledException)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
ticketInfo.Ticket = TicketId;
|
|
await UpdateM42TicketUnreadAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
|
|
return TicketId.ToString();
|
|
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private async Task ProtocollSupportCaseProtocollEntries(List<ProtocollEntryBase> supportCaseProtocollEntries, Guid ticketId, cF4sdWebRequestInfo requestInfo, int logDeep, CancellationToken token)
|
|
{
|
|
foreach (var protocollEntry in supportCaseProtocollEntries)
|
|
{
|
|
if (!(protocollEntry is QuickActionProtocollEntry entry))
|
|
continue;
|
|
|
|
cCreateJournalEntryInfo _entry = null;
|
|
switch (entry.ResultCode)
|
|
{
|
|
case -1:
|
|
case 1:
|
|
case 0:
|
|
var entryType = entry.WasRunningOnAffectedDevice ? 20602 : 20601;
|
|
_entry = new cCreateJournalEntryInfo()
|
|
{
|
|
Comments = "",
|
|
ObjectId = ticketId,
|
|
EntryType = entryType,
|
|
Parameters = new List<cCreateJournalEntryInfo.Parameter>() { new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "result",
|
|
Value = entry.HtmlContent ?? entry.MeasureValues ?? entry.ErrorMessage
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "quickActionName",
|
|
Value = entry.Name
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "QuickActionId",
|
|
Value = entry.Id
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "quickActionExecutionType",
|
|
Value = entry.ExecutionTypeId
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "ExecutionTime",
|
|
Value = entry.Time
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "AffectedDeviceName",
|
|
Value = entry.AffectedDeviceName
|
|
},}
|
|
};
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (_entry != null)
|
|
{
|
|
await CreateM42JournalAsync(_entry, requestInfo, logDeep + 1, token);
|
|
if (token.IsCancellationRequested) return;
|
|
}
|
|
}
|
|
}
|
|
|
|
private async Task ProtocollSupportCaseQuickActionHistory(List<cQuickActionResult> quickActionHistory, Guid ticketId, cF4sdWebRequestInfo requestInfo, int logDeep, CancellationToken token)
|
|
{
|
|
foreach (var entry in quickActionHistory)
|
|
{
|
|
cCreateJournalEntryInfo _entry = null;
|
|
switch (entry.ResultCode)
|
|
{
|
|
case -1:
|
|
case 1:
|
|
case 0:
|
|
var entryType = entry.wasRunningOnAffectedDevice ? 20602 : 20601;
|
|
_entry = new cCreateJournalEntryInfo()
|
|
{
|
|
Comments = "",
|
|
ObjectId = ticketId,
|
|
EntryType = entryType,
|
|
Parameters = new List<cCreateJournalEntryInfo.Parameter>() { new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "result",
|
|
Value = entry.Output ?? entry.MeasureValues ?? entry.ErrorMessage
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "quickActionName",
|
|
Value = entry.QuickActionName
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "QuickActionId",
|
|
Value = entry.QuickActionId
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "quickActionExecutionType",
|
|
Value = entry.QuickActionExecutionType
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "ExecutionTime",
|
|
Value = entry.ExecutionTime
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "AffectedDeviceName",
|
|
Value = entry.AffectedDeviceName
|
|
},}
|
|
};
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (_entry != null)
|
|
{
|
|
await CreateM42JournalAsync(_entry, requestInfo, logDeep + 1, token);
|
|
if (token.IsCancellationRequested) return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public async Task<string> UpdateM42TicketAsync(cApiM42Ticket ticketInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
string activityType = "SPSActivityTypeIncident";
|
|
|
|
if (ticketInfo.AdditionalValues.TryGetValue("ActivityType", out object value) && value is string stringValue)
|
|
{
|
|
activityType = stringValue;
|
|
}
|
|
var url = string.Format(constUrlObjectsUpdateObject, activityType, false);
|
|
var ticketID = (Guid)ticketInfo.Ticket;
|
|
var ticket = await GetObjectAsync(activityType, ticketID, false, requestInfo, LogDeep + 1, token);
|
|
|
|
if (ticketInfo.Quickcall.HasValue && ticketInfo.Quickcall.Value != Guid.Empty)
|
|
{
|
|
ticket["SPSActivityClassIncident"]["Quickcall"] = ticketInfo.Quickcall.Value;
|
|
}
|
|
|
|
if (ticketInfo.Category.HasValue && ticketInfo.Category.Value != Guid.Empty)
|
|
{
|
|
ticket["SPSActivityClassIncident"]["Category"] = ticketInfo.Category.Value;
|
|
}
|
|
if (ticketInfo.AffectedService.HasValue && ticketInfo.AffectedService.Value == Guid.Empty)
|
|
{
|
|
ticket["SPSActivityClassBase"]["Service"] = null;
|
|
}
|
|
else if (ticketInfo.AffectedService.HasValue && ticketInfo.AffectedService.Value != Guid.Empty)
|
|
ticket["SPSActivityClassBase"]["Service"] = ticketInfo.AffectedService.Value;
|
|
|
|
var createAssetNotFoundJournalEntry = false;
|
|
if (ticketInfo.AffectedAsset.Equals("RemoveAffectedAssetEntry", StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
ticket["SPSActivityClassIncident"]["Asset"] = null;
|
|
}
|
|
else if (!string.IsNullOrEmpty(ticketInfo.AffectedAsset))
|
|
{
|
|
var assetNotFound = true;
|
|
Guid? assetId = null;
|
|
var assetFragments = await GetFragmentListAsync(new cDataFragmentsParams()
|
|
{
|
|
Columns = "ID",
|
|
Ddname = "SPSAssetClassBase",
|
|
Pagenumber = 0,
|
|
Pagesize = 10,
|
|
Where = string.Format("T(SPSCommonClassbase).State = 710 AND T(SPSComputerClassBase).Name = '{0}'", ticketInfo.AffectedAsset)
|
|
}, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
|
|
if (assetFragments == null || assetFragments.Count == 0)
|
|
{
|
|
assetNotFound = true;
|
|
}
|
|
else
|
|
{
|
|
var idAsString = (string)assetFragments?[0]?.ID;
|
|
if (Guid.TryParse(idAsString, out Guid assetIdTemp))
|
|
{
|
|
assetId = assetIdTemp;
|
|
assetNotFound = false;
|
|
}
|
|
else
|
|
{
|
|
assetNotFound = true;
|
|
}
|
|
}
|
|
if (assetNotFound)
|
|
{
|
|
createAssetNotFoundJournalEntry = true;
|
|
}
|
|
if (assetId != null)
|
|
{
|
|
ticket["SPSActivityClassBase"]["AffectedAsset"] = assetId;
|
|
}
|
|
|
|
}
|
|
|
|
ticket["SPSActivityClassBase"]["Subject"] = ticketInfo.Summary;
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(ticket, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
var response = await _webClient.HttpEnh.PutAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
await AddWorkingTimesAsync(ticketID, ticketInfo.workTimes, requestInfo, LogDeep + 1, token);
|
|
|
|
cCreateJournalEntryInfo _entry = null;
|
|
|
|
if (createAssetNotFoundJournalEntry)
|
|
{
|
|
string assetNotFoundText = "";
|
|
if (ticketInfo.AdditionalValues.TryGetValue("Dialog.CloseCase.AssetNotFoundInMatrix42", out object valueObj))
|
|
{
|
|
assetNotFoundText = valueObj as string;
|
|
}
|
|
if (!string.IsNullOrEmpty(assetNotFoundText))
|
|
{
|
|
_entry = new cCreateJournalEntryInfo()
|
|
{
|
|
Comments = string.Format(assetNotFoundText, ticketInfo.AffectedAsset),
|
|
ObjectId = ticketID,
|
|
EntryType = 0
|
|
};
|
|
await CreateM42JournalAsync(_entry, requestInfo, LogDeep + 1, token);
|
|
}
|
|
}
|
|
|
|
// Case Notes as Journal Entry
|
|
if (!string.IsNullOrEmpty(ticketInfo.DescriptionHtml))
|
|
{
|
|
_entry = new cCreateJournalEntryInfo()
|
|
{
|
|
Comments = ticketInfo.DescriptionHtml,
|
|
ObjectId = ticketID,
|
|
EntryType = 20603,
|
|
};
|
|
await CreateM42JournalAsync(_entry, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
}
|
|
|
|
// CopyTemplates as Journal Entry
|
|
if (!string.IsNullOrEmpty(ticketInfo.CopyTemplates))
|
|
{
|
|
_entry = new cCreateJournalEntryInfo()
|
|
{
|
|
Comments = ticketInfo.CopyTemplates,
|
|
ObjectId = ticketID,
|
|
EntryType = 20604
|
|
};
|
|
await CreateM42JournalAsync(_entry, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
}
|
|
if (ticketInfo.SupportCaseProtocollEntries != null)
|
|
{
|
|
foreach (var protocollEntry in ticketInfo.SupportCaseProtocollEntries)
|
|
{
|
|
if (!(protocollEntry is QuickActionProtocollEntry entry))
|
|
continue;
|
|
|
|
switch (entry.ResultCode)
|
|
{
|
|
case -1:
|
|
case 1:
|
|
case 0:
|
|
var entryType = entry.WasRunningOnAffectedDevice ? 20602 : 20601;
|
|
_entry = new cCreateJournalEntryInfo()
|
|
{
|
|
Comments = "",
|
|
ObjectId = ticketID,
|
|
EntryType = entryType,
|
|
Parameters = new List<cCreateJournalEntryInfo.Parameter>() { new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "result",
|
|
Value = entry.HtmlContent ?? entry.MeasureValues ?? entry.ErrorMessage
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "quickActionName",
|
|
Value = entry.Name
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "QuickActionId",
|
|
Value = entry.Id
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "quickActionExecutionType",
|
|
Value = entry.ExecutionTypeId
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "ExecutionTime",
|
|
Value = entry.Time
|
|
},
|
|
new cCreateJournalEntryInfo.Parameter()
|
|
{
|
|
Name = "AffectedDeviceName",
|
|
Value = entry.AffectedDeviceName
|
|
},}
|
|
};
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (_entry != null)
|
|
{
|
|
await CreateM42JournalAsync(_entry, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
}
|
|
}
|
|
}
|
|
await UpdateM42TicketUnreadAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
return string.Empty;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public async Task<string> UpdateM42TicketUnreadAsync(cApiM42Ticket ticketInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
string activityType = "SPSActivityTypeIncident";
|
|
|
|
if (ticketInfo.AdditionalValues.TryGetValue("ActivityType", out object value) && value is string stringValue)
|
|
{
|
|
activityType = stringValue;
|
|
}
|
|
var url = string.Format(constUrlObjectsUpdateObject, activityType, false);
|
|
var ticketID = (Guid)ticketInfo.Ticket;
|
|
var ticket = await GetObjectAsync(activityType, ticketID, false, requestInfo, LogDeep + 1, token);
|
|
if (ticket != null)
|
|
{
|
|
ticket["SPSActivityClassBase"]["NewInformationReceived"] = 0;
|
|
var _jsonContent = JsonConvert.SerializeObject(ticket, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
var response = await _webClient.HttpEnh.PutAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
await Collector.ReportTicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
return string.Empty;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public async Task<string> CloseM42TicketAsync(cApiM42Ticket ticketInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
|
|
var ticketId = Guid.Empty;
|
|
if (ticketInfo.Ticket == null || ticketInfo.Ticket.HasValue && ticketInfo.Ticket.Equals(Guid.Empty))
|
|
{
|
|
|
|
var res = await CreateM42TicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (!string.IsNullOrEmpty(res))
|
|
{
|
|
Guid.TryParse(res, out ticketId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
await UpdateM42TicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
ticketId = (Guid)ticketInfo.Ticket;
|
|
}
|
|
|
|
bool isTicket = false;
|
|
if (ticketInfo.AdditionalValues.TryGetValue("IsTicket", out object value) && value is bool boolValue)
|
|
{
|
|
isTicket = boolValue;
|
|
if (isTicket)
|
|
{
|
|
await TransformM42TicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
}
|
|
}
|
|
|
|
var url = constUrlTicketClose;
|
|
var ticket = new cApiM42TicketClosureInfo()
|
|
{
|
|
ObjectIds = new List<Guid>() { ticketId },
|
|
Comments = ticketInfo.SolutionHtml,
|
|
ErrorType = (int)ticketInfo.ErrorType == -1 ? null : ticketInfo.ErrorType,
|
|
Reason = 408,
|
|
};
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(ticket, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
|
|
var response = await _webClient.HttpEnh.PostAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
ticketInfo.Ticket = ticketInfo.Ticket != null && ticketInfo.Ticket != Guid.Empty ? ticketInfo.Ticket : ticketId;
|
|
await UpdateM42TicketUnreadAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
return string.Empty;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public async Task<bool> AddWorkingTimesAsync(Guid TicketEOID, Dictionary<string, object> workTimes, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
if (Collector == null) return false;
|
|
var globalConfig = Collector.GetGlobalConfig();
|
|
var timeTrackingDisabled = globalConfig.TicketConfiguration.DisableAutomaticTimeTracking;
|
|
if (timeTrackingDisabled)
|
|
return false;
|
|
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return false;
|
|
|
|
|
|
if (token.IsCancellationRequested) return false;
|
|
var fragments = await GetFragmentListAsync(new cDataFragmentsParams()
|
|
{
|
|
Columns = "ID, TypeID",
|
|
Ddname = "SPSCommonClassBase",
|
|
Pagenumber = 0,
|
|
Pagesize = 10,
|
|
Where = string.Format("[Expression-ObjectId] = '{0}'", TicketEOID)
|
|
}, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return false;
|
|
var idAsString = "";
|
|
Guid? typeId = null;
|
|
if (fragments != null)
|
|
{
|
|
idAsString = (string)fragments?[0]?.ID;
|
|
if (Guid.TryParse(idAsString, out Guid typeIdTemp))
|
|
{
|
|
typeId = typeIdTemp;
|
|
}
|
|
}
|
|
|
|
string description = default;
|
|
DateTime startTime = default;
|
|
DateTime endTime = default;
|
|
TimeSpan bruttoWorkingTime = default;
|
|
int nettoWorkingTime = 0;
|
|
TimeSpan totalPausedTime = default;
|
|
|
|
|
|
if (workTimes.TryGetValue("Description", out object tempDescription) && tempDescription is string)
|
|
{
|
|
description = (string)tempDescription;
|
|
}
|
|
|
|
if (workTimes.TryGetValue("StartTime", out object tempStartTime) && tempStartTime is DateTime)
|
|
{
|
|
startTime = (DateTime)tempStartTime;
|
|
}
|
|
|
|
|
|
if (workTimes.TryGetValue("EndTime", out object tempEndTime) && tempEndTime is DateTime)
|
|
{
|
|
endTime = (DateTime)tempEndTime;
|
|
}
|
|
|
|
if (workTimes.TryGetValue("BruttoWorkingTime", out object tempBruttoWorkingTime) && tempBruttoWorkingTime is TimeSpan)
|
|
{
|
|
bruttoWorkingTime = (TimeSpan)tempBruttoWorkingTime;
|
|
}
|
|
|
|
if (workTimes.TryGetValue("NettoWorkingTime", out object tempNettoWorkingTime) && tempNettoWorkingTime is double)
|
|
{
|
|
nettoWorkingTime = (int)Math.Round((double)tempNettoWorkingTime / 60);
|
|
}
|
|
|
|
if (workTimes.TryGetValue("TotalPausedTime", out object tempTotalPausedTime) && tempTotalPausedTime is TimeSpan)
|
|
{
|
|
totalPausedTime = (TimeSpan)tempTotalPausedTime;
|
|
}
|
|
|
|
|
|
|
|
|
|
var requestBody = new cApiM42TicketAddWorkingTimesInfo()
|
|
{
|
|
ObjectIds = new List<Guid>() { TicketEOID },
|
|
Begin = startTime,
|
|
End = endTime,
|
|
TypeId = typeId,
|
|
ActivityType = 4,
|
|
Minutes = nettoWorkingTime <= 0 ? 1 : nettoWorkingTime,
|
|
Description = description
|
|
};
|
|
|
|
var url = constUrlActivityTrackWorkingTime;
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(requestBody, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
|
|
var response = await _webClient.HttpEnh.PostAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return false;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
public async Task<string> TransformM42TicketAsync(cApiM42Ticket ticketInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
|
|
var ticketId = Guid.Empty;
|
|
if (ticketInfo.Ticket == null || ticketInfo.Ticket.HasValue && ticketInfo.Ticket.Equals(Guid.Empty))
|
|
return null;
|
|
else
|
|
ticketId = ticketInfo.Ticket.Value;
|
|
var url = constUrlTicketTransform;
|
|
|
|
var ticket = new cM42TransformTicketInfo()
|
|
{
|
|
ObjectIds = new List<Guid>() { ticketId },
|
|
SourceTypeName = "SPSActivityTypeTicket",
|
|
TargetTypeName = "SPSActivityTypeIncident"
|
|
};
|
|
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(ticket, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
|
|
var response = await _webClient.HttpEnh.PostAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
await Collector.ReportTicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
return string.Empty;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public async Task<dynamic> GetQuickCallTemplateInfoAsync(Guid quickCallId, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
|
|
|
|
if (quickCallId.Equals(Guid.Empty))
|
|
return null;
|
|
|
|
var url = string.Format(constUrlActivityGetQuickCallTemplateInfo, quickCallId);
|
|
|
|
var response = await _webClient.HttpEnh.GetAsync(url, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var json = await response.Content.ReadAsStringAsync();
|
|
return JsonConvert.DeserializeObject(json);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public async Task<string> ReopenM42TicketAsync(cApiM42Ticket ticketInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
|
|
var ticketId = Guid.Empty;
|
|
if (ticketInfo.Ticket == null || ticketInfo.Ticket.HasValue && ticketInfo.Ticket.Equals(Guid.Empty))
|
|
return null;
|
|
else
|
|
ticketId = ticketInfo.Ticket.Value;
|
|
var url = constUrlActivityReopen;
|
|
string ReopenReasonText = "";
|
|
if (ticketInfo.AdditionalValues.TryGetValue("Dialog.CloseCase.ReopenReasonText", out object valueObj))
|
|
{
|
|
ReopenReasonText = valueObj as string;
|
|
}
|
|
var ticket = new cM42ReopenTicketInfo()
|
|
{
|
|
ObjectIds = new List<Guid>() { ticketId },
|
|
Reason = ReopenReasonText,
|
|
};
|
|
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(ticket, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
|
|
var response = await _webClient.HttpEnh.PostAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
//await Collector.ReportTicketAsync(ticketInfo, requestInfo, LogDeep + 1, token).ConfigureAwait(false);
|
|
return string.Empty;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public async Task<string> PauseM42TicketAsync(cApiM42Ticket ticketInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
|
|
var ticketId = Guid.Empty;
|
|
if (ticketInfo.Ticket == null || ticketInfo.Ticket.HasValue && ticketInfo.Ticket.Equals(Guid.Empty))
|
|
{
|
|
|
|
var res = await CreateM42TicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (!string.IsNullOrEmpty(res))
|
|
{
|
|
Guid.TryParse(res, out ticketId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
await UpdateM42TicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
ticketId = (Guid)ticketInfo.Ticket;
|
|
}
|
|
|
|
bool isTicket = false;
|
|
if (ticketInfo.AdditionalValues.TryGetValue("IsTicket", out object value) && value is bool boolValue)
|
|
{
|
|
isTicket = boolValue;
|
|
if (isTicket)
|
|
{
|
|
await TransformM42TicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
}
|
|
}
|
|
|
|
var url = constUrlActivityPause;
|
|
var ticket = new cApiM42TicketPauseInfo()
|
|
{
|
|
ObjectIds = new List<Guid>() { ticketId },
|
|
Comments = ticketInfo.Comment,
|
|
ReminderDate = (DateTime)ticketInfo.ReminderDate,
|
|
NotEscalateWhilePaused = (bool)ticketInfo.DoNotEscalateWhilePaused,
|
|
Reason = (int)ticketInfo.Reason
|
|
};
|
|
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(ticket, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
|
|
var response = await _webClient.HttpEnh.PostAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
ticketInfo.Ticket = ticketInfo.Ticket != null && ticketInfo.Ticket != Guid.Empty ? ticketInfo.Ticket : ticketId;
|
|
await UpdateM42TicketUnreadAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
return string.Empty;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
public async Task<string> ForwardM42TicketAsync(cApiM42Ticket ticketInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
|
|
var ticketId = Guid.Empty;
|
|
if (ticketInfo.Ticket == null || ticketInfo.Ticket.HasValue && ticketInfo.Ticket.Equals(Guid.Empty))
|
|
{
|
|
|
|
var res = await CreateM42TicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (!string.IsNullOrEmpty(res))
|
|
{
|
|
Guid.TryParse(res, out ticketId);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
await UpdateM42TicketAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
ticketId = (Guid)ticketInfo.Ticket;
|
|
}
|
|
var url = constUrlActivityForward;
|
|
|
|
|
|
var ticket = new cApiM42TicketForwardInfo()
|
|
{
|
|
Tickets = new List<cApiM42TicketForwardInfo.cTicket>() { new cApiM42TicketForwardInfo.cTicket() {
|
|
Item1 = "SPSActivityTypeIncident",
|
|
Item2 = ticketId
|
|
}},
|
|
Comments = ticketInfo.Comment,
|
|
RoleId = ticketInfo.ResponsibleRole,
|
|
UserId = ticketInfo.ResponsiblePerson,
|
|
};
|
|
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(ticket, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
|
|
var response = await _webClient.HttpEnh.PostAsync(url, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
ticketInfo.Ticket = ticketInfo.Ticket != null && ticketInfo.Ticket != Guid.Empty ? ticketInfo.Ticket : ticketId;
|
|
await UpdateM42TicketUnreadAsync(ticketInfo, requestInfo, LogDeep + 1, token);
|
|
return string.Empty;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public async Task<String> CreateM42JournalAsync(cCreateJournalEntryInfo journalEntryInfo, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null) return null;
|
|
|
|
var _jsonContent = JsonConvert.SerializeObject(journalEntryInfo, Formatting.None,
|
|
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
|
|
var _content = new StringContent(_jsonContent, Encoding.UTF8, "application/json");
|
|
|
|
var response = await _webClient.HttpEnh.PostAsync(constUrlCreateJournalEntry, _content, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var json = await response.Content.ReadAsStringAsync();
|
|
if (token.IsCancellationRequested) return null;
|
|
return json;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static string GetFragmentUrlWithParameters(cDataFragmentsParams parameters)
|
|
{
|
|
return string.Format(constUrlFragmentsGetList,
|
|
parameters.Ddname,
|
|
Uri.EscapeDataString(parameters.Where), // Ensure proper URI encoding
|
|
parameters.Columns,
|
|
parameters.Pagesize,
|
|
parameters.Pagenumber,
|
|
parameters.Sort);
|
|
}
|
|
|
|
|
|
public async Task CleanupApiTokensAsync(CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
|
|
if (WebClient is null)
|
|
return;
|
|
|
|
try
|
|
{
|
|
var _strFilter = (DateTime.UtcNow - TimeSpan.FromHours(24)).ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss");
|
|
_strFilter = string.Format("Name like 'F4SD_%' and ValidUntil < '{0}'", _strFilter);
|
|
var _strListToken = await WebClient.GetFragmentListAsync("PLSTSApiTokenBase", Token, Where: _strFilter, Columns: "ID,Name");
|
|
|
|
if (Token.IsCancellationRequested)
|
|
return;
|
|
|
|
if (!string.IsNullOrEmpty(_strListToken))
|
|
{
|
|
// remove all existing tokens with corresponding name
|
|
var lstIds = JsonConvert.DeserializeObject<List<cM42IdResult>>(_strListToken);
|
|
foreach (var objId in lstIds)
|
|
{
|
|
if (string.IsNullOrEmpty(objId.Name))
|
|
continue;
|
|
if (objId.Name.Length < 37)
|
|
continue;
|
|
var _strGuid = objId.Name.Substring(objId.Name.Length - 37, 37);
|
|
if (!_strGuid.StartsWith("_"))
|
|
continue;
|
|
_strGuid = _strGuid.Remove(0, 1);
|
|
if (!Guid.TryParse(_strGuid, out _))
|
|
continue;
|
|
|
|
var _delRequest = new Dictionary<Guid, string>()
|
|
{
|
|
{ objId.Id, "PLSTSApiTokenType" }
|
|
};
|
|
|
|
await WebClient.DeleteObjectsAsync("F4SD Cockpit", _delRequest, Token);
|
|
|
|
if (Token.IsCancellationRequested)
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
public override async Task<cF4SDAdditionalUserInfo> GetAdditionalUserInfo(enumAdditionalAuthentication Type, cF4sdWebRequestInfo RequestInfo, int LogDeep, CancellationToken Token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
try
|
|
{
|
|
if (Type != enumAdditionalAuthentication.M42WinLogon)
|
|
return null;
|
|
|
|
if (RequestInfo?.userInfo?.Id is null)
|
|
return null;
|
|
|
|
var _uc = await Collector.TokenCache.GetAsync(RequestInfo.userInfo.Id, cF4SDTokenRegistration.enumTokenType.M42Bearer, RequestInfo, LogDeep + 1);
|
|
if (_uc == null) return null;
|
|
|
|
var _m42 = new cM42WebClient(Collector.InfrastructureConfig.M42Wpm.Server, UseSSL: true);
|
|
_m42.SetBearerToken(_uc.secret);
|
|
var _m42Reason = await _m42.Open();
|
|
if (_m42Reason == eReason.ok && _m42.BearerToken != null)
|
|
{
|
|
var m42UserInfo = await _m42.GetUserInfoAsync();
|
|
if (m42UserInfo?.User != null)
|
|
{
|
|
var _retVal = new cF4SDAdditionalUserInfo()
|
|
{
|
|
internalID = m42UserInfo.User.Id.ToString(),
|
|
Name = m42UserInfo.User.LastName + ", " + m42UserInfo.User.FirstName,
|
|
Type = enumAdditionalAuthentication.M42WinLogon,
|
|
ValidUntil = _uc.validUntil
|
|
};
|
|
|
|
return _retVal;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
|
|
public async Task<dynamic> GetFragmentListAsync(cDataFragmentsParams fragmentsParams, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null)
|
|
return null;
|
|
|
|
var response = await _webClient.HttpEnh.GetAsync(GetFragmentUrlWithParameters(fragmentsParams), token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var json = await response.Content.ReadAsStringAsync();
|
|
return JsonConvert.DeserializeObject(json);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public async Task<dynamic> GetObjectAsync(string ci, Guid id, bool full, cF4sdWebRequestInfo requestInfo, int LogDeep, CancellationToken token)
|
|
{
|
|
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
|
|
var _startTime = DateTime.UtcNow;
|
|
|
|
try
|
|
{
|
|
var _webClient = await GetUserWebClient(requestInfo, LogDeep + 1, token);
|
|
if (token.IsCancellationRequested || _webClient == null)
|
|
return null;
|
|
|
|
var url = string.Format(constUrlObjectsGetObject, ci, id, full);
|
|
var response = await _webClient.HttpEnh.GetAsync(url, token);
|
|
if (token.IsCancellationRequested) return null;
|
|
|
|
if (response.IsSuccessStatusCode)
|
|
{
|
|
var json = await response.Content.ReadAsStringAsync();
|
|
if (token.IsCancellationRequested) return null;
|
|
return JsonConvert.DeserializeObject(json);
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
}
|
|
finally
|
|
{
|
|
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
|
|
if (CM != null) LogMethodEnd(CM);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
static string RemoveEmptyQueryParameters(string url)
|
|
{
|
|
var uri = new Uri("http://dummy.com/" + url);
|
|
var queryParts = HttpUtility.ParseQueryString(uri.Query);
|
|
|
|
var newQuery = "";
|
|
foreach (string key in queryParts.AllKeys)
|
|
{
|
|
if (!string.IsNullOrEmpty(queryParts[key]))
|
|
{
|
|
newQuery += string.IsNullOrEmpty(newQuery) ? "?" : "&";
|
|
newQuery += $"{key}={queryParts[key]}";
|
|
}
|
|
}
|
|
|
|
string cleanedUrl = uri.AbsolutePath.Substring(1) + newQuery;
|
|
return cleanedUrl;
|
|
}
|
|
|
|
public HashSet<enumFasdInformationClass> GetSupportedInformationClasses() => new HashSet<enumFasdInformationClass>() { enumFasdInformationClass.Ticket };
|
|
|
|
public async Task<cF4sdStagedSearchResultRelations> GetRelationsAsync(IEnumerable<cF4sdIdentityEntry> ids, enumFasdInformationClass informationClass, int age, CancellationToken token = default)
|
|
{
|
|
try
|
|
{
|
|
List<cF4sdConnectorIds> ticketIds = await _collector.getConnectorIdList(ids.ToList(), token, null, 0);
|
|
List<cF4sdApiSearchResultRelation> relations = await getTicketUsage(ticketIds, token, null, 0);
|
|
return new cF4sdStagedSearchResultRelations() { Relations = relations };
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogException(ex);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public class cDataFragmentsParams
|
|
{
|
|
public string Ddname { get; set; }
|
|
public string Where { get; set; }
|
|
public string Columns { get; set; }
|
|
public int Pagesize { get; set; }
|
|
public int Pagenumber { get; set; }
|
|
public string Sort { get; set; }
|
|
}
|
|
public class cCreateJournalEntryInfo
|
|
{
|
|
public Guid ObjectId { get; set; }
|
|
public Guid TypeId { get; set; }
|
|
public bool Publish { get; set; }
|
|
public string Comments { get; set; }
|
|
public int EntryType { get; set; }
|
|
public Guid Creator { get; set; }
|
|
public bool VisibleInPortal { get; set; }
|
|
public List<Guid> FileIds { get; set; }
|
|
public List<Parameter> Parameters { get; set; }
|
|
|
|
public class Parameter
|
|
{
|
|
public string Name { get; set; }
|
|
public object Value { get; set; }
|
|
public string Format { get; set; }
|
|
public bool IsCurrency { get; set; }
|
|
}
|
|
}
|
|
|
|
public class cM42TransformTicketInfo
|
|
{
|
|
public Guid? Category { get; set; } = null;
|
|
public Guid? Sla { get; set; } = null;
|
|
public Guid? RecipientRole { get; set; } = null;
|
|
public string SourceTypeName { get; set; } = null;
|
|
public string TargetTypeName { get; set; } = null;
|
|
public List<Guid> ObjectIds { get; set; } = new List<Guid>();
|
|
public bool? UpdateFavoriteView { get; set; } = null;
|
|
public bool? RaiseCoRuTypeInsertEvent { get; set; } = null;
|
|
}
|
|
public class cM42ReopenTicketInfo
|
|
{
|
|
public string Reason { get; set; } = null;
|
|
public List<Guid> ObjectIds { get; set; } = new List<Guid>();
|
|
}
|
|
public class cM42TicketInfo
|
|
{
|
|
public JournalEntryData EntryData { get; set; }
|
|
public Guid? Asset { get; set; } = null;
|
|
public Guid? AffectedAsset { get; set; } = null;
|
|
public Guid? AffectedService { get; set; } = null;
|
|
public string UserReachableAt { get; set; } = null;
|
|
public int EntryBy { get; set; } = 0;
|
|
public int Classification { get; set; } = 0;
|
|
public Guid? QueueProfile { get; set; } = null;
|
|
public Guid? Template { get; set; } = null;
|
|
public Guid? Category { get; set; } = null;
|
|
public string Subject { get; set; } = null;
|
|
public string Description { get; set; } = null;
|
|
public string DescriptionHTML { get; set; } = null;
|
|
public string Solution { get; set; } = null;
|
|
public string SolutionHTML { get; set; } = null;
|
|
public int ActivityAction { get; set; } = 0;
|
|
public int TaskType { get; set; } = 0;
|
|
public int ErrorType { get; set; } = 0;
|
|
public int State { get; set; } = 0;
|
|
public int Priority { get; set; } = 0;
|
|
public int Impact { get; set; } = 0;
|
|
public int Urgency { get; set; } = 0;
|
|
public Guid? User { get; set; } = null;
|
|
public Guid? ResponsibleUser { get; set; } = null;
|
|
public Guid? ResponsibleRole { get; set; } = null;
|
|
public Guid? Service { get; set; } = null;
|
|
public Guid? SLA { get; set; } = null;
|
|
public string TicketNumber { get; set; } = null;
|
|
public DateTime Deadline { get; set; } = DateTime.UtcNow;
|
|
public bool NotifyResponsible { get; set; } = false;
|
|
public int NotificationMode { get; set; } = 0;
|
|
public bool CloseOnTasksCompletion { get; set; } = false;
|
|
public Guid? WorkflowId { get; set; } = null;
|
|
public List<Guid> RelatedUsers { get; set; } = new List<Guid>();
|
|
public List<Guid> RelatedServices { get; set; } = new List<Guid>();
|
|
public List<Guid> SimpleServiceForms { get; set; } = new List<Guid>();
|
|
public List<Guid> ConfigurationItems { get; set; } = new List<Guid>();
|
|
public List<Guid> RelatedTasks { get; set; } = new List<Guid>();
|
|
public List<Guid> RelatedAssets { get; set; } = new List<Guid>();
|
|
public List<Guid> RelatedIncidents { get; set; } = new List<Guid>();
|
|
public List<Guid> RelatedProblems { get; set; } = new List<Guid>();
|
|
public bool NewInformationReceived { get; set; } = false;
|
|
public bool SkipSettingOwner { get; set; } = false;
|
|
public bool RecalculateResponsibleRole { get; set; } = false;
|
|
public List<ExtraProperty> ExtraProperties { get; set; } = new List<ExtraProperty>();
|
|
}
|
|
|
|
public class JournalEntryData
|
|
{
|
|
public Guid? ObjectId { get; set; } = null;
|
|
public Guid? TypeId { get; set; } = null;
|
|
public bool Publish { get; set; } = false;
|
|
public string Comments { get; set; } = null;
|
|
public int EntryType { get; set; } = 0;
|
|
public Guid? Creator { get; set; } = null;
|
|
public bool VisibleInPortal { get; set; } = false;
|
|
public List<Parameter> Parameters { get; set; } = new List<Parameter>();
|
|
public bool SkipRaiseCoRuEvent { get; set; } = false;
|
|
}
|
|
|
|
public class Parameter
|
|
{
|
|
public bool IsPortalMode { get; set; } = false;
|
|
public bool IsExportMode { get; set; } = false;
|
|
public string Name { get; set; } = null;
|
|
}
|
|
|
|
public class ExtraProperty
|
|
{
|
|
public string Name { get; set; } = null;
|
|
public object Value { get; set; } = null;
|
|
}
|
|
}
|
|
|
|
public class cM42DataQueryRelationInfo
|
|
{
|
|
public int ClientTimeOffset { get; set; } = 0;
|
|
public string EntityClassName { get; set; }
|
|
public string EntityTypeName { get; set; }
|
|
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
|
public string DataQueryName { get; set; }
|
|
public string AddedRelations { get; set; } = "";
|
|
public string RemovedRelations { get; set; } = "";
|
|
public string WhereExpression { get; set; } = "";
|
|
public cM42QueryFilterGroup AdditionalFilter { get; set; } = new cM42QueryFilterGroup();
|
|
public int pageSize { get; set; } = 20;
|
|
public int page { get; set; } = 0;
|
|
public bool totalCounted { get; set; } = false;
|
|
public string search { get; set; } = "";
|
|
public string orderBy { get; set; } = "";
|
|
public string columns { get; set; }
|
|
}
|
|
|
|
public class cM42DataQueryRelationInfo2
|
|
{
|
|
public int ClientTimeOffset { get; set; } = 0;
|
|
public string EntityClassName { get; set; }
|
|
public string EntityTypeName { get; set; }
|
|
public string AddedRelations { get; set; } = "";
|
|
public string RemovedRelations { get; set; } = "";
|
|
public string WhereExpression { get; set; } = "";
|
|
public cM42QueryFilterGroup AdditionalFilter { get; set; } = new cM42QueryFilterGroup();
|
|
public int pageSize { get; set; } = 0;
|
|
public int page { get; set; } = 0;
|
|
public string search { get; set; } = "";
|
|
public string orderBy { get; set; } = "";
|
|
public string columns { get; set; }
|
|
public string RelationName { get; set; }
|
|
public Guid FragmentId { get; set; }
|
|
public bool Archived { get; set; } = false;
|
|
public string Filters { get; set; } = "";
|
|
}
|
|
|
|
public class cM42QueryFilterGroup
|
|
{
|
|
public cM42QueryFilterCondition[] Conditions { get; set; } = new cM42QueryFilterCondition[0];
|
|
public cM42QueryFilterGroup[] Groups { get; set; } = new cM42QueryFilterGroup[0];
|
|
public int LogicalOperator { get; set; } = 1;
|
|
}
|
|
|
|
|
|
public class cM42QueryFilterCondition
|
|
{
|
|
public int Operator { get; set; }
|
|
public string Property { get; set; }
|
|
public string[] Value { get; set; }
|
|
public bool IsExpression { get; set; }
|
|
public bool DenyWildcard { get; set; }
|
|
}
|
|
|
|
public class cF4SDTicketSummary
|
|
{
|
|
public Guid TicketObjectId { get; set; }
|
|
public string Name { get; set; }
|
|
public string ActivityType { get; set; }
|
|
public string Summary { get; set; }
|
|
public string Sid { get; set; }
|
|
public string Status { get; set; }
|
|
public int StatusId { get; set; }
|
|
public string AssetCIName { get; set; }
|
|
public string AssetName { get; set; }
|
|
public string ServiceName { get; set; }
|
|
public Guid ServiceId { get; set; }
|
|
public bool IsPrimaryAccount { get; set; }
|
|
public Guid UserId { get; set; }
|
|
}
|
|
|
|
public class M42UserUserInfo
|
|
{
|
|
public class M42User
|
|
{
|
|
public Guid Id { get; set; } = Guid.Empty;
|
|
public Guid ObjectId { get; set; }
|
|
public string Name { get; set; }
|
|
public string FirstName { get; set; }
|
|
public string LastName { get; set; }
|
|
public string Email { get; set; }
|
|
public string Photo { get; set; }
|
|
public string Phone { get; set; }
|
|
public string Currency { get; set; }
|
|
public string Locale { get; set; }
|
|
public int LanguageId { get; set; }
|
|
public bool IsAdmin { get; set; }
|
|
public int State { get; set; }
|
|
public string StateDisp { get; set; }
|
|
}
|
|
|
|
public class M42Role
|
|
{
|
|
public Guid Id { get; set; }
|
|
public string Name { get; set; }
|
|
|
|
}
|
|
|
|
public M42User User { get; set; }
|
|
public List<M42Role> Roles { get; set; }
|
|
|
|
}
|
|
|
|
|