Skip to content

Commit 2b31e37

Browse files
committed
Performing JSON -> object conversions for Javascript input bindings
1 parent 678fa48 commit 2b31e37

File tree

5 files changed

+66
-11
lines changed

5 files changed

+66
-11
lines changed

sample/ManualTrigger/function.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,18 @@
33
{
44
"type": "manualTrigger",
55
"direction": "in"
6+
},
7+
{
8+
"type": "blob",
9+
"name": "status",
10+
"direction": "in",
11+
"path": "samples-input/status"
12+
},
13+
{
14+
"type": "blob",
15+
"name": "result",
16+
"direction": "out",
17+
"path": "samples-output/result"
618
}
719
]
820
}

sample/ManualTrigger/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
module.exports = function (context, input) {
22
context.log('Node.js manually triggered function called with input', input);
3+
4+
var status = context.bindings.status;
5+
context.log('Status: Level:%d Detail:%s', status.level, status.detail);
6+
7+
context.bindings.result = status.detail;
8+
39
context.done();
410
}

src/WebJobs.Script/Description/NodeFunctionInvoker.cs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private async Task ProcessInputBindingsAsync(IBinderEx binder, Dictionary<string
144144
var nonTriggerInputBindings = _inputBindings.Where(p => !p.Metadata.IsTrigger);
145145
foreach (var inputBinding in nonTriggerInputBindings)
146146
{
147-
string value = null;
147+
string stringValue = null;
148148
using (MemoryStream stream = new MemoryStream())
149149
{
150150
BindingContext bindingContext = new BindingContext
@@ -157,12 +157,15 @@ private async Task ProcessInputBindingsAsync(IBinderEx binder, Dictionary<string
157157

158158
stream.Seek(0, SeekOrigin.Begin);
159159
StreamReader sr = new StreamReader(stream);
160-
value = sr.ReadToEnd();
160+
stringValue = sr.ReadToEnd();
161161
}
162162

163-
bindings.Add(inputBinding.Metadata.Name, value);
163+
// if the string input is json, convert to an object
164+
object convertedValue = stringValue;
165+
convertedValue = TryConvertJsonToObject(stringValue);
164166

165-
inputs.Add(value);
167+
bindings.Add(inputBinding.Metadata.Name, convertedValue);
168+
inputs.Add(convertedValue);
166169
}
167170

168171
executionContext["inputs"] = inputs;
@@ -280,12 +283,8 @@ private Dictionary<string, object> CreateScriptExecutionContext(object input, Tr
280283
Type triggerParameterType = input.GetType();
281284
if (triggerParameterType == typeof(string))
282285
{
283-
// if the input is json, convert to a json object
284-
Dictionary<string, object> jsonObject;
285-
if (TryDeserializeJsonObject((string)input, out jsonObject))
286-
{
287-
input = jsonObject;
288-
}
286+
// if the input is json, convert to an object
287+
input = TryConvertJsonToObject((string)input);
289288
}
290289
else if (triggerParameterType == typeof(HttpRequestMessage))
291290
{
@@ -335,6 +334,20 @@ private Dictionary<string, object> CreateScriptExecutionContext(object input, Tr
335334
return context;
336335
}
337336

337+
private object TryConvertJsonToObject(string input)
338+
{
339+
object result = input;
340+
341+
// if the input is json, convert to an object
342+
Dictionary<string, object> jsonObject;
343+
if (TryDeserializeJsonObject(input, out jsonObject))
344+
{
345+
result = jsonObject;
346+
}
347+
348+
return result;
349+
}
350+
338351
private Dictionary<string, object> CreateRequestObject(HttpRequestMessage request)
339352
{
340353
// TODO: need to provide access to remaining request properties

src/WebJobs.Script/FileTraceWriter.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ public override void Trace(TraceEvent traceEvent)
112112
throw new ArgumentNullException("traceEvent");
113113
}
114114

115-
// TODO: buffer logs and write only periodically
116115
AppendLine(traceEvent.Message);
117116
if (traceEvent.Exception != null)
118117
{

test/WebJobs.Script.Tests/SamplesEndToEndTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,31 @@ public SamplesEndToEndTests(TestFixture fixture)
2929
_fixture = fixture;
3030
}
3131

32+
[Fact]
33+
public async Task ManualTrigger_Invoke_Succeeds()
34+
{
35+
CloudBlobContainer outputContainer = _fixture.BlobClient.GetContainerReference("samples-output");
36+
CloudBlockBlob outputBlob = outputContainer.GetBlockBlobReference("result");
37+
outputBlob.DeleteIfExists();
38+
39+
CloudBlobContainer inputContainer = _fixture.BlobClient.GetContainerReference("samples-input");
40+
CloudBlockBlob statusBlob = inputContainer.GetBlockBlobReference("status");
41+
statusBlob.UploadText("{ \"level\": 4, \"detail\": \"All systems are normal :)\" }");
42+
43+
string uri = "admin/functions/manualtrigger";
44+
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri);
45+
request.Headers.Add("x-functions-key", "t8laajal0a1ajkgzoqlfv5gxr4ebhqozebw4qzdy");
46+
request.Content = new StringContent("{ 'input': 'Hello Manual Trigger!' }");
47+
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
48+
49+
HttpResponseMessage response = await this._fixture.HttpClient.SendAsync(request);
50+
Assert.Equal(HttpStatusCode.Accepted, response.StatusCode);
51+
52+
// wait for completion
53+
string result = await TestHelpers.WaitForBlobAsync(outputBlob);
54+
Assert.Equal("All systems are normal :)", result);
55+
}
56+
3257
[Fact]
3358
public async Task Home_Get_Succeeds()
3459
{

0 commit comments

Comments
 (0)