Skip to content

Commit b6d98d0

Browse files
committed
First iteration of transport disgnostics
1 parent be5dbfa commit b6d98d0

3 files changed

Lines changed: 167 additions & 1 deletion

File tree

src/NServiceBus.AzureFunctions.Analyzer.Tests/AzureFunctionsConfigurationAnalyzerTests.cs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,5 +216,89 @@ void Bar()
216216

217217
return Assert(AzureFunctionsDiagnostics.RouteReplyToAnyInstanceNotAllowedId, source);
218218
}
219+
220+
[Test]
221+
public Task DiagnosticIsReportedForMaxAutoLockRenewalDuration()
222+
{
223+
var source =
224+
$@"using NServiceBus;
225+
using System;
226+
using System.Threading.Tasks;
227+
class Foo
228+
{{
229+
void Bar(ServiceBusTriggeredEndpointConfiguration endpointConfig)
230+
{{
231+
[|endpointConfig.Transport.MaxAutoLockRenewalDuration|] = new System.TimeSpan(0, 0, 5, 0);
232+
233+
var transportConfig = endpointConfig.Transport;
234+
[|transportConfig.MaxAutoLockRenewalDuration|] = new System.TimeSpan(0, 0, 5, 0);
235+
}}
236+
}}";
237+
238+
return Assert(AzureFunctionsDiagnostics.MaxAutoLockRenewalDurationNotAllowedId, source);
239+
}
240+
241+
[Test]
242+
public Task DiagnosticIsReportedForPrefetchCount()
243+
{
244+
var source =
245+
$@"using NServiceBus;
246+
using System;
247+
using System.Threading.Tasks;
248+
class Foo
249+
{{
250+
void Bar(ServiceBusTriggeredEndpointConfiguration endpointConfig)
251+
{{
252+
[|endpointConfig.Transport.PrefetchCount|] = 5;
253+
254+
var transportConfig = endpointConfig.Transport;
255+
[|transportConfig.PrefetchCount|] = 5;
256+
}}
257+
}}";
258+
259+
return Assert(AzureFunctionsDiagnostics.PrefetchCountNotAllowedId, source);
260+
}
261+
262+
[Test]
263+
public Task DiagnosticIsReportedForPrefetchMultiplier()
264+
{
265+
var source =
266+
$@"using NServiceBus;
267+
using System;
268+
using System.Threading.Tasks;
269+
class Foo
270+
{{
271+
void Bar(ServiceBusTriggeredEndpointConfiguration endpointConfig)
272+
{{
273+
[|endpointConfig.Transport.PrefetchMultiplier|] = 5;
274+
275+
var transportConfig = endpointConfig.Transport;
276+
[|transportConfig.PrefetchMultiplier|] = 5;
277+
}}
278+
}}";
279+
280+
return Assert(AzureFunctionsDiagnostics.PrefetchMultiplierNotAllowedId, source);
281+
}
282+
283+
[Test]
284+
public Task DiagnosticIsReportedForTimeToWaitBeforeTriggeringCircuitBreaker()
285+
{
286+
var source =
287+
$@"using NServiceBus;
288+
using System;
289+
using System.Threading.Tasks;
290+
class Foo
291+
{{
292+
void Bar(ServiceBusTriggeredEndpointConfiguration endpointConfig)
293+
{{
294+
[|endpointConfig.Transport.TimeToWaitBeforeTriggeringCircuitBreaker|] = new System.TimeSpan(0, 0, 5, 0);
295+
296+
var transportConfig = endpointConfig.Transport;
297+
[|transportConfig.TimeToWaitBeforeTriggeringCircuitBreaker|] = new System.TimeSpan(0, 0, 5, 0);
298+
}}
299+
}}";
300+
301+
return Assert(AzureFunctionsDiagnostics.TimeToWaitBeforeTriggeringCircuitBreakerNotAllowedId, source);
302+
}
219303
}
220304
}

