fix: load ticket history through journal portal api
This commit is contained in:
@@ -13,7 +13,7 @@
|
|||||||
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
||||||
<M42ExtensionId>6673a25d-33d6-4072-91d9-abed4be1a966</M42ExtensionId>
|
<M42ExtensionId>6673a25d-33d6-4072-91d9-abed4be1a966</M42ExtensionId>
|
||||||
<M42AssemblyPattern>C4ITF4SD*.*</M42AssemblyPattern>
|
<M42AssemblyPattern>C4ITF4SD*.*</M42AssemblyPattern>
|
||||||
<M42PackageVersion>1.4.0.30</M42PackageVersion>
|
<M42PackageVersion>1.4.0.31</M42PackageVersion>
|
||||||
<M42BuildPackage>true</M42BuildPackage>
|
<M42BuildPackage>true</M42BuildPackage>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -1408,29 +1408,9 @@ namespace C4IT.F4SD
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Task.Delay(0);
|
await Task.Delay(0);
|
||||||
List<cTicketJournalItem> journalEntries = new List<cTicketJournalItem>();
|
|
||||||
var entries = LoadJournalEntries(activityEOID);
|
var entries = LoadJournalEntries(activityEOID);
|
||||||
LogEntry($"{entries.Count} Journal entries found for ObjectID={activityEOID}", LogLevels.Debug);
|
LogEntry($"{entries.Count} Journal entries found for ObjectID={activityEOID}", LogLevels.Debug);
|
||||||
for (int i = 0; i < entries.Count; i++)
|
return CreateTicketJournalItems(activityEOID, entries);
|
||||||
{
|
|
||||||
Matrix42.Contracts.Platform.Data.JournalEntryInfo item = entries[i];
|
|
||||||
var text = item.Text ?? string.Empty;
|
|
||||||
var createdDate = item.CreatedDate ?? DateTime.MinValue;
|
|
||||||
|
|
||||||
LogEntry($"Journal entry {i + 1}/{entries.Count}: ID={item.Id}, CreatedDate={createdDate}, CreatedBy={item.Creator}, Header={item.Header}", LogLevels.Debug);
|
|
||||||
journalEntries.Add(new cTicketJournalItem()
|
|
||||||
{
|
|
||||||
JournalId = item.Id,
|
|
||||||
ActivityObjectId = activityEOID,
|
|
||||||
CreatedBy = item.Creator,
|
|
||||||
CreationDate = createdDate,
|
|
||||||
DescriptionHtml = text,
|
|
||||||
Description = string.IsNullOrEmpty(text) ? string.Empty : Matrix42.Common.Html.HtmlConverter.ConvertHtmlToPlainText(text),
|
|
||||||
Header = item.Header,
|
|
||||||
IsVisibleForUser = item.VisibleInPortal
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return journalEntries;
|
|
||||||
}
|
}
|
||||||
catch (MissingMethodException E)
|
catch (MissingMethodException E)
|
||||||
{
|
{
|
||||||
@@ -1447,6 +1427,32 @@ namespace C4IT.F4SD
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static List<cTicketJournalItem> CreateTicketJournalItems(Guid activityEOID, IReadOnlyList<Matrix42.Contracts.Platform.Data.JournalEntryInfo> entries)
|
||||||
|
{
|
||||||
|
List<cTicketJournalItem> journalEntries = new List<cTicketJournalItem>();
|
||||||
|
for (int i = 0; i < entries.Count; i++)
|
||||||
|
{
|
||||||
|
Matrix42.Contracts.Platform.Data.JournalEntryInfo item = entries[i];
|
||||||
|
var text = item.Text ?? string.Empty;
|
||||||
|
var createdDate = item.CreatedDate ?? DateTime.MinValue;
|
||||||
|
|
||||||
|
LogEntry($"Journal entry {i + 1}/{entries.Count}: ID={item.Id}, CreatedDate={createdDate}, CreatedBy={item.Creator}, Header={item.Header}", LogLevels.Debug);
|
||||||
|
journalEntries.Add(new cTicketJournalItem()
|
||||||
|
{
|
||||||
|
JournalId = item.Id,
|
||||||
|
ActivityObjectId = activityEOID,
|
||||||
|
CreatedBy = item.Creator,
|
||||||
|
CreationDate = createdDate,
|
||||||
|
DescriptionHtml = text,
|
||||||
|
Description = string.IsNullOrEmpty(text) ? string.Empty : Matrix42.Common.Html.HtmlConverter.ConvertHtmlToPlainText(text),
|
||||||
|
Header = item.Header,
|
||||||
|
IsVisibleForUser = item.VisibleInPortal
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return journalEntries;
|
||||||
|
}
|
||||||
|
|
||||||
private static IReadOnlyList<Matrix42.Contracts.Platform.Data.JournalEntryInfo> LoadJournalEntries(Guid activityEOID)
|
private static IReadOnlyList<Matrix42.Contracts.Platform.Data.JournalEntryInfo> LoadJournalEntries(Guid activityEOID)
|
||||||
{
|
{
|
||||||
var journalService = F4SDM42WebApiController.defaultInstance.GetJournalServiceInstance();
|
var journalService = F4SDM42WebApiController.defaultInstance.GetJournalServiceInstance();
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ namespace C4IT.F4SD
|
|||||||
private readonly F4SDHelperService _f4stHelperService;
|
private readonly F4SDHelperService _f4stHelperService;
|
||||||
private const string TeamsNotificationServiceTypeName = "Matrix42.Contracts.Platform.MsTeams.ITeamsNotificationService";
|
private const string TeamsNotificationServiceTypeName = "Matrix42.Contracts.Platform.MsTeams.ITeamsNotificationService";
|
||||||
private const string StorageServiceTypeName = "Matrix42.StorageService.Contracts.IStorageService";
|
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 BaseUrl => Request?.RequestUri == null ? string.Empty : $"{Request.RequestUri.Scheme}://{Request.RequestUri.Host}";
|
||||||
public string EndpointBaseUrl => $"{BaseUrl}/m42Services/api/c4itf4sdwebapi";
|
public string EndpointBaseUrl => $"{BaseUrl}/m42Services/api/c4itf4sdwebapi";
|
||||||
|
|
||||||
@@ -304,6 +308,13 @@ namespace C4IT.F4SD
|
|||||||
{
|
{
|
||||||
try
|
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);
|
return await _f4stHelperService.GetJournalEntries(objectId);
|
||||||
}
|
}
|
||||||
catch (MissingMethodException ex)
|
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)
|
internal static List<cTicketJournalItem> CreateMissingMethodDiagnostics(string stage, Guid objectId, MissingMethodException ex)
|
||||||
{
|
{
|
||||||
var details = BuildMissingMethodDiagnostic(stage, objectId, ex);
|
var details = BuildMissingMethodDiagnostic(stage, objectId, ex);
|
||||||
|
|||||||
Reference in New Issue
Block a user