Add Authority Advisory AI and API Lifecycle Configuration
- Introduced AuthorityAdvisoryAiOptions and related classes for managing advisory AI configurations, including remote inference options and tenant-specific settings. - Added AuthorityApiLifecycleOptions to control API lifecycle settings, including legacy OAuth endpoint configurations. - Implemented validation and normalization methods for both advisory AI and API lifecycle options to ensure proper configuration. - Created AuthorityNotificationsOptions and its related classes for managing notification settings, including ack tokens, webhooks, and escalation options. - Developed IssuerDirectoryClient and related models for interacting with the issuer directory service, including caching mechanisms and HTTP client configurations. - Added support for dependency injection through ServiceCollectionExtensions for the Issuer Directory Client. - Updated project file to include necessary package references for the new Issuer Directory Client library.
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace StellaOps.Scanner.Surface.Validation;
|
||||
|
||||
internal sealed class SurfaceValidatorRunner : ISurfaceValidatorRunner
|
||||
{
|
||||
private readonly IReadOnlyList<ISurfaceValidator> _validators;
|
||||
private readonly ILogger<SurfaceValidatorRunner> _logger;
|
||||
private readonly ISurfaceValidationReporter _reporter;
|
||||
private readonly SurfaceValidationOptions _options;
|
||||
|
||||
public SurfaceValidatorRunner(
|
||||
IEnumerable<ISurfaceValidator> validators,
|
||||
ILogger<SurfaceValidatorRunner> logger,
|
||||
ISurfaceValidationReporter reporter,
|
||||
IOptions<SurfaceValidationOptions> options)
|
||||
{
|
||||
_validators = validators?.ToArray() ?? Array.Empty<ISurfaceValidator>();
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_reporter = reporter ?? throw new ArgumentNullException(nameof(reporter));
|
||||
_options = options?.Value ?? new SurfaceValidationOptions();
|
||||
}
|
||||
|
||||
public async ValueTask<SurfaceValidationResult> RunAllAsync(
|
||||
SurfaceValidationContext context,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (context is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
if (_validators.Count == 0)
|
||||
{
|
||||
var success = SurfaceValidationResult.Success();
|
||||
_reporter.Report(context, success);
|
||||
return success;
|
||||
}
|
||||
|
||||
var issues = new List<SurfaceValidationIssue>();
|
||||
foreach (var validator in _validators)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
try
|
||||
{
|
||||
var result = await validator.ValidateAsync(context, cancellationToken).ConfigureAwait(false);
|
||||
if (!result.IsSuccess)
|
||||
{
|
||||
issues.AddRange(result.Issues);
|
||||
|
||||
if (!_options.ContinueOnError && result.Issues.Any(issue => issue.Severity == SurfaceValidationSeverity.Error))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Surface validator {Validator} threw an exception.", validator.GetType().FullName);
|
||||
issues.Add(SurfaceValidationIssue.Error(
|
||||
SurfaceValidationIssueCodes.ValidatorException,
|
||||
$"Validator '{validator.GetType().FullName}' threw an exception: {ex.Message}",
|
||||
"Inspect logs for stack trace."));
|
||||
|
||||
if (!_options.ContinueOnError)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var resultAggregate = issues.Count == 0
|
||||
? SurfaceValidationResult.Success()
|
||||
: SurfaceValidationResult.FromIssues(issues);
|
||||
|
||||
_reporter.Report(context, resultAggregate);
|
||||
return resultAggregate;
|
||||
}
|
||||
|
||||
public async ValueTask EnsureAsync(
|
||||
SurfaceValidationContext context,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var result = await RunAllAsync(context, cancellationToken).ConfigureAwait(false);
|
||||
if (!result.IsSuccess && _options.ThrowOnFailure)
|
||||
{
|
||||
throw new SurfaceValidationException(
|
||||
$"Surface validation failed for component '{context.ComponentName}'.",
|
||||
result.Issues);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user