src/NServiceBus.AzureFunctions.Analyzer/AzureFunctionsConfigurationAnalyzer.cs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,11 @@ public class AzureFunctionsConfigurationAnalyzer : DiagnosticAnalyzer
2121
AzureFunctionsDiagnostics.OverrideLocalAddressNotAllowed,
2222
AzureFunctionsDiagnostics.RouteReplyToThisInstanceNotAllowed,
2323
AzureFunctionsDiagnostics.RouteToThisInstanceNotAllowed,
24-
AzureFunctionsDiagnostics.RouteReplyToAnyInstanceNotAllowed
24+
AzureFunctionsDiagnostics.RouteReplyToAnyInstanceNotAllowed,
25+
AzureFunctionsDiagnostics.MaxAutoLockRenewalDurationNotAllowed,
26+
AzureFunctionsDiagnostics.PrefetchCountNotAllowed,
27+
AzureFunctionsDiagnostics.PrefetchMultiplierNotAllowed,
28+
AzureFunctionsDiagnostics.TimeToWaitBeforeTriggeringCircuitBreakerNotAllowed
2529
);
2630

2731
static readonly Dictionary<string, DiagnosticDescriptor> NotAllowedEndpointConfigurationMethods
@@ -44,11 +48,21 @@ static readonly Dictionary<string, DiagnosticDescriptor> NotAllowedSendAndReplyO
4448
["RouteReplyToAnyInstance"] = AzureFunctionsDiagnostics.RouteReplyToAnyInstanceNotAllowed
4549
};
4650

51+
static readonly Dictionary<string, DiagnosticDescriptor> NotAllowedTransportSettings
52+
= new Dictionary<string, DiagnosticDescriptor>
53+
{
54+
["MaxAutoLockRenewalDuration"] = AzureFunctionsDiagnostics.MaxAutoLockRenewalDurationNotAllowed,
55+
["PrefetchCount"] = AzureFunctionsDiagnostics.PrefetchCountNotAllowed,
56+
["PrefetchMultiplier"] = AzureFunctionsDiagnostics.PrefetchMultiplierNotAllowed,
57+
["TimeToWaitBeforeTriggeringCircuitBreaker"] = AzureFunctionsDiagnostics.TimeToWaitBeforeTriggeringCircuitBreakerNotAllowed
58+
};
59+
4760
public override void Initialize(AnalysisContext context)
4861
{
4962
context.EnableConcurrentExecution();
5063
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
5164
context.RegisterSyntaxNodeAction(Analyze, SyntaxKind.InvocationExpression);
65+
context.RegisterSyntaxNodeAction(AnalyzeTransport, SyntaxKind.SimpleMemberAccessExpression);
5266
}
5367

5468
static void Analyze(SyntaxNodeAnalysisContext context)
@@ -68,6 +82,33 @@ static void Analyze(SyntaxNodeAnalysisContext context)
6882
AnalyzeSendAndReplyOptions(context, invocationExpression, memberAccessExpression);
6983
}
7084

