Refactor and enhance LDAP plugin configuration and validation
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Updated `LdapPluginOptions` to enforce TLS and client certificate requirements.
- Added validation checks for TLS configuration in `LdapPluginOptionsTests`.
- Improved error handling in `DirectoryServicesLdapConnectionFactory` for StartTLS negotiation.
- Enhanced logging in `LdapCredentialStore` to include detailed audit properties for credential verification.
- Introduced `StubStructuredRetriever` and `StubVectorRetriever` for testing in `ToolsetServiceCollectionExtensionsTests`.
- Refactored `AdvisoryGuardrailPipelineTests` to improve test clarity and structure.
- Added `FileSystemAdvisoryTaskQueueTests` for testing queue functionality.
- Updated JSON test data for consistency with new requirements.
- Modified `AdvisoryPipelineOrchestratorTests` to reflect changes in metadata keys.
This commit is contained in:
master
2025-11-05 09:29:51 +02:00
parent 3bd0955202
commit 40e7f827da
37 changed files with 744 additions and 315 deletions

View File

@@ -3,72 +3,17 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using StellaOps.AdvisoryAI.Hosting;
using StellaOps.AdvisoryAI.Orchestration;
using StellaOps.AdvisoryAI.Worker.Services;
var builder = Host.CreateApplicationBuilder(args);
builder.Configuration.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables(prefix: "ADVISORYAI_");
builder.Configuration
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables(prefix: "ADVISORYAI_");
builder.Services.AddAdvisoryAiCore(builder.Configuration);
builder.Services.AddHostedService<AdvisoryPipelineWorker>();
builder.Services.AddHostedService<AdvisoryTaskWorker>();
var host = builder.Build();
await host.RunAsync();
internal sealed class AdvisoryPipelineWorker : BackgroundService
{
private readonly IAdvisoryPipelineQueueReceiver _queue;
private readonly IAdvisoryPipelineOrchestrator _orchestrator;
private readonly AdvisoryAiMetrics _metrics;
private readonly ILogger<AdvisoryPipelineWorker> _logger;
public AdvisoryPipelineWorker(
IAdvisoryPipelineQueueReceiver queue,
IAdvisoryPipelineOrchestrator orchestrator,
AdvisoryAiMetrics metrics,
ILogger<AdvisoryPipelineWorker> logger)
{
_queue = queue ?? throw new ArgumentNullException(nameof(queue));
_orchestrator = orchestrator ?? throw new ArgumentNullException(nameof(orchestrator));
_metrics = metrics ?? throw new ArgumentNullException(nameof(metrics));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
_logger.LogInformation("Advisory AI worker started");
while (!stoppingToken.IsCancellationRequested)
{
try
{
var message = await _queue.DequeueAsync(stoppingToken).ConfigureAwait(false);
if (message is null)
{
continue;
}
_metrics.RecordProcessed(message.Request.TaskType.ToString());
_logger.LogInformation(
"Processing advisory pipeline message {CacheKey} for {Task}",
message.PlanCacheKey,
message.Request.TaskType);
// TODO: Execute prompt assembly, guardrails, and inference workflows in future tasks.
}
catch (OperationCanceledException)
{
break;
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled exception while processing advisory pipeline queue");
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken).ConfigureAwait(false);
}
}
_logger.LogInformation("Advisory AI worker stopped");
}
}