Skip to content

Commit 0d4a057

Browse files
soujaybartekwasielak
authored andcommitted
Log email notification subject and body for all SendEmailNotificationHandler executions (#5139)
* remove duplicate custom check - Audit Message Ingestion * add email notification subject and body to log * apply code review suggestions Ensure RetryAcknowledgementBehavior gets triggered
1 parent d794df8 commit 0d4a057

File tree

17 files changed

+482
-43
lines changed

17 files changed

+482
-43
lines changed

src/ServiceControl.AcceptanceTests.RavenDB/ServiceControl.AcceptanceTests.RavenDB.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@
3030
<Compile Include="..\ServiceControl.Persistence.Tests.RavenDB\StopSharedDatabase.cs" />
3131
</ItemGroup>
3232

33+
<ItemGroup>
34+
<Folder Include="Shared\Recoverability\ExternalIntegration\" />
35+
</ItemGroup>
36+
3337
</Project>

src/ServiceControl.AcceptanceTests/Recoverability/ExternalIntegration/ExternalIntegrationAcceptanceTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public ErrorSender() =>
2020
EndpointSetup<DefaultServerWithoutAudit>(c =>
2121
{
2222
c.NoDelayedRetries();
23+
//TODO: Get back to this to determine whether or not this duplication for simulating the production code is really needed
2324
c.ReportSuccessfulRetriesToServiceControl();
2425
});
2526

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
// namespace ServiceControl.AcceptanceTests.Recoverability.ExternalIntegration
2+
// {
3+
// using System.Collections.Generic;
4+
// using System.Linq;
5+
// using System.Threading.Tasks;
6+
// using AcceptanceTesting;
7+
// using AcceptanceTesting.EndpointTemplates;
8+
// using Contracts;
9+
// using NServiceBus;
10+
// using NServiceBus.AcceptanceTesting;
11+
// using NUnit.Framework;
12+
// using ServiceControl.MessageFailures;
13+
// using ServiceControl.MessageFailures.Api;
14+
// using JsonSerializer = System.Text.Json.JsonSerializer;
15+
// using ServiceBus.Management.Infrastructure.Settings;
16+
//
17+
// class When_a_failed_edit_is_resolved_by_retry : ExternalIntegrationAcceptanceTest
18+
// {
19+
// [Test]
20+
// public async Task Should_publish_notification()
21+
// {
22+
// var context = await Define<EditMessageResolutionContext>()
23+
// .WithEndpoint<MessageReceiver>(b => b.When(async (bus, c) =>
24+
// {
25+
// await bus.Subscribe<MessageFailureResolvedByRetry>();
26+
// }).When(c => c.SendLocal(new EditResolutionMessage())).DoNotFailOnErrorMessages())
27+
// .Done(async ctx =>
28+
// {
29+
// if (!ctx.OriginalMessageHandled)
30+
// {
31+
// return false;
32+
// }
33+
//
34+
// if (!ctx.EditedAndRetriedMessage)
35+
// {
36+
// var allFailedMessages =
37+
// await this.TryGet<IList<FailedMessageView>>($"/api/errors/?status=unresolved");
38+
// if (!allFailedMessages.HasResult)
39+
// {
40+
// return false;
41+
// }
42+
//
43+
// if (allFailedMessages.Item.Count != 1)
44+
// {
45+
// return false;
46+
// }
47+
//
48+
// ctx.OriginalMessageFailureId = allFailedMessages.Item.First().Id;
49+
// ctx.EditedAndRetriedMessage = true;
50+
//
51+
// string editedMessage = JsonSerializer.Serialize(new EditResolutionMessage
52+
// {
53+
// HasBeenEdited = true
54+
// });
55+
//
56+
// SingleResult<FailedMessage> failedMessage =
57+
// await this.TryGet<FailedMessage>($"/api/errors/{ctx.OriginalMessageFailureId}");
58+
//
59+
// var editModel = new EditMessageModel
60+
// {
61+
// MessageBody = editedMessage,
62+
// MessageHeaders = failedMessage.Item.ProcessingAttempts.Last().Headers
63+
// };
64+
// await this.Post($"/api/edit/{ctx.OriginalMessageFailureId}", editModel);
65+
// return false;
66+
// }
67+
//
68+
// if (!ctx.RetriedMessage)
69+
// {
70+
// var allFailedMessagesAfterEdit =
71+
// await this.TryGet<IList<FailedMessageView>>($"/api/errors/?status=unresolved");
72+
// if (!allFailedMessagesAfterEdit.HasResult)
73+
// {
74+
// return false;
75+
// }
76+
//
77+
// if (allFailedMessagesAfterEdit.Item.Count != 1)
78+
// {
79+
// return false;
80+
// }
81+
//
82+
// ctx.EditedMessageFailureId = allFailedMessagesAfterEdit.Item.First().Id;
83+
// ctx.RetriedMessage = true;
84+
//
85+
// await this.Post<object>($"/api/errors/{ctx.EditedMessageFailureId}/retry");
86+
// return false;
87+
// }
88+
//
89+
// if (!ctx.RetriedMessageHandled)
90+
// {
91+
// return false;
92+
// }
93+
//
94+
// if (!ctx.MessageResolved)
95+
// {
96+
// return false;
97+
// }
98+
//
99+
// return true;
100+
// }).Run();
101+
//
102+
// Assert.That(context.ResolvedMessageId, Is.EqualTo(context.OriginalMessageFailureId));
103+
// }
104+
//
105+
//
106+
// public class EditMessageResolutionContext : ScenarioContext
107+
// {
108+
// public bool OriginalMessageHandled { get; set; }
109+
// public bool EditedMessage { get; set; }
110+
// public string OriginalMessageFailureId { get; set; }
111+
// public bool EditedMessageHandled { get; set; }
112+
// public string ResolvedMessageId { get; set; }
113+
// public bool MessageResolved { get; set; }
114+
// public bool EditedAndRetriedMessgaeHandled { get; set; }
115+
// public bool RetriedMessageHandled { get; set; }
116+
// public string EditedMessageFailureId { get; set; }
117+
// public bool EditedAndRetriedMessage { get; set; }
118+
// public bool RetriedMessage { get; set; }
119+
// }
120+
//
121+
// public class MessageReceiver : EndpointConfigurationBuilder
122+
// {
123+
// public MessageReceiver() =>
124+
// EndpointSetup<DefaultServerWithoutAudit>(c =>
125+
// {
126+
// var routing = c.ConfigureRouting();
127+
// routing.RouteToEndpoint(typeof(FailedMessagesArchived).Assembly,
128+
// Settings.DEFAULT_INSTANCE_NAME);
129+
// },
130+
// publisherMetadata =>
131+
// {
132+
// publisherMetadata.RegisterPublisherFor<FailedMessagesArchived>(Settings.DEFAULT_INSTANCE_NAME);
133+
// });
134+
//
135+
//
136+
// public class EditMessageResolutionHandler(EditMessageResolutionContext testContext)
137+
// : IHandleMessages<EditResolutionMessage>, IHandleMessages<MessageFailureResolvedByRetry>
138+
// {
139+
// public Task Handle(EditResolutionMessage message, IMessageHandlerContext context)
140+
// {
141+
// if (!message.HasBeenEdited)
142+
// {
143+
// testContext.OriginalMessageHandled = true;
144+
// throw new SimulatedException();
145+
// }
146+
//
147+
// if (!testContext.RetriedMessage)
148+
// {
149+
// testContext.EditedAndRetriedMessgaeHandled = true;
150+
// throw new SimulatedException();
151+
// }
152+
//
153+
//
154+
// testContext.RetriedMessageHandled = true;
155+
// return Task.CompletedTask;
156+
// }
157+
//
158+
// public Task Handle(MessageFailureResolvedByRetry message, IMessageHandlerContext context)
159+
// {
160+
// testContext.ResolvedMessageId = message.FailedMessageId;
161+
// testContext.MessageResolved = true;
162+
// return Task.CompletedTask;
163+
// }
164+
// }
165+
// }
166+
//
167+
// public class EditResolutionMessage : IMessage
168+
// {
169+
// public bool HasBeenEdited { get; init; }
170+
// }
171+
// }
172+
// }
173+
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
namespace ServiceControl.AcceptanceTests.Recoverability.ExternalIntegration
2+
{
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using AcceptanceTesting;
7+
using AcceptanceTesting.EndpointTemplates;
8+
using Contracts;
9+
using Google.Protobuf.Reflection;
10+
using NServiceBus;
11+
using NServiceBus.AcceptanceTesting;
12+
using NUnit.Framework;
13+
using ServiceControl.MessageFailures;
14+
using ServiceControl.MessageFailures.Api;
15+
using JsonSerializer = System.Text.Json.JsonSerializer;
16+
17+
class When_a_failed_msg_is_resolved_by_edit : AcceptanceTest
18+
{
19+
[Test]
20+
public async Task Should_publish_notification()
21+
{
22+
var context = await Define<EditMessageResolutionContext>()
23+
.WithEndpoint<MessageReceiver>(b => b.When(async (bus, c) =>
24+
{
25+
await bus.Subscribe<MessageFailureResolvedByRetry>();
26+
}).When(c => c.SendLocal(new EditResolutionMessage())).DoNotFailOnErrorMessages())
27+
.Done(async ctx =>
28+
{
29+
if (!ctx.OriginalMessageHandled)
30+
{
31+
return false;
32+
}
33+
34+
if (!ctx.EditedMessage)
35+
{
36+
var allFailedMessages =
37+
await this.TryGet<IList<FailedMessageView>>($"/api/errors/?status=unresolved");
38+
if (!allFailedMessages.HasResult)
39+
{
40+
return false;
41+
}
42+
43+
if (allFailedMessages.Item.Count != 1)
44+
{
45+
return false;
46+
}
47+
48+
ctx.OriginalMessageFailureId = allFailedMessages.Item.First().Id;
49+
50+
ctx.EditedMessage = true;
51+
string editedMessage = JsonSerializer.Serialize(new EditResolutionMessage
52+
{
53+
HasBeenEdited = true
54+
});
55+
56+
SingleResult<FailedMessage> failedMessage =
57+
await this.TryGet<FailedMessage>($"/api/errors/{ctx.OriginalMessageFailureId}");
58+
59+
var editModel = new EditMessageModel
60+
{
61+
MessageBody = editedMessage,
62+
MessageHeaders = failedMessage.Item.ProcessingAttempts.Last().Headers
63+
};
64+
await this.Post($"/api/edit/{ctx.OriginalMessageFailureId}", editModel);
65+
return false;
66+
}
67+
68+
if (!ctx.EditedMessageHandled)
69+
{
70+
return false;
71+
}
72+
73+
if (!ctx.MessageResolved)
74+
{
75+
return false;
76+
}
77+
78+
return true;
79+
}).Run();
80+
81+
Assert.That(context.ResolvedMessageId, Is.EqualTo(context.OriginalMessageFailureId));
82+
}
83+
84+
85+
class EditMessageResolutionContext : ScenarioContext
86+
{
87+
public bool OriginalMessageHandled { get; set; }
88+
public bool EditedMessage { get; set; }
89+
public string OriginalMessageFailureId { get; set; }
90+
public bool EditedMessageHandled { get; set; }
91+
public string ResolvedMessageId { get; set; }
92+
public bool MessageResolved { get; set; }
93+
}
94+
95+
class MessageReceiver : EndpointConfigurationBuilder
96+
{
97+
public MessageReceiver() => EndpointSetup<DefaultServerWithoutAudit>(c => c.NoRetries());
98+
99+
class EditMessageResolutionHandler(EditMessageResolutionContext testContext)
100+
: IHandleMessages<EditResolutionMessage>, IHandleMessages<MessageFailureResolvedByRetry>
101+
{
102+
public Task Handle(EditResolutionMessage message, IMessageHandlerContext context)
103+
{
104+
if (message.HasBeenEdited)
105+
{
106+
testContext.EditedMessageHandled = true;
107+
return Task.CompletedTask;
108+
}
109+
110+
testContext.OriginalMessageHandled = true;
111+
throw new SimulatedException();
112+
}
113+
114+
public Task Handle(MessageFailureResolvedByRetry message, IMessageHandlerContext context)
115+
{
116+
testContext.ResolvedMessageId = message.FailedMessageId;
117+
testContext.MessageResolved = true;
118+
return Task.CompletedTask;
119+
}
120+
}
121+
}
122+
123+
class EditResolutionMessage : IMessage
124+
{
125+
public bool HasBeenEdited { get; init; }
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)