DET-004: Refactor Policy BudgetLedger for determinism
- Inject TimeProvider and IGuidProvider in BudgetLedger constructor - Replace DateTimeOffset.UtcNow with _timeProvider.GetUtcNow() - Replace Guid.NewGuid() with _guidProvider.NewGuid() - Add Determinism.Abstractions reference to Policy csproj Sprint: SPRINT_20260104_001_BE_determinism_timeprovider_injection Task: DET-004 (in progress - Policy module)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Logging.Abstractions;
|
using Microsoft.Extensions.Logging.Abstractions;
|
||||||
|
using StellaOps.Determinism;
|
||||||
|
|
||||||
namespace StellaOps.Policy.Gates;
|
namespace StellaOps.Policy.Gates;
|
||||||
|
|
||||||
@@ -10,10 +11,18 @@ public sealed class BudgetLedger : IBudgetLedger
|
|||||||
{
|
{
|
||||||
private readonly IBudgetStore _store;
|
private readonly IBudgetStore _store;
|
||||||
private readonly ILogger<BudgetLedger> _logger;
|
private readonly ILogger<BudgetLedger> _logger;
|
||||||
|
private readonly TimeProvider _timeProvider;
|
||||||
|
private readonly IGuidProvider _guidProvider;
|
||||||
|
|
||||||
public BudgetLedger(IBudgetStore store, ILogger<BudgetLedger>? logger = null)
|
public BudgetLedger(
|
||||||
|
IBudgetStore store,
|
||||||
|
TimeProvider? timeProvider = null,
|
||||||
|
IGuidProvider? guidProvider = null,
|
||||||
|
ILogger<BudgetLedger>? logger = null)
|
||||||
{
|
{
|
||||||
_store = store ?? throw new ArgumentNullException(nameof(store));
|
_store = store ?? throw new ArgumentNullException(nameof(store));
|
||||||
|
_timeProvider = timeProvider ?? TimeProvider.System;
|
||||||
|
_guidProvider = guidProvider ?? SystemGuidProvider.Instance;
|
||||||
_logger = logger ?? NullLogger<BudgetLedger>.Instance;
|
_logger = logger ?? NullLogger<BudgetLedger>.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,12 +73,12 @@ public sealed class BudgetLedger : IBudgetLedger
|
|||||||
// Record the consumption
|
// Record the consumption
|
||||||
var entry = new BudgetEntry
|
var entry = new BudgetEntry
|
||||||
{
|
{
|
||||||
EntryId = Guid.NewGuid().ToString(),
|
EntryId = _guidProvider.NewGuid().ToString(),
|
||||||
ServiceId = serviceId,
|
ServiceId = serviceId,
|
||||||
Window = budget.Window,
|
Window = budget.Window,
|
||||||
ReleaseId = releaseId,
|
ReleaseId = releaseId,
|
||||||
RiskPoints = riskPoints,
|
RiskPoints = riskPoints,
|
||||||
ConsumedAt = DateTimeOffset.UtcNow
|
ConsumedAt = _timeProvider.GetUtcNow()
|
||||||
};
|
};
|
||||||
|
|
||||||
await _store.AddEntryAsync(entry, ct).ConfigureAwait(false);
|
await _store.AddEntryAsync(entry, ct).ConfigureAwait(false);
|
||||||
@@ -78,7 +87,7 @@ public sealed class BudgetLedger : IBudgetLedger
|
|||||||
var updatedBudget = budget with
|
var updatedBudget = budget with
|
||||||
{
|
{
|
||||||
Consumed = budget.Consumed + riskPoints,
|
Consumed = budget.Consumed + riskPoints,
|
||||||
UpdatedAt = DateTimeOffset.UtcNow
|
UpdatedAt = _timeProvider.GetUtcNow()
|
||||||
};
|
};
|
||||||
|
|
||||||
await _store.UpdateAsync(updatedBudget, ct).ConfigureAwait(false);
|
await _store.UpdateAsync(updatedBudget, ct).ConfigureAwait(false);
|
||||||
@@ -122,7 +131,7 @@ public sealed class BudgetLedger : IBudgetLedger
|
|||||||
var updatedBudget = budget with
|
var updatedBudget = budget with
|
||||||
{
|
{
|
||||||
Allocated = newAllocation,
|
Allocated = newAllocation,
|
||||||
UpdatedAt = DateTimeOffset.UtcNow
|
UpdatedAt = _timeProvider.GetUtcNow()
|
||||||
};
|
};
|
||||||
|
|
||||||
await _store.UpdateAsync(updatedBudget, ct).ConfigureAwait(false);
|
await _store.UpdateAsync(updatedBudget, ct).ConfigureAwait(false);
|
||||||
@@ -148,15 +157,15 @@ public sealed class BudgetLedger : IBudgetLedger
|
|||||||
Window = window,
|
Window = window,
|
||||||
Allocated = DefaultBudgetAllocations.GetMonthlyAllocation(tier),
|
Allocated = DefaultBudgetAllocations.GetMonthlyAllocation(tier),
|
||||||
Consumed = 0,
|
Consumed = 0,
|
||||||
UpdatedAt = DateTimeOffset.UtcNow
|
UpdatedAt = _timeProvider.GetUtcNow()
|
||||||
};
|
};
|
||||||
|
|
||||||
await _store.CreateAsync(budget, ct).ConfigureAwait(false);
|
await _store.CreateAsync(budget, ct).ConfigureAwait(false);
|
||||||
return budget;
|
return budget;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCurrentWindow() =>
|
private string GetCurrentWindow() =>
|
||||||
DateTimeOffset.UtcNow.ToString("yyyy-MM");
|
_timeProvider.GetUtcNow().ToString("yyyy-MM");
|
||||||
|
|
||||||
private Task<ServiceTier> GetServiceTierAsync(string serviceId, CancellationToken ct)
|
private Task<ServiceTier> GetServiceTierAsync(string serviceId, CancellationToken ct)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,5 +28,6 @@
|
|||||||
<ProjectReference Include="../../../Attestor/__Libraries/StellaOps.Attestor.ProofChain/StellaOps.Attestor.ProofChain.csproj" />
|
<ProjectReference Include="../../../Attestor/__Libraries/StellaOps.Attestor.ProofChain/StellaOps.Attestor.ProofChain.csproj" />
|
||||||
<ProjectReference Include="../../../__Libraries/StellaOps.Canonical.Json/StellaOps.Canonical.Json.csproj" />
|
<ProjectReference Include="../../../__Libraries/StellaOps.Canonical.Json/StellaOps.Canonical.Json.csproj" />
|
||||||
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />
|
<ProjectReference Include="../../../__Libraries/StellaOps.Cryptography/StellaOps.Cryptography.csproj" />
|
||||||
|
<ProjectReference Include="../../../__Libraries/StellaOps.Determinism.Abstractions/StellaOps.Determinism.Abstractions.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user