diff --git a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/AttributeDiscoverer.cs b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/AttributeDiscoverer.cs
deleted file mode 100644
index 1a1434c7..00000000
--- a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/AttributeDiscoverer.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-namespace NServiceBus.AzureFunctions.InProcess.ServiceBus
-{
- using System;
- using System.Diagnostics;
- using System.Reflection;
- using Microsoft.Azure.WebJobs;
-
- static class TriggerDiscoverer
- {
- ///
- /// Attempts to derive the required configuration information from the Azure Function and trigger attributes via reflection.
- ///
- public static TTransportTriggerAttribute TryGet() where TTransportTriggerAttribute : Attribute
- {
- var frames = new StackTrace().GetFrames();
- foreach (var stackFrame in frames)
- {
- var method = stackFrame.GetMethod();
- var functionAttribute = method.GetCustomAttribute(false);
- if (functionAttribute != null)
- {
- foreach (var parameter in method.GetParameters())
- {
- var triggerConfiguration = parameter.GetCustomAttribute(false);
- if (triggerConfiguration != null)
- {
- return triggerConfiguration;
- }
- }
-
- return null;
- }
- }
-
- return null;
- }
- }
-}
\ No newline at end of file
diff --git a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/FunctionEndpoint.cs b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/FunctionEndpoint.cs
index d147f1ee..f390ae12 100644
--- a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/FunctionEndpoint.cs
+++ b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/FunctionEndpoint.cs
@@ -11,6 +11,7 @@
using Logging;
using Microsoft.Azure.ServiceBus;
using Microsoft.Azure.ServiceBus.Core;
+ using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Transport;
using ExecutionContext = Microsoft.Azure.WebJobs.ExecutionContext;
@@ -29,8 +30,17 @@ internal FunctionEndpoint(IStartableEndpointWithExternallyManagedContainer exter
endpointFactory = _ => externallyManagedContainerEndpoint.Start(serviceProvider);
}
+ ///
+ /// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline. This method will lookup the setting to determine whether to use transactional or non-transactional processing.
+ ///
+ public Task Process(Message message, ExecutionContext executionContext, IMessageReceiver messageReceiver, ILogger functionsLogger = null) =>
+ ReflectionHelper.GetAutoCompleteValue()
+ ? ProcessNonTransactional(message, executionContext, messageReceiver, functionsLogger)
+ : ProcessTransactional(message, executionContext, messageReceiver, functionsLogger);
+
///
/// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline. All messages are committed transactionally with the successful processing of the incoming message.
+ /// Requires to be set to false!
///
public async Task ProcessTransactional(Message message, ExecutionContext executionContext, IMessageReceiver messageReceiver, ILogger functionsLogger = null)
{
@@ -57,6 +67,15 @@ await InitializeEndpointIfNecessary(functionExecutionContext, CancellationToken.
///
/// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline.
///
+ public Task ProcessNonTransactional(Message message, ExecutionContext executionContext, IMessageReceiver messageReceiver, ILogger functionsLogger = null) => Process(message, executionContext, functionsLogger);
+
+ ///
+ /// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline.
+ ///
+ [ObsoleteEx(
+ ReplacementTypeOrMember = "Process(Message, ExecutionContext, IMessageReceiver, ILogger)",
+ TreatAsErrorFromVersion = "2",
+ RemoveInVersion = "3")]
public async Task Process(Message message, ExecutionContext executionContext, ILogger functionsLogger = null)
{
FunctionsLoggerFactory.Instance.SetCurrentLogger(functionsLogger);
diff --git a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/IFunctionEndpoint.cs b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/IFunctionEndpoint.cs
index 496d5f40..5b7de981 100644
--- a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/IFunctionEndpoint.cs
+++ b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/IFunctionEndpoint.cs
@@ -14,13 +14,17 @@
public interface IFunctionEndpoint
{
///
- /// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline. All messages are committed transactionally with the successful processing of the incoming message.
+ /// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline. This method will lookup the setting to determine whether to use transactional or non-transactional processing.
///
- Task ProcessTransactional(Message message, ExecutionContext executionContext, IMessageReceiver messageReceiver, ILogger functionsLogger = null);
+ Task Process(Message message, ExecutionContext executionContext, IMessageReceiver messageReceiver, ILogger functionsLogger = null);
///
/// Processes a message received from an AzureServiceBus trigger using the NServiceBus message pipeline.
///
+ [ObsoleteEx(
+ ReplacementTypeOrMember = "Process(Message, ExecutionContext, IMessageReceiver, ILogger)",
+ TreatAsErrorFromVersion = "2",
+ RemoveInVersion = "3")]
Task Process(Message message, ExecutionContext executionContext, ILogger functionsLogger = null);
///
diff --git a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/ReflectionHelper.cs b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/ReflectionHelper.cs
new file mode 100644
index 00000000..21d7bd08
--- /dev/null
+++ b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/ReflectionHelper.cs
@@ -0,0 +1,50 @@
+namespace NServiceBus.AzureFunctions.InProcess.ServiceBus
+{
+ using System;
+ using System.Diagnostics;
+ using System.Reflection;
+ using Microsoft.Azure.ServiceBus;
+ using Microsoft.Azure.WebJobs;
+
+ class ReflectionHelper
+ {
+ public static bool GetAutoCompleteValue()
+ {
+ var triggerAttribute = FindTriggerAttributeInternal();
+ if (triggerAttribute != null)
+ {
+ return triggerAttribute.AutoComplete;
+ }
+
+ throw new Exception($"Could not locate {nameof(ServiceBusTriggerAttribute)} to infer the AutoComplete setting. Make sure that the function trigger contains a parameter decorated with {nameof(ServiceBusTriggerAttribute)} or use the advanced APIs exposed via the {nameof(FunctionEndpoint)} type instead.");
+ }
+
+ public static ServiceBusTriggerAttribute FindBusTriggerAttribute() => FindTriggerAttributeInternal();
+
+ static ServiceBusTriggerAttribute FindTriggerAttributeInternal()
+ {
+ var st = new StackTrace(skipFrames: 2); // skip first two frames because it is this method + the public method
+ var frames = st.GetFrames();
+ foreach (var frame in frames)
+ {
+ var method = frame?.GetMethod();
+ if (method?.GetCustomAttribute(false) != null)
+ {
+ foreach (var parameter in method.GetParameters())
+ {
+ ServiceBusTriggerAttribute serviceBusTriggerAttribute;
+ if (parameter.ParameterType == typeof(Message)
+ && (serviceBusTriggerAttribute = parameter.GetCustomAttribute(false)) != null)
+ {
+ return serviceBusTriggerAttribute;
+ }
+ }
+
+ return null;
+ }
+ }
+
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/ServiceBusTriggeredEndpointConfiguration.cs b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/ServiceBusTriggeredEndpointConfiguration.cs
index 0b3a6cc0..3a2f544e 100644
--- a/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/ServiceBusTriggeredEndpointConfiguration.cs
+++ b/src/NServiceBus.AzureFunctions.InProcess.ServiceBus/ServiceBusTriggeredEndpointConfiguration.cs
@@ -4,7 +4,6 @@
using System.Threading.Tasks;
using AzureFunctions.InProcess.ServiceBus;
using Logging;
- using Microsoft.Azure.WebJobs;
using Serialization;
using Transport;
@@ -77,10 +76,10 @@ public ServiceBusTriggeredEndpointConfiguration(string endpointName, string conn
///
public static ServiceBusTriggeredEndpointConfiguration FromAttributes()
{
- var configuration = TriggerDiscoverer.TryGet();
- if (configuration != null)
+ var serviceBusTriggerAttribute = ReflectionHelper.FindBusTriggerAttribute();
+ if (serviceBusTriggerAttribute != null)
{
- return new ServiceBusTriggeredEndpointConfiguration(configuration.QueueName, configuration.Connection);
+ return new ServiceBusTriggeredEndpointConfiguration(serviceBusTriggerAttribute.QueueName, serviceBusTriggerAttribute.Connection);
}
throw new Exception(
diff --git a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Can_enable_transactions.approved.txt b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Can_enable_transactions.approved.txt
index bfdbfd4a..4c8ea9d2 100644
--- a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Can_enable_transactions.approved.txt
+++ b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Can_enable_transactions.approved.txt
@@ -8,9 +8,9 @@ using NServiceBus;
class FunctionEndpointTrigger
{
- readonly IFunctionEndpoint endpoint;
+ readonly FunctionEndpoint endpoint;
- public FunctionEndpointTrigger(IFunctionEndpoint endpoint)
+ public FunctionEndpointTrigger(FunctionEndpoint endpoint)
{
this.endpoint = endpoint;
}
diff --git a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Can_override_trigger_function_name.approved.txt b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Can_override_trigger_function_name.approved.txt
index efad0593..fd792927 100644
--- a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Can_override_trigger_function_name.approved.txt
+++ b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Can_override_trigger_function_name.approved.txt
@@ -8,9 +8,9 @@ using NServiceBus;
class FunctionEndpointTrigger
{
- readonly IFunctionEndpoint endpoint;
+ readonly FunctionEndpoint endpoint;
- public FunctionEndpointTrigger(IFunctionEndpoint endpoint)
+ public FunctionEndpointTrigger(FunctionEndpoint endpoint)
{
this.endpoint = endpoint;
}
@@ -23,6 +23,6 @@ class FunctionEndpointTrigger
ILogger logger,
ExecutionContext executionContext)
{
- await endpoint.Process(message, executionContext, logger);
+ await endpoint.ProcessNonTransactional(message, executionContext, messageReceiver, logger);
}
}
\ No newline at end of file
diff --git a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.NameIsStringValue.approved.txt b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.NameIsStringValue.approved.txt
index 99e48622..e16a7f0f 100644
--- a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.NameIsStringValue.approved.txt
+++ b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.NameIsStringValue.approved.txt
@@ -8,9 +8,9 @@ using NServiceBus;
class FunctionEndpointTrigger
{
- readonly IFunctionEndpoint endpoint;
+ readonly FunctionEndpoint endpoint;
- public FunctionEndpointTrigger(IFunctionEndpoint endpoint)
+ public FunctionEndpointTrigger(FunctionEndpoint endpoint)
{
this.endpoint = endpoint;
}
@@ -23,6 +23,6 @@ class FunctionEndpointTrigger
ILogger logger,
ExecutionContext executionContext)
{
- await endpoint.Process(message, executionContext, logger);
+ await endpoint.ProcessNonTransactional(message, executionContext, messageReceiver, logger);
}
}
\ No newline at end of file
diff --git a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Two_optionals_out_of_order.approved.txt b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Two_optionals_out_of_order.approved.txt
index bbb25c31..70cc6c8a 100644
--- a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Two_optionals_out_of_order.approved.txt
+++ b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Two_optionals_out_of_order.approved.txt
@@ -8,9 +8,9 @@ using NServiceBus;
class FunctionEndpointTrigger
{
- readonly IFunctionEndpoint endpoint;
+ readonly FunctionEndpoint endpoint;
- public FunctionEndpointTrigger(IFunctionEndpoint endpoint)
+ public FunctionEndpointTrigger(FunctionEndpoint endpoint)
{
this.endpoint = endpoint;
}
diff --git a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Use_two_optionals.approved.txt b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Use_two_optionals.approved.txt
index bbb25c31..70cc6c8a 100644
--- a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Use_two_optionals.approved.txt
+++ b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.Use_two_optionals.approved.txt
@@ -8,9 +8,9 @@ using NServiceBus;
class FunctionEndpointTrigger
{
- readonly IFunctionEndpoint endpoint;
+ readonly FunctionEndpoint endpoint;
- public FunctionEndpointTrigger(IFunctionEndpoint endpoint)
+ public FunctionEndpointTrigger(FunctionEndpoint endpoint)
{
this.endpoint = endpoint;
}
diff --git a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.UsingFullyQualifiedAttributeName.approved.txt b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.UsingFullyQualifiedAttributeName.approved.txt
index 99e48622..e16a7f0f 100644
--- a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.UsingFullyQualifiedAttributeName.approved.txt
+++ b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.UsingFullyQualifiedAttributeName.approved.txt
@@ -8,9 +8,9 @@ using NServiceBus;
class FunctionEndpointTrigger
{
- readonly IFunctionEndpoint endpoint;
+ readonly FunctionEndpoint endpoint;
- public FunctionEndpointTrigger(IFunctionEndpoint endpoint)
+ public FunctionEndpointTrigger(FunctionEndpoint endpoint)
{
this.endpoint = endpoint;
}
@@ -23,6 +23,6 @@ class FunctionEndpointTrigger
ILogger logger,
ExecutionContext executionContext)
{
- await endpoint.Process(message, executionContext, logger);
+ await endpoint.ProcessNonTransactional(message, executionContext, messageReceiver, logger);
}
}
\ No newline at end of file
diff --git a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.UsingNamespace.approved.txt b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.UsingNamespace.approved.txt
index 99e48622..e16a7f0f 100644
--- a/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.UsingNamespace.approved.txt
+++ b/src/NServiceBus.AzureFunctions.SourceGenerator.Tests/ApprovalFiles/SourceGeneratorApprovals2.UsingNamespace.approved.txt
@@ -8,9 +8,9 @@ using NServiceBus;
class FunctionEndpointTrigger
{
- readonly IFunctionEndpoint endpoint;
+ readonly FunctionEndpoint endpoint;
- public FunctionEndpointTrigger(IFunctionEndpoint endpoint)
+ public FunctionEndpointTrigger(FunctionEndpoint endpoint)
{
this.endpoint = endpoint;
}
@@ -23,6 +23,6 @@ class FunctionEndpointTrigger
ILogger logger,
ExecutionContext executionContext)
{
- await endpoint.Process(message, executionContext, logger);
+ await endpoint.ProcessNonTransactional(message, executionContext, messageReceiver, logger);
}
}
\ No newline at end of file
diff --git a/src/NServiceBus.AzureFunctions.SourceGenerator/TriggerFunctionGenerator2.cs b/src/NServiceBus.AzureFunctions.SourceGenerator/TriggerFunctionGenerator2.cs
index 98ab503b..47805cb6 100644
--- a/src/NServiceBus.AzureFunctions.SourceGenerator/TriggerFunctionGenerator2.cs
+++ b/src/NServiceBus.AzureFunctions.SourceGenerator/TriggerFunctionGenerator2.cs
@@ -116,9 +116,9 @@ public void Execute(GeneratorExecutionContext context)
class FunctionEndpointTrigger
{{
- readonly IFunctionEndpoint endpoint;
+ readonly FunctionEndpoint endpoint;
- public FunctionEndpointTrigger(IFunctionEndpoint endpoint)
+ public FunctionEndpointTrigger(FunctionEndpoint endpoint)
{{
this.endpoint = endpoint;
}}
@@ -133,7 +133,7 @@ public async Task Run(
{{
{(syntaxReceiver.enableCrossEntityTransactions
? "await endpoint.ProcessTransactional(message, executionContext, messageReceiver, logger);"
- : "await endpoint.Process(message, executionContext, logger);")}
+ : "await endpoint.ProcessNonTransactional(message, executionContext, messageReceiver, logger);")}
}}
}}";
context.AddSource("NServiceBus__FunctionEndpointTrigger", SourceText.From(source, Encoding.UTF8));
diff --git a/src/ServiceBus.Tests/ApprovalFiles/APIApprovals.Approve.approved.txt b/src/ServiceBus.Tests/ApprovalFiles/APIApprovals.Approve.approved.txt
index b7783608..d46ca1f2 100644
--- a/src/ServiceBus.Tests/ApprovalFiles/APIApprovals.Approve.approved.txt
+++ b/src/ServiceBus.Tests/ApprovalFiles/APIApprovals.Approve.approved.txt
@@ -3,7 +3,11 @@ namespace NServiceBus
{
public class FunctionEndpoint : NServiceBus.IFunctionEndpoint
{
+ [System.Obsolete("Use `Process(Message, ExecutionContext, IMessageReceiver, ILogger)` instead. Will" +
+ " be treated as an error from version 2.0.0. Will be removed in version 3.0.0.", false)]
public System.Threading.Tasks.Task Process(Microsoft.Azure.ServiceBus.Message message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Extensions.Logging.ILogger functionsLogger = null) { }
+ public System.Threading.Tasks.Task Process(Microsoft.Azure.ServiceBus.Message message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Azure.ServiceBus.Core.IMessageReceiver messageReceiver, Microsoft.Extensions.Logging.ILogger functionsLogger = null) { }
+ public System.Threading.Tasks.Task ProcessNonTransactional(Microsoft.Azure.ServiceBus.Message message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Azure.ServiceBus.Core.IMessageReceiver messageReceiver, Microsoft.Extensions.Logging.ILogger functionsLogger = null) { }
public System.Threading.Tasks.Task ProcessTransactional(Microsoft.Azure.ServiceBus.Message message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Azure.ServiceBus.Core.IMessageReceiver messageReceiver, Microsoft.Extensions.Logging.ILogger functionsLogger = null) { }
public System.Threading.Tasks.Task Publish(object message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Extensions.Logging.ILogger functionsLogger = null) { }
public System.Threading.Tasks.Task Publish(object message, NServiceBus.PublishOptions options, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Extensions.Logging.ILogger functionsLogger = null) { }
@@ -30,8 +34,10 @@ namespace NServiceBus
}
public interface IFunctionEndpoint
{
+ [System.Obsolete("Use `Process(Message, ExecutionContext, IMessageReceiver, ILogger)` instead. Will" +
+ " be treated as an error from version 2.0.0. Will be removed in version 3.0.0.", false)]
System.Threading.Tasks.Task Process(Microsoft.Azure.ServiceBus.Message message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Extensions.Logging.ILogger functionsLogger = null);
- System.Threading.Tasks.Task ProcessTransactional(Microsoft.Azure.ServiceBus.Message message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Azure.ServiceBus.Core.IMessageReceiver messageReceiver, Microsoft.Extensions.Logging.ILogger functionsLogger = null);
+ System.Threading.Tasks.Task Process(Microsoft.Azure.ServiceBus.Message message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Azure.ServiceBus.Core.IMessageReceiver messageReceiver, Microsoft.Extensions.Logging.ILogger functionsLogger = null);
System.Threading.Tasks.Task Publish(object message, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Extensions.Logging.ILogger functionsLogger = null);
System.Threading.Tasks.Task Publish(object message, NServiceBus.PublishOptions options, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Extensions.Logging.ILogger functionsLogger = null);
System.Threading.Tasks.Task Publish(System.Action messageConstructor, Microsoft.Azure.WebJobs.ExecutionContext executionContext, Microsoft.Extensions.Logging.ILogger functionsLogger = null);
diff --git a/src/ServiceBus.Tests/FunctionEndpointComponent.cs b/src/ServiceBus.Tests/FunctionEndpointComponent.cs
index 3aa61dbf..a5b5f21e 100644
--- a/src/ServiceBus.Tests/FunctionEndpointComponent.cs
+++ b/src/ServiceBus.Tests/FunctionEndpointComponent.cs
@@ -100,7 +100,7 @@ public override async Task ComponentsStarted(CancellationToken token)
{
var transportMessage = MessageHelper.GenerateMessage(message);
var context = new ExecutionContext();
- await endpoint.Process(transportMessage, context);
+ await endpoint.ProcessNonTransactional(transportMessage, context, null);
}
}
diff --git a/src/ServiceBus.Tests/ReflectionHelperTests.cs b/src/ServiceBus.Tests/ReflectionHelperTests.cs
new file mode 100644
index 00000000..bea7620f
--- /dev/null
+++ b/src/ServiceBus.Tests/ReflectionHelperTests.cs
@@ -0,0 +1,148 @@
+namespace ServiceBus.Tests
+{
+ using System;
+ using Microsoft.Azure.ServiceBus;
+ using Microsoft.Azure.WebJobs;
+ using NServiceBus.AzureFunctions.InProcess.ServiceBus;
+ using NUnit.Framework;
+
+ [TestFixture]
+ public class ReflectionHelperTests
+ {
+ [Test]
+ public void When_no_attributes_defined_should_throw()
+ {
+ var exception = Assert.Throws(() => ReflectionHelper.GetAutoCompleteValue());
+
+ StringAssert.Contains($"Could not locate {nameof(ServiceBusTriggerAttribute)} to infer the AutoComplete setting.", exception.Message);
+ }
+
+ [Test]
+ public void When_no_function_name_attribute_defined_should_throw()
+ {
+ var exception = Assert.Throws(() => FunctionWithNoFunctionNameAttribute(null));
+
+ StringAssert.Contains($"Could not locate {nameof(ServiceBusTriggerAttribute)} to infer the AutoComplete setting.", exception.Message);
+
+ void FunctionWithNoFunctionNameAttribute(
+ [ServiceBusTrigger("queueName", "subscriptionname", AutoComplete = true)] Message _)
+ {
+ ReflectionHelper.GetAutoCompleteValue();
+ }
+ }
+
+ [Test]
+ public void When_no_trigger_attribute_defined_should_throw()
+ {
+ var exception = Assert.Throws(() => FunctionWithNoServiceBusTriggerAttribute(null));
+
+ StringAssert.Contains($"Could not locate {nameof(ServiceBusTriggerAttribute)} to infer the AutoComplete setting.", exception.Message);
+
+ [FunctionName("TestFunction")]
+ void FunctionWithNoServiceBusTriggerAttribute(
+ Message _)
+ {
+ ReflectionHelper.GetAutoCompleteValue();
+ }
+ }
+
+ [Test]
+ public void When_auto_complete_set_to_false_should_return_false()
+ {
+ FunctionTriggerWithAutoCompleteExplicitlySetToFalse(null);
+
+ [FunctionName("TestFunction")]
+ void FunctionTriggerWithAutoCompleteExplicitlySetToFalse(
+ [ServiceBusTrigger("queueName", "subscriptionname", AutoComplete = false)] Message _)
+ {
+ Assert.IsFalse(ReflectionHelper.GetAutoCompleteValue());
+ }
+ }
+
+ [Test]
+ public void When_auto_complete_set_to_true_should_return_true()
+ {
+ FunctionTriggerWithAutoCompleteExplicitlySetToTrue(null);
+
+ [FunctionName("TestFunction")]
+ void FunctionTriggerWithAutoCompleteExplicitlySetToTrue(
+ [ServiceBusTrigger("queueName", "subscriptionname", AutoComplete = true)] Message _)
+ {
+ Assert.IsTrue(ReflectionHelper.GetAutoCompleteValue());
+ }
+ }
+
+ [Test]
+ public void When_auto_complete_not_set_should_return_true()
+ {
+ FunctionTriggerWithoutAutoCompleteConfiguration(null);
+
+ [FunctionName("TestFunction")]
+ void FunctionTriggerWithoutAutoCompleteConfiguration(
+ [ServiceBusTrigger("queueName", "subscriptionname")] Message _)
+ {
+ Assert.True(ReflectionHelper.GetAutoCompleteValue());
+ }
+ }
+
+ [Test]
+ public void When_helper_invoked_in_nested_methods()
+ {
+ NestedTrigger(null);
+
+ [FunctionName("TestFunction")]
+ void NestedTrigger(
+ [ServiceBusTrigger("queueName", "subscriptionname", AutoComplete = false)] Message _)
+ {
+ One();
+ }
+
+ void One()
+ {
+ Two();
+ }
+
+ void Two()
+ {
+ Three();
+ }
+
+ void Three()
+ {
+ Assert.IsFalse(ReflectionHelper.GetAutoCompleteValue());
+ }
+ }
+
+ [Test]
+ public void When_helper_invoked_in_local_function()
+ {
+ LocalFunction(null);
+
+ [FunctionName("TestFunction")]
+ void LocalFunction(
+ [ServiceBusTrigger("queueName", "subscriptionname", AutoComplete = false)] Message _)
+ {
+ LocalFunction();
+
+ void LocalFunction()
+ {
+ Assert.IsFalse(ReflectionHelper.GetAutoCompleteValue());
+ }
+ }
+ }
+
+ [Test]
+ public void When_helper_invoked_in_expression()
+ {
+ Expression(null);
+
+ [FunctionName("TestFunction")]
+ void Expression(
+ [ServiceBusTrigger("queueName", "subscriptionname", AutoComplete = false)] Message _)
+ {
+ Func expression = () => ReflectionHelper.GetAutoCompleteValue();
+ Assert.IsFalse(expression());
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ServiceBus.Tests/ServiceBus.Tests.csproj b/src/ServiceBus.Tests/ServiceBus.Tests.csproj
index 22cc3d0f..dfe67d94 100644
--- a/src/ServiceBus.Tests/ServiceBus.Tests.csproj
+++ b/src/ServiceBus.Tests/ServiceBus.Tests.csproj
@@ -4,6 +4,7 @@
netcoreapp3.1;net5.0
true
..\Test.snk
+ 9
diff --git a/src/ServiceBus.Tests/When_shipping_handlers_in_dedicated_assembly.cs b/src/ServiceBus.Tests/When_shipping_handlers_in_dedicated_assembly.cs
index da2e6ec5..23dd7501 100644
--- a/src/ServiceBus.Tests/When_shipping_handlers_in_dedicated_assembly.cs
+++ b/src/ServiceBus.Tests/When_shipping_handlers_in_dedicated_assembly.cs
@@ -42,7 +42,7 @@ public async Task Should_load_handlers_from_assembly_when_using_FunctionsHostBui
// we need to process an actual message to have the endpoint being created
- await endpoint.Process(GenerateMessage(), new ExecutionContext());
+ await endpoint.ProcessNonTransactional(GenerateMessage(), new ExecutionContext(), null);
// The message handler assembly should be loaded now because scanning should find and load the handler assembly
Assert.True(AppDomain.CurrentDomain.GetAssemblies().Any(a => a.FullName == "Testing.Handlers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"));