up
Some checks failed
api-governance / spectral-lint (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Some checks failed
api-governance / spectral-lint (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
oas-ci / oas-validate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
using StellaOps.AirGap.Controller.Domain;
|
||||
using StellaOps.AirGap.Controller.Stores;
|
||||
using StellaOps.AirGap.Time.Models;
|
||||
using StellaOps.AirGap.Time.Services;
|
||||
|
||||
namespace StellaOps.AirGap.Controller.Services;
|
||||
|
||||
public sealed class AirGapStateService
|
||||
{
|
||||
private readonly IAirGapStateStore _store;
|
||||
private readonly StalenessCalculator _stalenessCalculator;
|
||||
|
||||
public AirGapStateService(IAirGapStateStore store, StalenessCalculator stalenessCalculator)
|
||||
{
|
||||
_store = store;
|
||||
_stalenessCalculator = stalenessCalculator;
|
||||
}
|
||||
|
||||
public async Task<AirGapState> SealAsync(
|
||||
string tenantId,
|
||||
string policyHash,
|
||||
TimeAnchor timeAnchor,
|
||||
StalenessBudget budget,
|
||||
DateTimeOffset nowUtc,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(policyHash);
|
||||
budget.Validate();
|
||||
|
||||
var newState = new AirGapState
|
||||
{
|
||||
TenantId = tenantId,
|
||||
Sealed = true,
|
||||
PolicyHash = policyHash,
|
||||
TimeAnchor = timeAnchor,
|
||||
StalenessBudget = budget,
|
||||
LastTransitionAt = nowUtc
|
||||
};
|
||||
|
||||
await _store.SetAsync(newState, cancellationToken);
|
||||
return newState;
|
||||
}
|
||||
|
||||
public async Task<AirGapState> UnsealAsync(
|
||||
string tenantId,
|
||||
DateTimeOffset nowUtc,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var current = await _store.GetAsync(tenantId, cancellationToken);
|
||||
var newState = current with
|
||||
{
|
||||
Sealed = false,
|
||||
LastTransitionAt = nowUtc
|
||||
};
|
||||
await _store.SetAsync(newState, cancellationToken);
|
||||
return newState;
|
||||
}
|
||||
|
||||
public async Task<AirGapStatus> GetStatusAsync(
|
||||
string tenantId,
|
||||
DateTimeOffset nowUtc,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var state = await _store.GetAsync(tenantId, cancellationToken);
|
||||
var staleness = _stalenessCalculator.Evaluate(state.TimeAnchor, state.StalenessBudget, nowUtc);
|
||||
return new AirGapStatus(state, staleness, nowUtc);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed record AirGapStatus(AirGapState State, StalenessEvaluation Staleness, DateTimeOffset EvaluatedAt);
|
||||
Reference in New Issue
Block a user