Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Particular.LicensingComponent.Contracts;

/// <summary>
/// The environment data each audit remote served when last polled, one dictionary per remote that
/// responded. Never saved by versions that predate it, so a null read means unknown and the report
/// omits the keys.
/// </summary>
public record AuditEnvironmentMetadata(List<Dictionary<string, string>> Instances)
{
/// <summary>
/// The key under which the primary stores which database an instance's data came from, so that
/// instances sharing a database are counted once when sizes and counts are summed. Underscore
/// prefixed keys are collection bookkeeping and never reach the report.
/// </summary>
public const string DatabaseKey = "_DatabaseKey";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class InMemoryLicensingDataStore : ILicensingDataStore
readonly Dictionary<EndpointIdentifier, ThroughputData> allThroughput = [];
BrokerMetadata brokerMetadata = new(null, []);
AuditServiceMetadata auditServiceMetadata = new([], []);
AuditEnvironmentMetadata? auditEnvironmentMetadata;
List<string> reportMasks = [];
LicensedEndpointDetails? endpointDetails = null;
LicensedEndpointDetailsAmendment? endpointDetailsAmendment = null;
Expand Down Expand Up @@ -168,6 +169,14 @@ public Task SaveAuditServiceMetadata(AuditServiceMetadata auditServiceMetadata,
return Task.CompletedTask;
}

public Task<AuditEnvironmentMetadata?> GetAuditEnvironmentMetadata(CancellationToken cancellationToken = default) => Task.FromResult(auditEnvironmentMetadata);

public Task SaveAuditEnvironmentMetadata(AuditEnvironmentMetadata auditEnvironmentMetadata, CancellationToken cancellationToken = default)
{
this.auditEnvironmentMetadata = auditEnvironmentMetadata;
return Task.CompletedTask;
}

public Task<List<string>> GetReportMasks(CancellationToken cancellationToken = default) => Task.FromResult(reportMasks);

public Task SaveReportMasks(List<string> reportMasks, CancellationToken cancellationToken = default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ Task RecordEndpointThroughput(string endpointName, ThroughputSource throughputSo
Task<AuditServiceMetadata> GetAuditServiceMetadata(CancellationToken cancellationToken = default);

Task SaveAuditServiceMetadata(AuditServiceMetadata auditServiceMetadata, CancellationToken cancellationToken = default);

Task<AuditEnvironmentMetadata?> GetAuditEnvironmentMetadata(CancellationToken cancellationToken = default);

Task SaveAuditEnvironmentMetadata(AuditEnvironmentMetadata auditEnvironmentMetadata, CancellationToken cancellationToken = default);
Task<List<string>> GetReportMasks(CancellationToken cancellationToken = default);
Task SaveReportMasks(List<string> reportMasks, CancellationToken cancellationToken = default);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ public Task<RemoteConfiguration[]> GetRemoteConfigs(CancellationToken cancellati
}

public Task<RootUrls> GetUrls(string baseUrl, CancellationToken cancellationToken = default) => throw new NotImplementedException();

public Task<RemoteEnvironment[]> GetRemoteEnvironments(CancellationToken cancellationToken = default) => throw new NotImplementedException();
}

class ConfigurationApi_ReturningRemotes(params RemoteConfiguration[] remotes) : IConfigurationApi
Expand All @@ -237,6 +239,8 @@ class ConfigurationApi_ReturningRemotes(params RemoteConfiguration[] remotes) :
public Task<RemoteConfiguration[]> GetRemoteConfigs(CancellationToken cancellationToken = default) => Task.FromResult(remotes);

public Task<RootUrls> GetUrls(string baseUrl, CancellationToken cancellationToken = default) => throw new NotImplementedException();

public Task<RemoteEnvironment[]> GetRemoteEnvironments(CancellationToken cancellationToken = default) => throw new NotImplementedException();
}

class ConfigurationApi_Configurable : IConfigurationApi
Expand All @@ -257,6 +261,8 @@ public Task<RemoteConfiguration[]> GetRemoteConfigs(CancellationToken cancellati

public Task<RootUrls> GetUrls(string baseUrl, CancellationToken cancellationToken = default) => throw new NotImplementedException();

public Task<RemoteEnvironment[]> GetRemoteEnvironments(CancellationToken cancellationToken = default) => throw new NotImplementedException();

public bool ReturnAuditConfig { get; set; }
public string RemoteStatus { get; set; }
public string RemoteVersion { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,10 +272,40 @@ public async Task Should_store_how_many_audit_instances_are_configured_and_how_m
}
}

[Test]
public async Task Should_store_the_environment_data_of_every_responding_audit_instance()
{
var auditQuery = new AuditQuery_WithRemotes([new RemoteInstanceInformation { Status = "online" }])
{
Environments =
[
new Dictionary<string, string> { ["Storage.Type"] = "RavenDB", ["Host.ProcessorCount"] = "4" },
new Dictionary<string, string> { ["Storage.Type"] = "RavenDB", ["Host.ProcessorCount"] = "8" }
]
};

using var auditThroughputCollectorHostedService = new AuditThroughputCollectorHostedService(
NullLogger<AuditThroughputCollectorHostedService>.Instance, configuration.ThroughputSettings, DataStore,
auditQuery, new FakeTimeProvider())
{ DelayStart = TimeSpan.Zero };

await auditThroughputCollectorHostedService.StartAsync(CancellationToken.None);
await auditQuery.KnownEndpointsRequested.WaitAsync(TimeSpan.FromSeconds(30));
await auditThroughputCollectorHostedService.StopAsync(CancellationToken.None);

var auditEnvironmentMetadata = await DataStore.GetAuditEnvironmentMetadata();

Assert.That(auditEnvironmentMetadata, Is.Not.Null);
Assert.That(auditEnvironmentMetadata.Instances, Is.EqualTo(auditQuery.Environments));
}

class AuditQuery_NoAuditRemotes : IAuditQuery
{
public SemanticVersion MinAuditCountsVersion => new(4, 29, 0);

public Task<List<Dictionary<string, string>>> GetAuditEnvironments(CancellationToken cancellationToken = default) =>
Task.FromResult<List<Dictionary<string, string>>>([]);

public Func<RemoteInstanceInformation, bool> ValidRemoteInstances => r => true;

public Task<IEnumerable<AuditCount>> GetAuditCountForEndpoint(string endpointUrlName,
Expand Down Expand Up @@ -309,6 +339,9 @@ public AuditQuery_WithOneEndpoint(string endpointName, long throughputCount, Dat

public SemanticVersion MinAuditCountsVersion => new(4, 29, 0);

public Task<List<Dictionary<string, string>>> GetAuditEnvironments(CancellationToken cancellationToken = default) =>
Task.FromResult<List<Dictionary<string, string>>>([]);

public Func<RemoteInstanceInformation, bool> ValidRemoteInstances => r => true;

public Task<IEnumerable<AuditCount>> GetAuditCountForEndpoint(string endpointUrlName,
Expand Down Expand Up @@ -341,6 +374,9 @@ class AuditQuery_ThrowingAnExceptionOnKnownEndpointsCall : IAuditQuery
{
public SemanticVersion MinAuditCountsVersion => new(4, 29, 0);

public Task<List<Dictionary<string, string>>> GetAuditEnvironments(CancellationToken cancellationToken = default) =>
Task.FromResult<List<Dictionary<string, string>>>([]);

public Func<RemoteInstanceInformation, bool> ValidRemoteInstances => r => true;

public Task<IEnumerable<AuditCount>> GetAuditCountForEndpoint(string endpointUrlName,
Expand Down Expand Up @@ -420,6 +456,10 @@ public AuditQuery_WithTwoEndpointsAndSelectiveCounts(
}

public SemanticVersion MinAuditCountsVersion => new(4, 29, 0);

public Task<List<Dictionary<string, string>>> GetAuditEnvironments(CancellationToken cancellationToken = default) =>
Task.FromResult<List<Dictionary<string, string>>>([]);

public Func<RemoteInstanceInformation, bool> ValidRemoteInstances => _ => true;

public Task<IEnumerable<ServiceControlEndpoint>> GetKnownEndpoints(CancellationToken cancellationToken = default) =>
Expand Down Expand Up @@ -456,6 +496,12 @@ class AuditQuery_WithRemotes(List<RemoteInstanceInformation> remotes) : IAuditQu
public Task KnownEndpointsRequested => knownEndpointsRequested.Task;

public SemanticVersion MinAuditCountsVersion => new(4, 29, 0);

public List<Dictionary<string, string>> Environments { get; init; } = [];

public Task<List<Dictionary<string, string>>> GetAuditEnvironments(CancellationToken cancellationToken = default) =>
Task.FromResult(Environments);

public Func<RemoteInstanceInformation, bool> ValidRemoteInstances => _ => true;

public Task<List<RemoteInstanceInformation>> GetAuditRemotes(CancellationToken cancellationToken = default) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class FakeConfigurationApi : IConfigurationApi
{
public Task<object> GetConfig(CancellationToken cancellationToken = default) => throw new NotImplementedException();
public Task<RemoteConfiguration[]> GetRemoteConfigs(CancellationToken cancellationToken = default) => throw new NotImplementedException();
public Task<RemoteEnvironment[]> GetRemoteEnvironments(CancellationToken cancellationToken = default) => throw new NotImplementedException();
public Task<RootUrls> GetUrls(string baseUrl, CancellationToken cancellationToken = default) => throw new NotImplementedException();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,12 @@ public Task<AuditServiceMetadata> GetAuditServiceMetadata(CancellationToken canc
public Task SaveAuditServiceMetadata(AuditServiceMetadata auditServiceMetadata, CancellationToken cancellationToken = default) =>
throw new NotSupportedException();

public Task<AuditEnvironmentMetadata> GetAuditEnvironmentMetadata(CancellationToken cancellationToken = default) =>
throw new NotSupportedException();

public Task SaveAuditEnvironmentMetadata(AuditEnvironmentMetadata auditEnvironmentMetadata, CancellationToken cancellationToken = default) =>
throw new NotSupportedException();

public Task<List<string>> GetReportMasks(CancellationToken cancellationToken = default) =>
throw new NotSupportedException();

Expand Down
Loading
Loading