V15: Add webhooklogs endpoint (#17838)

* Add webhook logs endpoint

* Add attribute routing

* Add to open api json
This commit is contained in:
Nikolaj Geisle
2025-01-07 11:18:32 +01:00
committed by GitHub
parent e4c5da18d5
commit 66f2b60141
6 changed files with 187 additions and 5 deletions

View File

@@ -0,0 +1,34 @@
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Factories;
using Umbraco.Cms.Api.Management.ViewModels.Webhook;
using Umbraco.Cms.Api.Management.ViewModels.Webhook.Logs;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
namespace Umbraco.Cms.Api.Management.Controllers.Webhook.Logs;
[ApiVersion("1.0")]
public class AllWebhookLogController : WebhookLogControllerBase
{
private readonly IWebhookLogService _webhookLogService;
private readonly IWebhookPresentationFactory _webhookPresentationFactory;
public AllWebhookLogController(IWebhookLogService webhookLogService, IWebhookPresentationFactory webhookPresentationFactory)
{
_webhookLogService = webhookLogService;
_webhookPresentationFactory = webhookPresentationFactory;
}
[HttpGet("logs")]
[MapToApiVersion("1.0")]
[ProducesResponseType(typeof(WebhookResponseModel), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
public async Task<IActionResult> Logs(CancellationToken cancellationToken, int skip = 0, int take = 100)
{
PagedModel<WebhookLog> logs = await _webhookLogService.Get(skip, take);
IEnumerable<WebhookLogResponseModel> logResponseModels = logs.Items.Select(x => _webhookPresentationFactory.CreateResponseModel(x));
return Ok(logResponseModels);
}
}

View File

@@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Api.Management.Routing;
using Umbraco.Cms.Core;
namespace Umbraco.Cms.Api.Management.Controllers.Webhook.Logs;
[VersionedApiBackOfficeRoute($"{Constants.UdiEntityType.Webhook}")]
[ApiExplorerSettings(GroupName = "Webhook")]
public class WebhookLogControllerBase : ManagementApiControllerBase;

View File

@@ -1,6 +1,6 @@
using Umbraco.Cms.Api.Management.ViewModels.Webhook;
using Umbraco.Cms.Api.Management.ViewModels.Webhook.Logs;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Web.Common.Models;
namespace Umbraco.Cms.Api.Management.Factories;
@@ -11,4 +11,6 @@ public interface IWebhookPresentationFactory
IWebhook CreateWebhook(CreateWebhookRequestModel webhookRequestModel);
IWebhook CreateWebhook(UpdateWebhookRequestModel webhookRequestModel, Guid existingWebhookKey);
WebhookLogResponseModel CreateResponseModel(WebhookLog webhookLog) => new();
}

View File

@@ -1,6 +1,9 @@
using Umbraco.Cms.Api.Management.ViewModels.Webhook;
using Umbraco.Cms.Api.Management.ViewModels.Webhook.Logs;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Webhooks;
namespace Umbraco.Cms.Api.Management.Factories;
@@ -8,8 +11,18 @@ namespace Umbraco.Cms.Api.Management.Factories;
internal class WebhookPresentationFactory : IWebhookPresentationFactory
{
private readonly WebhookEventCollection _webhookEventCollection;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly ILocalizedTextService _localizedTextService;
public WebhookPresentationFactory(WebhookEventCollection webhookEventCollection) => _webhookEventCollection = webhookEventCollection;
public WebhookPresentationFactory(
WebhookEventCollection webhookEventCollection,
IHostingEnvironment hostingEnvironment,
ILocalizedTextService localizedTextService)
{
_webhookEventCollection = webhookEventCollection;
_hostingEnvironment = hostingEnvironment;
_localizedTextService = localizedTextService;
}
public WebhookResponseModel CreateResponseModel(IWebhook webhook)
{
@@ -44,6 +57,34 @@ internal class WebhookPresentationFactory : IWebhookPresentationFactory
return target;
}
public WebhookLogResponseModel CreateResponseModel(WebhookLog webhookLog)
{
var webhookLogResponseModel = new WebhookLogResponseModel
{
Date = webhookLog.Date, EventAlias = webhookLog.EventAlias, Key = webhookLog.Key, RequestBody = webhookLog.RequestBody ?? string.Empty,
RetryCount = webhookLog.RetryCount,
Url = webhookLog.Url,
RequestHeaders = webhookLog.RequestHeaders,
WebhookKey = webhookLog.WebhookKey,
IsSuccessStatusCode = webhookLog.IsSuccessStatusCode
};
if (_hostingEnvironment.IsDebugMode)
{
webhookLogResponseModel.ExceptionOccured = webhookLog.ExceptionOccured;
webhookLogResponseModel.ResponseBody = webhookLog.ResponseBody;
webhookLogResponseModel.ResponseHeaders = webhookLog.ResponseHeaders;
webhookLogResponseModel.StatusCode = webhookLog.StatusCode;
}
else
{
webhookLogResponseModel.ResponseBody = _localizedTextService.Localize("webhooks", "toggleDebug", Thread.CurrentThread.CurrentUICulture);
webhookLogResponseModel.StatusCode = webhookLog.StatusCode is "OK (200)" ? webhookLog.StatusCode : _localizedTextService.Localize("webhooks", "statusNotOk", Thread.CurrentThread.CurrentUICulture);
}
return webhookLogResponseModel;
}
private WebhookEventResponseModel Create(string alias)
{
IWebhookEvent? webhookEvent = _webhookEventCollection.FirstOrDefault(x => x.Alias == alias);

View File

@@ -33875,6 +33875,72 @@
}
]
}
},
"/umbraco/management/api/v1/webhook/logs": {
"get": {
"tags": [
"Webhook"
],
"operationId": "GetWebhookLogs",
"parameters": [
{
"name": "skip",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 0
}
},
{
"name": "take",
"in": "query",
"schema": {
"type": "integer",
"format": "int32",
"default": 100
}
}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/WebhookResponseModel"
}
]
}
}
}
},
"404": {
"description": "Not Found",
"content": {
"application/json": {
"schema": {
"oneOf": [
{
"$ref": "#/components/schemas/ProblemDetails"
}
]
}
}
}
},
"401": {
"description": "The resource is protected and requires an authentication token"
}
},
"security": [
{
"Backoffice User": [ ]
}
]
}
}
},
"components": {
@@ -38339,8 +38405,8 @@
"enum": [
"Healthy",
"Unhealthy",
"Corrupt",
"Rebuilding"
"Rebuilding",
"Corrupt"
],
"type": "string"
},
@@ -46100,4 +46166,4 @@
}
}
}
}
}

View File

@@ -0,0 +1,30 @@
namespace Umbraco.Cms.Api.Management.ViewModels.Webhook.Logs;
public class WebhookLogResponseModel
{
public Guid Key { get; set; }
public Guid WebhookKey { get; set; }
public string StatusCode { get; set; } = string.Empty;
public bool IsSuccessStatusCode { get; set; }
public DateTime Date { get; set; }
public string EventAlias { get; set; } = string.Empty;
public string Url { get; set; } = string.Empty;
public int RetryCount { get; set; }
public string RequestHeaders { get; set; } = string.Empty;
public string RequestBody { get; set; } = string.Empty;
public string ResponseHeaders { get; set; } = string.Empty;
public string ResponseBody { get; set; } = string.Empty;
public bool ExceptionOccured { get; set; }
}