fix: load ticket history through journal portal api

This commit is contained in:
Meik
2026-07-01 00:50:23 +02:00
parent 45b8e1d223
commit 258ca8a837
3 changed files with 123 additions and 22 deletions

View File

@@ -45,6 +45,10 @@ namespace C4IT.F4SD
private readonly F4SDHelperService _f4stHelperService;
private const string TeamsNotificationServiceTypeName = "Matrix42.Contracts.Platform.MsTeams.ITeamsNotificationService";
private const string StorageServiceTypeName = "Matrix42.StorageService.Contracts.IStorageService";
private const int JournalStart = 0;
private const int JournalCount = 50;
private const int JournalTimeOffset = 120;
private const string JournalObjectLinkTemplate = "<a href=\"#\" class=\"mx-object-journal--link {0} {1}\">{2}</a>";
public string BaseUrl => Request?.RequestUri == null ? string.Empty : $"{Request.RequestUri.Scheme}://{Request.RequestUri.Host}";
public string EndpointBaseUrl => $"{BaseUrl}/m42Services/api/c4itf4sdwebapi";
@@ -304,6 +308,13 @@ namespace C4IT.F4SD
{
try
{
var journalPortalEntries = await TryGetJournalPortalEntries(objectId);
if (journalPortalEntries != null)
{
LogEntry($"{journalPortalEntries.Count} Journal entries loaded from Matrix42 JournalPortalController for ObjectID={objectId}", LogLevels.Debug);
return F4SDHelperService.CreateTicketJournalItems(objectId, journalPortalEntries);
}
return await _f4stHelperService.GetJournalEntries(objectId);
}
catch (MissingMethodException ex)
@@ -312,6 +323,90 @@ namespace C4IT.F4SD
}
}
private async Task<IReadOnlyList<Matrix42.Contracts.Platform.Data.JournalEntryInfo>> TryGetJournalPortalEntries(Guid objectId)
{
if (Request?.RequestUri == null)
return null;
foreach (var requestUri in BuildJournalPortalUris(objectId))
{
try
{
using (var handler = new HttpClientHandler { UseDefaultCredentials = true, AutomaticDecompression = DecompressionMethods.All })
using (var client = new HttpClient(handler))
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
{
client.Timeout = TimeSpan.FromSeconds(15);
CopyIncomingHeaders(request);
using (var response = await client.SendAsync(request))
{
var responseText = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
LogEntry($"Matrix42 JournalPortalController returned {(int)response.StatusCode} {response.ReasonPhrase} for {requestUri}. {responseText}", LogLevels.Warning);
continue;
}
var entries = DeserializeJournalPortalEntries(responseText);
if (entries != null)
return entries;
LogEntry($"Matrix42 JournalPortalController response could not be deserialized for {requestUri}. {responseText}", LogLevels.Warning);
}
}
}
catch (Exception ex)
{
LogEntry($"Matrix42 JournalPortalController request failed for {requestUri}. {ex.GetType().FullName}: {ex.Message}", LogLevels.Warning);
}
}
return null;
}
private IEnumerable<Uri> BuildJournalPortalUris(Guid objectId)
{
var query = $"objectId={Uri.EscapeDataString(objectId.ToString())}&start={JournalStart}&count={JournalCount}&objectLinkTemplate={Uri.EscapeDataString(JournalObjectLinkTemplate)}&timeOffset={JournalTimeOffset}";
yield return new Uri($"{BaseUrl}/m42Services/api/journalPortal?{query}");
yield return new Uri($"{BaseUrl}/api/journalPortal?{query}");
}
private void CopyIncomingHeaders(HttpRequestMessage request)
{
foreach (var header in Request.Headers)
{
if (string.Equals(header.Key, "Host", StringComparison.OrdinalIgnoreCase)
|| string.Equals(header.Key, "Connection", StringComparison.OrdinalIgnoreCase)
|| string.Equals(header.Key, "Accept-Encoding", StringComparison.OrdinalIgnoreCase))
continue;
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
}
private static Matrix42.Contracts.Platform.Data.JournalEntryInfo[] DeserializeJournalPortalEntries(string responseText)
{
try
{
return Newtonsoft.Json.JsonConvert.DeserializeObject<Matrix42.Contracts.Platform.Data.JournalEntryInfo[]>(responseText);
}
catch
{
var token = Newtonsoft.Json.Linq.JToken.Parse(responseText);
if (token.Type == Newtonsoft.Json.Linq.JTokenType.Array)
return token.ToObject<Matrix42.Contracts.Platform.Data.JournalEntryInfo[]>();
foreach (var propertyName in new[] { "result", "Result", "value", "Value" })
{
var resultToken = token[propertyName];
if (resultToken != null && resultToken.Type != Newtonsoft.Json.Linq.JTokenType.Null)
return resultToken.ToObject<Matrix42.Contracts.Platform.Data.JournalEntryInfo[]>();
}
return null;
}
}
internal static List<cTicketJournalItem> CreateMissingMethodDiagnostics(string stage, Guid objectId, MissingMethodException ex)
{
var details = BuildMissingMethodDiagnostic(stage, objectId, ex);