up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Symbols Server CI / symbols-smoke (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
Symbols Server CI / symbols-smoke (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
This commit is contained in:
@@ -1,28 +1,42 @@
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Nodes;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using StellaOps.Notifier.WebService.Contracts;
|
||||
using StellaOps.Notifier.WebService.Setup;
|
||||
using StellaOps.Notify.Storage.Mongo;
|
||||
using StellaOps.Notify.Storage.Mongo.Documents;
|
||||
using StellaOps.Notify.Storage.Mongo.Repositories;
|
||||
using StellaOps.Notify.Models;
|
||||
using StellaOps.Notify.Queue;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
var isTesting = builder.Environment.IsEnvironment("Testing");
|
||||
|
||||
builder.Configuration
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddEnvironmentVariables(prefix: "NOTIFIER_");
|
||||
|
||||
var mongoSection = builder.Configuration.GetSection("notifier:storage:mongo");
|
||||
builder.Services.AddNotifyMongoStorage(mongoSection);
|
||||
// OpenAPI cache resolved inline for simplicity in tests
|
||||
builder.Services.AddSingleton<TimeProvider>(TimeProvider.System);
|
||||
|
||||
if (!isTesting)
|
||||
{
|
||||
var mongoSection = builder.Configuration.GetSection("notifier:storage:mongo");
|
||||
builder.Services.AddNotifyMongoStorage(mongoSection);
|
||||
builder.Services.AddHostedService<MongoInitializationHostedService>();
|
||||
builder.Services.AddHostedService<PackApprovalTemplateSeeder>();
|
||||
}
|
||||
|
||||
// Fallback no-op event queue for environments that do not configure a real backend.
|
||||
builder.Services.TryAddSingleton<INotifyEventQueue, NullNotifyEventQueue>();
|
||||
|
||||
builder.Services.AddHealthChecks();
|
||||
builder.Services.AddHostedService<MongoInitializationHostedService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
@@ -48,6 +62,7 @@ app.MapPost("/api/v1/notify/pack-approvals", async (
|
||||
INotifyLockRepository locks,
|
||||
INotifyPackApprovalRepository packApprovals,
|
||||
INotifyAuditRepository audit,
|
||||
INotifyEventQueue? eventQueue,
|
||||
TimeProvider timeProvider) =>
|
||||
{
|
||||
var tenantId = context.Request.Headers["X-StellaOps-Tenant"].ToString();
|
||||
@@ -112,6 +127,38 @@ app.MapPost("/api/v1/notify/pack-approvals", async (
|
||||
};
|
||||
|
||||
await audit.AppendAsync(auditEntry, context.RequestAborted).ConfigureAwait(false);
|
||||
|
||||
if (eventQueue is not null)
|
||||
{
|
||||
var payload = JsonSerializer.SerializeToNode(new
|
||||
{
|
||||
request.PackId,
|
||||
request.Kind,
|
||||
request.Decision,
|
||||
request.Policy,
|
||||
request.ResumeToken,
|
||||
request.Summary,
|
||||
request.Labels
|
||||
}) ?? new JsonObject();
|
||||
|
||||
var notifyEvent = NotifyEvent.Create(
|
||||
eventId: request.EventId != Guid.Empty ? request.EventId : Guid.NewGuid(),
|
||||
kind: request.Kind ?? "pack.approval",
|
||||
tenant: tenantId,
|
||||
ts: request.IssuedAt != default ? request.IssuedAt : timeProvider.GetUtcNow(),
|
||||
payload: payload,
|
||||
actor: request.Actor,
|
||||
version: "1");
|
||||
|
||||
await eventQueue.PublishAsync(
|
||||
new NotifyQueueEventMessage(
|
||||
notifyEvent,
|
||||
stream: "notify:events",
|
||||
idempotencyKey: lockKey,
|
||||
partitionKey: tenantId,
|
||||
traceId: context.TraceIdentifier),
|
||||
context.RequestAborted).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -177,7 +224,23 @@ app.MapPost("/api/v1/notify/pack-approvals/{packId}/ack", async (
|
||||
return Results.NoContent();
|
||||
});
|
||||
|
||||
app.MapGet("/.well-known/openapi", () => Results.Content("# notifier openapi stub\nopenapi: 3.1.0\npaths: {}", "application/yaml"));
|
||||
app.MapGet("/.well-known/openapi", (HttpContext context) =>
|
||||
{
|
||||
context.Response.Headers["X-OpenAPI-Scope"] = "notify";
|
||||
context.Response.Headers.ETag = "\"notifier-oas-stub\"";
|
||||
|
||||
const string stub = """
|
||||
# notifier openapi stub
|
||||
openapi: 3.1.0
|
||||
info:
|
||||
title: StellaOps Notifier
|
||||
paths:
|
||||
/api/v1/notify/quiet-hours: {}
|
||||
/api/v1/notify/incidents: {}
|
||||
""";
|
||||
|
||||
return Results.Text(stub, "application/yaml", Encoding.UTF8);
|
||||
});
|
||||
|
||||
static object Error(string code, string message, HttpContext context) => new
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user