From 2bb56f1b81a84df3ef03ba0170f741cea6007c28 Mon Sep 17 00:00:00 2001 From: Lars-Erik Date: Thu, 4 Apr 2024 13:44:20 +0200 Subject: [PATCH 1/5] Implementors using Umbraco.Tests.Integration won't have to override GetLocalizedTextService (cherry picked from commit b0016687eb583a549da8992f5fba92e269b4cbfa) --- .../DependencyInjection/UmbracoBuilderExtensions.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs b/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs index dac260b985..bae9c7efbe 100644 --- a/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs +++ b/tests/Umbraco.Tests.Integration/DependencyInjection/UmbracoBuilderExtensions.cs @@ -123,7 +123,18 @@ public static class UmbracoBuilderExtensions var currFolder = new DirectoryInfo(srcFolder); - var uiProject = currFolder.GetDirectories("Umbraco.Web.UI", SearchOption.TopDirectoryOnly).First(); + if (!currFolder.Exists) + { + currFolder = new DirectoryInfo(Path.GetTempPath()); + } + + var uiProject = currFolder.GetDirectories("Umbraco.Web.UI", SearchOption.TopDirectoryOnly).FirstOrDefault(); + if (uiProject == null) + { + uiProject = new DirectoryInfo(Path.Combine(Path.GetTempPath(), "Umbraco.Web.UI")); + uiProject.Create(); + } + var mainLangFolder = new DirectoryInfo(Path.Combine(uiProject.FullName, globalSettings.Value.UmbracoPath.TrimStart("~/"), "config", "lang")); return new LocalizedTextServiceFileSources( From 096991ac794ec22f4b76b66e91e603e66a88711c Mon Sep 17 00:00:00 2001 From: Mole Date: Tue, 16 Apr 2024 14:36:02 +0200 Subject: [PATCH 2/5] V13: Add webhook information to detailed telemetry (#16060) * Cleanup ReportSiteJob * Report on registered webhook event types * Report on custom header webhook count * Use constants instead of magic strings * Update tests * Update translation files --- src/Umbraco.Core/Constants-Telemetry.cs | 4 ++ .../EmbeddedResources/Lang/en.xml | 2 +- .../EmbeddedResources/Lang/en_us.xml | 4 +- .../BackgroundJobs/Jobs/ReportSiteJob.cs | 21 ++++++---- .../UmbracoBuilder.TelemetryProviders.cs | 1 + .../Providers/WebhookTelemetryProvider.cs | 41 +++++++++++++++++++ .../Telemetry/TelemetryServiceTests.cs | 18 +++++--- 7 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 src/Umbraco.Infrastructure/Telemetry/Providers/WebhookTelemetryProvider.cs diff --git a/src/Umbraco.Core/Constants-Telemetry.cs b/src/Umbraco.Core/Constants-Telemetry.cs index 52bf5d108f..b5c1e15c94 100644 --- a/src/Umbraco.Core/Constants-Telemetry.cs +++ b/src/Umbraco.Core/Constants-Telemetry.cs @@ -32,5 +32,9 @@ public static partial class Constants public static string BackofficeExternalLoginProviderCount = "BackofficeExternalLoginProviderCount"; public static string DeliverApiEnabled = "DeliverApiEnabled"; public static string DeliveryApiPublicAccess = "DeliveryApiPublicAccess"; + public static string WebhookPrefix = "WebhookCount_"; + public static string WebhookTotal = $"{WebhookPrefix}Total"; + public static string WebhookCustomHeaders = $"{WebhookPrefix}CustomHeaders"; + public static string WebhookCustomEvent = $"{WebhookPrefix}CustomEvent"; } } diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml index b344ed784a..5559768c67 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml @@ -3077,7 +3077,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont
  • Anonymized site ID, Umbraco version, and packages installed.
  • -
  • Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, and Property Editors in use.
  • +
  • Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, and Property Editors in use.
  • System information: Webserver, server OS, server framework, server OS language, and database provider.
  • Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.
  • diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml index 58a6f8b704..35dfc458ce 100644 --- a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml +++ b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml @@ -2035,7 +2035,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont Webhook key Retry count Toggle debug mode for more information. - Not OK status code + Not OK status code The url to call when the webhook is triggered. The events for which the webhook should be triggered. Only trigger the webhook for a specific content type. @@ -3096,7 +3096,7 @@ To manage your website, simply open the Umbraco backoffice and start adding cont We will send:
    • Anonymized site ID, Umbraco version, and packages installed.
    • -
    • Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, and Property Editors in use.
    • +
    • Number of: Root nodes, Content nodes, Macros, Media, Document Types, Templates, Languages, Domains, User Group, Users, Members, Backoffice external login providers, Webhooks, and Property Editors in use.
    • System information: Webserver, server OS, server framework, server OS language, and database provider.
    • Configuration settings: Modelsbuilder mode, if custom Umbraco path exists, ASP environment, whether the delivery API is enabled, and allows public access, and if you are in debug mode.
    diff --git a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ReportSiteJob.cs b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ReportSiteJob.cs index 5d39b57add..64d827a225 100644 --- a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ReportSiteJob.cs +++ b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ReportSiteJob.cs @@ -17,18 +17,24 @@ namespace Umbraco.Cms.Infrastructure.BackgroundJobs.Jobs; public class ReportSiteJob : IRecurringBackgroundJob { - public TimeSpan Period { get => TimeSpan.FromDays(1); } - public TimeSpan Delay { get => TimeSpan.FromMinutes(5); } - public ServerRole[] ServerRoles { get => Enum.GetValues(); } + public TimeSpan Period => TimeSpan.FromDays(1); + + public TimeSpan Delay => TimeSpan.FromMinutes(5); + + public ServerRole[] ServerRoles => Enum.GetValues(); // No-op event as the period never changes on this job - public event EventHandler PeriodChanged { add { } remove { } } - + public event EventHandler PeriodChanged + { + add { } remove { } + } private static HttpClient _httpClient = new(); + private readonly ILogger _logger; + private readonly ITelemetryService _telemetryService; - + public ReportSiteJob( ILogger logger, @@ -43,9 +49,8 @@ public class ReportSiteJob : IRecurringBackgroundJob /// Runs the background task to send the anonymous ID /// to telemetry service /// - public async Task RunJobAsync() + public async Task RunJobAsync() { - if (_telemetryService.TryGetTelemetryReportData(out TelemetryReportData? telemetryReportData) is false) { _logger.LogWarning("No telemetry marker found"); diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.TelemetryProviders.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.TelemetryProviders.cs index 0a89c20d2f..69ee653c19 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.TelemetryProviders.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.TelemetryProviders.cs @@ -20,6 +20,7 @@ public static class UmbracoBuilder_TelemetryProviders builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); + builder.Services.AddTransient(); return builder; } } diff --git a/src/Umbraco.Infrastructure/Telemetry/Providers/WebhookTelemetryProvider.cs b/src/Umbraco.Infrastructure/Telemetry/Providers/WebhookTelemetryProvider.cs new file mode 100644 index 0000000000..9aa5ae74c6 --- /dev/null +++ b/src/Umbraco.Infrastructure/Telemetry/Providers/WebhookTelemetryProvider.cs @@ -0,0 +1,41 @@ +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Infrastructure.Telemetry.Interfaces; + +namespace Umbraco.Cms.Infrastructure.Telemetry.Providers; + +public class WebhookTelemetryProvider : IDetailedTelemetryProvider +{ + private readonly IWebhookService _webhookService; + + public WebhookTelemetryProvider(IWebhookService webhookService) => _webhookService = webhookService; + + private readonly string[] _defaultEventTypes = + [ + "Umbraco.ContentDelete", + "Umbraco.ContentPublish", + "Umbraco.ContentUnpublish", + "Umbraco.MediaDelete", + "Umbraco.MediaSave" + ]; + + public IEnumerable GetInformation() + { + IWebhook[] allWebhooks = _webhookService.GetAllAsync(0, int.MaxValue).GetAwaiter().GetResult().Items.ToArray(); + + yield return new UsageInformation(Constants.Telemetry.WebhookTotal, allWebhooks.Length); + + foreach (var eventType in _defaultEventTypes) + { + IWebhook[] webhooks = allWebhooks.Where(x => x.Events.Contains(eventType)).ToArray(); + yield return new UsageInformation($"{Constants.Telemetry.WebhookPrefix}{eventType}", webhooks.Length); + } + + IEnumerable customWebhooks = allWebhooks.Where(x => x.Events.Except(_defaultEventTypes).Any()); + yield return new UsageInformation(Constants.Telemetry.WebhookCustomEvent, customWebhooks.Count()); + + IEnumerable customHeaderWebhooks = allWebhooks.Where(x => x.Headers.Any()); + yield return new UsageInformation(Constants.Telemetry.WebhookCustomHeaders, customHeaderWebhooks.Count()); + } +} diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Core/Telemetry/TelemetryServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Core/Telemetry/TelemetryServiceTests.cs index c92416402f..e5691c15cb 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Core/Telemetry/TelemetryServiceTests.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Core/Telemetry/TelemetryServiceTests.cs @@ -1,12 +1,11 @@ -using System.Linq; using Microsoft.Extensions.DependencyInjection; using NUnit.Framework; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Configuration.Models; -using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Telemetry; +using Umbraco.Cms.Core.Webhooks; using Umbraco.Cms.Tests.Common.Testing; using Umbraco.Cms.Tests.Integration.Testing; @@ -20,12 +19,15 @@ public class TelemetryServiceTests : UmbracoIntegrationTest builder.Services.Configure(options => options.Id = Guid.NewGuid().ToString()); private ITelemetryService TelemetryService => GetRequiredService(); + private IMetricsConsentService MetricsConsentService => GetRequiredService(); + private WebhookEventCollection WebhookEventCollection => GetRequiredService(); + [Test] public void Expected_Detailed_Telemetry_Exists() { - var expectedData = new[] + var expectedData = new List { Constants.Telemetry.RootCount, Constants.Telemetry.DomainCount, @@ -52,9 +54,15 @@ public class TelemetryServiceTests : UmbracoIntegrationTest Constants.Telemetry.BackofficeExternalLoginProviderCount, Constants.Telemetry.RuntimeMode, Constants.Telemetry.DeliverApiEnabled, - Constants.Telemetry.DeliveryApiPublicAccess + Constants.Telemetry.DeliveryApiPublicAccess, + Constants.Telemetry.WebhookTotal, + Constants.Telemetry.WebhookCustomHeaders, + Constants.Telemetry.WebhookCustomEvent, }; + // Add the default webhook events. + expectedData.AddRange(WebhookEventCollection.Select(eventInfo => $"{Constants.Telemetry.WebhookPrefix}{eventInfo.Alias}")); + MetricsConsentService.SetConsentLevel(TelemetryLevel.Detailed); var success = TelemetryService.TryGetTelemetryReportData(out var telemetryReportData); var detailed = telemetryReportData.Detailed.ToArray(); @@ -63,7 +71,7 @@ public class TelemetryServiceTests : UmbracoIntegrationTest Assert.Multiple(() => { Assert.IsNotNull(detailed); - Assert.AreEqual(expectedData.Length, detailed.Length); + Assert.AreEqual(expectedData.Count, detailed.Length); foreach (var expectedInfo in expectedData) { From 0993a61d391f481c0745f1db28087b08881a3e7f Mon Sep 17 00:00:00 2001 From: Zeegaan Date: Wed, 17 Apr 2024 08:07:01 +0200 Subject: [PATCH 3/5] dont depend on e2e --- build/azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/azure-pipelines.yml b/build/azure-pipelines.yml index 8facd5b5cf..e67a3c08f2 100644 --- a/build/azure-pipelines.yml +++ b/build/azure-pipelines.yml @@ -715,7 +715,7 @@ stages: dependsOn: - Unit - Integration - - E2E +# - E2E condition: and(succeeded(), or(eq(dependencies.Build.outputs['A.build.NBGV_PublicRelease'], 'True'), ${{parameters.myGetDeploy}})) jobs: - job: From 8a15c14e7052016b93957e2cddb6c4a6cbe5e6b5 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Wed, 17 Apr 2024 11:21:17 +0200 Subject: [PATCH 4/5] update backoffice submodule --- src/Umbraco.Web.UI.Client | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client b/src/Umbraco.Web.UI.Client index b245fa90ac..ecbf7cc4c0 160000 --- a/src/Umbraco.Web.UI.Client +++ b/src/Umbraco.Web.UI.Client @@ -1 +1 @@ -Subproject commit b245fa90acaa4059ce9ed8ceb8f4d3a4962ecd23 +Subproject commit ecbf7cc4c08a93ec63c60f35721ef3be0c7bdd19 From 8b0bf9da27b427d131bcdc817751a3205331d144 Mon Sep 17 00:00:00 2001 From: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> Date: Thu, 18 Apr 2024 09:01:17 +0200 Subject: [PATCH 5/5] bump version --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 5ddc3e1cc6..5b6736ddb4 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "14.0.0-rc1", + "version": "14.0.0-rc2", "assemblyVersion": { "precision": "build" },