diff --git a/src/Microsoft.Azure.WebJobs.Host/Executors/ITriggeredFunctionExecutorWithHook.cs b/src/Microsoft.Azure.WebJobs.Host/Executors/ITriggeredFunctionExecutorWithHook.cs new file mode 100644 index 0000000000..e575033320 --- /dev/null +++ b/src/Microsoft.Azure.WebJobs.Host/Executors/ITriggeredFunctionExecutorWithHook.cs @@ -0,0 +1,26 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the MIT License. See License.txt in the project root for license information. + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Microsoft.Azure.WebJobs.Host.Executors +{ + /// + /// Interface defining the contract for executing a triggered function. + /// Allows a hook around the underlying execution. + /// This should only be used by extensions that need very specific control over the invocation. + /// + public interface ITriggeredFunctionExecutorWithHook + { + /// + /// Try to invoke the triggered function using the values specified. + /// + /// The trigger invocation details. + /// The cancellation token + /// a hook that wraps the underlying invocation + /// A describing the results of the invocation. + Task TryExecuteAsync(TriggeredFunctionData input, CancellationToken cancellationToken, Func, Task> hook); + } +} diff --git a/src/Microsoft.Azure.WebJobs.Host/Executors/TriggeredFunctionExecutor.cs b/src/Microsoft.Azure.WebJobs.Host/Executors/TriggeredFunctionExecutor.cs index 45ed1b1c4e..0576a560b2 100644 --- a/src/Microsoft.Azure.WebJobs.Host/Executors/TriggeredFunctionExecutor.cs +++ b/src/Microsoft.Azure.WebJobs.Host/Executors/TriggeredFunctionExecutor.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. See License.txt in the project root for license information. using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.WebJobs.Host.Protocols; @@ -9,7 +10,7 @@ namespace Microsoft.Azure.WebJobs.Host.Executors { - internal class TriggeredFunctionExecutor : ITriggeredFunctionExecutor + internal class TriggeredFunctionExecutor : ITriggeredFunctionExecutor, ITriggeredFunctionExecutorWithHook { private FunctionDescriptor _descriptor; private ITriggeredFunctionInstanceFactory _instanceFactory; @@ -33,6 +34,11 @@ public FunctionDescriptor Function public async Task TryExecuteAsync(TriggeredFunctionData input, CancellationToken cancellationToken) { IFunctionInstance instance = _instanceFactory.Create((TTriggerValue)input.TriggerValue, input.ParentId); + return await TryExecuteAsync(instance, cancellationToken); + } + + private async Task TryExecuteAsync(IFunctionInstance instance, CancellationToken cancellationToken) + { IDelayedException exception = await _executor.TryExecuteAsync(instance, cancellationToken); FunctionResult result = exception != null ? @@ -41,5 +47,35 @@ public async Task TryExecuteAsync(TriggeredFunctionData input, C return result; } + + public async Task TryExecuteAsync(TriggeredFunctionData input, CancellationToken cancellationToken, Func, Task> wrapper) + { + IFunctionInstance instance = _instanceFactory.Create((TTriggerValue)input.TriggerValue, input.ParentId); + if (wrapper != null) + { + IFunctionInvoker invoker = new InvokeWrapper(instance.Invoker, wrapper); + instance = new FunctionInstance(instance.Id, instance.ParentId, instance.Reason, instance.BindingSource, invoker, instance.FunctionDescriptor); + } + return await TryExecuteAsync(instance, cancellationToken); + } + + private class InvokeWrapper : IFunctionInvoker + { + private readonly IFunctionInvoker _inner; + private readonly Func, Task> _hook; + + public InvokeWrapper(IFunctionInvoker inner, Func, Task> hook) + { + _inner = inner; + _hook = hook; + } + public IReadOnlyList ParameterNames => _inner.ParameterNames; + + public Task InvokeAsync(object[] arguments) + { + Func inner = () => _inner.InvokeAsync(arguments); + return _hook(inner); + } + } } } diff --git a/src/Microsoft.Azure.WebJobs.Host/WebJobs.Host.csproj b/src/Microsoft.Azure.WebJobs.Host/WebJobs.Host.csproj index 9bed7b5a20..c9c0e0bfa6 100644 --- a/src/Microsoft.Azure.WebJobs.Host/WebJobs.Host.csproj +++ b/src/Microsoft.Azure.WebJobs.Host/WebJobs.Host.csproj @@ -490,6 +490,7 @@ + diff --git a/test/Microsoft.Azure.WebJobs.Host.UnitTests/PublicSurfaceTests.cs b/test/Microsoft.Azure.WebJobs.Host.UnitTests/PublicSurfaceTests.cs index d79593773f..0d3d4d2f1b 100644 --- a/test/Microsoft.Azure.WebJobs.Host.UnitTests/PublicSurfaceTests.cs +++ b/test/Microsoft.Azure.WebJobs.Host.UnitTests/PublicSurfaceTests.cs @@ -196,6 +196,7 @@ public void WebJobsHostPublicSurface_LimitedToSpecificTypes() "AmbientConnectionStringProvider", "IExtensionRegistryExtensions", "ITriggeredFunctionExecutor", + "ITriggeredFunctionExecutorWithHook", "ListenerFactoryContext", "BindingTemplateSource", "TriggeredFunctionData",