From 412e7714babbcc504df60ed0cd446e8bd93073f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 02:00:37 +0000 Subject: [PATCH 01/19] Bump NUnit from 4.2.2 to 4.3.2 in /src Bumps [NUnit](https://github.com/nunit/nunit) from 4.2.2 to 4.3.2. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/main/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/4.2.2...4.3.2) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- src/Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index cfcf2d0015..dae53a3e35 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -47,7 +47,7 @@ - + From 95d3e57643755569d1eddf9d21a8198cb498929f Mon Sep 17 00:00:00 2001 From: David Boike Date: Fri, 10 Jan 2025 13:39:41 -0600 Subject: [PATCH 02/19] Unsync, remove dependabot, remove from Weekly CI --- .github/dependabot.yml | 36 -------------------- .github/workflows/{ci.yml => ci-renamed.yml} | 0 .reposync.yml | 2 -- 3 files changed, 38 deletions(-) delete mode 100644 .github/dependabot.yml rename .github/workflows/{ci.yml => ci-renamed.yml} (100%) delete mode 100644 .reposync.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index bc1175f8eb..0000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,36 +0,0 @@ -version: 2 -registries: - particular-packages: - type: nuget-feed - url: https://f.feedz.io/particular-software/packages/nuget/index.json -updates: -- package-ecosystem: nuget - directory: "/src" - registries: "*" - schedule: - interval: daily - open-pull-requests-limit: 1000 - groups: - AWSSDK: - patterns: - - "AWSSDK.*" - NServiceBusCore: - patterns: - - "NServiceBus" - - "NServiceBus.AcceptanceTesting" - - "NServiceBus.AcceptanceTests.Sources" - - "NServiceBus.PersistenceTests.Sources" - - "NServiceBus.TransportTests.Sources" - ignore: - # Particular.Analyzers updates are distributed via RepoStandards - - dependency-name: "Particular.Analyzers" - # Changing these 3 dependencies affects the .NET SDK and Visual Studio versions we support - # These types of updates should be more intentional than an automated update - - dependency-name: "Microsoft.Build.Utilities.Core" - - dependency-name: "Microsoft.CodeAnalysis.CSharp" - - dependency-name: "Microsoft.CodeAnalysis.CSharp.Workspaces" -- package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 1000 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci-renamed.yml similarity index 100% rename from .github/workflows/ci.yml rename to .github/workflows/ci-renamed.yml diff --git a/.reposync.yml b/.reposync.yml deleted file mode 100644 index 05ec9e3185..0000000000 --- a/.reposync.yml +++ /dev/null @@ -1,2 +0,0 @@ -exclusions: -- src/NServiceBus.snk From dbb0a761ddc0f30ff478c3e955b3e74ae7b8cb78 Mon Sep 17 00:00:00 2001 From: Phil Bastian Date: Fri, 1 Nov 2024 13:50:18 +0800 Subject: [PATCH 03/19] record connected application by heartbeat control message rather than looking at failed message headers --- .../InternalMessages/ConnectedApplication.cs | 9 +++++++ .../Transport/ConnectedApplicationHandler.cs | 17 ++++++++++++ .../Operations/MassTransitDetector.cs | 27 ------------------- 3 files changed, 26 insertions(+), 27 deletions(-) create mode 100644 src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs create mode 100644 src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs delete mode 100644 src/ServiceControl/Operations/MassTransitDetector.cs diff --git a/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs b/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs new file mode 100644 index 0000000000..734005b487 --- /dev/null +++ b/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs @@ -0,0 +1,9 @@ +namespace ServiceControl.Monitoring; + +using NServiceBus; + +public class ConnectedApplication : IMessage +{ + public string Application { get; set; } + public string[] ErrorQueues { get; set; } +} diff --git a/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs b/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs new file mode 100644 index 0000000000..e78dbc0b01 --- /dev/null +++ b/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs @@ -0,0 +1,17 @@ +namespace ServiceControl.Monitoring.Transport +{ + using System.Threading.Tasks; + using NServiceBus; + using ServiceControl.Monitoring; + using ServiceControl.Persistence; + + public class ConnectedApplicationHandler(IConnectedApplicationsDataStore connectedApplicationsDataStore) : IHandleMessages + { + public Task Handle(ConnectedApplication message, IMessageHandlerContext context) + { + _ = connectedApplicationsDataStore.Add(message.Application); + + return Task.CompletedTask; + } + } +} diff --git a/src/ServiceControl/Operations/MassTransitDetector.cs b/src/ServiceControl/Operations/MassTransitDetector.cs deleted file mode 100644 index 7b75ea0616..0000000000 --- a/src/ServiceControl/Operations/MassTransitDetector.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace ServiceControl.Operations -{ - using System.Linq; - using Persistence; - - class MassTransitDetector(IConnectedApplicationsDataStore connectedApplicationsDataStore) : IEnrichImportedErrorMessages - { - public void Enrich(ErrorEnricherContext context) - { - if (alreadyDetected) - { - return; - } - - if (context.Headers.Any(h => IsMassTransitHeader(h.Key))) - { - alreadyDetected = true; - - _ = connectedApplicationsDataStore.Add("MassTransitConnector"); - } - } - - static bool IsMassTransitHeader(string headerName) => headerName.StartsWith("MT-", System.StringComparison.InvariantCultureIgnoreCase); - - static bool alreadyDetected; - } -} From 9ccb5467a3aed3c615575e6ca4b1756c48ad5ba0 Mon Sep 17 00:00:00 2001 From: Phil Bastian Date: Thu, 21 Nov 2024 12:53:29 +0800 Subject: [PATCH 04/19] change connected application to dedicated collection and link to knownendpoints to allow for attached properties --- .../ConnectedApplicationsDataStore.cs | 39 ++++++++----------- .../Indexes/ConnectedApplicationIndex.cs | 20 ++++++++++ .../RavenMonitoringDataStore.cs | 8 +++- .../ConnectedApplication.cs | 9 +++++ .../EndpointDetails.cs | 2 + .../EndpointInstanceId.cs | 4 +- .../EndpointsView.cs | 1 + .../IConnectedApplicationsDataStore.cs | 7 ++-- .../IEndpointInstanceMonitoring.cs | 2 +- ...tEndpointSettingsSyncHostedServiceTests.cs | 2 +- .../Infrastructure/Api/ConfigurationApi.cs | 5 +-- .../Licensing/LicenseController.cs | 7 ++-- .../Monitoring/EndpointDetailsExtensions.cs | 2 +- .../Monitoring/EndpointInstanceMonitor.cs | 1 + .../Monitoring/EndpointInstanceMonitoring.cs | 4 +- .../InternalMessages/ConnectedApplication.cs | 1 + .../Transport/ConnectedApplicationHandler.cs | 13 ++++--- .../Monitoring/Transport/HeartbeatHandler.cs | 2 +- .../Operations/EndpointDetailsParser.cs | 7 ++-- 19 files changed, 86 insertions(+), 50 deletions(-) create mode 100644 src/ServiceControl.Persistence.RavenDB/Indexes/ConnectedApplicationIndex.cs create mode 100644 src/ServiceControl.Persistence/ConnectedApplication.cs diff --git a/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs b/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs index 96bc4c1476..80902c9138 100644 --- a/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs +++ b/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs @@ -1,38 +1,31 @@ namespace ServiceControl.Persistence.RavenDB { - using System.Collections.Generic; - using System.Linq; + using System.Threading; using System.Threading.Tasks; + using Raven.Client.Documents; + using Raven.Client.Documents.Session; + using ServiceControl.Persistence.Infrastructure; class ConnectedApplicationsDataStore(IRavenSessionProvider sessionProvider) : IConnectedApplicationsDataStore { - public async Task Add(string connectedApplication) - { - using var session = await sessionProvider.OpenSession(); - var connectedApplications = await session.LoadAsync(StorageKey) ?? new ConnectedApplications(); - - if (!connectedApplications.Applications.Any(application => string.Equals(application, connectedApplication, System.StringComparison.InvariantCultureIgnoreCase))) - { - connectedApplications.Applications.Add(connectedApplication); - } + public static string MakeDocumentId(string name) => $"{ConnectedApplication.CollectionName}/{DeterministicGuid.MakeId(name)}"; - await session.StoreAsync(connectedApplications, StorageKey); - await session.SaveChangesAsync(); + public async Task GetAllConnectedApplications() + { + using IAsyncDocumentSession session = await sessionProvider.OpenSession(); + return await session + .Query() + .ToArrayAsync(); } - public async Task> GetConnectedApplications() + public async Task UpdateConnectedApplication(ConnectedApplication connectedApplication, CancellationToken cancellationToken) { - using var session = await sessionProvider.OpenSession(); - var applications = await session.LoadAsync(StorageKey); + string docId = MakeDocumentId(connectedApplication.Name); - return applications?.Applications; - } + using IAsyncDocumentSession session = await sessionProvider.OpenSession(cancellationToken: cancellationToken); - class ConnectedApplications - { - public List Applications { get; set; } = []; + await session.StoreAsync(connectedApplication, docId, cancellationToken); + await session.SaveChangesAsync(cancellationToken); } - - const string StorageKey = "ConnectedApplications"; } } \ No newline at end of file diff --git a/src/ServiceControl.Persistence.RavenDB/Indexes/ConnectedApplicationIndex.cs b/src/ServiceControl.Persistence.RavenDB/Indexes/ConnectedApplicationIndex.cs new file mode 100644 index 0000000000..81a05d59a8 --- /dev/null +++ b/src/ServiceControl.Persistence.RavenDB/Indexes/ConnectedApplicationIndex.cs @@ -0,0 +1,20 @@ +namespace ServiceControl.Persistence +{ + using System.Linq; + using Raven.Client.Documents.Indexes; + + class ConnectedApplicationIndex : AbstractIndexCreationTask + { + public ConnectedApplicationIndex() + { + Map = applications => + + from application in applications + select new + { + application.Name, + application.SupportsHeartbeats + }; + } + } +} \ No newline at end of file diff --git a/src/ServiceControl.Persistence.RavenDB/RavenMonitoringDataStore.cs b/src/ServiceControl.Persistence.RavenDB/RavenMonitoringDataStore.cs index 494b92b788..98c8eabca1 100644 --- a/src/ServiceControl.Persistence.RavenDB/RavenMonitoringDataStore.cs +++ b/src/ServiceControl.Persistence.RavenDB/RavenMonitoringDataStore.cs @@ -2,6 +2,7 @@ { using System; using System.Collections.Generic; + using System.Linq; using System.Threading.Tasks; using Raven.Client.Documents; using ServiceControl.Operations; @@ -86,12 +87,17 @@ public async Task WarmupMonitoringFromPersistence(IEndpointInstanceMonitoring en { using var session = await sessionProvider.OpenSession(); await using var endpointsEnumerator = await session.Advanced.StreamAsync(session.Query()); + var connectedApplications = await session.Advanced.LoadStartingWithAsync(ConnectedApplication.CollectionName, pageSize: 1024); while (await endpointsEnumerator.MoveNextAsync()) { var endpoint = endpointsEnumerator.Current.Document; - endpointInstanceMonitoring.DetectEndpointFromPersistentStore(endpoint.EndpointDetails, endpoint.Monitored); + endpointInstanceMonitoring.DetectEndpointFromPersistentStore( + endpoint.EndpointDetails, + endpoint.Monitored, + connectedApplications.SingleOrDefault(ca => ConnectedApplicationsDataStore.MakeDocumentId(ca.Name) == endpoint.EndpointDetails.ConnectedApplicationId)?.SupportsHeartbeats ?? true + ); } } diff --git a/src/ServiceControl.Persistence/ConnectedApplication.cs b/src/ServiceControl.Persistence/ConnectedApplication.cs new file mode 100644 index 0000000000..969fe9ca83 --- /dev/null +++ b/src/ServiceControl.Persistence/ConnectedApplication.cs @@ -0,0 +1,9 @@ +namespace ServiceControl.Persistence; + +public class ConnectedApplication +{ + public string Name { get; set; } + public bool SupportsHeartbeats { get; set; } + + public const string CollectionName = "ConnectedApplications"; +} \ No newline at end of file diff --git a/src/ServiceControl.Persistence/EndpointDetails.cs b/src/ServiceControl.Persistence/EndpointDetails.cs index c123ab6dba..9c3c6ad00c 100644 --- a/src/ServiceControl.Persistence/EndpointDetails.cs +++ b/src/ServiceControl.Persistence/EndpointDetails.cs @@ -11,6 +11,8 @@ public class EndpointDetails public string Host { get; set; } + public string ConnectedApplicationId { get; set; } + public Guid GetDeterministicId() => DeterministicGuid.MakeId(Name, HostId.ToString()); } } \ No newline at end of file diff --git a/src/ServiceControl.Persistence/EndpointInstanceId.cs b/src/ServiceControl.Persistence/EndpointInstanceId.cs index 36d4448879..beb7876568 100644 --- a/src/ServiceControl.Persistence/EndpointInstanceId.cs +++ b/src/ServiceControl.Persistence/EndpointInstanceId.cs @@ -5,12 +5,13 @@ namespace ServiceControl.Persistence public class EndpointInstanceId : IEquatable { - public EndpointInstanceId(string logicalName, string hostName, Guid hostGuid) + public EndpointInstanceId(string logicalName, string hostName, Guid hostGuid, bool supportsHeartbeats) { LogicalName = logicalName; HostName = hostName; HostGuid = hostGuid; UniqueId = DeterministicGuid.MakeId(LogicalName, HostGuid.ToString()); + SupportsHeartbeats = supportsHeartbeats; } public Guid UniqueId { get; } @@ -49,5 +50,6 @@ public override int GetHashCode() public readonly string LogicalName; public readonly string HostName; public readonly Guid HostGuid; + public readonly bool SupportsHeartbeats; } } \ No newline at end of file diff --git a/src/ServiceControl.Persistence/EndpointsView.cs b/src/ServiceControl.Persistence/EndpointsView.cs index 7be54e4c01..8e2079b0d2 100644 --- a/src/ServiceControl.Persistence/EndpointsView.cs +++ b/src/ServiceControl.Persistence/EndpointsView.cs @@ -10,6 +10,7 @@ public class EndpointsView public bool Monitored { get; set; } public bool MonitorHeartbeat { get; set; } public HeartbeatInformation HeartbeatInformation { get; set; } + public bool SupportsHeartbeats { get; set; } public bool IsSendingHeartbeats { get; set; } } } \ No newline at end of file diff --git a/src/ServiceControl.Persistence/IConnectedApplicationsDataStore.cs b/src/ServiceControl.Persistence/IConnectedApplicationsDataStore.cs index dd45cc72ca..494c4ecfc6 100644 --- a/src/ServiceControl.Persistence/IConnectedApplicationsDataStore.cs +++ b/src/ServiceControl.Persistence/IConnectedApplicationsDataStore.cs @@ -1,11 +1,12 @@ namespace ServiceControl.Persistence { - using System.Collections.Generic; + using System.Threading; using System.Threading.Tasks; public interface IConnectedApplicationsDataStore { - Task Add(string connectedApplication); - Task> GetConnectedApplications(); + Task GetAllConnectedApplications(); + + Task UpdateConnectedApplication(ConnectedApplication connectedApplication, CancellationToken token); } } \ No newline at end of file diff --git a/src/ServiceControl.Persistence/IEndpointInstanceMonitoring.cs b/src/ServiceControl.Persistence/IEndpointInstanceMonitoring.cs index 63b6788289..0b8d29df86 100644 --- a/src/ServiceControl.Persistence/IEndpointInstanceMonitoring.cs +++ b/src/ServiceControl.Persistence/IEndpointInstanceMonitoring.cs @@ -9,7 +9,7 @@ public interface IEndpointInstanceMonitoring { Task CheckEndpoints(DateTime threshold); Task DetectEndpointFromHeartbeatStartup(EndpointDetails newEndpointDetails, DateTime startedAt); - void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored); + void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored, bool supportsHeartbeats); Task DisableMonitoring(Guid id); Task EnableMonitoring(Guid id); Task EndpointDetected(EndpointDetails newEndpointDetails); diff --git a/src/ServiceControl.UnitTests/Monitoring/HeartbeatEndpointSettingsSyncHostedServiceTests.cs b/src/ServiceControl.UnitTests/Monitoring/HeartbeatEndpointSettingsSyncHostedServiceTests.cs index 6189431088..103f761cfb 100644 --- a/src/ServiceControl.UnitTests/Monitoring/HeartbeatEndpointSettingsSyncHostedServiceTests.cs +++ b/src/ServiceControl.UnitTests/Monitoring/HeartbeatEndpointSettingsSyncHostedServiceTests.cs @@ -211,7 +211,7 @@ class MockEndpointInstanceMonitoring(EndpointsView[] endpointsViews) : IEndpoint public Task DetectEndpointFromHeartbeatStartup(EndpointDetails newEndpointDetails, DateTime startedAt) => throw new NotImplementedException(); - public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored) => + public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored, bool supportsHeartbeats) => throw new NotImplementedException(); public Task DisableMonitoring(Guid id) => throw new NotImplementedException(); diff --git a/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs b/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs index 4212fc51c5..faa1c905cd 100644 --- a/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs +++ b/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs @@ -85,10 +85,7 @@ public async Task GetConfig(CancellationToken cancellationToken) { settings.HeartbeatGracePeriod }, - ConnectedApplications = new - { - ConnectedApplications = await connectedApplicationsDataStore.GetConnectedApplications() - } + ConnectedApplications = await connectedApplicationsDataStore.GetAllConnectedApplications(), }; return content; diff --git a/src/ServiceControl/Licensing/LicenseController.cs b/src/ServiceControl/Licensing/LicenseController.cs index 75cd044f58..1d7d2e0ac9 100644 --- a/src/ServiceControl/Licensing/LicenseController.cs +++ b/src/ServiceControl/Licensing/LicenseController.cs @@ -1,5 +1,6 @@ namespace ServiceControl.Licensing { + using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; @@ -39,10 +40,10 @@ public async Task> License(bool refresh, string client async Task BuildConnectedApplicationsListPart() { - var connectedApplications = await connectedApplicationsStore.GetConnectedApplications(); + var connectedApplications = await connectedApplicationsStore.GetAllConnectedApplications(); - return connectedApplications != null - ? $"&ca={string.Join(',', connectedApplications)}" + return connectedApplications != null && connectedApplications.Length > 0 + ? $"&ca={string.Join(',', connectedApplications.Select(ca => ca.Name))}" : string.Empty; } diff --git a/src/ServiceControl/Monitoring/EndpointDetailsExtensions.cs b/src/ServiceControl/Monitoring/EndpointDetailsExtensions.cs index 939dc8e8e5..1a947bcc42 100644 --- a/src/ServiceControl/Monitoring/EndpointDetailsExtensions.cs +++ b/src/ServiceControl/Monitoring/EndpointDetailsExtensions.cs @@ -7,7 +7,7 @@ public static class EndpointDetailsExtensions { public static EndpointInstanceId ToInstanceId(this EndpointDetails endpointDetails) { - return new EndpointInstanceId(endpointDetails.Name, endpointDetails.Host, endpointDetails.HostId); + return new EndpointInstanceId(endpointDetails.Name, endpointDetails.Host, endpointDetails.HostId, true); } } } \ No newline at end of file diff --git a/src/ServiceControl/Monitoring/EndpointInstanceMonitor.cs b/src/ServiceControl/Monitoring/EndpointInstanceMonitor.cs index 355499d519..562326eb8f 100644 --- a/src/ServiceControl/Monitoring/EndpointInstanceMonitor.cs +++ b/src/ServiceControl/Monitoring/EndpointInstanceMonitor.cs @@ -116,6 +116,7 @@ public EndpointsView GetView() HostDisplayName = Id.HostName, Monitored = Monitored, MonitorHeartbeat = Monitored, + SupportsHeartbeats = Id.SupportsHeartbeats, HeartbeatInformation = lastSeen.HasValue ? new HeartbeatInformation { diff --git a/src/ServiceControl/Monitoring/EndpointInstanceMonitoring.cs b/src/ServiceControl/Monitoring/EndpointInstanceMonitoring.cs index 0829135c43..63ba7b16d3 100644 --- a/src/ServiceControl/Monitoring/EndpointInstanceMonitoring.cs +++ b/src/ServiceControl/Monitoring/EndpointInstanceMonitoring.cs @@ -73,9 +73,9 @@ await domainEvents.Raise(new EndpointStarted }); } - public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored) + public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored, bool supportsHeartbeats) { - var endpointInstanceId = new EndpointInstanceId(endpointDetails.Name, endpointDetails.Host, endpointDetails.HostId); + var endpointInstanceId = new EndpointInstanceId(endpointDetails.Name, endpointDetails.Host, endpointDetails.HostId, supportsHeartbeats); endpoints.GetOrAdd(endpointInstanceId.UniqueId, id => new EndpointInstanceMonitor(endpointInstanceId, monitored, domainEvents)); } diff --git a/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs b/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs index 734005b487..2f2c7b9210 100644 --- a/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs +++ b/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs @@ -5,5 +5,6 @@ public class ConnectedApplication : IMessage { public string Application { get; set; } + public bool SupportsHeartbeats { get; set; } public string[] ErrorQueues { get; set; } } diff --git a/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs b/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs index e78dbc0b01..32ce090b84 100644 --- a/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs +++ b/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs @@ -2,16 +2,19 @@ { using System.Threading.Tasks; using NServiceBus; - using ServiceControl.Monitoring; using ServiceControl.Persistence; + using ConnectedApplication = ConnectedApplication; public class ConnectedApplicationHandler(IConnectedApplicationsDataStore connectedApplicationsDataStore) : IHandleMessages { - public Task Handle(ConnectedApplication message, IMessageHandlerContext context) + public async Task Handle(ConnectedApplication message, IMessageHandlerContext context) { - _ = connectedApplicationsDataStore.Add(message.Application); - - return Task.CompletedTask; + var connectedApplication = new Persistence.ConnectedApplication + { + Name = message.Application, + SupportsHeartbeats = message.SupportsHeartbeats + }; + await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication, context.CancellationToken); } } } diff --git a/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs b/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs index ccb1675063..be1b0c7797 100644 --- a/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs +++ b/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs @@ -14,7 +14,7 @@ public HeartbeatHandler(IEndpointInstanceMonitoring monitor) public Task Handle(EndpointHeartbeat message, IMessageHandlerContext context) { - var endpointInstanceId = new EndpointInstanceId(message.EndpointName, message.Host, message.HostId); + var endpointInstanceId = new EndpointInstanceId(message.EndpointName, message.Host, message.HostId, true); monitor.RecordHeartbeat(endpointInstanceId, message.ExecutedAt); diff --git a/src/ServiceControl/Operations/EndpointDetailsParser.cs b/src/ServiceControl/Operations/EndpointDetailsParser.cs index 557295e478..7665dedda6 100644 --- a/src/ServiceControl/Operations/EndpointDetailsParser.cs +++ b/src/ServiceControl/Operations/EndpointDetailsParser.cs @@ -5,6 +5,7 @@ namespace ServiceControl.Contracts.Operations using Infrastructure; using NServiceBus; using ServiceControl.Operations; + using ServiceControl.Persistence; class EndpointDetailsParser { @@ -39,10 +40,8 @@ public static EndpointDetails ReceivingEndpoint(IReadOnlyDictionary endpoint.HostId = Guid.Parse(s)); + DictionaryExtensions.CheckIfKeyExists("NServiceBus.ConnectedApplication", headers, s => endpoint.ConnectedApplicationId = $"{ConnectedApplication.CollectionName}/{DeterministicGuid.MakeId(s)}"); if (headers.TryGetValue(Headers.HostDisplayName, out var hostDisplayNameHeader)) { From 0697d0a1cbda1a9f8cb85b6845f0791c390333dc Mon Sep 17 00:00:00 2001 From: Phil Bastian Date: Mon, 25 Nov 2024 13:04:14 +0800 Subject: [PATCH 05/19] fix test projects --- .../ConnectedApplicationsTests.cs | 13 +++++++------ .../Monitoring/EndpointInstanceMonitoringTests.cs | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs b/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs index 760279079f..34f1d1fd96 100644 --- a/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs +++ b/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs @@ -1,5 +1,6 @@ namespace ServiceControl.Persistence.Tests.RavenDB.ConnectedApplications { + using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using NUnit.Framework; @@ -19,15 +20,15 @@ public async Task ConnectedApplications_can_be_saved() { var connectedApplicationsDataStore = ServiceProvider.GetRequiredService(); - var connectedApplication1 = "ServiceControl.Connector.MassTransit"; - var connectedApplication2 = "ServiceControl.Connector.Kafka"; + var connectedApplication1 = new ConnectedApplication { Name = "ServiceControl.Connector.MassTransit" }; + var connectedApplication2 = new ConnectedApplication { Name = "ServiceControl.Connector.Kafka" }; - await connectedApplicationsDataStore.Add(connectedApplication1).ConfigureAwait(false); - await connectedApplicationsDataStore.Add(connectedApplication2).ConfigureAwait(false); + await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication1, new System.Threading.CancellationToken()).ConfigureAwait(false); + await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication2, new System.Threading.CancellationToken()).ConfigureAwait(false); - var result = await connectedApplicationsDataStore.GetConnectedApplications(); + var result = await connectedApplicationsDataStore.GetAllConnectedApplications(); - Assert.That(result, Is.EqualTo(new[] { connectedApplication1, connectedApplication2 }).AsCollection); + Assert.That(result.Select(x => x.Name), Is.EqualTo(new[] { connectedApplication1.Name, connectedApplication2.Name }).AsCollection); } } } \ No newline at end of file diff --git a/src/ServiceControl.UnitTests/Monitoring/EndpointInstanceMonitoringTests.cs b/src/ServiceControl.UnitTests/Monitoring/EndpointInstanceMonitoringTests.cs index d1ad39c947..cc9996fbae 100644 --- a/src/ServiceControl.UnitTests/Monitoring/EndpointInstanceMonitoringTests.cs +++ b/src/ServiceControl.UnitTests/Monitoring/EndpointInstanceMonitoringTests.cs @@ -14,7 +14,7 @@ public async Task When_endpoint_removed_should_stay_removed() { var monitor = new EndpointInstanceMonitoring(new FakeDomainEvents()); - var monitoredEndpoint = new EndpointInstanceId("MonitoredEndpoint", "HostName", Guid.NewGuid()); + var monitoredEndpoint = new EndpointInstanceId("MonitoredEndpoint", "HostName", Guid.NewGuid(), true); var lastHeartbeat = DateTime.UtcNow; monitor.RecordHeartbeat(monitoredEndpoint, lastHeartbeat); From b4f4c6ba50a39e769270bdec34e9950e26107249 Mon Sep 17 00:00:00 2001 From: Phil Bastian <155411597+PhilBastian@users.noreply.github.com> Date: Wed, 27 Nov 2024 07:13:11 +0800 Subject: [PATCH 06/19] Update src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs Co-authored-by: John Simons --- .../ConnectedApplications/ConnectedApplicationsTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs b/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs index 34f1d1fd96..3a28ddb620 100644 --- a/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs +++ b/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs @@ -23,8 +23,8 @@ public async Task ConnectedApplications_can_be_saved() var connectedApplication1 = new ConnectedApplication { Name = "ServiceControl.Connector.MassTransit" }; var connectedApplication2 = new ConnectedApplication { Name = "ServiceControl.Connector.Kafka" }; - await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication1, new System.Threading.CancellationToken()).ConfigureAwait(false); - await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication2, new System.Threading.CancellationToken()).ConfigureAwait(false); + await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication1, CancellationToken.None).ConfigureAwait(false); + await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication2, CancellationToken.None).ConfigureAwait(false); var result = await connectedApplicationsDataStore.GetAllConnectedApplications(); From 7e0a1688fa69a8126add12e95cf46dba3a477ca0 Mon Sep 17 00:00:00 2001 From: Phil Bastian Date: Fri, 29 Nov 2024 10:48:01 +0800 Subject: [PATCH 07/19] fix missing using --- .../ConnectedApplications/ConnectedApplicationsTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs b/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs index 3a28ddb620..dc5d7d730a 100644 --- a/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs +++ b/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs @@ -1,6 +1,7 @@ namespace ServiceControl.Persistence.Tests.RavenDB.ConnectedApplications { using System.Linq; + using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.DependencyInjection; using NUnit.Framework; From fd7573820afa3da3e1ac6ad3ba47223f745a59f0 Mon Sep 17 00:00:00 2001 From: John Simons Date: Thu, 5 Dec 2024 11:06:59 +1000 Subject: [PATCH 08/19] Let endpoint details include only queue name --- .../ConnectedApplicationsDataStore.cs | 5 +---- .../EndpointDetailsParser.cs | 2 +- .../RavenMonitoringDataStore.cs | 2 +- src/ServiceControl.Persistence/ConnectedApplication.cs | 4 ++++ src/ServiceControl/Operations/EndpointDetailsParser.cs | 5 +++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs b/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs index 80902c9138..608deebe3a 100644 --- a/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs +++ b/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs @@ -4,12 +4,9 @@ using System.Threading.Tasks; using Raven.Client.Documents; using Raven.Client.Documents.Session; - using ServiceControl.Persistence.Infrastructure; class ConnectedApplicationsDataStore(IRavenSessionProvider sessionProvider) : IConnectedApplicationsDataStore { - public static string MakeDocumentId(string name) => $"{ConnectedApplication.CollectionName}/{DeterministicGuid.MakeId(name)}"; - public async Task GetAllConnectedApplications() { using IAsyncDocumentSession session = await sessionProvider.OpenSession(); @@ -20,7 +17,7 @@ public async Task GetAllConnectedApplications() public async Task UpdateConnectedApplication(ConnectedApplication connectedApplication, CancellationToken cancellationToken) { - string docId = MakeDocumentId(connectedApplication.Name); + string docId = ConnectedApplication.MakeDocumentId(connectedApplication.Name); using IAsyncDocumentSession session = await sessionProvider.OpenSession(cancellationToken: cancellationToken); diff --git a/src/ServiceControl.Persistence.RavenDB/EndpointDetailsParser.cs b/src/ServiceControl.Persistence.RavenDB/EndpointDetailsParser.cs index 1cda01af30..8d2ce553b2 100644 --- a/src/ServiceControl.Persistence.RavenDB/EndpointDetailsParser.cs +++ b/src/ServiceControl.Persistence.RavenDB/EndpointDetailsParser.cs @@ -80,7 +80,7 @@ public static EndpointDetails ReceivingEndpoint(IReadOnlyDictionary ConnectedApplicationsDataStore.MakeDocumentId(ca.Name) == endpoint.EndpointDetails.ConnectedApplicationId)?.SupportsHeartbeats ?? true + connectedApplications.SingleOrDefault(ca => ConnectedApplication.MakeDocumentId(ca.Name) == endpoint.EndpointDetails.ConnectedApplicationId)?.SupportsHeartbeats ?? true ); } } diff --git a/src/ServiceControl.Persistence/ConnectedApplication.cs b/src/ServiceControl.Persistence/ConnectedApplication.cs index 969fe9ca83..aef51bbb82 100644 --- a/src/ServiceControl.Persistence/ConnectedApplication.cs +++ b/src/ServiceControl.Persistence/ConnectedApplication.cs @@ -1,9 +1,13 @@ namespace ServiceControl.Persistence; +using Infrastructure; + public class ConnectedApplication { public string Name { get; set; } public bool SupportsHeartbeats { get; set; } public const string CollectionName = "ConnectedApplications"; + + public static string MakeDocumentId(string name) => $"{CollectionName}/{DeterministicGuid.MakeId(name)}"; } \ No newline at end of file diff --git a/src/ServiceControl/Operations/EndpointDetailsParser.cs b/src/ServiceControl/Operations/EndpointDetailsParser.cs index 7665dedda6..0eb3f9e759 100644 --- a/src/ServiceControl/Operations/EndpointDetailsParser.cs +++ b/src/ServiceControl/Operations/EndpointDetailsParser.cs @@ -41,7 +41,8 @@ public static EndpointDetails ReceivingEndpoint(IReadOnlyDictionary endpoint.HostId = Guid.Parse(s)); - DictionaryExtensions.CheckIfKeyExists("NServiceBus.ConnectedApplication", headers, s => endpoint.ConnectedApplicationId = $"{ConnectedApplication.CollectionName}/{DeterministicGuid.MakeId(s)}"); + DictionaryExtensions.CheckIfKeyExists("NServiceBus.ConnectedApplication", headers, + s => endpoint.ConnectedApplicationId = ConnectedApplication.MakeDocumentId(s)); if (headers.TryGetValue(Headers.HostDisplayName, out var hostDisplayNameHeader)) { @@ -79,7 +80,7 @@ public static EndpointDetails ReceivingEndpoint(IReadOnlyDictionary Date: Wed, 11 Dec 2024 11:43:51 +1000 Subject: [PATCH 09/19] Fix test --- .../ConnectedApplicationsDataStore.cs | 2 +- .../Indexes/ConnectedApplicationIndex.cs | 20 ------------------- 2 files changed, 1 insertion(+), 21 deletions(-) delete mode 100644 src/ServiceControl.Persistence.RavenDB/Indexes/ConnectedApplicationIndex.cs diff --git a/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs b/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs index 608deebe3a..69262b15da 100644 --- a/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs +++ b/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs @@ -11,7 +11,7 @@ public async Task GetAllConnectedApplications() { using IAsyncDocumentSession session = await sessionProvider.OpenSession(); return await session - .Query() + .Query() .ToArrayAsync(); } diff --git a/src/ServiceControl.Persistence.RavenDB/Indexes/ConnectedApplicationIndex.cs b/src/ServiceControl.Persistence.RavenDB/Indexes/ConnectedApplicationIndex.cs deleted file mode 100644 index 81a05d59a8..0000000000 --- a/src/ServiceControl.Persistence.RavenDB/Indexes/ConnectedApplicationIndex.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace ServiceControl.Persistence -{ - using System.Linq; - using Raven.Client.Documents.Indexes; - - class ConnectedApplicationIndex : AbstractIndexCreationTask - { - public ConnectedApplicationIndex() - { - Map = applications => - - from application in applications - select new - { - application.Name, - application.SupportsHeartbeats - }; - } - } -} \ No newline at end of file From 96a21c28c35debd9a4174b8fce6476e50c4d0623 Mon Sep 17 00:00:00 2001 From: John Simons Date: Fri, 17 Jan 2025 16:38:39 +1000 Subject: [PATCH 10/19] Remove connectapplications We replacing it with a specific implementation --- .../ConnectedApplicationsDataStore.cs | 28 --------------- .../EndpointDetailsParser.cs | 2 +- .../RavenMonitoringDataStore.cs | 8 +---- .../RavenPersistence.cs | 1 - .../ConnectedApplicationsTests.cs | 35 ------------------- .../ConnectedApplication.cs | 13 ------- .../EndpointDetails.cs | 2 -- .../EndpointInstanceId.cs | 3 +- .../EndpointsView.cs | 1 - .../IConnectedApplicationsDataStore.cs | 12 ------- .../IEndpointInstanceMonitoring.cs | 2 +- .../API/APIApprovals.cs | 1 - .../EndpointInstanceMonitoringTests.cs | 2 +- ...tEndpointSettingsSyncHostedServiceTests.cs | 2 +- .../Infrastructure/Api/ConfigurationApi.cs | 11 +++--- .../Licensing/LicenseController.cs | 15 ++------ .../Monitoring/EndpointDetailsExtensions.cs | 2 +- .../Monitoring/EndpointInstanceMonitor.cs | 2 -- .../Monitoring/EndpointInstanceMonitoring.cs | 4 +-- .../InternalMessages/ConnectedApplication.cs | 10 ------ .../Transport/ConnectedApplicationHandler.cs | 20 ----------- .../Monitoring/Transport/HeartbeatHandler.cs | 2 +- .../Operations/EndpointDetailsParser.cs | 10 +++--- 23 files changed, 23 insertions(+), 165 deletions(-) delete mode 100644 src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs delete mode 100644 src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs delete mode 100644 src/ServiceControl.Persistence/ConnectedApplication.cs delete mode 100644 src/ServiceControl.Persistence/IConnectedApplicationsDataStore.cs delete mode 100644 src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs delete mode 100644 src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs diff --git a/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs b/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs deleted file mode 100644 index 69262b15da..0000000000 --- a/src/ServiceControl.Persistence.RavenDB/ConnectedApplicationsDataStore.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace ServiceControl.Persistence.RavenDB -{ - using System.Threading; - using System.Threading.Tasks; - using Raven.Client.Documents; - using Raven.Client.Documents.Session; - - class ConnectedApplicationsDataStore(IRavenSessionProvider sessionProvider) : IConnectedApplicationsDataStore - { - public async Task GetAllConnectedApplications() - { - using IAsyncDocumentSession session = await sessionProvider.OpenSession(); - return await session - .Query() - .ToArrayAsync(); - } - - public async Task UpdateConnectedApplication(ConnectedApplication connectedApplication, CancellationToken cancellationToken) - { - string docId = ConnectedApplication.MakeDocumentId(connectedApplication.Name); - - using IAsyncDocumentSession session = await sessionProvider.OpenSession(cancellationToken: cancellationToken); - - await session.StoreAsync(connectedApplication, docId, cancellationToken); - await session.SaveChangesAsync(cancellationToken); - } - } -} \ No newline at end of file diff --git a/src/ServiceControl.Persistence.RavenDB/EndpointDetailsParser.cs b/src/ServiceControl.Persistence.RavenDB/EndpointDetailsParser.cs index 8d2ce553b2..1cda01af30 100644 --- a/src/ServiceControl.Persistence.RavenDB/EndpointDetailsParser.cs +++ b/src/ServiceControl.Persistence.RavenDB/EndpointDetailsParser.cs @@ -80,7 +80,7 @@ public static EndpointDetails ReceivingEndpoint(IReadOnlyDictionary()); - var connectedApplications = await session.Advanced.LoadStartingWithAsync(ConnectedApplication.CollectionName, pageSize: 1024); while (await endpointsEnumerator.MoveNextAsync()) { var endpoint = endpointsEnumerator.Current.Document; - endpointInstanceMonitoring.DetectEndpointFromPersistentStore( - endpoint.EndpointDetails, - endpoint.Monitored, - connectedApplications.SingleOrDefault(ca => ConnectedApplication.MakeDocumentId(ca.Name) == endpoint.EndpointDetails.ConnectedApplicationId)?.SupportsHeartbeats ?? true - ); + endpointInstanceMonitoring.DetectEndpointFromPersistentStore(endpoint.EndpointDetails, endpoint.Monitored); } } diff --git a/src/ServiceControl.Persistence.RavenDB/RavenPersistence.cs b/src/ServiceControl.Persistence.RavenDB/RavenPersistence.cs index 335e8a8d4f..7b1e07ecbb 100644 --- a/src/ServiceControl.Persistence.RavenDB/RavenPersistence.cs +++ b/src/ServiceControl.Persistence.RavenDB/RavenPersistence.cs @@ -66,7 +66,6 @@ public void AddPersistence(IServiceCollection services) services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); } public void AddInstaller(IServiceCollection services) diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs b/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs deleted file mode 100644 index dc5d7d730a..0000000000 --- a/src/ServiceControl.Persistence.Tests.RavenDB/ConnectedApplications/ConnectedApplicationsTests.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace ServiceControl.Persistence.Tests.RavenDB.ConnectedApplications -{ - using System.Linq; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.Extensions.DependencyInjection; - using NUnit.Framework; - using ServiceControl.Persistence.RavenDB; - - [TestFixture] - class ConnectedApplicationsTests : RavenPersistenceTestBase - { - public ConnectedApplicationsTests() => - RegisterServices = services => - { - services.AddSingleton(); - }; - - [Test] - public async Task ConnectedApplications_can_be_saved() - { - var connectedApplicationsDataStore = ServiceProvider.GetRequiredService(); - - var connectedApplication1 = new ConnectedApplication { Name = "ServiceControl.Connector.MassTransit" }; - var connectedApplication2 = new ConnectedApplication { Name = "ServiceControl.Connector.Kafka" }; - - await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication1, CancellationToken.None).ConfigureAwait(false); - await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication2, CancellationToken.None).ConfigureAwait(false); - - var result = await connectedApplicationsDataStore.GetAllConnectedApplications(); - - Assert.That(result.Select(x => x.Name), Is.EqualTo(new[] { connectedApplication1.Name, connectedApplication2.Name }).AsCollection); - } - } -} \ No newline at end of file diff --git a/src/ServiceControl.Persistence/ConnectedApplication.cs b/src/ServiceControl.Persistence/ConnectedApplication.cs deleted file mode 100644 index aef51bbb82..0000000000 --- a/src/ServiceControl.Persistence/ConnectedApplication.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace ServiceControl.Persistence; - -using Infrastructure; - -public class ConnectedApplication -{ - public string Name { get; set; } - public bool SupportsHeartbeats { get; set; } - - public const string CollectionName = "ConnectedApplications"; - - public static string MakeDocumentId(string name) => $"{CollectionName}/{DeterministicGuid.MakeId(name)}"; -} \ No newline at end of file diff --git a/src/ServiceControl.Persistence/EndpointDetails.cs b/src/ServiceControl.Persistence/EndpointDetails.cs index 9c3c6ad00c..c123ab6dba 100644 --- a/src/ServiceControl.Persistence/EndpointDetails.cs +++ b/src/ServiceControl.Persistence/EndpointDetails.cs @@ -11,8 +11,6 @@ public class EndpointDetails public string Host { get; set; } - public string ConnectedApplicationId { get; set; } - public Guid GetDeterministicId() => DeterministicGuid.MakeId(Name, HostId.ToString()); } } \ No newline at end of file diff --git a/src/ServiceControl.Persistence/EndpointInstanceId.cs b/src/ServiceControl.Persistence/EndpointInstanceId.cs index beb7876568..42ff79c8fc 100644 --- a/src/ServiceControl.Persistence/EndpointInstanceId.cs +++ b/src/ServiceControl.Persistence/EndpointInstanceId.cs @@ -5,13 +5,12 @@ namespace ServiceControl.Persistence public class EndpointInstanceId : IEquatable { - public EndpointInstanceId(string logicalName, string hostName, Guid hostGuid, bool supportsHeartbeats) + public EndpointInstanceId(string logicalName, string hostName, Guid hostGuid) { LogicalName = logicalName; HostName = hostName; HostGuid = hostGuid; UniqueId = DeterministicGuid.MakeId(LogicalName, HostGuid.ToString()); - SupportsHeartbeats = supportsHeartbeats; } public Guid UniqueId { get; } diff --git a/src/ServiceControl.Persistence/EndpointsView.cs b/src/ServiceControl.Persistence/EndpointsView.cs index 8e2079b0d2..7be54e4c01 100644 --- a/src/ServiceControl.Persistence/EndpointsView.cs +++ b/src/ServiceControl.Persistence/EndpointsView.cs @@ -10,7 +10,6 @@ public class EndpointsView public bool Monitored { get; set; } public bool MonitorHeartbeat { get; set; } public HeartbeatInformation HeartbeatInformation { get; set; } - public bool SupportsHeartbeats { get; set; } public bool IsSendingHeartbeats { get; set; } } } \ No newline at end of file diff --git a/src/ServiceControl.Persistence/IConnectedApplicationsDataStore.cs b/src/ServiceControl.Persistence/IConnectedApplicationsDataStore.cs deleted file mode 100644 index 494c4ecfc6..0000000000 --- a/src/ServiceControl.Persistence/IConnectedApplicationsDataStore.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ServiceControl.Persistence -{ - using System.Threading; - using System.Threading.Tasks; - - public interface IConnectedApplicationsDataStore - { - Task GetAllConnectedApplications(); - - Task UpdateConnectedApplication(ConnectedApplication connectedApplication, CancellationToken token); - } -} \ No newline at end of file diff --git a/src/ServiceControl.Persistence/IEndpointInstanceMonitoring.cs b/src/ServiceControl.Persistence/IEndpointInstanceMonitoring.cs index 0b8d29df86..63b6788289 100644 --- a/src/ServiceControl.Persistence/IEndpointInstanceMonitoring.cs +++ b/src/ServiceControl.Persistence/IEndpointInstanceMonitoring.cs @@ -9,7 +9,7 @@ public interface IEndpointInstanceMonitoring { Task CheckEndpoints(DateTime threshold); Task DetectEndpointFromHeartbeatStartup(EndpointDetails newEndpointDetails, DateTime startedAt); - void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored, bool supportsHeartbeats); + void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored); Task DisableMonitoring(Guid id); Task EnableMonitoring(Guid id); Task EndpointDetected(EndpointDetails newEndpointDetails); diff --git a/src/ServiceControl.UnitTests/API/APIApprovals.cs b/src/ServiceControl.UnitTests/API/APIApprovals.cs index 4e8708febb..80247a93eb 100644 --- a/src/ServiceControl.UnitTests/API/APIApprovals.cs +++ b/src/ServiceControl.UnitTests/API/APIApprovals.cs @@ -33,7 +33,6 @@ public async Task RootPathValue() var controller = new RootController(new ConfigurationApi( new ActiveLicense(null) { IsValid = true }, new Settings(), - null, null ) ) diff --git a/src/ServiceControl.UnitTests/Monitoring/EndpointInstanceMonitoringTests.cs b/src/ServiceControl.UnitTests/Monitoring/EndpointInstanceMonitoringTests.cs index cc9996fbae..d1ad39c947 100644 --- a/src/ServiceControl.UnitTests/Monitoring/EndpointInstanceMonitoringTests.cs +++ b/src/ServiceControl.UnitTests/Monitoring/EndpointInstanceMonitoringTests.cs @@ -14,7 +14,7 @@ public async Task When_endpoint_removed_should_stay_removed() { var monitor = new EndpointInstanceMonitoring(new FakeDomainEvents()); - var monitoredEndpoint = new EndpointInstanceId("MonitoredEndpoint", "HostName", Guid.NewGuid(), true); + var monitoredEndpoint = new EndpointInstanceId("MonitoredEndpoint", "HostName", Guid.NewGuid()); var lastHeartbeat = DateTime.UtcNow; monitor.RecordHeartbeat(monitoredEndpoint, lastHeartbeat); diff --git a/src/ServiceControl.UnitTests/Monitoring/HeartbeatEndpointSettingsSyncHostedServiceTests.cs b/src/ServiceControl.UnitTests/Monitoring/HeartbeatEndpointSettingsSyncHostedServiceTests.cs index 103f761cfb..6189431088 100644 --- a/src/ServiceControl.UnitTests/Monitoring/HeartbeatEndpointSettingsSyncHostedServiceTests.cs +++ b/src/ServiceControl.UnitTests/Monitoring/HeartbeatEndpointSettingsSyncHostedServiceTests.cs @@ -211,7 +211,7 @@ class MockEndpointInstanceMonitoring(EndpointsView[] endpointsViews) : IEndpoint public Task DetectEndpointFromHeartbeatStartup(EndpointDetails newEndpointDetails, DateTime startedAt) => throw new NotImplementedException(); - public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored, bool supportsHeartbeats) => + public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored) => throw new NotImplementedException(); public Task DisableMonitoring(Guid id) => throw new NotImplementedException(); diff --git a/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs b/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs index faa1c905cd..793f1184da 100644 --- a/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs +++ b/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs @@ -12,11 +12,9 @@ using ServiceBus.Management.Infrastructure.Settings; using ServiceControl.Api; using ServiceControl.Api.Contracts; -using ServiceControl.Persistence; class ConfigurationApi(ActiveLicense license, Settings settings, - IConnectedApplicationsDataStore connectedApplicationsDataStore, IHttpClientFactory httpClientFactory) : IConfigurationApi { public Task GetUrls(string baseUrl, CancellationToken cancellationToken) @@ -51,7 +49,7 @@ public Task GetUrls(string baseUrl, CancellationToken cancellationToke } - public async Task GetConfig(CancellationToken cancellationToken) + public Task GetConfig(CancellationToken cancellationToken) { object content = new { @@ -85,10 +83,13 @@ public async Task GetConfig(CancellationToken cancellationToken) { settings.HeartbeatGracePeriod }, - ConnectedApplications = await connectedApplicationsDataStore.GetAllConnectedApplications(), + MassTransitConnector = new + { + foobar = "barfoo" + } }; - return content; + return Task.FromResult(content); } public async Task GetRemoteConfigs(CancellationToken cancellationToken = default) diff --git a/src/ServiceControl/Licensing/LicenseController.cs b/src/ServiceControl/Licensing/LicenseController.cs index 1d7d2e0ac9..09303eb166 100644 --- a/src/ServiceControl/Licensing/LicenseController.cs +++ b/src/ServiceControl/Licensing/LicenseController.cs @@ -1,16 +1,14 @@ namespace ServiceControl.Licensing { - using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Particular.ServiceControl.Licensing; - using Persistence; using ServiceBus.Management.Infrastructure.Settings; [ApiController] [Route("api")] - public class LicenseController(ActiveLicense activeLicense, Settings settings, IConnectedApplicationsDataStore connectedApplicationsStore) : ControllerBase + public class LicenseController(ActiveLicense activeLicense, Settings settings) : ControllerBase { [HttpGet] [Route("license")] @@ -32,21 +30,12 @@ public async Task> License(bool refresh, string client LicenseType = activeLicense.Details.LicenseType ?? string.Empty, InstanceName = settings.InstanceName ?? string.Empty, LicenseStatus = activeLicense.Details.Status, - LicenseExtensionUrl = $"https://particular.net/extend-your-trial?p={clientName}{await BuildConnectedApplicationsListPart()}" + LicenseExtensionUrl = $"https://particular.net/extend-your-trial?p={clientName}" }; return licenseInfo; } - async Task BuildConnectedApplicationsListPart() - { - var connectedApplications = await connectedApplicationsStore.GetAllConnectedApplications(); - - return connectedApplications != null && connectedApplications.Length > 0 - ? $"&ca={string.Join(',', connectedApplications.Select(ca => ca.Name))}" - : string.Empty; - } - public class LicenseInfo { public bool TrialLicense { get; set; } diff --git a/src/ServiceControl/Monitoring/EndpointDetailsExtensions.cs b/src/ServiceControl/Monitoring/EndpointDetailsExtensions.cs index 1a947bcc42..939dc8e8e5 100644 --- a/src/ServiceControl/Monitoring/EndpointDetailsExtensions.cs +++ b/src/ServiceControl/Monitoring/EndpointDetailsExtensions.cs @@ -7,7 +7,7 @@ public static class EndpointDetailsExtensions { public static EndpointInstanceId ToInstanceId(this EndpointDetails endpointDetails) { - return new EndpointInstanceId(endpointDetails.Name, endpointDetails.Host, endpointDetails.HostId, true); + return new EndpointInstanceId(endpointDetails.Name, endpointDetails.Host, endpointDetails.HostId); } } } \ No newline at end of file diff --git a/src/ServiceControl/Monitoring/EndpointInstanceMonitor.cs b/src/ServiceControl/Monitoring/EndpointInstanceMonitor.cs index 562326eb8f..7a375746ed 100644 --- a/src/ServiceControl/Monitoring/EndpointInstanceMonitor.cs +++ b/src/ServiceControl/Monitoring/EndpointInstanceMonitor.cs @@ -5,7 +5,6 @@ namespace ServiceControl.Monitoring using Contracts.HeartbeatMonitoring; using EndpointControl.Contracts; using Infrastructure.DomainEvents; - using NLog.Fluent; using NServiceBus.Logging; using ServiceControl.Operations; using ServiceControl.Persistence; @@ -116,7 +115,6 @@ public EndpointsView GetView() HostDisplayName = Id.HostName, Monitored = Monitored, MonitorHeartbeat = Monitored, - SupportsHeartbeats = Id.SupportsHeartbeats, HeartbeatInformation = lastSeen.HasValue ? new HeartbeatInformation { diff --git a/src/ServiceControl/Monitoring/EndpointInstanceMonitoring.cs b/src/ServiceControl/Monitoring/EndpointInstanceMonitoring.cs index 63ba7b16d3..0829135c43 100644 --- a/src/ServiceControl/Monitoring/EndpointInstanceMonitoring.cs +++ b/src/ServiceControl/Monitoring/EndpointInstanceMonitoring.cs @@ -73,9 +73,9 @@ await domainEvents.Raise(new EndpointStarted }); } - public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored, bool supportsHeartbeats) + public void DetectEndpointFromPersistentStore(EndpointDetails endpointDetails, bool monitored) { - var endpointInstanceId = new EndpointInstanceId(endpointDetails.Name, endpointDetails.Host, endpointDetails.HostId, supportsHeartbeats); + var endpointInstanceId = new EndpointInstanceId(endpointDetails.Name, endpointDetails.Host, endpointDetails.HostId); endpoints.GetOrAdd(endpointInstanceId.UniqueId, id => new EndpointInstanceMonitor(endpointInstanceId, monitored, domainEvents)); } diff --git a/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs b/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs deleted file mode 100644 index 2f2c7b9210..0000000000 --- a/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/ConnectedApplication.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ServiceControl.Monitoring; - -using NServiceBus; - -public class ConnectedApplication : IMessage -{ - public string Application { get; set; } - public bool SupportsHeartbeats { get; set; } - public string[] ErrorQueues { get; set; } -} diff --git a/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs b/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs deleted file mode 100644 index 32ce090b84..0000000000 --- a/src/ServiceControl/Monitoring/Transport/ConnectedApplicationHandler.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace ServiceControl.Monitoring.Transport -{ - using System.Threading.Tasks; - using NServiceBus; - using ServiceControl.Persistence; - using ConnectedApplication = ConnectedApplication; - - public class ConnectedApplicationHandler(IConnectedApplicationsDataStore connectedApplicationsDataStore) : IHandleMessages - { - public async Task Handle(ConnectedApplication message, IMessageHandlerContext context) - { - var connectedApplication = new Persistence.ConnectedApplication - { - Name = message.Application, - SupportsHeartbeats = message.SupportsHeartbeats - }; - await connectedApplicationsDataStore.UpdateConnectedApplication(connectedApplication, context.CancellationToken); - } - } -} diff --git a/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs b/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs index be1b0c7797..ccb1675063 100644 --- a/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs +++ b/src/ServiceControl/Monitoring/Transport/HeartbeatHandler.cs @@ -14,7 +14,7 @@ public HeartbeatHandler(IEndpointInstanceMonitoring monitor) public Task Handle(EndpointHeartbeat message, IMessageHandlerContext context) { - var endpointInstanceId = new EndpointInstanceId(message.EndpointName, message.Host, message.HostId, true); + var endpointInstanceId = new EndpointInstanceId(message.EndpointName, message.Host, message.HostId); monitor.RecordHeartbeat(endpointInstanceId, message.ExecutedAt); diff --git a/src/ServiceControl/Operations/EndpointDetailsParser.cs b/src/ServiceControl/Operations/EndpointDetailsParser.cs index 0eb3f9e759..557295e478 100644 --- a/src/ServiceControl/Operations/EndpointDetailsParser.cs +++ b/src/ServiceControl/Operations/EndpointDetailsParser.cs @@ -5,7 +5,6 @@ namespace ServiceControl.Contracts.Operations using Infrastructure; using NServiceBus; using ServiceControl.Operations; - using ServiceControl.Persistence; class EndpointDetailsParser { @@ -40,9 +39,10 @@ public static EndpointDetails ReceivingEndpoint(IReadOnlyDictionary endpoint.HostId = Guid.Parse(s)); - DictionaryExtensions.CheckIfKeyExists("NServiceBus.ConnectedApplication", headers, - s => endpoint.ConnectedApplicationId = ConnectedApplication.MakeDocumentId(s)); + if (headers.TryGetValue(Headers.HostId, out var hostIdHeader)) + { + endpoint.HostId = Guid.Parse(hostIdHeader); + } if (headers.TryGetValue(Headers.HostDisplayName, out var hostDisplayNameHeader)) { @@ -80,7 +80,7 @@ public static EndpointDetails ReceivingEndpoint(IReadOnlyDictionary Date: Mon, 20 Jan 2025 15:20:38 +1000 Subject: [PATCH 11/19] Adding in-memory heartbeats --- .../Infrastructure/Api/ConfigurationApi.cs | 8 +++--- .../MassTransitConnectorHeartbeat.cs | 27 +++++++++++++++++++ .../MassTransitConnectorHeartbeatStatus.cs | 11 ++++++++ .../HeartbeatMonitoringComponent.cs | 2 ++ .../MassTransitConnectorHeartbeatHandler.cs | 19 +++++++++++++ 5 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/MassTransitConnectorHeartbeat.cs create mode 100644 src/ServiceControl/Monitoring/HeartbeatMonitoring/MassTransitConnectorHeartbeatStatus.cs create mode 100644 src/ServiceControl/Monitoring/Transport/MassTransitConnectorHeartbeatHandler.cs diff --git a/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs b/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs index 793f1184da..fa06e80bc9 100644 --- a/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs +++ b/src/ServiceControl/Infrastructure/Api/ConfigurationApi.cs @@ -8,6 +8,7 @@ using System.Threading; using System.Threading.Tasks; using Configuration; +using Monitoring.HeartbeatMonitoring; using Particular.ServiceControl.Licensing; using ServiceBus.Management.Infrastructure.Settings; using ServiceControl.Api; @@ -15,7 +16,7 @@ class ConfigurationApi(ActiveLicense license, Settings settings, - IHttpClientFactory httpClientFactory) : IConfigurationApi + IHttpClientFactory httpClientFactory, MassTransitConnectorHeartbeatStatus connectorHeartbeatStatus) : IConfigurationApi { public Task GetUrls(string baseUrl, CancellationToken cancellationToken) { @@ -83,10 +84,7 @@ public Task GetConfig(CancellationToken cancellationToken) { settings.HeartbeatGracePeriod }, - MassTransitConnector = new - { - foobar = "barfoo" - } + MassTransitConnector = connectorHeartbeatStatus.LastHeartbeat }; return Task.FromResult(content); diff --git a/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/MassTransitConnectorHeartbeat.cs b/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/MassTransitConnectorHeartbeat.cs new file mode 100644 index 0000000000..a9a8c70f48 --- /dev/null +++ b/src/ServiceControl/Monitoring/HeartbeatMonitoring/InternalMessages/MassTransitConnectorHeartbeat.cs @@ -0,0 +1,27 @@ +namespace ServiceControl.Connector.MassTransit; + +using System; +using NServiceBus; + +public class MassTransitConnectorHeartbeat : IMessage +{ + public required string Version { get; set; } + public required ErrorQueue[] ErrorQueues { get; set; } + public required LogEntry[] Logs { get; set; } + public required DateTimeOffset SentDateTimeOffset { get; set; } +} + +#pragma warning disable CA1711 +public class ErrorQueue +#pragma warning restore CA1711 +{ + public required string Name { get; set; } + public required bool Ingesting { get; set; } +} + +public class LogEntry +{ + public string Message { get; set; } + public DateTimeOffset Date { get; set; } + public string Level { get; set; } +} \ No newline at end of file diff --git a/src/ServiceControl/Monitoring/HeartbeatMonitoring/MassTransitConnectorHeartbeatStatus.cs b/src/ServiceControl/Monitoring/HeartbeatMonitoring/MassTransitConnectorHeartbeatStatus.cs new file mode 100644 index 0000000000..f837d42ef5 --- /dev/null +++ b/src/ServiceControl/Monitoring/HeartbeatMonitoring/MassTransitConnectorHeartbeatStatus.cs @@ -0,0 +1,11 @@ +#nullable enable +namespace ServiceControl.Monitoring.HeartbeatMonitoring; + +using Connector.MassTransit; + +public class MassTransitConnectorHeartbeatStatus +{ + public MassTransitConnectorHeartbeat? LastHeartbeat { get; private set; } + + public void Update(MassTransitConnectorHeartbeat lastHeartbeat) => LastHeartbeat = lastHeartbeat; +} \ No newline at end of file diff --git a/src/ServiceControl/Monitoring/HeartbeatMonitoringComponent.cs b/src/ServiceControl/Monitoring/HeartbeatMonitoringComponent.cs index 3b519d0640..eb6ed312e3 100644 --- a/src/ServiceControl/Monitoring/HeartbeatMonitoringComponent.cs +++ b/src/ServiceControl/Monitoring/HeartbeatMonitoringComponent.cs @@ -4,6 +4,7 @@ using EndpointControl.Handlers; using EventLog; using ExternalIntegrations; + using HeartbeatMonitoring; using Infrastructure.DomainEvents; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -21,6 +22,7 @@ public override void Configure(Settings settings, ITransportCustomization transp hostBuilder.Services.AddHostedService(); hostBuilder.Services.AddSingleton(); + hostBuilder.Services.AddSingleton(); hostBuilder.Services.AddDomainEventHandler(); diff --git a/src/ServiceControl/Monitoring/Transport/MassTransitConnectorHeartbeatHandler.cs b/src/ServiceControl/Monitoring/Transport/MassTransitConnectorHeartbeatHandler.cs new file mode 100644 index 0000000000..68871aa92b --- /dev/null +++ b/src/ServiceControl/Monitoring/Transport/MassTransitConnectorHeartbeatHandler.cs @@ -0,0 +1,19 @@ +namespace ServiceControl.Monitoring; + +using System.Threading.Tasks; +using Connector.MassTransit; +using HeartbeatMonitoring; +using NServiceBus; + +class MassTransitConnectorHeartbeatHandler(MassTransitConnectorHeartbeatStatus connectorHeartbeatStatus) : IHandleMessages +{ + public Task Handle(MassTransitConnectorHeartbeat message, IMessageHandlerContext context) + { + if (connectorHeartbeatStatus.LastHeartbeat == null || message.SentDateTimeOffset > connectorHeartbeatStatus.LastHeartbeat.SentDateTimeOffset) + { + connectorHeartbeatStatus.Update(message); + } + + return Task.CompletedTask; + } +} \ No newline at end of file From ac06483c8cd5ac2c2c42eaf1770457156ae3cb9a Mon Sep 17 00:00:00 2001 From: John Simons Date: Tue, 21 Jan 2025 12:10:08 +1000 Subject: [PATCH 12/19] Add new license url for MassTransit --- src/ServiceControl/Licensing/LicenseController.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ServiceControl/Licensing/LicenseController.cs b/src/ServiceControl/Licensing/LicenseController.cs index 09303eb166..87d636d9a2 100644 --- a/src/ServiceControl/Licensing/LicenseController.cs +++ b/src/ServiceControl/Licensing/LicenseController.cs @@ -3,12 +3,13 @@ using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; + using Monitoring.HeartbeatMonitoring; using Particular.ServiceControl.Licensing; using ServiceBus.Management.Infrastructure.Settings; [ApiController] [Route("api")] - public class LicenseController(ActiveLicense activeLicense, Settings settings) : ControllerBase + public class LicenseController(ActiveLicense activeLicense, Settings settings, MassTransitConnectorHeartbeatStatus connectorHeartbeatStatus) : ControllerBase { [HttpGet] [Route("license")] @@ -30,7 +31,9 @@ public async Task> License(bool refresh, string client LicenseType = activeLicense.Details.LicenseType ?? string.Empty, InstanceName = settings.InstanceName ?? string.Empty, LicenseStatus = activeLicense.Details.Status, - LicenseExtensionUrl = $"https://particular.net/extend-your-trial?p={clientName}" + LicenseExtensionUrl = connectorHeartbeatStatus.LastHeartbeat == null + ? $"https://particular.net/extend-your-trial?p={clientName}" + : $"https://particular.net/extend-your-connector-trial?p={clientName}" }; return licenseInfo; From 26d7d2065b202a2021923e11e8e97634425b2bbb Mon Sep 17 00:00:00 2001 From: Irina Scurtu Date: Tue, 21 Jan 2025 14:24:10 +0200 Subject: [PATCH 13/19] added mt specific license --- ...alid_remotes_exist.status_unavailable.version_null.reten.txt | 0 src/ServiceControl/Licensing/LicenseController.cs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 src/Particular.LicensingComponent.UnitTests/ApprovalFiles/AuditQuery_Tests.Should_always_return_diagnostics_and_relevant_errors_when_invalid_remotes_exist.status_unavailable.version_null.reten.txt diff --git a/src/Particular.LicensingComponent.UnitTests/ApprovalFiles/AuditQuery_Tests.Should_always_return_diagnostics_and_relevant_errors_when_invalid_remotes_exist.status_unavailable.version_null.reten.txt b/src/Particular.LicensingComponent.UnitTests/ApprovalFiles/AuditQuery_Tests.Should_always_return_diagnostics_and_relevant_errors_when_invalid_remotes_exist.status_unavailable.version_null.reten.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/ServiceControl/Licensing/LicenseController.cs b/src/ServiceControl/Licensing/LicenseController.cs index 87d636d9a2..6b95fb955a 100644 --- a/src/ServiceControl/Licensing/LicenseController.cs +++ b/src/ServiceControl/Licensing/LicenseController.cs @@ -33,7 +33,7 @@ public async Task> License(bool refresh, string client LicenseStatus = activeLicense.Details.Status, LicenseExtensionUrl = connectorHeartbeatStatus.LastHeartbeat == null ? $"https://particular.net/extend-your-trial?p={clientName}" - : $"https://particular.net/extend-your-connector-trial?p={clientName}" + : $"https://particular.net/license/mt?p={clientName}&t={(activeLicense.Details.IsTrialLicense ? 0 : 1)}" }; return licenseInfo; From bdc9a39981642fff96bcde89770019fc9c629b34 Mon Sep 17 00:00:00 2001 From: John Simons Date: Thu, 23 Jan 2025 11:13:37 +1000 Subject: [PATCH 14/19] Revert "Unsync, remove dependabot, remove from Weekly CI" This reverts commit 928d98fe69d8e04cb294ce02edab74faeb9303c7. --- .github/dependabot.yml | 36 ++++++++++++++++++++ .github/workflows/{ci-renamed.yml => ci.yml} | 0 .reposync.yml | 2 ++ 3 files changed, 38 insertions(+) create mode 100644 .github/dependabot.yml rename .github/workflows/{ci-renamed.yml => ci.yml} (100%) create mode 100644 .reposync.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..bc1175f8eb --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,36 @@ +version: 2 +registries: + particular-packages: + type: nuget-feed + url: https://f.feedz.io/particular-software/packages/nuget/index.json +updates: +- package-ecosystem: nuget + directory: "/src" + registries: "*" + schedule: + interval: daily + open-pull-requests-limit: 1000 + groups: + AWSSDK: + patterns: + - "AWSSDK.*" + NServiceBusCore: + patterns: + - "NServiceBus" + - "NServiceBus.AcceptanceTesting" + - "NServiceBus.AcceptanceTests.Sources" + - "NServiceBus.PersistenceTests.Sources" + - "NServiceBus.TransportTests.Sources" + ignore: + # Particular.Analyzers updates are distributed via RepoStandards + - dependency-name: "Particular.Analyzers" + # Changing these 3 dependencies affects the .NET SDK and Visual Studio versions we support + # These types of updates should be more intentional than an automated update + - dependency-name: "Microsoft.Build.Utilities.Core" + - dependency-name: "Microsoft.CodeAnalysis.CSharp" + - dependency-name: "Microsoft.CodeAnalysis.CSharp.Workspaces" +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 1000 diff --git a/.github/workflows/ci-renamed.yml b/.github/workflows/ci.yml similarity index 100% rename from .github/workflows/ci-renamed.yml rename to .github/workflows/ci.yml diff --git a/.reposync.yml b/.reposync.yml new file mode 100644 index 0000000000..05ec9e3185 --- /dev/null +++ b/.reposync.yml @@ -0,0 +1,2 @@ +exclusions: +- src/NServiceBus.snk From 6ded50fa4b637ce23f46658c2868d618e1616377 Mon Sep 17 00:00:00 2001 From: John Simons Date: Thu, 23 Jan 2025 11:24:49 +1000 Subject: [PATCH 15/19] Remove empty file --- ...nvalid_remotes_exist.status_unavailable.version_null.reten.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/Particular.LicensingComponent.UnitTests/ApprovalFiles/AuditQuery_Tests.Should_always_return_diagnostics_and_relevant_errors_when_invalid_remotes_exist.status_unavailable.version_null.reten.txt diff --git a/src/Particular.LicensingComponent.UnitTests/ApprovalFiles/AuditQuery_Tests.Should_always_return_diagnostics_and_relevant_errors_when_invalid_remotes_exist.status_unavailable.version_null.reten.txt b/src/Particular.LicensingComponent.UnitTests/ApprovalFiles/AuditQuery_Tests.Should_always_return_diagnostics_and_relevant_errors_when_invalid_remotes_exist.status_unavailable.version_null.reten.txt deleted file mode 100644 index e69de29bb2..0000000000 From 5b5c8bdd5b5e225487189e2567d7ce2267a9ebf8 Mon Sep 17 00:00:00 2001 From: John Simons Date: Thu, 23 Jan 2025 11:26:52 +1000 Subject: [PATCH 16/19] Remove unnecessary prop --- src/ServiceControl.Persistence/EndpointInstanceId.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ServiceControl.Persistence/EndpointInstanceId.cs b/src/ServiceControl.Persistence/EndpointInstanceId.cs index 42ff79c8fc..36d4448879 100644 --- a/src/ServiceControl.Persistence/EndpointInstanceId.cs +++ b/src/ServiceControl.Persistence/EndpointInstanceId.cs @@ -49,6 +49,5 @@ public override int GetHashCode() public readonly string LogicalName; public readonly string HostName; public readonly Guid HostGuid; - public readonly bool SupportsHeartbeats; } } \ No newline at end of file From 00a7306471f5d13c7064a77651195175596466d3 Mon Sep 17 00:00:00 2001 From: John Simons Date: Thu, 23 Jan 2025 11:53:55 +1000 Subject: [PATCH 17/19] Use isEvaluation for license --- src/ServiceControl.UnitTests/API/APIApprovals.cs | 4 +++- src/ServiceControl/Licensing/ActiveLicense.cs | 7 +++++-- src/ServiceControl/Licensing/LicenseController.cs | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/ServiceControl.UnitTests/API/APIApprovals.cs b/src/ServiceControl.UnitTests/API/APIApprovals.cs index 80247a93eb..af4da85885 100644 --- a/src/ServiceControl.UnitTests/API/APIApprovals.cs +++ b/src/ServiceControl.UnitTests/API/APIApprovals.cs @@ -19,6 +19,7 @@ using ServiceBus.Management.Infrastructure.Settings; using ServiceControl.Infrastructure.Api; using ServiceControl.Infrastructure.WebApi; + using ServiceControl.Monitoring.HeartbeatMonitoring; [TestFixture] class APIApprovals @@ -33,7 +34,8 @@ public async Task RootPathValue() var controller = new RootController(new ConfigurationApi( new ActiveLicense(null) { IsValid = true }, new Settings(), - null + null, + new MassTransitConnectorHeartbeatStatus() ) ) { diff --git a/src/ServiceControl/Licensing/ActiveLicense.cs b/src/ServiceControl/Licensing/ActiveLicense.cs index f72f4f72f0..d50a5bdb38 100644 --- a/src/ServiceControl/Licensing/ActiveLicense.cs +++ b/src/ServiceControl/Licensing/ActiveLicense.cs @@ -1,8 +1,8 @@ namespace Particular.ServiceControl.Licensing { - using System.Threading.Tasks; - using System.Threading; using System; + using System.Threading; + using System.Threading.Tasks; using global::ServiceControl.LicenseManagement; using global::ServiceControl.Persistence; using NServiceBus.Logging; @@ -10,6 +10,7 @@ public class ActiveLicense(ITrialLicenseDataProvider trialLicenseDataProvider) { public bool IsValid { get; set; } + public bool IsEvaluation { get; set; } public LicenseDetails Details { get; set; } @@ -22,6 +23,8 @@ public async Task Refresh(CancellationToken cancellationToken) Details = await ValidateTrialLicense(detectedLicense.Details, trialLicenseDataProvider, cancellationToken); IsValid = !Details.HasLicenseExpired(); + + IsEvaluation = detectedLicense.IsEvaluationLicense; } internal static async Task ValidateTrialLicense(LicenseDetails licenseDetails, ITrialLicenseDataProvider trialLicenseDataProvider, CancellationToken cancellationToken) diff --git a/src/ServiceControl/Licensing/LicenseController.cs b/src/ServiceControl/Licensing/LicenseController.cs index 6b95fb955a..15539d9db0 100644 --- a/src/ServiceControl/Licensing/LicenseController.cs +++ b/src/ServiceControl/Licensing/LicenseController.cs @@ -33,7 +33,7 @@ public async Task> License(bool refresh, string client LicenseStatus = activeLicense.Details.Status, LicenseExtensionUrl = connectorHeartbeatStatus.LastHeartbeat == null ? $"https://particular.net/extend-your-trial?p={clientName}" - : $"https://particular.net/license/mt?p={clientName}&t={(activeLicense.Details.IsTrialLicense ? 0 : 1)}" + : $"https://particular.net/license/mt?p={clientName}&t={(activeLicense.IsEvaluation ? 0 : 1)}" }; return licenseInfo; From 83bad334073a9518d00abd60769460391971e2f4 Mon Sep 17 00:00:00 2001 From: John Simons Date: Thu, 23 Jan 2025 12:09:24 +1000 Subject: [PATCH 18/19] Remove legacy nunit usage --- .../Recoverability/When_editing_message_headers.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ServiceControl.AcceptanceTests/Recoverability/When_editing_message_headers.cs b/src/ServiceControl.AcceptanceTests/Recoverability/When_editing_message_headers.cs index faa49666b8..113d45a820 100644 --- a/src/ServiceControl.AcceptanceTests/Recoverability/When_editing_message_headers.cs +++ b/src/ServiceControl.AcceptanceTests/Recoverability/When_editing_message_headers.cs @@ -66,8 +66,8 @@ public async Task A_new_message_with_edited_headers_is_sent() { Assert.That(context.EditedMessageId, Is.Not.EqualTo(context.OriginalMessageId)); Assert.That(context.OriginalMessageFailure.Status, Is.EqualTo(FailedMessageStatus.Resolved)); - Assert.That(context.EditedMessageHeaders["AcceptanceTest.NewHeader"], Is.EqualTo("42").AsCollection); - Assert.That(context.EditedMessageHeaders["ServiceControl.EditOf"], Is.EqualTo(context.UniqueMessageId).AsCollection); + Assert.That(context.EditedMessageHeaders["AcceptanceTest.NewHeader"], Is.EqualTo("42")); + Assert.That(context.EditedMessageHeaders["ServiceControl.EditOf"], Is.EqualTo(context.UniqueMessageId)); }); } From 91a8480d513df943f0b00f869bf5b43f90d641a0 Mon Sep 17 00:00:00 2001 From: David Boike Date: Wed, 22 Jan 2025 16:01:23 -0600 Subject: [PATCH 19/19] Update build workflow because dotnet --info is throwing --- .github/workflows/build-windows.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 6ed834bcd0..bee9b88012 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -18,8 +18,6 @@ jobs: uses: actions/setup-dotnet@v4.2.0 with: dotnet-version: 8.0.x - - name: dotnet info - run: dotnet --info - name: Download RavenDB Server shell: pwsh run: ./tools/download-ravendb-server.ps1