Skip to content

Commit

Permalink
Output notification handler messages as a header (#15786)
Browse files Browse the repository at this point in the history
* Output notification handler messages as a header

* Make the notification contract public

* Moved the Notification type and added it to swagger schema

* Update swagger docs

---------

Co-authored-by: Bjarke Berg <mail@bergmania.dk>
  • Loading branch information
kjac and bergmania committed Feb 28, 2024
1 parent 4b4b003 commit fa007ac
Show file tree
Hide file tree
Showing 7 changed files with 5,480 additions and 176 deletions.
Expand Up @@ -60,7 +60,7 @@ public void Configure(SwaggerGenOptions swaggerGenOptions)

// Sets Security requirement on backoffice apis
swaggerGenOptions.OperationFilter<BackOfficeSecurityRequirementsOperationFilter>();
swaggerGenOptions.OperationFilter<NotificationHeaderFilter>();
swaggerGenOptions.SchemaFilter<RequireNonNullablePropertiesSchemaFilter>();
}

}
Expand Up @@ -7,6 +7,7 @@
using Umbraco.Cms.Api.Common.Filters;
using Umbraco.Cms.Api.Common.Mvc.ActionResults;
using Umbraco.Cms.Api.Management.DependencyInjection;
using Umbraco.Cms.Api.Management.Filters;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Features;
using Umbraco.Cms.Core.Models.Membership;
Expand All @@ -19,6 +20,7 @@ namespace Umbraco.Cms.Api.Management.Controllers;
[Authorize(Policy = "New" + AuthorizationPolicies.UmbracoFeatureEnabled)]
[MapToApi(ManagementApiConfiguration.ApiName)]
[JsonOptionsName(Constants.JsonOptionsNames.BackOffice)]
[AppendEventMessages]
public abstract class ManagementApiControllerBase : Controller, IUmbracoFeature
{
protected IActionResult CreatedAtId<T>(Expression<Func<T, string>> action, Guid id)
Expand Down
@@ -0,0 +1,67 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Umbraco.Cms.Api.Management.ViewModels;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Serialization;

namespace Umbraco.Cms.Api.Management.Filters;

/// <summary>
/// When applied to a controller, this ensures that any event messages created during a request (e.g. by notification
/// handlers) are appended to the response in a custom header.
/// </summary>
/// <remarks>
/// GET operations are explicitly ignored by this, as they are not expected to generate event messages.
/// </remarks>
public sealed class AppendEventMessagesAttribute : TypeFilterAttribute
{
public AppendEventMessagesAttribute()
: base(typeof(AppendEventMessagesFilter))
{
}

private class AppendEventMessagesFilter : IActionFilter
{
private readonly IEventMessagesFactory _eventMessagesFactory;
private readonly IJsonSerializer _jsonSerializer;

public AppendEventMessagesFilter(IEventMessagesFactory eventMessagesFactory, IJsonSerializer jsonSerializer)
{
_eventMessagesFactory = eventMessagesFactory;
_jsonSerializer = jsonSerializer;
}

public void OnActionExecuted(ActionExecutedContext context)
{
if (context.HttpContext.Response is null)
{
return;
}

if (context.HttpContext.Request.Method == HttpMethod.Get.Method)
{
return;
}

EventMessage[]? eventMessages = _eventMessagesFactory.GetOrDefault()?.GetAll()?.ToArray();
if (eventMessages is null || eventMessages.Any() is false)
{
return;
}

var headerContent = _jsonSerializer.Serialize(eventMessages.Select(message =>
new NotificationHeaderModel
{
Message = message.Message, Category = message.Category, Type = message.MessageType
}));

context.HttpContext.Response.Headers[Constants.Headers.Notifications] = headerContent;
}

public void OnActionExecuting(ActionExecutingContext context)
{
}

}
}

0 comments on commit fa007ac

Please sign in to comment.