Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/usage-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ The primary's `TransportEnvironmentDataProvider` emits `Transport.Type` and adds
| --- | --- | --- | --- |
| `Features.IntegratedServicePulse` | `Enabled`, `Disabled` | `ServiceControl/EnableIntegratedServicePulse` | 6.13.0 |
| `Features.MessageEditing` | `Enabled`, `Disabled` | `ServiceControl/AllowMessageEditing` | 6.20.0 |
| `Features.ExternalIntegrationsPublishing` | `Enabled`, `Disabled` | `ServiceControl/DisableExternalIntegrationsPublishing`, inverted | 6.20.0 |
| `Features.ExternalIntegrationsPublishing` | `Enabled`, `Disabled` | `ServiceControl/EnableExternalIntegrationsPublishing`, or the legacy `ServiceControl/DisableExternalIntegrationsPublishing` inverted | 6.20.0 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this change been made to the docs PR?

| `Features.ForwardErrorMessages` | `Enabled`, `Disabled` | `ServiceControl/ForwardErrorMessages` | 6.20.0 |
| `Features.EmailNotifications` | `Enabled`, `Disabled`, `NotConfigured` | the stored email settings | 6.20.0 |
| `Features.ErrorIngestion` | `Enabled`, `Disabled` | `ServiceControl/IngestErrorMessages` | Unreleased |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class When_a_custom_check_fails : AcceptanceTest
public async Task Should_publish_notification()
{
var externalProcessorSubscribed = false;
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<MyContext>((s, ctx) =>
{
if (s.SubscriberReturnAddress.IndexOf("ExternalProcessor", StringComparison.OrdinalIgnoreCase) >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class When_a_custom_check_succeeds : AcceptanceTest
public async Task Should_publish_notification()
{
var externalProcessorSubscribed = false;
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<MyContext>((s, ctx) =>
{
if (s.SubscriberReturnAddress.IndexOf("ExternalProcessor", StringComparison.OrdinalIgnoreCase) >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public async Task Should_publish_notification()
{
var externalProcessorSubscribed = false;

SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<MyContext>((s, ctx) =>
{
if (s.SubscriberReturnAddress.IndexOf("ExternalProcessor", StringComparison.OrdinalIgnoreCase) >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public async Task Should_publish_notification()
{
var externalProcessorSubscribed = false;

SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<MyContext>((s, ctx) =>
{
if (s.SubscriberReturnAddress.IndexOf("ExternalProcessor", StringComparison.OrdinalIgnoreCase) >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class When_a_failed_edit_is_resolved_by_retry : AcceptanceTest
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<EditMessageResolutionContext>((s, ctx) =>
{
ctx.ExternalProcessorSubscribed = s.SubscriberReturnAddress.Contains(nameof(MessageReceiver));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class When_a_failed_message_is_archived : ExternalIntegrationAcceptanceTest
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<Context>((s, ctx) =>
{
ctx.ExternalProcessorSubscribed = s.SubscriberReturnAddress.Contains(nameof(ExternalProcessor));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class When_a_failed_message_is_resolved_by_retry : ExternalIntegrationAcceptance
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<Context>((s, ctx) =>
{
ctx.ExternalProcessorSubscribed = s.SubscriberReturnAddress.Contains(nameof(ExternalProcessor));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class When_a_failed_message_is_resolved_manually : ExternalIntegrationAcceptance
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<Context>((s, ctx) =>
{
if (s.SubscriberReturnAddress.IndexOf("ExternalProcessor", StringComparison.OrdinalIgnoreCase) >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class When_a_failed_message_is_unarchived : ExternalIntegrationAcceptanceTest
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<Context>((s, ctx) =>
{
if (s.SubscriberReturnAddress.IndexOf("ExternalProcessor", StringComparison.OrdinalIgnoreCase) >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class When_a_failed_msg_is_resolved_by_edit : AcceptanceTest
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<EditMessageResolutionContext>((s, ctx) =>
{
ctx.ExternalProcessorSubscribed = s.SubscriberReturnAddress.Contains(nameof(MessageReceiver));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class When_a_group_is_archived : ExternalIntegrationAcceptanceTest
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<Context>((s, ctx) =>
{
if (s.SubscriberReturnAddress.IndexOf("ExternalProcessor", StringComparison.OrdinalIgnoreCase) >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class When_a_message_has_failed_detected : AcceptanceTest
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<MyContext>((s, ctx) =>
{
if (s.SubscriberReturnAddress.IndexOf("ExternalProcessor", StringComparison.OrdinalIgnoreCase) >= 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class When_a_reedit_solves_a_failed_msg : AcceptanceTest
[Test]
public async Task Should_publish_notification()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<EditMessageResolutionContext>((s, ctx) =>
{
ctx.ExternalProcessorSubscribed = s.SubscriberReturnAddress.Contains(nameof(MessageReceiver));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public async Task Should_restart_dispatch_thread()
{
var externalProcessorSubscribed = false;

SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomizeHostBuilder = builder => builder.Services.AddSingleton<IEventPublisher, FaultyPublisher>();

CustomConfiguration = config =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class When_edited_message_fails_to_process : AcceptanceTest
[Test]
public async Task A_new_message_failure_is_created()
{
SetSettings = settings => settings.EnableExternalIntegrationsPublishing = true;
CustomConfiguration = config => config.OnEndpointSubscribed<EditMessageFailureContext>((s, ctx) =>
{
ctx.ExternalProcessorSubscribed = s.SubscriberReturnAddress.Contains(nameof(FailingEditedMessageReceiver));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
"EmailDropFolder": null,
"ValidateConfiguration": true,
"ExternalIntegrationsDispatchingBatchSize": 100,
"DisableExternalIntegrationsPublishing": false,
"EnableExternalIntegrationsPublishing": false,
"RunCleanupBundle": false,
"RootUrl": "http://localhost:8888/",
"ApiUrl": "http://localhost:8888/api",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
namespace ServiceControl.UnitTests.Infrastructure.Settings;

using System;
using NUnit.Framework;
using ServiceBus.Management.Infrastructure.Settings;

[TestFixture]
[NonParallelizable]
class ExternalIntegrationsPublishingSettingsTests
{
const string Variable = "SERVICECONTROL_ENABLEEXTERNALINTEGRATIONSPUBLISHING";
const string LegacyVariable = "SERVICECONTROL_DISABLEEXTERNALINTEGRATIONSPUBLISHING";

string originalValue;
string originalLegacyValue;

[SetUp]
public void SetUp()
{
originalValue = Environment.GetEnvironmentVariable(Variable);
originalLegacyValue = Environment.GetEnvironmentVariable(LegacyVariable);
Environment.SetEnvironmentVariable(Variable, null);
Environment.SetEnvironmentVariable(LegacyVariable, null);
}

[TearDown]
public void TearDown()
{
Environment.SetEnvironmentVariable(Variable, originalValue);
Environment.SetEnvironmentVariable(LegacyVariable, originalLegacyValue);
}

[Test]
public void Is_disabled_when_neither_setting_is_configured() =>
Assert.That(new Settings().EnableExternalIntegrationsPublishing, Is.False);

[TestCase("true", true)]
[TestCase("false", false)]
public void Reads_the_enable_setting(string value, bool expected)
{
Environment.SetEnvironmentVariable(Variable, value);

Assert.That(new Settings().EnableExternalIntegrationsPublishing, Is.EqualTo(expected));
}

[TestCase("true", false)]
[TestCase("false", true)]
public void Treats_the_legacy_setting_as_the_inverse(string value, bool expected)
{
Environment.SetEnvironmentVariable(LegacyVariable, value);

Assert.That(new Settings().EnableExternalIntegrationsPublishing, Is.EqualTo(expected));
}

[TestCase("true", "true")]
[TestCase("true", "false")]
[TestCase("false", "true")]
[TestCase("false", "false")]
public void Rejects_both_settings_being_configured(string enable, string disable)
{
Environment.SetEnvironmentVariable(Variable, enable);
Environment.SetEnvironmentVariable(LegacyVariable, disable);

var ex = Assert.Throws<Exception>(() => _ = new Settings());

Assert.That(ex.Message, Does.Contain("cannot both be configured"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ public async Task Should_report_feature_switches_from_configuration()
}
}

[TestCase("SERVICECONTROL_ENABLEEXTERNALINTEGRATIONSPUBLISHING", "true", "Enabled")]
[TestCase("SERVICECONTROL_ENABLEEXTERNALINTEGRATIONSPUBLISHING", "false", "Disabled")]
[TestCase("SERVICECONTROL_DISABLEEXTERNALINTEGRATIONSPUBLISHING", "false", "Enabled")]
[TestCase("SERVICECONTROL_DISABLEEXTERNALINTEGRATIONSPUBLISHING", "true", "Disabled")]
public async Task Should_report_external_integrations_publishing_from_either_key(string variable, string value, string expected)
{
Environment.SetEnvironmentVariable(variable, value);

var data = await GetData();

Assert.That(data["Features.ExternalIntegrationsPublishing"], Is.EqualTo(expected));
}

[Test]
public async Task Should_report_otlp_metrics_export_without_the_endpoint()
{
Expand Down Expand Up @@ -158,6 +171,8 @@ public Task SaveSettings(NotificationsSettings settings, CancellationToken cance
"DEFAULT_ROUTE",
"SHOW_PENDING_RETRY",
"SERVICECONTROL_INGESTERRORMESSAGES",
"SERVICECONTROL_VIRTUALDIRECTORY"
"SERVICECONTROL_VIRTUALDIRECTORY",
"SERVICECONTROL_ENABLEEXTERNALINTEGRATIONSPUBLISHING",
"SERVICECONTROL_DISABLEEXTERNALINTEGRATIONSPUBLISHING"
];
}
2 changes: 1 addition & 1 deletion src/ServiceControl/CustomChecks/CustomChecksComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class CustomChecksComponent : ServiceControlComponent
public override void Setup(Settings settings, IComponentInstallationContext context, IHostApplicationBuilder hostBuilder)
{
// Integration Events
if (!settings.DisableExternalIntegrationsPublishing)
if (settings.EnableExternalIntegrationsPublishing)
{
context.AddEventPublished<CustomCheckFailed>();
context.AddEventPublished<CustomCheckSucceeded>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public override void Configure(Settings settings, ITransportCustomization transp
var services = hostBuilder.Services;
services.AddEventLogMapping<ExternalIntegrationEventFailedToBePublishedDefinition>();

if (!settings.DisableExternalIntegrationsPublishing)
if (settings.EnableExternalIntegrationsPublishing)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MessageFailed is written by whichever process ingests, and an --error-ingestion-only worker reads this flag itself.

With the default now false, enabling publishing on the primary instance only means MessageFailed is never published while every other event is. Could a worker log a warning when it ingests with publishing disabled? The docs should also say the key must be set on every worker.

{
services.AddDomainEventHandler<IntegrationEventWriter>();

Expand Down
1 change: 1 addition & 0 deletions src/ServiceControl/HostApplicationBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ Audit Retention Period (optional): {settings.AuditRetentionPeriod}
ServiceControl Logging Level: {settings.LoggingSettings.LogLevel}
Selected Transport Customization: {settings.TransportType}
Integrated ServicePulse: {(settings.EnableIntegratedServicePulse ? "Enabled" : "Disabled")}
External Integrations Publishing: {(settings.EnableExternalIntegrationsPublishing ? "Enabled" : "Disabled")}
-------------------------------------------------------------";

var logger = LoggerUtil.CreateStaticLogger(typeof(HostApplicationBuilderExtensions), settings.LoggingSettings.LogLevel);
Expand Down
2 changes: 1 addition & 1 deletion src/ServiceControl/Infrastructure/NServiceBusFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public static void Configure(Settings.Settings settings, ITransportCustomization
configuration.GetSettings().Set(settings.LoggingSettings);
configuration.SetDiagnosticsPath(settings.LoggingSettings.LogPath);

if (!settings.DisableExternalIntegrationsPublishing)
if (settings.EnableExternalIntegrationsPublishing)
{
configuration.EnableFeature<ExternalIntegrationsFeature>();
}
Expand Down
19 changes: 17 additions & 2 deletions src/ServiceControl/Infrastructure/Settings/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public Settings(
ErrorIngestionBatchSize = IngestionSettingsReader.ReadBatchSize(SettingsRootNamespace, nameof(ErrorIngestionBatchSize), ValidateConfiguration);
ErrorIngestionMaxParallelWriters = IngestionSettingsReader.ReadMaxParallelWriters(SettingsRootNamespace, nameof(ErrorIngestionMaxParallelWriters), ValidateConfiguration);
ErrorIngestionBatchTimeout = IngestionSettingsReader.ReadBatchTimeout(SettingsRootNamespace, nameof(ErrorIngestionBatchTimeout), ValidateConfiguration);
DisableExternalIntegrationsPublishing = SettingsReader.Read(SettingsRootNamespace, "DisableExternalIntegrationsPublishing", false);
EnableExternalIntegrationsPublishing = ReadEnableExternalIntegrationsPublishing();
TrackInstancesInitialValue = SettingsReader.Read(SettingsRootNamespace, "TrackInstancesInitialValue", true);
ShutdownTimeout = SettingsReader.Read(SettingsRootNamespace, ShutdownTimeoutKey, ShutdownTimeout);
AssemblyLoadContextResolver = static assemblyPath => new PluginAssemblyLoadContext(assemblyPath);
Expand Down Expand Up @@ -132,7 +132,7 @@ public Settings(

public int ExternalIntegrationsDispatchingBatchSize => SettingsReader.Read(SettingsRootNamespace, ExternalIntegrationsDispatchingBatchSizeKey, 100);

public bool DisableExternalIntegrationsPublishing { get; set; }
public bool EnableExternalIntegrationsPublishing { get; set; }

public bool RunCleanupBundle { get; set; }

Expand Down Expand Up @@ -305,6 +305,21 @@ TimeSpan GetEventRetentionPeriod()
return SettingsReader.Read(SettingsRootNamespace, "EventsRetentionPeriod", TimeSpan.FromDays(14));
}

bool ReadEnableExternalIntegrationsPublishing()
{
var legacyConfigured = SettingsReader.TryRead<bool>(SettingsRootNamespace, "DisableExternalIntegrationsPublishing", out var disable);
var configured = SettingsReader.TryRead<bool>(SettingsRootNamespace, "EnableExternalIntegrationsPublishing", out var enable);

if (legacyConfigured && configured)
{
const string message = "EnableExternalIntegrationsPublishing and the legacy DisableExternalIntegrationsPublishing settings cannot both be configured, please remove DisableExternalIntegrationsPublishing";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to rather check if they disagree, and then throw? Is it really a critical if they are both added but agree?

logger.LogCritical(message);
throw new Exception(message);
}

return legacyConfigured ? !disable : enable;
}

TimeSpan GetErrorRetentionPeriod()
{
string message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class HeartbeatMonitoringComponent : ServiceControlComponent
public override void Setup(Settings settings, IComponentInstallationContext context, IHostApplicationBuilder hostBuilder)
{
// Integration Events
if (!settings.DisableExternalIntegrationsPublishing)
if (settings.EnableExternalIntegrationsPublishing)
{
context.AddEventPublished<HeartbeatRestored>();
context.AddEventPublished<HeartbeatStopped>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public override void Setup(Settings settings, IComponentInstallationContext cont
}

// Integration Events
if (!settings.DisableExternalIntegrationsPublishing)
if (settings.EnableExternalIntegrationsPublishing)
{
context.AddEventPublished<FailedMessagesArchived>();
context.AddEventPublished<FailedMessagesUnArchived>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public IEnumerable<EnvironmentDatum> GetData() =>
[
Value("Features.IntegratedServicePulse", () => Toggle(settings.EnableIntegratedServicePulse)),
Value("Features.MessageEditing", () => Toggle(settings.AllowMessageEditing)),
Value("Features.ExternalIntegrationsPublishing", () => Toggle(!settings.DisableExternalIntegrationsPublishing)),
Value("Features.ExternalIntegrationsPublishing", () => Toggle(settings.EnableExternalIntegrationsPublishing)),
Value("Features.ForwardErrorMessages", () => Toggle(settings.ForwardErrorMessages)),
Value("Features.ErrorIngestion", () => Toggle(settings.IngestErrorMessages)),
Value("Features.ConfigurationValidation", () => Toggle(settings.ValidateConfiguration)),
Expand Down
Loading