From 2a826241c81f4ea2b94eb7363b3a3697a07eab6e Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Mon, 25 Mar 2024 17:31:04 +0100 Subject: [PATCH 1/7] Remove reference to Particular.License.Sources Co-authored-by: Brandon Ording --- .../LicenseDetails.cs | 20 +++++++------- src/ServiceControl/Licensing/ActiveLicense.cs | 26 +++++-------------- .../Licensing/LicenseController.cs | 2 +- src/ServiceControl/ServiceControl.csproj | 1 - 4 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/ServiceControl.LicenseManagement/LicenseDetails.cs b/src/ServiceControl.LicenseManagement/LicenseDetails.cs index f5d0739a20..e7fa60c492 100644 --- a/src/ServiceControl.LicenseManagement/LicenseDetails.cs +++ b/src/ServiceControl.LicenseManagement/LicenseDetails.cs @@ -12,7 +12,7 @@ public class LicenseDetails public bool IsCommercialLicense { get; private set; } public bool IsExtendedTrial { get; private set; } public string LicenseType { get; private set; } - public string Edition { get; set; } + public string Edition { get; private set; } public string RegisteredTo { get; private set; } public bool ValidForServiceControl { get; private set; } public int? DaysUntilSubscriptionExpires { get; private set; } @@ -23,9 +23,12 @@ public class LicenseDetails public bool WarnUserSubscriptionHasExpired { get; private set; } public bool WarnUserUpgradeProtectionIsExpiring { get; private set; } public bool WarnUserUpgradeProtectionHasExpired { get; private set; } + public string Status { get; private set; } internal static LicenseDetails FromLicense(License license) { + LicenseStatus licenseStatus = license.GetLicenseStatus(); + var details = new LicenseDetails { UpgradeProtectionExpiration = license.UpgradeProtectionExpiration, @@ -41,10 +44,11 @@ internal static LicenseDetails FromLicense(License license) Edition = license.Edition, ValidForServiceControl = license.ValidForApplication("ServiceControl"), DaysUntilSubscriptionExpires = license.GetDaysUntilLicenseExpires(), - DaysUntilUpgradeProtectionExpires = license.GetDaysUntilUpgradeProtectionExpires() + DaysUntilUpgradeProtectionExpires = license.GetDaysUntilUpgradeProtectionExpires(), + Status = licenseStatus.ToString() }; - switch (license.GetLicenseStatus()) + switch (licenseStatus) { case LicenseStatus.Valid: break; @@ -77,15 +81,9 @@ internal static LicenseDetails FromLicense(License license) return details; } - public bool HasLicenseExpired() - { - return ExpirationDate.HasValue && HasLicenseDateExpired(ExpirationDate.Value); - } + public bool HasLicenseExpired() => ExpirationDate.HasValue && HasLicenseDateExpired(ExpirationDate.Value); - public bool ReleaseNotCoveredByMaintenance(DateTime buildTimeStamp) - { - return buildTimeStamp > UpgradeProtectionExpiration; - } + public bool ReleaseNotCoveredByMaintenance(DateTime buildTimeStamp) => buildTimeStamp > UpgradeProtectionExpiration; static bool HasLicenseDateExpired(DateTime licenseDate) { diff --git a/src/ServiceControl/Licensing/ActiveLicense.cs b/src/ServiceControl/Licensing/ActiveLicense.cs index d4a1e9bc23..e8934a46ac 100644 --- a/src/ServiceControl/Licensing/ActiveLicense.cs +++ b/src/ServiceControl/Licensing/ActiveLicense.cs @@ -1,39 +1,25 @@ namespace Particular.ServiceControl.Licensing { + using global::ServiceControl.LicenseManagement; using NServiceBus.Logging; - using Particular.Licensing; public class ActiveLicense { - public ActiveLicense() - { - Refresh(); - } + public ActiveLicense() => Refresh(); public bool IsValid { get; set; } - internal License Details { get; set; } + internal LicenseDetails Details { get; set; } public void Refresh() { Logger.Debug("Refreshing ActiveLicense"); - var sources = LicenseSource.GetStandardLicenseSources(); - var result = Particular.Licensing.ActiveLicense.Find("ServiceControl", sources.ToArray()); - - IsValid = !result.License.HasExpired(); - - if (!IsValid) - { - foreach (var report in result.Report) - { - Logger.Info(report); - } + var detectedLicense = LicenseManager.FindLicense(); - Logger.Warn("License has expired"); - } + IsValid = !detectedLicense.Details.HasLicenseExpired(); - Details = result.License; + Details = detectedLicense.Details; } static readonly ILog Logger = LogManager.GetLogger(typeof(ActiveLicense)); diff --git a/src/ServiceControl/Licensing/LicenseController.cs b/src/ServiceControl/Licensing/LicenseController.cs index 02838b4ec2..6ce8da2f17 100644 --- a/src/ServiceControl/Licensing/LicenseController.cs +++ b/src/ServiceControl/Licensing/LicenseController.cs @@ -27,7 +27,7 @@ public ActionResult License(bool refresh) Status = activeLicense.IsValid ? "valid" : "invalid", LicenseType = activeLicense.Details.LicenseType ?? string.Empty, InstanceName = settings.ServiceName ?? string.Empty, - LicenseStatus = activeLicense.Details.GetLicenseStatus().ToString() + LicenseStatus = activeLicense.Details.Status }; return licenseInfo; diff --git a/src/ServiceControl/ServiceControl.csproj b/src/ServiceControl/ServiceControl.csproj index 887099e155..a1cd1feb23 100644 --- a/src/ServiceControl/ServiceControl.csproj +++ b/src/ServiceControl/ServiceControl.csproj @@ -31,7 +31,6 @@ - From 15fe580f462fa244ea15c8bcb2ee84ad5d30c300 Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Mon, 25 Mar 2024 17:34:10 +0100 Subject: [PATCH 2/7] Remove parenthesis --- src/ServiceControl.LicenseManagement/LicenseDetails.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceControl.LicenseManagement/LicenseDetails.cs b/src/ServiceControl.LicenseManagement/LicenseDetails.cs index e7fa60c492..b9cafd317d 100644 --- a/src/ServiceControl.LicenseManagement/LicenseDetails.cs +++ b/src/ServiceControl.LicenseManagement/LicenseDetails.cs @@ -34,7 +34,7 @@ internal static LicenseDetails FromLicense(License license) UpgradeProtectionExpiration = license.UpgradeProtectionExpiration, //If expiration date is greater that 50 years treat is as no expiration date ExpirationDate = license.ExpirationDate.HasValue - ? (license.ExpirationDate.Value > DateTime.UtcNow.AddYears(50) ? null : license.ExpirationDate) + ? license.ExpirationDate.Value > DateTime.UtcNow.AddYears(50) ? null : license.ExpirationDate : license.ExpirationDate, RegisteredTo = license.RegisteredTo, IsCommercialLicense = license.IsCommercialLicense, From d4690663921be8fb11e0e2eebb104ac66f374995 Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Mon, 25 Mar 2024 17:45:25 +0100 Subject: [PATCH 3/7] More cleanups --- .../DetectedLicense.cs | 13 +--- .../LicenseDetails.cs | 76 +++++++------------ 2 files changed, 30 insertions(+), 59 deletions(-) diff --git a/src/ServiceControl.LicenseManagement/DetectedLicense.cs b/src/ServiceControl.LicenseManagement/DetectedLicense.cs index fcde7c79f7..27567994a3 100644 --- a/src/ServiceControl.LicenseManagement/DetectedLicense.cs +++ b/src/ServiceControl.LicenseManagement/DetectedLicense.cs @@ -2,19 +2,14 @@ { public class DetectedLicense { - public DetectedLicense() - { - Details = new LicenseDetails(); - } - - public DetectedLicense(string licensePath, LicenseDetails details) : this() + public DetectedLicense(string licensePath, LicenseDetails details) { Location = licensePath; Details = details; } - public string Location { get; set; } - public LicenseDetails Details; - public bool IsEvaluationLicense { get; set; } + public string Location { get; } + public LicenseDetails Details { get; } + public bool IsEvaluationLicense { get; init; } } } \ No newline at end of file diff --git a/src/ServiceControl.LicenseManagement/LicenseDetails.cs b/src/ServiceControl.LicenseManagement/LicenseDetails.cs index b9cafd317d..bf1be0db6f 100644 --- a/src/ServiceControl.LicenseManagement/LicenseDetails.cs +++ b/src/ServiceControl.LicenseManagement/LicenseDetails.cs @@ -5,25 +5,25 @@ public class LicenseDetails { - public DateTime? ExpirationDate { get; private set; } - public DateTime? UpgradeProtectionExpiration { get; private set; } + public DateTime? ExpirationDate { get; private init; } + public DateTime? UpgradeProtectionExpiration { get; private init; } - public bool IsTrialLicense { get; private set; } - public bool IsCommercialLicense { get; private set; } - public bool IsExtendedTrial { get; private set; } - public string LicenseType { get; private set; } - public string Edition { get; private set; } - public string RegisteredTo { get; private set; } - public bool ValidForServiceControl { get; private set; } - public int? DaysUntilSubscriptionExpires { get; private set; } - public int? DaysUntilUpgradeProtectionExpires { get; private set; } - public bool WarnUserTrialIsExpiring { get; private set; } - public bool WarnUserTrialHasExpired { get; private set; } - public bool WarnUserSubscriptionIsExpiring { get; private set; } - public bool WarnUserSubscriptionHasExpired { get; private set; } - public bool WarnUserUpgradeProtectionIsExpiring { get; private set; } - public bool WarnUserUpgradeProtectionHasExpired { get; private set; } - public string Status { get; private set; } + public bool IsTrialLicense { get; private init; } + public bool IsCommercialLicense { get; private init; } + public bool IsExtendedTrial { get; private init; } + public string LicenseType { get; private init; } + public string Edition { get; private init; } + public string RegisteredTo { get; private init; } + public bool ValidForServiceControl { get; private init; } + public int? DaysUntilSubscriptionExpires { get; private init; } + public int? DaysUntilUpgradeProtectionExpires { get; private init; } + public bool WarnUserTrialIsExpiring { get; private init; } + public bool WarnUserTrialHasExpired { get; private init; } + public bool WarnUserSubscriptionIsExpiring { get; private init; } + public bool WarnUserSubscriptionHasExpired { get; private init; } + public bool WarnUserUpgradeProtectionIsExpiring { get; private init; } + public bool WarnUserUpgradeProtectionHasExpired { get; private init; } + public string Status { get; private init; } internal static LicenseDetails FromLicense(License license) { @@ -45,45 +45,21 @@ internal static LicenseDetails FromLicense(License license) ValidForServiceControl = license.ValidForApplication("ServiceControl"), DaysUntilSubscriptionExpires = license.GetDaysUntilLicenseExpires(), DaysUntilUpgradeProtectionExpires = license.GetDaysUntilUpgradeProtectionExpires(), + WarnUserUpgradeProtectionHasExpired = licenseStatus is LicenseStatus.ValidWithExpiredUpgradeProtection or LicenseStatus.InvalidDueToExpiredUpgradeProtection, + WarnUserTrialIsExpiring = licenseStatus == LicenseStatus.ValidWithExpiringTrial, + WarnUserSubscriptionIsExpiring = licenseStatus == LicenseStatus.ValidWithExpiringSubscription, + WarnUserUpgradeProtectionIsExpiring = licenseStatus == LicenseStatus.ValidWithExpiringUpgradeProtection, + WarnUserTrialHasExpired = licenseStatus == LicenseStatus.InvalidDueToExpiredTrial, + WarnUserSubscriptionHasExpired = licenseStatus == LicenseStatus.InvalidDueToExpiredSubscription, Status = licenseStatus.ToString() }; - - switch (licenseStatus) - { - case LicenseStatus.Valid: - break; - case LicenseStatus.ValidWithExpiredUpgradeProtection: - details.WarnUserUpgradeProtectionHasExpired = true; - break; - case LicenseStatus.ValidWithExpiringTrial: - details.WarnUserTrialIsExpiring = true; - break; - case LicenseStatus.ValidWithExpiringSubscription: - details.WarnUserSubscriptionIsExpiring = true; - break; - case LicenseStatus.ValidWithExpiringUpgradeProtection: - details.WarnUserUpgradeProtectionIsExpiring = true; - break; - case LicenseStatus.InvalidDueToExpiredTrial: - details.WarnUserTrialHasExpired = true; - break; - case LicenseStatus.InvalidDueToExpiredSubscription: - details.WarnUserSubscriptionHasExpired = true; - break; - case LicenseStatus.InvalidDueToExpiredUpgradeProtection: - details.WarnUserUpgradeProtectionHasExpired = true; - break; - default: - throw new ArgumentOutOfRangeException(); - } - - return details; } public bool HasLicenseExpired() => ExpirationDate.HasValue && HasLicenseDateExpired(ExpirationDate.Value); - public bool ReleaseNotCoveredByMaintenance(DateTime buildTimeStamp) => buildTimeStamp > UpgradeProtectionExpiration; + public bool ReleaseNotCoveredByMaintenance(DateTime buildTimeStamp) => + buildTimeStamp > UpgradeProtectionExpiration; static bool HasLicenseDateExpired(DateTime licenseDate) { From 79485125a2b1626352cdb7b5326ad7f8467ec642 Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Mon, 25 Mar 2024 17:53:46 +0100 Subject: [PATCH 4/7] LicenseComponentFactory small cleanup --- .../UI/License/LicenseComponentFactory.cs | 14 +++++++------- .../UI/License/LicenseViewModel.cs | 7 ++----- .../UI/Shell/LicenseStatusManager.cs | 18 +++++++++--------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/ServiceControl.Config/UI/License/LicenseComponentFactory.cs b/src/ServiceControl.Config/UI/License/LicenseComponentFactory.cs index c69743927c..345a524e7e 100644 --- a/src/ServiceControl.Config/UI/License/LicenseComponentFactory.cs +++ b/src/ServiceControl.Config/UI/License/LicenseComponentFactory.cs @@ -4,18 +4,18 @@ using System.Linq; using ServiceControl.LicenseManagement; - class LicenseComponentFactory + static class LicenseComponentFactory { const string UpgradeProtectionLicenseText = "Please extend your upgrade protection so that we can continue to provide you with support and new versions of the Particular Service Platform."; const string SubscriptionLicenseText = "Please extend your license to continue using the Particular Service Platform."; - CountInflector daysInflector = new CountInflector + static readonly CountInflector DaysInflector = new() { Singular = "{0} day", Plural = "{0} days" }; - public IEnumerable CreateComponents(LicenseDetails details) + public static IEnumerable CreateComponents(LicenseDetails details) { yield return new LicenseComponent { @@ -38,7 +38,7 @@ public IEnumerable CreateComponents(LicenseDetails details) } } - LicenseComponent SubscriptionExpiryComponent(LicenseDetails details) + static LicenseComponent SubscriptionExpiryComponent(LicenseDetails details) { if (details.WarnUserSubscriptionHasExpired || details.WarnUserTrialHasExpired) { @@ -54,7 +54,7 @@ LicenseComponent SubscriptionExpiryComponent(LicenseDetails details) if (details.WarnUserSubscriptionIsExpiring || details.WarnUserTrialIsExpiring) { - var daysRemain = daysInflector.Inflect(details.DaysUntilSubscriptionExpires ?? 0); + var daysRemain = DaysInflector.Inflect(details.DaysUntilSubscriptionExpires ?? 0); return new LicenseComponent { Label = "Platform license expiry date:", @@ -72,7 +72,7 @@ LicenseComponent SubscriptionExpiryComponent(LicenseDetails details) }; } - LicenseComponent UpgradeProtectionExpiryComponent(LicenseDetails details) + static LicenseComponent UpgradeProtectionExpiryComponent(LicenseDetails details) { if (details.WarnUserUpgradeProtectionHasExpired) { @@ -88,7 +88,7 @@ LicenseComponent UpgradeProtectionExpiryComponent(LicenseDetails details) if (details.WarnUserUpgradeProtectionIsExpiring) { - var daysRemain = daysInflector.Inflect(details.DaysUntilUpgradeProtectionExpires ?? 0); + var daysRemain = DaysInflector.Inflect(details.DaysUntilUpgradeProtectionExpires ?? 0); return new LicenseComponent { Label = "Upgrade protection expiry date:", diff --git a/src/ServiceControl.Config/UI/License/LicenseViewModel.cs b/src/ServiceControl.Config/UI/License/LicenseViewModel.cs index 6768c03477..efcfd2d27d 100644 --- a/src/ServiceControl.Config/UI/License/LicenseViewModel.cs +++ b/src/ServiceControl.Config/UI/License/LicenseViewModel.cs @@ -13,10 +13,7 @@ class LicenseViewModel : RxScreen { - public LicenseViewModel(IEventAggregator eventAggregator) - { - EventAggregator = eventAggregator; - } + public LicenseViewModel(IEventAggregator eventAggregator) => EventAggregator = eventAggregator; public string ApplyLicenseError { get; set; } @@ -42,7 +39,7 @@ void RefreshLicenseInfo() { license = LicenseManager.FindLicense(); - Components = new LicenseComponentFactory().CreateComponents(license.Details).ToList(); + Components = LicenseComponentFactory.CreateComponents(license.Details).ToList(); CanExtendTrial = license.Details.IsTrialLicense; diff --git a/src/ServiceControl.Config/UI/Shell/LicenseStatusManager.cs b/src/ServiceControl.Config/UI/Shell/LicenseStatusManager.cs index ef9338e208..44b76daec2 100644 --- a/src/ServiceControl.Config/UI/Shell/LicenseStatusManager.cs +++ b/src/ServiceControl.Config/UI/Shell/LicenseStatusManager.cs @@ -3,17 +3,17 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; - using System.Windows.Input; using Caliburn.Micro; - using Commands; using Events; + using Framework.Commands; using Framework.Rx; using License; using ServiceControl.LicenseManagement; + using ICommand = System.Windows.Input.ICommand; class LicenseStatusManager : RxScreen, IHandle, IHandle { - public LicenseStatusManager(OpenViewModelCommand openLicense) + public LicenseStatusManager(AwaitableAbstractCommand openLicense) { openLicense.OnCommandExecuting = () => ShowPopup = false; OpenLicense = openLicense; @@ -29,13 +29,13 @@ public bool ShowPopup } public string PopupHeading { get; set; } - public string PopupText { get; set; } + public string PopupText { get; private set; } public ICommand OpenLicense { get; set; } - public bool IsWarning { get; set; } - public bool IsSerious { get; set; } - public bool HasFocus { get; set; } + public bool IsWarning { get; private set; } + public bool IsSerious { get; private set; } + public bool HasFocus { get; private set; } public Task HandleAsync(FocusChanged message, CancellationToken cancellationToken) { @@ -53,9 +53,9 @@ void RefreshStatus(bool updatePopupDisplay) { var license = LicenseManager.FindLicense(); - var components = new LicenseComponentFactory().CreateComponents(license.Details); + var components = LicenseComponentFactory.CreateComponents(license.Details); - var mostPressingComponent = components.OrderByDescending(d => d.Importance).FirstOrDefault(); + var mostPressingComponent = components.MaxBy(d => d.Importance); IsWarning = mostPressingComponent?.IsWarning ?? false; IsSerious = mostPressingComponent?.IsSerious ?? false; From b488a50364e9314f1cf76af2ba5e886c8f1c3fbf Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Mon, 25 Mar 2024 17:59:08 +0100 Subject: [PATCH 5/7] Remove Particular.Licensing.Sources from monitoring --- .../Licensing/LicenseManager.cs | 20 +++++-------------- .../ServiceControl.Monitoring.csproj | 1 - 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/ServiceControl.Monitoring/Licensing/LicenseManager.cs b/src/ServiceControl.Monitoring/Licensing/LicenseManager.cs index 680a6ea1a6..b587011d53 100644 --- a/src/ServiceControl.Monitoring/Licensing/LicenseManager.cs +++ b/src/ServiceControl.Monitoring/Licensing/LicenseManager.cs @@ -1,32 +1,22 @@ namespace ServiceControl.Monitoring.Licensing { + using LicenseManagement; using NServiceBus.Logging; - using Particular.Licensing; public class LicenseManager { - internal License Details { get; set; } + internal LicenseDetails Details { get; set; } internal bool IsValid { get; set; } public void Refresh() { Logger.Debug("Checking License Status"); - var sources = LicenseSource.GetStandardLicenseSources(); - var result = ActiveLicense.Find("ServiceControl", sources.ToArray()); + var detectedLicense = ServiceControl.LicenseManagement.LicenseManager.FindLicense(); - if (result.License.HasExpired()) - { - foreach (var report in result.Report) - { - Logger.Info(report); - } + IsValid = !detectedLicense.Details.HasLicenseExpired(); - Logger.Warn("License has expired"); - } - - IsValid = !result.License.HasExpired(); - Details = result.License; + Details = detectedLicense.Details; } static readonly ILog Logger = LogManager.GetLogger(typeof(LicenseManager)); diff --git a/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj b/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj index 7faa4c3a30..8d000018df 100644 --- a/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj +++ b/src/ServiceControl.Monitoring/ServiceControl.Monitoring.csproj @@ -27,7 +27,6 @@ - From 5deee393211c43bc5d8c58b030e53af04381ec7d Mon Sep 17 00:00:00 2001 From: danielmarbach Date: Mon, 25 Mar 2024 18:07:57 +0100 Subject: [PATCH 6/7] Align concepts --- .../HostApplicationBuilderExtensions.cs | 7 ++- .../Http/LicenseController.cs | 22 ++++------ .../{LicenseManager.cs => ActiveLicense.cs} | 15 ++++--- .../Licensing/LicenseCheckFeature.cs | 44 ------------------- .../Licensing/LicenseCheckHostedService.cs | 30 +++++++++++++ ...LicenseCheckServiceCollectionExtensions.cs | 13 ++++++ .../HostApplicationBuilderExtensions.cs | 2 +- .../LicenseCheckHostBuilderExtensions.cs | 16 ------- .../Licensing/LicenseCheckHostedService.cs | 22 +++------- ...LicenseCheckServiceCollectionExtensions.cs | 13 ++++++ 10 files changed, 83 insertions(+), 101 deletions(-) rename src/ServiceControl.Monitoring/Licensing/{LicenseManager.cs => ActiveLicense.cs} (55%) delete mode 100644 src/ServiceControl.Monitoring/Licensing/LicenseCheckFeature.cs create mode 100644 src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs create mode 100644 src/ServiceControl.Monitoring/Licensing/LicenseCheckServiceCollectionExtensions.cs delete mode 100644 src/ServiceControl/Licensing/LicenseCheckHostBuilderExtensions.cs create mode 100644 src/ServiceControl/Licensing/LicenseCheckServiceCollectionExtensions.cs diff --git a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs index c13bb689eb..6037c32ebf 100644 --- a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs @@ -38,7 +38,6 @@ public static class HostApplicationBuilderExtensions var services = hostBuilder.Services; services.AddSingleton(settings); - services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -61,11 +60,13 @@ public static class HostApplicationBuilderExtensions // directly and to make things more complex of course the order of registration still matters ;) services.AddSingleton(provider => new Lazy(provider.GetRequiredService)); + services.AddLicenseCheck(); + ConfigureEndpoint(endpointConfiguration, onCriticalError, transportCustomization, settings); hostBuilder.UseNServiceBus(endpointConfiguration); } - internal static void ConfigureEndpoint(EndpointConfiguration config, Func onCriticalError, ITransportCustomization transportCustomization, Settings settings) + static void ConfigureEndpoint(EndpointConfiguration config, Func onCriticalError, ITransportCustomization transportCustomization, Settings settings) { if (!string.IsNullOrWhiteSpace(settings.LicenseFileText)) { @@ -107,8 +108,6 @@ internal static void ConfigureEndpoint(EndpointConfiguration config, Func(); config.Pipeline.Register(typeof(MessagePoolReleasingBehavior), "Releases pooled message."); config.EnableFeature(); - - config.EnableFeature(); } static Func QueueLengthProviderBuilder(string connectionString, diff --git a/src/ServiceControl.Monitoring/Http/LicenseController.cs b/src/ServiceControl.Monitoring/Http/LicenseController.cs index fb2158cc11..f70ab068c2 100644 --- a/src/ServiceControl.Monitoring/Http/LicenseController.cs +++ b/src/ServiceControl.Monitoring/Http/LicenseController.cs @@ -4,24 +4,20 @@ namespace ServiceControl.Monitoring.Http using Microsoft.AspNetCore.Mvc; [ApiController] - public class LicenseController(LicenseManager licenseManager) : ControllerBase + public class LicenseController(ActiveLicense activeLicense) : ControllerBase { [Route("license")] [HttpGet] - public ActionResult License() - { - licenseManager.Refresh(); - - return new LicenseInfo + public ActionResult License() => + new LicenseInfo { - TrialLicense = licenseManager.Details.IsTrialLicense, - Edition = licenseManager.Details.Edition ?? string.Empty, - RegisteredTo = licenseManager.Details.RegisteredTo ?? string.Empty, - UpgradeProtectionExpiration = licenseManager.Details.UpgradeProtectionExpiration?.ToString("O") ?? string.Empty, - ExpirationDate = licenseManager.Details.ExpirationDate?.ToString("O") ?? string.Empty, - Status = licenseManager.IsValid ? "valid" : "invalid" + TrialLicense = activeLicense.Details.IsTrialLicense, + Edition = activeLicense.Details.Edition ?? string.Empty, + RegisteredTo = activeLicense.Details.RegisteredTo ?? string.Empty, + UpgradeProtectionExpiration = activeLicense.Details.UpgradeProtectionExpiration?.ToString("O") ?? string.Empty, + ExpirationDate = activeLicense.Details.ExpirationDate?.ToString("O") ?? string.Empty, + Status = activeLicense.IsValid ? "valid" : "invalid" }; - } public class LicenseInfo { diff --git a/src/ServiceControl.Monitoring/Licensing/LicenseManager.cs b/src/ServiceControl.Monitoring/Licensing/ActiveLicense.cs similarity index 55% rename from src/ServiceControl.Monitoring/Licensing/LicenseManager.cs rename to src/ServiceControl.Monitoring/Licensing/ActiveLicense.cs index b587011d53..a3a001e0ad 100644 --- a/src/ServiceControl.Monitoring/Licensing/LicenseManager.cs +++ b/src/ServiceControl.Monitoring/Licensing/ActiveLicense.cs @@ -1,24 +1,27 @@ namespace ServiceControl.Monitoring.Licensing { - using LicenseManagement; + using global::ServiceControl.LicenseManagement; using NServiceBus.Logging; - public class LicenseManager + public class ActiveLicense { + public ActiveLicense() => Refresh(); + + public bool IsValid { get; set; } + internal LicenseDetails Details { get; set; } - internal bool IsValid { get; set; } public void Refresh() { - Logger.Debug("Checking License Status"); + Logger.Debug("Refreshing ActiveLicense"); - var detectedLicense = ServiceControl.LicenseManagement.LicenseManager.FindLicense(); + var detectedLicense = LicenseManager.FindLicense(); IsValid = !detectedLicense.Details.HasLicenseExpired(); Details = detectedLicense.Details; } - static readonly ILog Logger = LogManager.GetLogger(typeof(LicenseManager)); + static readonly ILog Logger = LogManager.GetLogger(typeof(ActiveLicense)); } } \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/Licensing/LicenseCheckFeature.cs b/src/ServiceControl.Monitoring/Licensing/LicenseCheckFeature.cs deleted file mode 100644 index d456688c7d..0000000000 --- a/src/ServiceControl.Monitoring/Licensing/LicenseCheckFeature.cs +++ /dev/null @@ -1,44 +0,0 @@ -namespace ServiceControl.Monitoring.Licensing -{ - using System; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.Extensions.DependencyInjection; - using NServiceBus; - using NServiceBus.Features; - - class LicenseCheckFeature : Feature - { - protected override void Setup(FeatureConfigurationContext context) - { - context.Services.AddSingleton(); - context.RegisterStartupTask(b => b.GetRequiredService()); - } - } - - class LicenseCheckFeatureStartup : FeatureStartupTask, IDisposable - { - public LicenseCheckFeatureStartup(LicenseManager licenseManager) - { - this.licenseManager = licenseManager; - } - - public void Dispose() - { - checklicenseTimer?.Dispose(); - } - - protected override Task OnStart(IMessageSession session, CancellationToken cancellationToken = default) - { - return Task.Run(() => checklicenseTimer = new Timer(objectstate => { licenseManager.Refresh(); }, null, TimeSpan.Zero, TimeSpan.FromHours(8))); - } - - protected override Task OnStop(IMessageSession session, CancellationToken cancellationToken = default) - { - return Task.CompletedTask; - } - - Timer checklicenseTimer; - LicenseManager licenseManager; - } -} \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs b/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs new file mode 100644 index 0000000000..df3b13b9cd --- /dev/null +++ b/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs @@ -0,0 +1,30 @@ +namespace ServiceControl.Monitoring.Licensing +{ + using System; + using System.Threading; + using System.Threading.Tasks; + using global::ServiceControl.Infrastructure.BackgroundTasks; + using Microsoft.Extensions.Hosting; + using NServiceBus.Logging; + + class LicenseCheckHostedService(ActiveLicense activeLicense, IAsyncTimer scheduler) : IHostedService + { + public Task StartAsync(CancellationToken cancellationToken) + { + var due = TimeSpan.FromHours(8); + timer = scheduler.Schedule(_ => + { + activeLicense.Refresh(); + return ScheduleNextExecutionTask; + }, due, due, ex => { Logger.Error("Unhandled error while refreshing the license.", ex); }); + return Task.CompletedTask; + } + + public Task StopAsync(CancellationToken cancellationToken) => timer.Stop(); + + TimerJob timer; + + static readonly ILog Logger = LogManager.GetLogger(); + static readonly Task ScheduleNextExecutionTask = Task.FromResult(TimerJobExecutionResult.ScheduleNextExecution); + } +} \ No newline at end of file diff --git a/src/ServiceControl.Monitoring/Licensing/LicenseCheckServiceCollectionExtensions.cs b/src/ServiceControl.Monitoring/Licensing/LicenseCheckServiceCollectionExtensions.cs new file mode 100644 index 0000000000..677bf58a0e --- /dev/null +++ b/src/ServiceControl.Monitoring/Licensing/LicenseCheckServiceCollectionExtensions.cs @@ -0,0 +1,13 @@ +namespace ServiceControl.Monitoring.Licensing +{ + using Microsoft.Extensions.DependencyInjection; + + static class LicenseCheckServiceCollectionExtensions + { + public static void AddLicenseCheck(this IServiceCollection services) + { + services.AddSingleton(); + services.AddHostedService(); + } + } +} \ No newline at end of file diff --git a/src/ServiceControl/HostApplicationBuilderExtensions.cs b/src/ServiceControl/HostApplicationBuilderExtensions.cs index e4139bf50a..98b9024c42 100644 --- a/src/ServiceControl/HostApplicationBuilderExtensions.cs +++ b/src/ServiceControl/HostApplicationBuilderExtensions.cs @@ -82,7 +82,7 @@ public static void AddServiceControl(this IHostApplicationBuilder hostBuilder, S // directly and to make things more complex of course the order of registration still matters ;) services.AddSingleton(provider => new Lazy(provider.GetRequiredService)); - hostBuilder.AddLicenseCheck(); + services.AddLicenseCheck(); services.AddPersistence(settings); services.AddMetrics(settings.PrintMetrics); diff --git a/src/ServiceControl/Licensing/LicenseCheckHostBuilderExtensions.cs b/src/ServiceControl/Licensing/LicenseCheckHostBuilderExtensions.cs deleted file mode 100644 index d21e92953f..0000000000 --- a/src/ServiceControl/Licensing/LicenseCheckHostBuilderExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Particular.ServiceControl.Licensing -{ - using Microsoft.Extensions.DependencyInjection; - using Microsoft.Extensions.Hosting; - - static class LicenseCheckHostBuilderExtensions - { - public static IHostApplicationBuilder AddLicenseCheck(this IHostApplicationBuilder hostBuilder) - { - var services = hostBuilder.Services; - services.AddSingleton(); - services.AddHostedService(); - return hostBuilder; - } - } -} \ No newline at end of file diff --git a/src/ServiceControl/Licensing/LicenseCheckHostedService.cs b/src/ServiceControl/Licensing/LicenseCheckHostedService.cs index f507e647a4..bda122d893 100644 --- a/src/ServiceControl/Licensing/LicenseCheckHostedService.cs +++ b/src/ServiceControl/Licensing/LicenseCheckHostedService.cs @@ -7,15 +7,8 @@ using Microsoft.Extensions.Hosting; using NServiceBus.Logging; - class LicenseCheckHostedService : IHostedService + class LicenseCheckHostedService(ActiveLicense activeLicense, IAsyncTimer scheduler) : IHostedService { - public LicenseCheckHostedService(ActiveLicense activeLicense, IAsyncTimer scheduler) - { - this.activeLicense = activeLicense; - this.scheduler = scheduler; - ScheduleNextExecutionTask = Task.FromResult(TimerJobExecutionResult.ScheduleNextExecution); - } - public Task StartAsync(CancellationToken cancellationToken) { var due = TimeSpan.FromHours(8); @@ -23,20 +16,15 @@ public Task StartAsync(CancellationToken cancellationToken) { activeLicense.Refresh(); return ScheduleNextExecutionTask; - }, due, due, ex => { log.Error("Unhandled error while refreshing the license.", ex); }); + }, due, due, ex => { Logger.Error("Unhandled error while refreshing the license.", ex); }); return Task.CompletedTask; } - public Task StopAsync(CancellationToken cancellationToken) - { - return timer.Stop(); - } + public Task StopAsync(CancellationToken cancellationToken) => timer.Stop(); - ActiveLicense activeLicense; - readonly IAsyncTimer scheduler; TimerJob timer; - static ILog log = LogManager.GetLogger(); - static Task ScheduleNextExecutionTask; + static readonly ILog Logger = LogManager.GetLogger(); + static readonly Task ScheduleNextExecutionTask = Task.FromResult(TimerJobExecutionResult.ScheduleNextExecution); } } \ No newline at end of file diff --git a/src/ServiceControl/Licensing/LicenseCheckServiceCollectionExtensions.cs b/src/ServiceControl/Licensing/LicenseCheckServiceCollectionExtensions.cs new file mode 100644 index 0000000000..c3902ef34b --- /dev/null +++ b/src/ServiceControl/Licensing/LicenseCheckServiceCollectionExtensions.cs @@ -0,0 +1,13 @@ +namespace Particular.ServiceControl.Licensing +{ + using Microsoft.Extensions.DependencyInjection; + + static class LicenseCheckServiceCollectionExtensions + { + public static void AddLicenseCheck(this IServiceCollection services) + { + services.AddSingleton(); + services.AddHostedService(); + } + } +} \ No newline at end of file From a2f27d687dda62b7fb736f99e3277e25c6dee3c7 Mon Sep 17 00:00:00 2001 From: Brandon Ording Date: Mon, 25 Mar 2024 17:02:30 -0400 Subject: [PATCH 7/7] Tweaks --- .../HostApplicationBuilderExtensions.cs | 3 +++ .../Http/LicenseController.cs | 23 ++++++++++++++++--- .../AsyncTimerHostBuilderExtensions.cs | 12 ++++++++++ .../Licensing/LicenseCheckHostedService.cs | 4 ++-- .../Licensing/LicenseCheckHostedService.cs | 2 +- 5 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 src/ServiceControl.Monitoring/Infrastructure/BackgroundTasks/AsyncTimerHostBuilderExtensions.cs diff --git a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs index 6037c32ebf..5cd575acb2 100644 --- a/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs +++ b/src/ServiceControl.Monitoring/HostApplicationBuilderExtensions.cs @@ -18,6 +18,7 @@ namespace ServiceControl.Monitoring; using NServiceBus.Features; using NServiceBus.Transport; using QueueLength; +using ServiceControl.Monitoring.Infrastructure.BackgroundTasks; using Timings; using Transports; @@ -64,6 +65,8 @@ public static class HostApplicationBuilderExtensions ConfigureEndpoint(endpointConfiguration, onCriticalError, transportCustomization, settings); hostBuilder.UseNServiceBus(endpointConfiguration); + + hostBuilder.AddAsyncTimer(); } static void ConfigureEndpoint(EndpointConfiguration config, Func onCriticalError, ITransportCustomization transportCustomization, Settings settings) diff --git a/src/ServiceControl.Monitoring/Http/LicenseController.cs b/src/ServiceControl.Monitoring/Http/LicenseController.cs index f70ab068c2..d76e2e9361 100644 --- a/src/ServiceControl.Monitoring/Http/LicenseController.cs +++ b/src/ServiceControl.Monitoring/Http/LicenseController.cs @@ -1,15 +1,21 @@ namespace ServiceControl.Monitoring.Http { - using Licensing; using Microsoft.AspNetCore.Mvc; + using ServiceControl.Monitoring.Licensing; [ApiController] public class LicenseController(ActiveLicense activeLicense) : ControllerBase { [Route("license")] [HttpGet] - public ActionResult License() => - new LicenseInfo + public ActionResult License(bool refresh) + { + if (refresh) + { + activeLicense.Refresh(); + } + + var licenseInfo = new LicenseInfo { TrialLicense = activeLicense.Details.IsTrialLicense, Edition = activeLicense.Details.Edition ?? string.Empty, @@ -19,16 +25,27 @@ public class LicenseController(ActiveLicense activeLicense) : ControllerBase Status = activeLicense.IsValid ? "valid" : "invalid" }; + return licenseInfo; + } + public class LicenseInfo { public bool TrialLicense { get; set; } + public string Edition { get; set; } + public string RegisteredTo { get; set; } + public string UpgradeProtectionExpiration { get; set; } + public string ExpirationDate { get; set; } + public string Status { get; set; } + public string LicenseType { get; set; } + public string InstanceName { get; set; } + public string LicenseStatus { get; set; } } } diff --git a/src/ServiceControl.Monitoring/Infrastructure/BackgroundTasks/AsyncTimerHostBuilderExtensions.cs b/src/ServiceControl.Monitoring/Infrastructure/BackgroundTasks/AsyncTimerHostBuilderExtensions.cs new file mode 100644 index 0000000000..79c5e3155c --- /dev/null +++ b/src/ServiceControl.Monitoring/Infrastructure/BackgroundTasks/AsyncTimerHostBuilderExtensions.cs @@ -0,0 +1,12 @@ +namespace ServiceControl.Monitoring.Infrastructure.BackgroundTasks +{ + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Hosting; + using ServiceControl.Infrastructure.BackgroundTasks; + + static class AsyncTimerHostBuilderExtensions + { + public static void AddAsyncTimer(this IHostApplicationBuilder hostBuilder) => + hostBuilder.Services.AddSingleton(); + } +} diff --git a/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs b/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs index df3b13b9cd..1842f8603d 100644 --- a/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs +++ b/src/ServiceControl.Monitoring/Licensing/LicenseCheckHostedService.cs @@ -3,9 +3,9 @@ using System; using System.Threading; using System.Threading.Tasks; - using global::ServiceControl.Infrastructure.BackgroundTasks; using Microsoft.Extensions.Hosting; using NServiceBus.Logging; + using ServiceControl.Infrastructure.BackgroundTasks; class LicenseCheckHostedService(ActiveLicense activeLicense, IAsyncTimer scheduler) : IHostedService { @@ -16,7 +16,7 @@ public Task StartAsync(CancellationToken cancellationToken) { activeLicense.Refresh(); return ScheduleNextExecutionTask; - }, due, due, ex => { Logger.Error("Unhandled error while refreshing the license.", ex); }); + }, due, due, ex => Logger.Error("Unhandled error while refreshing the license.", ex)); return Task.CompletedTask; } diff --git a/src/ServiceControl/Licensing/LicenseCheckHostedService.cs b/src/ServiceControl/Licensing/LicenseCheckHostedService.cs index bda122d893..565c1fa467 100644 --- a/src/ServiceControl/Licensing/LicenseCheckHostedService.cs +++ b/src/ServiceControl/Licensing/LicenseCheckHostedService.cs @@ -16,7 +16,7 @@ public Task StartAsync(CancellationToken cancellationToken) { activeLicense.Refresh(); return ScheduleNextExecutionTask; - }, due, due, ex => { Logger.Error("Unhandled error while refreshing the license.", ex); }); + }, due, due, ex => Logger.Error("Unhandled error while refreshing the license.", ex)); return Task.CompletedTask; }