Skip to content

Commit

Permalink
Licensing (#4030)
Browse files Browse the repository at this point in the history
* Remove reference to Particular.License.Sources

Co-authored-by: Brandon Ording <bording@gmail.com>

* Remove parenthesis

* More cleanups

* LicenseComponentFactory small cleanup

* Remove Particular.Licensing.Sources from monitoring

* Align concepts

* Tweaks

---------

Co-authored-by: Brandon Ording <bording@gmail.com>
  • Loading branch information
danielmarbach and bording committed Mar 25, 2024
1 parent 7824d6b commit b70dfcc
Show file tree
Hide file tree
Showing 21 changed files with 192 additions and 238 deletions.
14 changes: 7 additions & 7 deletions src/ServiceControl.Config/UI/License/LicenseComponentFactory.cs
Expand Up @@ -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<LicenseComponent> CreateComponents(LicenseDetails details)
public static IEnumerable<LicenseComponent> CreateComponents(LicenseDetails details)
{
yield return new LicenseComponent
{
Expand All @@ -38,7 +38,7 @@ public IEnumerable<LicenseComponent> CreateComponents(LicenseDetails details)
}
}

LicenseComponent SubscriptionExpiryComponent(LicenseDetails details)
static LicenseComponent SubscriptionExpiryComponent(LicenseDetails details)
{
if (details.WarnUserSubscriptionHasExpired || details.WarnUserTrialHasExpired)
{
Expand All @@ -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:",
Expand All @@ -72,7 +72,7 @@ LicenseComponent SubscriptionExpiryComponent(LicenseDetails details)
};
}

LicenseComponent UpgradeProtectionExpiryComponent(LicenseDetails details)
static LicenseComponent UpgradeProtectionExpiryComponent(LicenseDetails details)
{
if (details.WarnUserUpgradeProtectionHasExpired)
{
Expand All @@ -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:",
Expand Down
7 changes: 2 additions & 5 deletions src/ServiceControl.Config/UI/License/LicenseViewModel.cs
Expand Up @@ -13,10 +13,7 @@

class LicenseViewModel : RxScreen
{
public LicenseViewModel(IEventAggregator eventAggregator)
{
EventAggregator = eventAggregator;
}
public LicenseViewModel(IEventAggregator eventAggregator) => EventAggregator = eventAggregator;

public string ApplyLicenseError { get; set; }

Expand All @@ -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;

Expand Down
18 changes: 9 additions & 9 deletions src/ServiceControl.Config/UI/Shell/LicenseStatusManager.cs
Expand Up @@ -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<LicenseUpdated>, IHandle<FocusChanged>
{
public LicenseStatusManager(OpenViewModelCommand<LicenseViewModel> openLicense)
public LicenseStatusManager(AwaitableAbstractCommand<object> openLicense)
{
openLicense.OnCommandExecuting = () => ShowPopup = false;
OpenLicense = openLicense;
Expand All @@ -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)
{
Expand All @@ -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;
Expand Down
13 changes: 4 additions & 9 deletions src/ServiceControl.LicenseManagement/DetectedLicense.cs
Expand Up @@ -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; }
}
}
90 changes: 32 additions & 58 deletions src/ServiceControl.LicenseManagement/LicenseDetails.cs
Expand Up @@ -5,33 +5,36 @@

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; 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 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)
{
LicenseStatus licenseStatus = license.GetLicenseStatus();

var details = new LicenseDetails
{
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,
Expand All @@ -41,51 +44,22 @@ internal static LicenseDetails FromLicense(License license)
Edition = license.Edition,
ValidForServiceControl = license.ValidForApplication("ServiceControl"),
DaysUntilSubscriptionExpires = license.GetDaysUntilLicenseExpires(),
DaysUntilUpgradeProtectionExpires = license.GetDaysUntilUpgradeProtectionExpires()
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 (license.GetLicenseStatus())
{
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()
{
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)
{
Expand Down
Expand Up @@ -18,6 +18,7 @@ namespace ServiceControl.Monitoring;
using NServiceBus.Features;
using NServiceBus.Transport;
using QueueLength;
using ServiceControl.Monitoring.Infrastructure.BackgroundTasks;
using Timings;
using Transports;

Expand All @@ -38,7 +39,6 @@ public static class HostApplicationBuilderExtensions

var services = hostBuilder.Services;
services.AddSingleton(settings);
services.AddSingleton<LicenseCheckFeatureStartup>();
services.AddSingleton<EndpointRegistry>();
services.AddSingleton<MessageTypeRegistry>();
services.AddSingleton<EndpointInstanceActivityTracker>();
Expand All @@ -61,11 +61,15 @@ public static class HostApplicationBuilderExtensions
// directly and to make things more complex of course the order of registration still matters ;)
services.AddSingleton(provider => new Lazy<IMessageDispatcher>(provider.GetRequiredService<IMessageDispatcher>));

services.AddLicenseCheck();

ConfigureEndpoint(endpointConfiguration, onCriticalError, transportCustomization, settings);
hostBuilder.UseNServiceBus(endpointConfiguration);

hostBuilder.AddAsyncTimer();
}

internal static void ConfigureEndpoint(EndpointConfiguration config, Func<ICriticalErrorContext, CancellationToken, Task> onCriticalError, ITransportCustomization transportCustomization, Settings settings)
static void ConfigureEndpoint(EndpointConfiguration config, Func<ICriticalErrorContext, CancellationToken, Task> onCriticalError, ITransportCustomization transportCustomization, Settings settings)
{
if (!string.IsNullOrWhiteSpace(settings.LicenseFileText))
{
Expand Down Expand Up @@ -107,8 +111,6 @@ internal static void ConfigureEndpoint(EndpointConfiguration config, Func<ICriti
config.AddDeserializer<TaggedLongValueWriterOccurrenceSerializerDefinition>();
config.Pipeline.Register(typeof(MessagePoolReleasingBehavior), "Releases pooled message.");
config.EnableFeature<QueueLength.QueueLength>();

config.EnableFeature<LicenseCheckFeature>();
}

static Func<QueueLengthStore, IProvideQueueLength> QueueLengthProviderBuilder(string connectionString,
Expand Down
35 changes: 24 additions & 11 deletions src/ServiceControl.Monitoring/Http/LicenseController.cs
@@ -1,38 +1,51 @@
namespace ServiceControl.Monitoring.Http
{
using Licensing;
using Microsoft.AspNetCore.Mvc;
using ServiceControl.Monitoring.Licensing;

[ApiController]
public class LicenseController(LicenseManager licenseManager) : ControllerBase
public class LicenseController(ActiveLicense activeLicense) : ControllerBase
{
[Route("license")]
[HttpGet]
public ActionResult<LicenseInfo> License()
public ActionResult<LicenseInfo> License(bool refresh)
{
licenseManager.Refresh();
if (refresh)
{
activeLicense.Refresh();
}

return new LicenseInfo
var licenseInfo = 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"
};

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; }
}
}
Expand Down
@@ -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<IAsyncTimer, AsyncTimer>();
}
}

0 comments on commit b70dfcc

Please sign in to comment.