feat(dashboard): host-side Galaxy summary projector over lib cache entry
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
using ZB.MOM.WW.GalaxyRepository;
|
||||
using ZB.MOM.WW.GalaxyRepository.Grpc;
|
||||
|
||||
namespace ZB.MOM.WW.MxGateway.Server.Dashboard;
|
||||
|
||||
/// <summary>
|
||||
/// Projects a shared-library <see cref="GalaxyHierarchyCacheEntry"/> into the
|
||||
/// dashboard's host-side <see cref="DashboardGalaxySummary"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The shared <c>ZB.MOM.WW.GalaxyRepository</c> cache entry does not compute a
|
||||
/// dashboard summary; this projector relocates the summary logic that previously
|
||||
/// lived inside the gateway's inline Galaxy hierarchy cache. It groups the entry's
|
||||
/// objects into template usage and category counts, maps the cache status to the
|
||||
/// dashboard status, and copies the timestamps and counts the entry already carries.
|
||||
/// </remarks>
|
||||
public static class DashboardGalaxySummaryProjector
|
||||
{
|
||||
private const int MaxTopTemplates = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Builds a <see cref="DashboardGalaxySummary"/> from a shared-library Galaxy
|
||||
/// hierarchy cache entry.
|
||||
/// </summary>
|
||||
/// <param name="entry">The shared-library cache entry to project.</param>
|
||||
/// <returns>The dashboard summary derived from <paramref name="entry"/>.</returns>
|
||||
public static DashboardGalaxySummary Project(GalaxyHierarchyCacheEntry entry)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(entry);
|
||||
|
||||
IReadOnlyList<DashboardGalaxyTemplateUsage> topTemplates;
|
||||
IReadOnlyList<DashboardGalaxyCategoryCount> objectCategories;
|
||||
|
||||
if (entry.Objects.Count == 0)
|
||||
{
|
||||
topTemplates = Array.Empty<DashboardGalaxyTemplateUsage>();
|
||||
objectCategories = Array.Empty<DashboardGalaxyCategoryCount>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Dictionary<int, int> objectsByCategory = new();
|
||||
Dictionary<string, int> templateUsage = new(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (GalaxyObject obj in entry.Objects)
|
||||
{
|
||||
objectsByCategory.TryGetValue(obj.CategoryId, out int categoryCount);
|
||||
objectsByCategory[obj.CategoryId] = categoryCount + 1;
|
||||
|
||||
if (obj.TemplateChain.Count > 0)
|
||||
{
|
||||
string immediate = obj.TemplateChain[0];
|
||||
if (!string.IsNullOrWhiteSpace(immediate))
|
||||
{
|
||||
templateUsage.TryGetValue(immediate, out int templateCount);
|
||||
templateUsage[immediate] = templateCount + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
topTemplates = templateUsage
|
||||
.OrderByDescending(usage => usage.Value)
|
||||
.ThenBy(usage => usage.Key, StringComparer.OrdinalIgnoreCase)
|
||||
.Take(MaxTopTemplates)
|
||||
.Select(usage => new DashboardGalaxyTemplateUsage(usage.Key, usage.Value))
|
||||
.ToArray();
|
||||
|
||||
objectCategories = objectsByCategory
|
||||
.OrderByDescending(category => category.Value)
|
||||
.ThenBy(category => category.Key)
|
||||
.Select(category => new DashboardGalaxyCategoryCount(
|
||||
category.Key,
|
||||
ResolveCategoryName(category.Key),
|
||||
category.Value))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
return new DashboardGalaxySummary(
|
||||
Status: MapDashboardStatus(entry.Status),
|
||||
LastQueriedAt: entry.LastQueriedAt,
|
||||
LastSuccessAt: entry.LastSuccessAt,
|
||||
LastDeployTime: entry.LastDeployTime,
|
||||
LastError: entry.LastError,
|
||||
ObjectCount: entry.ObjectCount,
|
||||
AreaCount: entry.AreaCount,
|
||||
AttributeCount: entry.AttributeCount,
|
||||
HistorizedAttributeCount: entry.HistorizedAttributeCount,
|
||||
AlarmAttributeCount: entry.AlarmAttributeCount,
|
||||
TopTemplates: topTemplates,
|
||||
ObjectCategories: objectCategories);
|
||||
}
|
||||
|
||||
private static DashboardGalaxyStatus MapDashboardStatus(GalaxyCacheStatus status) => status switch
|
||||
{
|
||||
GalaxyCacheStatus.Healthy => DashboardGalaxyStatus.Healthy,
|
||||
GalaxyCacheStatus.Stale => DashboardGalaxyStatus.Stale,
|
||||
GalaxyCacheStatus.Unavailable => DashboardGalaxyStatus.Unavailable,
|
||||
_ => DashboardGalaxyStatus.Unknown,
|
||||
};
|
||||
|
||||
private static string ResolveCategoryName(int categoryId) => categoryId switch
|
||||
{
|
||||
1 => "WinPlatform",
|
||||
3 => "AppEngine",
|
||||
4 => "InTouchViewApp",
|
||||
10 => "UserDefined",
|
||||
11 => "FieldReference",
|
||||
13 => "Area",
|
||||
17 => "DIObject",
|
||||
24 => "DDESuiteLinkClient",
|
||||
26 => "OPCClient",
|
||||
_ => $"Category {categoryId}",
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user