85+
static void AnalyzeTransport(SyntaxNodeAnalysisContext context)
86+
{
87+
if (!(context.Node is MemberAccessExpressionSyntax memberAccess))
88+
{
89+
return;
90+
}
91+
92+
if (!NotAllowedTransportSettings.TryGetValue(memberAccess.Name.ToString(), out var diagnosticDescriptor))
93+
{
94+
return;
95+
96+
}
97+
98+
var memberAccessSymbol = context.SemanticModel.GetSymbolInfo(memberAccess, context.CancellationToken);
99+
100+
if (!(memberAccessSymbol.Symbol is IPropertySymbol propertySymbol))
101+
{
102+
return;
103+
}
104+
105+
if (propertySymbol.ContainingType.ToString() == "NServiceBus.AzureServiceBusTransport")
106+
{
107+
context.ReportDiagnostic(diagnosticDescriptor, memberAccess);
108+
109+
}
110+
}
111+
71112
static void AnalyzeEndpointConfiguration(SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocationExpression, MemberAccessExpressionSyntax memberAccessExpression)
72113
{
73114
if (!NotAllowedEndpointConfigurationMethods.TryGetValue(memberAccessExpression.Name.Identifier.Text, out var diagnosticDescriptor))

src/NServiceBus.AzureFunctions.Analyzer/AzureFunctionsDiagnostics.cs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ public static class AzureFunctionsDiagnostics
1515
public const string RouteToThisInstanceNotAllowedId = "NSBFUNC011";
1616
public const string RouteReplyToAnyInstanceNotAllowedId = "NSBFUNC012";
1717

18+
public const string MaxAutoLockRenewalDurationNotAllowedId = "NSBFUNC013";
19+
public const string PrefetchCountNotAllowedId = "NSBFUNC014";
20+
public const string PrefetchMultiplierNotAllowedId = "NSBFUNC015";
21+
public const string TimeToWaitBeforeTriggeringCircuitBreakerNotAllowedId = "NSBFUNC016";
22+
1823
const string DiagnosticCategory = "NServiceBus.AzureFunctions";
1924

2025
internal static readonly DiagnosticDescriptor PurgeOnStartupNotAllowed = new DiagnosticDescriptor(
@@ -106,5 +111,41 @@ public static class AzureFunctionsDiagnostics
106111
defaultSeverity: DiagnosticSeverity.Warning,
107112
isEnabledByDefault: true
108113
);
114+
115+
internal static readonly DiagnosticDescriptor MaxAutoLockRenewalDurationNotAllowed = new DiagnosticDescriptor(
116+
id: MaxAutoLockRenewalDurationNotAllowedId,
117+
title: "MaxAutoLockRenewalDuration is not supported in Azure Functions",
118+
messageFormat: "Azure Functions endpoints do not control the message receiver and cannot decide the lock renewal duration.",
119+
category: DiagnosticCategory,
120+
defaultSeverity: DiagnosticSeverity.Error,
121+
isEnabledByDefault: true
122+
);
123+
124+
internal static readonly DiagnosticDescriptor PrefetchCountNotAllowed = new DiagnosticDescriptor(
125+
id: PrefetchCountNotAllowedId,
126+
title: "PrefetchCount is not supported in Azure Functions",
127+
messageFormat: "Azure Functions endpoints do not control the message receiver and cannot decide the prefetch count.",
128+
category: DiagnosticCategory,
129+
defaultSeverity: DiagnosticSeverity.Error,
130+
isEnabledByDefault: true
131+
);
132+
133+
internal static readonly DiagnosticDescriptor PrefetchMultiplierNotAllowed = new DiagnosticDescriptor(
134+
id: PrefetchMultiplierNotAllowedId,
135+
title: "PrefetchMultiplier is not supported in Azure Functions",
136+
messageFormat: "Azure Functions endpoints do not control the message receiver and cannot decide the prefetch multiplier.",
137+
category: DiagnosticCategory,
138+
defaultSeverity: DiagnosticSeverity.Error,
139+
isEnabledByDefault: true
140+
);
141+
142+
internal static readonly DiagnosticDescriptor TimeToWaitBeforeTriggeringCircuitBreakerNotAllowed = new DiagnosticDescriptor(
143+
id: TimeToWaitBeforeTriggeringCircuitBreakerNotAllowedId,
144+
title: "TimeToWaitBeforeTriggeringCircuitBreaker is not supported in Azure Functions",
145+
messageFormat: "Azure Functions endpoints do not control the message receiver and cannot access circuit breaker settings.",
146+
category: DiagnosticCategory,
147+
defaultSeverity: DiagnosticSeverity.Error,
148+
isEnabledByDefault: true
149+
);
109150
}
110151
}

0 commit comments

Comments
 (0)