feat: Implement Scheduler Worker Options and Planner Loop
- Added `SchedulerWorkerOptions` class to encapsulate configuration for the scheduler worker. - Introduced `PlannerBackgroundService` to manage the planner loop, fetching and processing planning runs. - Created `PlannerExecutionService` to handle the execution logic for planning runs, including impact targeting and run persistence. - Developed `PlannerExecutionResult` and `PlannerExecutionStatus` to standardize execution outcomes. - Implemented validation logic within `SchedulerWorkerOptions` to ensure proper configuration. - Added documentation for the planner loop and impact targeting features. - Established health check endpoints and authentication mechanisms for the Signals service. - Created unit tests for the Signals API to ensure proper functionality and response handling. - Configured options for authority integration and fallback authentication methods.
This commit is contained in:
@@ -46,16 +46,50 @@ public static class PolicyDigest
|
||||
}
|
||||
|
||||
writer.WritePropertyName("rules");
|
||||
writer.WriteStartArray();
|
||||
foreach (var rule in document.Rules)
|
||||
{
|
||||
WriteRule(writer, rule);
|
||||
}
|
||||
writer.WriteEndArray();
|
||||
|
||||
writer.WriteEndObject();
|
||||
writer.Flush();
|
||||
}
|
||||
writer.WriteStartArray();
|
||||
foreach (var rule in document.Rules)
|
||||
{
|
||||
WriteRule(writer, rule);
|
||||
}
|
||||
writer.WriteEndArray();
|
||||
|
||||
if (!document.Exceptions.Effects.IsDefaultOrEmpty || !document.Exceptions.RoutingTemplates.IsDefaultOrEmpty)
|
||||
{
|
||||
writer.WritePropertyName("exceptions");
|
||||
writer.WriteStartObject();
|
||||
|
||||
if (!document.Exceptions.Effects.IsDefaultOrEmpty)
|
||||
{
|
||||
writer.WritePropertyName("effects");
|
||||
writer.WriteStartArray();
|
||||
foreach (var effect in document.Exceptions.Effects
|
||||
.OrderBy(static e => e.Id, StringComparer.Ordinal))
|
||||
{
|
||||
WriteExceptionEffect(writer, effect);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
|
||||
if (!document.Exceptions.RoutingTemplates.IsDefaultOrEmpty)
|
||||
{
|
||||
writer.WritePropertyName("routingTemplates");
|
||||
writer.WriteStartArray();
|
||||
foreach (var template in document.Exceptions.RoutingTemplates
|
||||
.OrderBy(static t => t.Id, StringComparer.Ordinal))
|
||||
{
|
||||
WriteExceptionRoutingTemplate(writer, template);
|
||||
}
|
||||
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
writer.Flush();
|
||||
}
|
||||
|
||||
private static void WriteRule(Utf8JsonWriter writer, PolicyRule rule)
|
||||
{
|
||||
@@ -193,19 +227,78 @@ public static class PolicyDigest
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
|
||||
private static void WriteStringArray(Utf8JsonWriter writer, string propertyName, ImmutableArray<string> values)
|
||||
{
|
||||
if (values.IsDefaultOrEmpty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WritePropertyName(propertyName);
|
||||
writer.WriteStartArray();
|
||||
foreach (var value in values)
|
||||
{
|
||||
writer.WriteStringValue(value);
|
||||
}
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
}
|
||||
private static void WriteStringArray(Utf8JsonWriter writer, string propertyName, ImmutableArray<string> values)
|
||||
{
|
||||
if (values.IsDefaultOrEmpty)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
writer.WritePropertyName(propertyName);
|
||||
writer.WriteStartArray();
|
||||
foreach (var value in values)
|
||||
{
|
||||
writer.WriteStringValue(value);
|
||||
}
|
||||
writer.WriteEndArray();
|
||||
}
|
||||
|
||||
private static void WriteExceptionEffect(Utf8JsonWriter writer, PolicyExceptionEffect effect)
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
writer.WriteString("id", effect.Id);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(effect.Name))
|
||||
{
|
||||
writer.WriteString("name", effect.Name);
|
||||
}
|
||||
|
||||
writer.WriteString("effect", effect.Effect.ToString().ToLowerInvariant());
|
||||
|
||||
if (effect.DowngradeSeverity is { } downgradeSeverity)
|
||||
{
|
||||
writer.WriteString("downgradeSeverity", downgradeSeverity.ToString());
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(effect.RequiredControlId))
|
||||
{
|
||||
writer.WriteString("requiredControlId", effect.RequiredControlId);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(effect.RoutingTemplate))
|
||||
{
|
||||
writer.WriteString("routingTemplate", effect.RoutingTemplate);
|
||||
}
|
||||
|
||||
if (effect.MaxDurationDays is int maxDurationDays)
|
||||
{
|
||||
writer.WriteNumber("maxDurationDays", maxDurationDays);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(effect.Description))
|
||||
{
|
||||
writer.WriteString("description", effect.Description);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
private static void WriteExceptionRoutingTemplate(Utf8JsonWriter writer, PolicyExceptionRoutingTemplate template)
|
||||
{
|
||||
writer.WriteStartObject();
|
||||
writer.WriteString("id", template.Id);
|
||||
writer.WriteString("authorityRouteId", template.AuthorityRouteId);
|
||||
|
||||
if (template.RequireMfa)
|
||||
{
|
||||
writer.WriteBoolean("requireMfa", true);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(template.Description))
|
||||
{
|
||||
writer.WriteString("description", template.Description);
|
||||
}
|
||||
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user