Skip to content

Commit

Permalink
feat: add applicationbuilder endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
ArneD committed Jan 8, 2025
1 parent a6abf76 commit f2908d0
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Be.Vlaanderen.Basisregisters.Projector.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UseConfigureAwaitFalse/@EntryIndexedValue">ERROR</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">True</s:Boolean>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="aa_bb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"&gt;&lt;ElementKinds&gt;&lt;Kind Name="NAMESPACE" /&gt;&lt;Kind Name="CLASS" /&gt;&lt;Kind Name="STRUCT" /&gt;&lt;Kind Name="ENUM" /&gt;&lt;Kind Name="DELEGATE" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"&gt;&lt;ExtraRule Prefix="" Suffix="" Style="aa_bb" /&gt;&lt;/Policy&gt;&lt;/Policy&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/Editor/UseCamelHumps/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/ExternalSources/PdbNavigation/UseSymbolFiles/@EntryValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Backoff/@EntryIndexedValue">True</s:Boolean>
</wpf:ResourceDictionary>
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
namespace Be.Vlaanderen.Basisregisters.Projector
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using ConnectedProjections;
using Controllers;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using SqlStreamStore;

public static class ApplicationBuilderExtensions
{
public static IApplicationBuilder UseProjectorEndpoints(
this IApplicationBuilder builder,
string baseUrl,
JsonSerializerSettings? jsonSerializerSettings)
{
ArgumentNullException.ThrowIfNull(baseUrl);

builder.UseEndpoints(endpoints =>
{
endpoints.MapGet("/v1/projections", async context => { await GetProjections(builder, context, baseUrl, jsonSerializerSettings).NoContext(); });
endpoints.MapGet("/projections", async context => { await GetProjections(builder, context, baseUrl, jsonSerializerSettings).NoContext(); });

endpoints.MapPost("/projections/start/all", async context => { await StartAll(builder, context).NoContext(); });
endpoints.MapPost("/v1/projections/start/all", async context => { await StartAll(builder, context).NoContext(); });

endpoints.MapPost("/projections/start/{projectionId}", async context
=> await StartProjection(builder, context.Request.RouteValues["projectionId"].ToString(), context).NoContext());
endpoints.MapPost("/v1/projections/start/{projectionId}", async context
=> await StartProjection(builder, context.Request.RouteValues["projectionId"].ToString(), context).NoContext());

endpoints.MapPost("/projections/stop/all", async context => { await StopAll(builder, context).NoContext(); });
endpoints.MapPost("/v1/projections/stop/all", async context => { await StopAll(builder, context).NoContext(); });

endpoints.MapPost("/projections/stop/{projectionId}", async context
=> await StopProjection(builder, context.Request.RouteValues["projectionId"].ToString(), context).NoContext());
endpoints.MapPost("/v1/projections/stop/{projectionId}", async context
=> await StopProjection(builder, context.Request.RouteValues["projectionId"].ToString(), context).NoContext());
});

return builder;
}

private static async Task StopProjection(IApplicationBuilder app, string? projectionId, HttpContext context)
{
var manager = app.ApplicationServices.GetRequiredService<IConnectedProjectionsManager>();
if (!manager.Exists(projectionId))
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync("Invalid projection Id.").NoContext();
return;
}

await manager.Stop(projectionId, CancellationToken.None).NoContext();

context.Response.StatusCode = StatusCodes.Status202Accepted;
}

private static async Task StopAll(IApplicationBuilder app, HttpContext context)
{
var manager = app.ApplicationServices.GetRequiredService<IConnectedProjectionsManager>();
await manager.Stop(CancellationToken.None).NoContext();

context.Response.StatusCode = StatusCodes.Status202Accepted;
}

private static async Task StartProjection(IApplicationBuilder app, string? projectionId, HttpContext context)
{
var manager = app.ApplicationServices.GetRequiredService<IConnectedProjectionsManager>();
if (!manager.Exists(projectionId))
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
await context.Response.WriteAsync("Invalid projection Id.").NoContext();
return;
}

await manager.Start(projectionId, CancellationToken.None).NoContext();

context.Response.StatusCode = StatusCodes.Status202Accepted;
}

private static async Task StartAll(IApplicationBuilder app, HttpContext context)
{
var manager = app.ApplicationServices.GetRequiredService<IConnectedProjectionsManager>();
await manager.Start(CancellationToken.None).NoContext();

context.Response.StatusCode = StatusCodes.Status202Accepted;
}

private static async Task GetProjections(
IApplicationBuilder app,
HttpContext context,
string baseUrl,
JsonSerializerSettings? jsonSerializerSettings = null)
{
var manager = app.ApplicationServices.GetRequiredService<IConnectedProjectionsManager>();
var streamStore = app.ApplicationServices.GetRequiredService<IStreamStore>();

var registeredConnectedProjections = manager
.GetRegisteredProjections()
.ToList();
var projectionStates = await manager.GetProjectionStates(CancellationToken.None).NoContext();
var responses = registeredConnectedProjections.Aggregate(
new List<ProjectionResponse>(),
(list, projection) =>
{
var projectionState = projectionStates.SingleOrDefault(x => x.Name == projection.Id);
list.Add(new ProjectionResponse(
projection,
projectionState,
baseUrl));
return list;
});

var streamPosition = await streamStore.ReadHeadPosition().NoContext();

var projectionResponseList = new ProjectionResponseList(responses, baseUrl)
{
StreamPosition = streamPosition
};

var json = JsonConvert.SerializeObject(projectionResponseList, jsonSerializerSettings ?? new JsonSerializerSettings());

context.Response.Headers.ContentType = MediaTypeNames.Application.Json;
await context.Response.WriteAsync(json).NoContext();
}
}
}

0 comments on commit f2908d0

Please sign in to comment.