Skip to content

Commit 7945f7a

Browse files
authored
Merge pull request #2049 from kashimiz/feature/node-return-values
Enable passing return values from non-C# functions.
2 parents 9aa7572 + d24e152 commit 7945f7a

File tree

5 files changed

+72
-14
lines changed

5 files changed

+72
-14
lines changed

src/WebJobs.Script.WebHost/WebJobs.Script.WebHost.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
<PackageReference Include="Microsoft.Azure.AppService.Proxy.Client.Contract" Version="0.3.1.1">
3838
<NoWarn>NU1701</NoWarn>
3939
</PackageReference>
40-
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta3" />
40+
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta3-11077" />
4141
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="3.0.0-beta3" />
4242
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.0.0-beta3">
4343
<NoWarn>NU1701</NoWarn>

src/WebJobs.Script/Binding/Http/HttpBinding.cs

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,21 @@
77
using System.Dynamic;
88
using System.Globalization;
99
using System.IO;
10-
using System.Linq;
1110
using System.Net;
1211
using System.Reflection.Emit;
1312
using System.Threading.Tasks;
1413
using Microsoft.AspNetCore.Http;
1514
using Microsoft.AspNetCore.Mvc;
1615
using Microsoft.AspNetCore.Mvc.WebApiCompatShim;
1716
using Microsoft.Azure.WebJobs.Script.Description;
18-
using Microsoft.Net.Http.Headers;
1917
using Newtonsoft.Json;
2018
using Newtonsoft.Json.Linq;
2119

2220
namespace Microsoft.Azure.WebJobs.Script.Binding
2321
{
2422
public class HttpBinding : FunctionBinding
2523
{
26-
public HttpBinding(ScriptHostConfiguration config, BindingMetadata metadata, FileAccess access)
24+
public HttpBinding(ScriptHostConfiguration config, BindingMetadata metadata, FileAccess access)
2725
: base(config, metadata, access)
2826
{
2927
}
@@ -188,17 +186,31 @@ internal static void SetResponse(HttpRequest request, object result)
188186
IActionResult actionResult = result as IActionResult;
189187
if (actionResult == null)
190188
{
191-
var objectResult = new ObjectResult(result);
192-
193-
if (result is System.Net.Http.HttpResponseMessage)
189+
if (result is Stream)
190+
{
191+
// for script language functions (e.g. PowerShell, BAT, etc.) the value
192+
// will be a Stream which we need to convert to string
193+
FunctionBinding.ConvertStreamToValue((Stream)result, DataType.String, ref result);
194+
actionResult = CreateResult(request, result);
195+
}
196+
else if (result is JObject)
194197
{
195-
// To maintain backwards compatibility, if the type returned is an
196-
// instance of an HttpResponseMessage, add the appropriate formatter to
197-
// handle the response
198-
objectResult.Formatters.Add(new HttpResponseMessageOutputFormatter());
198+
actionResult = CreateResult(request, result);
199199
}
200+
else
201+
{
202+
var objectResult = new ObjectResult(result);
203+
204+
if (result is System.Net.Http.HttpResponseMessage)
205+
{
206+
// To maintain backwards compatibility, if the type returned is an
207+
// instance of an HttpResponseMessage, add the appropriate formatter to
208+
// handle the response
209+
objectResult.Formatters.Add(new HttpResponseMessageOutputFormatter());
210+
}
200211

201-
actionResult = objectResult;
212+
actionResult = objectResult;
213+
}
202214
}
203215

204216
request.HttpContext.Items[ScriptConstants.AzureFunctionsHttpResponseKey] = actionResult;

src/WebJobs.Script/Description/Rpc/WorkerFunctionDescriptorProvider.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
using System;
55
using System.Collections.ObjectModel;
6+
using System.Linq;
7+
using System.Reflection;
8+
using System.Reflection.Emit;
69
using System.Threading.Tasks.Dataflow;
10+
using Microsoft.Azure.WebJobs.Description;
711
using Microsoft.Azure.WebJobs.Script.Binding;
812
using Microsoft.Azure.WebJobs.Script.Rpc;
913

@@ -40,5 +44,47 @@ protected override IFunctionInvoker CreateFunctionInvoker(string scriptFilePath,
4044
});
4145
return new WorkerLanguageInvoker(Host, triggerMetadata, functionMetadata, inputBindings, outputBindings, inputBuffer);
4246
}
47+
48+
protected override Collection<ParameterDescriptor> GetFunctionParameters(IFunctionInvoker functionInvoker, FunctionMetadata functionMetadata,
49+
BindingMetadata triggerMetadata, Collection<CustomAttributeBuilder> methodAttributes, Collection<FunctionBinding> inputBindings, Collection<FunctionBinding> outputBindings)
50+
{
51+
var parameters = base.GetFunctionParameters(functionInvoker, functionMetadata, triggerMetadata, methodAttributes, inputBindings, outputBindings);
52+
53+
var bindings = inputBindings.Union(outputBindings);
54+
55+
try
56+
{
57+
var triggerHandlesReturnValueBinding = bindings.SingleOrDefault(b =>
58+
b.Metadata.IsTrigger &&
59+
(b as ExtensionBinding)?.Attributes.SingleOrDefault(a =>
60+
(a.GetType().GetCustomAttribute(typeof(BindingAttribute)) as BindingAttribute)?.TriggerHandlesReturnValue == true)
61+
!= null);
62+
63+
if (triggerHandlesReturnValueBinding != null)
64+
{
65+
var byRefType = typeof(object).MakeByRefType();
66+
67+
ParameterDescriptor returnDescriptor = new ParameterDescriptor(ScriptConstants.SystemReturnParameterName, byRefType);
68+
returnDescriptor.Attributes |= ParameterAttributes.Out;
69+
70+
Collection<CustomAttributeBuilder> customAttributes = triggerHandlesReturnValueBinding.GetCustomAttributes(byRefType);
71+
if (customAttributes != null)
72+
{
73+
foreach (var customAttribute in customAttributes)
74+
{
75+
returnDescriptor.CustomAttributes.Add(customAttribute);
76+
}
77+
}
78+
79+
parameters.Add(returnDescriptor);
80+
}
81+
}
82+
catch (InvalidOperationException ex)
83+
{
84+
throw new InvalidOperationException("Multiple bindings cannot be designated as HandlesReturnValue.", ex);
85+
}
86+
87+
return parameters;
88+
}
4389
}
4490
}

src/WebJobs.Script/Description/Rpc/WorkerLanguageInvoker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ protected override async Task<object> InvokeCore(object[] parameters, FunctionIn
7373
result = await invocationContext.ResultSource.Task;
7474

7575
await BindOutputsAsync(triggerValue, context.Binder, result);
76-
return null;
76+
return result.Return;
7777
}
7878

7979
private async Task<(string name, DataType type, object value)[]> BindInputsAsync(Binder binder)

src/WebJobs.Script/WebJobs.Script.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<PackageReference Include="Microsoft.Azure.Functions.NodeJsWorker" Version="1.0.0-beta1-10022">
2626
<PrivateAssets>None</PrivateAssets>
2727
</PackageReference>
28-
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta3" />
28+
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.0-beta3-11077" />
2929
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="3.0.0-beta3" />
3030
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Http" Version="3.0.0-beta3">
3131
<NoWarn>NU1701</NoWarn>

0 commit comments

Comments
 (0)