mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
Merge pull request #2033 from DuendeSoftware/beh/license-usage-summary-diagnostic-entry
License Usage Summary Diagnostic Entry
This commit is contained in:
commit
2a4086ae8b
3 changed files with 157 additions and 0 deletions
|
|
@ -219,6 +219,7 @@ public static class IdentityServerBuilderExtensionsCore
|
|||
builder.Services.AddSingleton<IDiagnosticEntry, IdentityServerOptionsDiagnosticEntry>();
|
||||
builder.Services.AddSingleton<IDiagnosticEntry, DataProtectionDiagnosticEntry>();
|
||||
builder.Services.AddSingleton<IDiagnosticEntry, TokenIssueCountDiagnosticEntry>();
|
||||
builder.Services.AddSingleton<IDiagnosticEntry, LicenseUsageDiagnosticEntry>();
|
||||
builder.Services.AddSingleton<DiagnosticSummary>();
|
||||
builder.Services.AddHostedService<DiagnosticHostedService>();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Duende.IdentityServer.Licensing.V2.Diagnostics.DiagnosticEntries;
|
||||
|
||||
internal class LicenseUsageDiagnosticEntry(LicenseUsageTracker licenseUsageTracker) : IDiagnosticEntry
|
||||
{
|
||||
public Task WriteAsync(Utf8JsonWriter writer)
|
||||
{
|
||||
writer.WriteStartObject("LicenseUsageSummary");
|
||||
|
||||
var licenseUsageSummary = licenseUsageTracker.GetSummary();
|
||||
|
||||
writer.WriteNumber("ClientsUsedCount", licenseUsageSummary.ClientsUsed.Count);
|
||||
|
||||
writer.WriteStartArray("IssuersUsed");
|
||||
foreach (var issuer in licenseUsageSummary.IssuersUsed)
|
||||
{
|
||||
writer.WriteStringValue(issuer);
|
||||
}
|
||||
writer.WriteEndArray();
|
||||
|
||||
writer.WriteStartArray("FeaturesUsed");
|
||||
foreach (var feature in licenseUsageSummary.FeaturesUsed)
|
||||
{
|
||||
writer.WriteStringValue(feature);
|
||||
}
|
||||
writer.WriteEndArray();
|
||||
|
||||
writer.WriteString("LicenseEdition", licenseUsageSummary.LicenseEdition);
|
||||
|
||||
writer.WriteEndObject();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
// Copyright (c) Duende Software. All rights reserved.
|
||||
// See LICENSE in the project root for license information.
|
||||
|
||||
using Duende.IdentityModel.Client;
|
||||
using Duende.IdentityServer.Configuration;
|
||||
using Duende.IdentityServer.Licensing.V2;
|
||||
using Duende.IdentityServer.Licensing.V2.Diagnostics.DiagnosticEntries;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace IdentityServer.UnitTests.Licensing.V2.DiagnosticEntries;
|
||||
|
||||
public class LicenseUsageDiagnosticEntryTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Handles_Single_Value_For_Each_Entry()
|
||||
{
|
||||
var licenseAccessor = new LicenseAccessor(new IdentityServerOptions(), new NullLogger<LicenseAccessor>());
|
||||
var licenseUsageTracker = new LicenseUsageTracker(licenseAccessor, new NullLoggerFactory());
|
||||
var subject = new LicenseUsageDiagnosticEntry(licenseUsageTracker);
|
||||
|
||||
licenseUsageTracker.ClientUsed("Client1");
|
||||
licenseUsageTracker.IssuerUsed("https://localhost:50001");
|
||||
licenseUsageTracker.FeatureUsed(LicenseFeature.KeyManagement);
|
||||
|
||||
var result = await DiagnosticEntryTestHelper.WriteEntryToJson(subject);
|
||||
|
||||
var licenseElement = result.RootElement;
|
||||
licenseElement.TryGetProperty("LicenseUsageSummary", out var summaryElement).ShouldBeTrue();
|
||||
summaryElement.GetProperty("LicenseEdition").GetString().ShouldBe("None");
|
||||
summaryElement.GetProperty("ClientsUsedCount").GetInt32().ShouldBe(1);
|
||||
summaryElement.TryGetStringArray("IssuersUsed").ShouldBe(["https://localhost:50001"]);
|
||||
summaryElement.TryGetStringArray("FeaturesUsed").ShouldBe(["KeyManagement"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handles_Multiple_Values_For_Each_Entry()
|
||||
{
|
||||
var licenseAccessor = new LicenseAccessor(new IdentityServerOptions(), new NullLogger<LicenseAccessor>());
|
||||
var licenseUsageTracker = new LicenseUsageTracker(licenseAccessor, new NullLoggerFactory());
|
||||
var subject = new LicenseUsageDiagnosticEntry(licenseUsageTracker);
|
||||
|
||||
licenseUsageTracker.ClientUsed("Client1");
|
||||
licenseUsageTracker.ClientUsed("Client2");
|
||||
licenseUsageTracker.IssuerUsed("https://localhost:50001");
|
||||
licenseUsageTracker.IssuerUsed("https://localhost:50002");
|
||||
licenseUsageTracker.FeatureUsed(LicenseFeature.KeyManagement);
|
||||
licenseUsageTracker.FeatureUsed(LicenseFeature.ResourceIsolation);
|
||||
|
||||
var result = await DiagnosticEntryTestHelper.WriteEntryToJson(subject);
|
||||
|
||||
var licenseElement = result.RootElement;
|
||||
licenseElement.TryGetProperty("LicenseUsageSummary", out var summaryElement).ShouldBeTrue();
|
||||
summaryElement.GetProperty("LicenseEdition").GetString().ShouldBe("None");
|
||||
summaryElement.GetProperty("ClientsUsedCount").GetInt32().ShouldBe(2);
|
||||
summaryElement.TryGetStringArray("IssuersUsed").ShouldContain(["https://localhost:50001", "https://localhost:50002"]);
|
||||
summaryElement.TryGetStringArray("FeaturesUsed").ShouldContain(["KeyManagement", "ResourceIsolation"]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EmptySummary_ContainsNoValues()
|
||||
{
|
||||
var licenseAccessor = new LicenseAccessor(new IdentityServerOptions(), new NullLogger<LicenseAccessor>());
|
||||
var licenseUsageTracker = new LicenseUsageTracker(licenseAccessor, new NullLoggerFactory());
|
||||
var subject = new LicenseUsageDiagnosticEntry(licenseUsageTracker);
|
||||
|
||||
var result = await DiagnosticEntryTestHelper.WriteEntryToJson(subject);
|
||||
|
||||
var licenseElement = result.RootElement;
|
||||
licenseElement.TryGetProperty("LicenseUsageSummary", out var summaryElement).ShouldBeTrue();
|
||||
summaryElement.GetProperty("LicenseEdition").GetString().ShouldBe("None");
|
||||
summaryElement.GetProperty("ClientsUsedCount").GetInt32().ShouldBe(0);
|
||||
summaryElement.TryGetStringArray("IssuersUsed").ShouldBeEmpty();
|
||||
summaryElement.TryGetStringArray("FeaturesUsed").ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Handles_Duplicate_Values()
|
||||
{
|
||||
var licenseAccessor = new LicenseAccessor(new IdentityServerOptions(), new NullLogger<LicenseAccessor>());
|
||||
var licenseUsageTracker = new LicenseUsageTracker(licenseAccessor, new NullLoggerFactory());
|
||||
var subject = new LicenseUsageDiagnosticEntry(licenseUsageTracker);
|
||||
|
||||
licenseUsageTracker.ClientUsed("Client1");
|
||||
licenseUsageTracker.ClientUsed("Client1");
|
||||
licenseUsageTracker.IssuerUsed("https://localhost:50001");
|
||||
licenseUsageTracker.IssuerUsed("https://localhost:50001");
|
||||
licenseUsageTracker.FeatureUsed(LicenseFeature.KeyManagement);
|
||||
licenseUsageTracker.FeatureUsed(LicenseFeature.KeyManagement);
|
||||
|
||||
var result = await DiagnosticEntryTestHelper.WriteEntryToJson(subject);
|
||||
|
||||
var licenseElement = result.RootElement;
|
||||
licenseElement.TryGetProperty("LicenseUsageSummary", out var summaryElement).ShouldBeTrue();
|
||||
summaryElement.GetProperty("LicenseEdition").GetString().ShouldBe("None");
|
||||
summaryElement.GetProperty("ClientsUsedCount").GetInt32().ShouldBe(1);
|
||||
summaryElement.TryGetStringArray("IssuersUsed").ShouldBe(["https://localhost:50001"]);
|
||||
summaryElement.TryGetStringArray("FeaturesUsed").ShouldBe(["KeyManagement"]);
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task Different_License_Edition_Is_Reflected()
|
||||
{
|
||||
var options = new IdentityServerOptions
|
||||
{
|
||||
LicenseKey = "eyJhbGciOiJQUzI1NiIsImtpZCI6IklkZW50aXR5U2VydmVyTGljZW5zZWtleS83Y2VhZGJiNzgxMzA0NjllODgwNjg5MTAyNTQxNGYxNiIsInR5cCI6ImxpY2Vuc2Urand0In0.eyJpc3MiOiJodHRwczovL2R1ZW5kZXNvZnR3YXJlLmNvbSIsImF1ZCI6IklkZW50aXR5U2VydmVyIiwiaWF0IjoxNzMwNDE5MjAwLCJleHAiOjE3MzE2Mjg4MDAsImNvbXBhbnlfbmFtZSI6Il90ZXN0IiwiY29udGFjdF9pbmZvIjoiam9lQGR1ZW5kZXNvZnR3YXJlLmNvbSIsImVkaXRpb24iOiJFbnRlcnByaXNlIiwiaWQiOiI2Njg1In0.UgguIFVBciR8lpTF5RuM3FNcIm8m8wGR4Mt0xOCgo-XknFwXBpxOfr0zVjciGboteOl9AFtrqZLopEjsYXGFh2dkl5AzRyq--Ai5y7aezszlMpq8SkjRRCeBUYLNnEO41_YnfjYhNrcmb0Jx9wMomCv74vU3f8Hulz1ppWtoL-MVcGq0fhv_KOCP49aImCgiawPJ6a_bfs2C1QLpj-GG411OhdyrO9QLIH_We4BEvRUyajraisljB1VQzC8Q6188Mm_BLwl4ZENPaoNE4egiqTAuoTS5tb1l732-CGZwpGuU80NSpJbrUc6jd3rVi_pNf_1rH-O4Xt0HRCWiNCDYgg"
|
||||
};
|
||||
var licenseAccessor = new LicenseAccessor(options, new NullLogger<LicenseAccessor>());
|
||||
var licenseUsageTracker = new LicenseUsageTracker(licenseAccessor, new NullLoggerFactory());
|
||||
var subject = new LicenseUsageDiagnosticEntry(licenseUsageTracker);
|
||||
|
||||
var result = await DiagnosticEntryTestHelper.WriteEntryToJson(subject);
|
||||
|
||||
var licenseElement = result.RootElement;
|
||||
licenseElement.TryGetProperty("LicenseUsageSummary", out var summaryElement).ShouldBeTrue();
|
||||
summaryElement.GetProperty("LicenseEdition").GetString().ShouldBe("Enterprise");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue