Skip to content

Commit 25f9c78

Browse files
Fixed a permenant routing failure after the first error. The folder router most likely did not experience this issue. But plugin routers would see this. A new router instance is now used for each message. Test added.
1 parent 93cc847 commit 25f9c78

File tree

9 files changed

+330
-23
lines changed

9 files changed

+330
-23
lines changed

csharp/gateway/smtpAgent/FolderRoute.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ public FolderBalancer<ISmtpMessage> LoadBalancer
9494
return m_loadBalancer;
9595
}
9696
}
97-
97+
98+
/// <inheritdoc />
9899
public override void Validate()
99100
{
100101
base.Validate();
@@ -104,11 +105,25 @@ public override void Validate()
104105
}
105106
}
106107

108+
/// <inheritdoc />
109+
public override Route Clone()
110+
{
111+
var route = new FolderRoute();
112+
route.CopyFolders = this.CopyFolders;
113+
route.AddressType = this.AddressType;
114+
route.CopyMessageHandler = this.CopyMessageHandler;
115+
route.FailedDelivery = this.FailedDelivery;
116+
117+
return route;
118+
}
119+
120+
/// <inheritdoc />
107121
public override void Init()
108122
{
109123
this.Validate();
110124
}
111125

126+
/// <inheritdoc />
112127
public override bool Process(ISmtpMessage message)
113128
{
114129
return m_loadBalancer.Process(message);

csharp/gateway/smtpAgent/MessageRouter.cs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ internal MessageRouter(AgentDiagnostics diagnostics)
4343
m_diagnostics = diagnostics;
4444
m_routes = new Dictionary<string, Route>(StringComparer.OrdinalIgnoreCase);
4545
}
46-
46+
47+
internal MessageRouter(AgentDiagnostics diagnostics, Dictionary<string, Route> routes)
48+
{
49+
m_diagnostics = diagnostics;
50+
m_routes = routes;
51+
}
52+
4753
internal ILogger Logger
4854
{
4955
get
@@ -200,7 +206,25 @@ void Route(ISmtpMessage message, Route route)
200206
m_diagnostics.Logger.Error("Routing Error {0}, {1}", route.AddressType, ex);
201207
}
202208
}
203-
209+
210+
/// <summary>
211+
/// new copy of router instance
212+
/// </summary>
213+
/// <returns></returns>
214+
public MessageRouter Clone()
215+
{
216+
Dictionary<string, Route> routes = new Dictionary<string, Route>(StringComparer.OrdinalIgnoreCase);
217+
218+
foreach (var mRoute in m_routes)
219+
{
220+
routes[mRoute.Key] = mRoute.Value.Clone();
221+
}
222+
223+
var messageRouter = new MessageRouter(m_diagnostics, routes);
224+
225+
return messageRouter;
226+
}
227+
204228
public IEnumerator<Route> GetEnumerator()
205229
{
206230
return m_routes.Values.GetEnumerator();

csharp/gateway/smtpAgent/PluginRoute.cs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public bool HasReceivers
119119
return (!this.Receivers.IsNullOrEmpty());
120120
}
121121
}
122-
122+
/// <inheritdoc />
123123
public override void Validate()
124124
{
125125
base.Validate();
@@ -136,7 +136,20 @@ public override void Validate()
136136
}
137137
}
138138
}
139-
139+
140+
/// <inheritdoc />
141+
public override Route Clone()
142+
{
143+
var route = new PluginRoute();
144+
route.AddressType = this.AddressType;
145+
route.m_plugins = this.ReceiverDefinitions;
146+
route.Receivers = this.Receivers;
147+
route.FailedDelivery = this.FailedDelivery;
148+
route.m_loadBalancer = this.m_loadBalancer;
149+
150+
return route;
151+
}
152+
140153
public override void Init()
141154
{
142155
m_loadBalancer = new LoadBalancer<ISmtpMessage>(this.Receivers);

csharp/gateway/smtpAgent/Route.cs

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@ Neither the name of The Direct Project (directproject.org) nor the names of its
1414
1515
*/
1616
using System;
17-
using System.Collections.Generic;
18-
using System.Linq;
19-
using System.Text;
20-
using Health.Direct.Agent;
21-
using Health.Direct.Config.Store;
22-
using Health.Direct.Common.Extensions;
2317
using System.Xml.Serialization;
2418

2519
namespace Health.Direct.SmtpAgent
@@ -33,10 +27,16 @@ public abstract class Route
3327
{
3428
string m_addressType;
3529

30+
/// <summary>
31+
/// Constructor
32+
/// </summary>
3633
public Route()
3734
{
3835
}
39-
36+
37+
/// <summary>
38+
/// Marker to indicate which router can route an email address
39+
/// </summary>
4040
[XmlElement]
4141
public string AddressType
4242
{
@@ -55,32 +55,62 @@ public string AddressType
5555
}
5656
}
5757

58+
/// <summary>
59+
///
60+
/// </summary>
5861
public event Action<Route, Exception> Error;
5962

60-
public abstract void Init();
63+
/// <summary>
64+
/// Initialize router
65+
/// </summary>
66+
public abstract void Init();
67+
68+
/// <summary>
69+
/// Process message though route
70+
/// </summary>
71+
/// <param name="message"></param>
72+
/// <returns></returns>
6173
public abstract bool Process(ISmtpMessage message);
74+
75+
/// <summary>
76+
/// Validate route config settings.
77+
/// </summary>
6278
public virtual void Validate()
6379
{
64-
if (string.IsNullOrEmpty(this.AddressType))
80+
if (string.IsNullOrEmpty(AddressType))
6581
{
6682
throw new SmtpAgentException(SmtpAgentError.MissingAddressTypeInRoute);
6783
}
6884
}
6985

86+
/// <summary>
87+
///
88+
/// </summary>
89+
/// <param name="ex"></param>
7090
protected void NotifyError(Exception ex)
7191
{
72-
if (this.Error != null)
92+
if (Error != null)
7393
{
7494
try
7595
{
76-
this.Error(this, ex);
96+
Error(this, ex);
7797
}
7898
catch
7999
{
100+
// ignored
80101
}
81102
}
82103
}
83104

105+
/// <summary>
106+
/// Mark route as failed
107+
/// </summary>
84108
public bool FailedDelivery { get; set; }
109+
110+
/// <summary>
111+
/// Copy route
112+
/// </summary>
113+
/// <returns></returns>
114+
public abstract Route Clone();
85115
}
86116
}

csharp/gateway/smtpAgent/SmtpAgent.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -745,12 +745,12 @@ void PostProcessIncoming(ISmtpMessage message, IncomingMessage envelope)
745745

746746
if (envelope.HasDomainRecipients)
747747
{
748-
DirectAddressCollection routedRecipients = new DirectAddressCollection();
749-
m_router.Route(message, envelope, routedRecipients);
748+
var routedRecipients = new DirectAddressCollection();
749+
var messageRoute = m_router.Clone();
750+
messageRoute.Route(message, envelope, routedRecipients);
750751

751-
this.SendNotifications(envelope, routedRecipients);
752-
753-
SendDeliveryStatus(m_router, envelope, routedRecipients);
752+
SendNotifications(envelope, routedRecipients);
753+
SendDeliveryStatus(messageRoute, envelope, routedRecipients);
754754
}
755755
//
756756
// Any recipients that were handled by routes are no longer in the DomainRecipients collection (removed)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<SmtpAgentConfig>
3+
<Domain>nhind.hsgincubator.com</Domain>
4+
<Log>
5+
<DirectoryPath>C:\inetpub\logs</DirectoryPath>
6+
<NamePrefix>testSmtpAgent</NamePrefix>
7+
<RolloverFrequency>Day</RolloverFrequency>
8+
<Level>Trace</Level>
9+
</Log>
10+
<Notifications>
11+
<AutoResponse>false</AutoResponse>
12+
<AlwaysAck>false</AlwaysAck>
13+
<Text>Message Delivery Notification</Text>
14+
</Notifications>
15+
<PrivateCerts>
16+
<MachineResolver>
17+
<Name>NHINDPrivate</Name>
18+
</MachineResolver>
19+
</PrivateCerts>
20+
<PublicCerts>
21+
<MachineResolver>
22+
<Name>NHINDExternal</Name>
23+
</MachineResolver>
24+
</PublicCerts>
25+
<Anchors>
26+
<MachineResolver>
27+
<Incoming>
28+
<Name>NHINDAnchors</Name>
29+
</Incoming>
30+
<Outgoing>
31+
<Name>NHINDAnchors</Name>
32+
</Outgoing>
33+
</MachineResolver>
34+
</Anchors>
35+
<IncomingRoutes>
36+
<PluginRoute>
37+
<AddressType>STUB</AddressType>
38+
<Receiver>
39+
<TypeName>Health.Direct.SmtpAgent.Tests.StubPluginReciver, Health.Direct.SmtpAgent.Tests</TypeName>
40+
<Settings>
41+
<CopyFolder>C:\inetpub\mailroot\Incoming</CopyFolder>
42+
</Settings>
43+
</Receiver>
44+
</PluginRoute>
45+
<Route>
46+
<AddressType>Undeliverable</AddressType>
47+
<CopyFolder>C:\inetpub\mailroot\Gateway\Secure\Unknown</CopyFolder>
48+
</Route>
49+
<Route>
50+
<AddressType>NormalCopy</AddressType>
51+
<CopyFolder>C:\inetpub\mailroot\Incoming</CopyFolder>
52+
</Route>
53+
</IncomingRoutes>
54+
<Container>
55+
<Component>
56+
<Service>Health.Direct.Common.Diagnostics.IAuditor, Health.Direct.Common</Service>
57+
<Type>Health.Direct.SmtpAgent.Tests.DummyAuditor, Health.Direct.SmtpAgent.Tests</Type>
58+
<Scope>Singleton</Scope>
59+
</Component>
60+
</Container>
61+
</SmtpAgentConfig>

csharp/unittests/smtpAgent/SmtpAgentTester.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Neither the name of The Direct Project (directproject.org) nor the names of its
2222
using System.Net.Mime;
2323
using Health.Direct.Agent;
2424
using Health.Direct.Common.Cryptography;
25+
using Health.Direct.Common.Extensions;
2526
using Health.Direct.Common.Mail;
2627
using Health.Direct.Common.Mail.DSN;
2728
using Health.Direct.Common.Mail.Notifications;
@@ -45,6 +46,17 @@ public class SmtpAgentTester
4546
MIME-Version: 1.0
4647
Content-Type: text/plain
4748
49+
Yo. Wassup?";
50+
51+
public static string TestMessageLoad =
52+
53+
54+
Subject: {1}
55+
Message-ID: {0}
56+
Date: Tue, 30 May 2017 22:10:27 -0700
57+
MIME-Version: 1.0
58+
Content-Type: text/plain
59+
4860
Yo. Wassup?";
4961

5062
public static string TestMessageTimelyAndReliable =
@@ -193,7 +205,8 @@ private void CleanMessages(string[] path)
193205
}
194206
private void CleanMessages(MessageProcessingSettings settings)
195207
{
196-
if (settings == null) return;
208+
if (settings == null || settings.CopyFolder.IsNullOrWhiteSpace()) return;
209+
197210
CleanMessages(settings.CopyFolder);
198211
}
199212

0 commit comments

Comments
 (0)