From 394a061a696ac32ceaf5b752aa263a9a804c34cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ole=20J=C3=B8rgen=20Skogstad?= Date: Tue, 7 Jan 2025 14:44:51 +0100 Subject: [PATCH] fix patch --- docs/schema/V1/swagger.verified.json | 7 ++++- .../CreateDialogTransmissionEndpoint.cs | 1 - .../Dialogs/Patch/PatchDialogsController.cs | 1 + .../Patch/ProducesResponseHeaderAttribute.cs | 16 ++++++++++ ...roducesResponseHeaderOperationProcessor.cs | 29 +++++++++++++++++++ .../Program.cs | 5 +++- 6 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/ProducesResponseHeaderAttribute.cs create mode 100644 src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/ProducesResponseHeaderOperationProcessor.cs diff --git a/docs/schema/V1/swagger.verified.json b/docs/schema/V1/swagger.verified.json index e9b137db6..9fe8192a6 100644 --- a/docs/schema/V1/swagger.verified.json +++ b/docs/schema/V1/swagger.verified.json @@ -6086,7 +6086,12 @@ }, "responses": { "204": { - "description": "Patch was successfully applied." + "description": "Patch was successfully applied.", + "headers": { + "Etag": { + "description": "The new UUID ETag of the dialog" + } + } }, "400": { "content": { diff --git a/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/DialogTransmissions/Create/CreateDialogTransmissionEndpoint.cs b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/DialogTransmissions/Create/CreateDialogTransmissionEndpoint.cs index 2a8b01db4..27623c061 100644 --- a/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/DialogTransmissions/Create/CreateDialogTransmissionEndpoint.cs +++ b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/DialogTransmissions/Create/CreateDialogTransmissionEndpoint.cs @@ -4,7 +4,6 @@ using Digdir.Domain.Dialogporten.WebApi.Common.Authorization; using Digdir.Domain.Dialogporten.WebApi.Common.Extensions; using Digdir.Domain.Dialogporten.WebApi.Endpoints.V1.Common.Extensions; -using Digdir.Domain.Dialogporten.WebApi.Endpoints.V1.Common.Headers; using Digdir.Domain.Dialogporten.WebApi.Endpoints.V1.ServiceOwner.DialogTransmissions.Get; using Digdir.Library.Entity.Abstractions.Features.Identifiable; using FastEndpoints; diff --git a/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/PatchDialogsController.cs b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/PatchDialogsController.cs index f444d72ab..f56fbb7ef 100644 --- a/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/PatchDialogsController.cs +++ b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/PatchDialogsController.cs @@ -60,6 +60,7 @@ public PatchDialogsController(ISender sender, IMapper mapper) [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status412PreconditionFailed)] [ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status422UnprocessableEntity)] + [ProducesResponseHeader(StatusCodes.Status204NoContent, Constants.ETag, "The new UUID ETag of the dialog")] public async Task Patch( [FromRoute] Guid dialogId, [FromHeader(Name = Constants.IfMatch)] Guid? etag, diff --git a/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/ProducesResponseHeaderAttribute.cs b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/ProducesResponseHeaderAttribute.cs new file mode 100644 index 000000000..77e2d3e12 --- /dev/null +++ b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/ProducesResponseHeaderAttribute.cs @@ -0,0 +1,16 @@ +namespace Digdir.Domain.Dialogporten.WebApi.Endpoints.V1.ServiceOwner.Dialogs.Patch; + +[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] +public sealed class ProducesResponseHeaderAttribute : Attribute +{ + public ProducesResponseHeaderAttribute(int statusCode, string headerName, string description) + { + HeaderName = headerName; + StatusCode = statusCode; + Description = description; + } + + public string HeaderName { get; } + public int StatusCode { get; } + public string Description { get; } +} diff --git a/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/ProducesResponseHeaderOperationProcessor.cs b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/ProducesResponseHeaderOperationProcessor.cs new file mode 100644 index 000000000..26ec4387e --- /dev/null +++ b/src/Digdir.Domain.Dialogporten.WebApi/Endpoints/V1/ServiceOwner/Dialogs/Patch/ProducesResponseHeaderOperationProcessor.cs @@ -0,0 +1,29 @@ +using System.Globalization; +using System.Reflection; +using NSwag; +using NSwag.Generation.Processors; +using NSwag.Generation.Processors.Contexts; + +namespace Digdir.Domain.Dialogporten.WebApi.Endpoints.V1.ServiceOwner.Dialogs.Patch; + +public sealed class ProducesResponseHeaderOperationProcessor : IOperationProcessor +{ + public bool Process(OperationProcessorContext context) + { + var headerAttribute = context.MethodInfo.GetCustomAttribute(); + if (headerAttribute == null) + { + return true; + } + + var statusCode = headerAttribute.StatusCode.ToString(CultureInfo.InvariantCulture); + var response = context.OperationDescription.Operation.Responses[statusCode]; + var header = new OpenApiHeader + { + Description = headerAttribute.Description, + }; + + response.Headers.Add(headerAttribute.HeaderName, header); + return true; + } +} diff --git a/src/Digdir.Domain.Dialogporten.WebApi/Program.cs b/src/Digdir.Domain.Dialogporten.WebApi/Program.cs index 6b58f6b5a..b9c5c24de 100644 --- a/src/Digdir.Domain.Dialogporten.WebApi/Program.cs +++ b/src/Digdir.Domain.Dialogporten.WebApi/Program.cs @@ -9,12 +9,12 @@ using Digdir.Domain.Dialogporten.Application.Externals.Presentation; using Digdir.Domain.Dialogporten.WebApi.Common.Extensions; using Digdir.Domain.Dialogporten.Infrastructure; -using Digdir.Domain.Dialogporten.WebApi; using Digdir.Domain.Dialogporten.WebApi.Common; using Digdir.Domain.Dialogporten.WebApi.Common.Authentication; using Digdir.Domain.Dialogporten.WebApi.Common.Authorization; using Digdir.Domain.Dialogporten.WebApi.Common.Json; using Digdir.Domain.Dialogporten.WebApi.Common.Swagger; +using Digdir.Domain.Dialogporten.WebApi.Endpoints.V1.ServiceOwner.Dialogs.Patch; using Digdir.Library.Utils.AspNet; using FastEndpoints; using FastEndpoints.Swagger; @@ -125,6 +125,9 @@ static void BuildAndRun(string[] args, TelemetryConfiguration telemetryConfigura // generic "2" suffix duplicate names get, so we add a "SO" suffix to the serviceowner specific schemas. // This should match the operationIds used for service owners. s.AddServiceOwnerSuffixToSchemas(); + + // Adding ResponseHeaders for PATCH MVC controller + s.OperationProcessors.Add(new ProducesResponseHeaderOperationProcessor()); }; }) .AddControllers(options => options.InputFormatters.Insert(0, JsonPatchInputFormatter.Get()))