Skip to content

Commit 24995db

Browse files
authored
Support array result include sequence action (#65)
* Support array result * Add test case * Add another test case * Add document for support array result
1 parent fdfe9c8 commit 24995db

File tree

8 files changed

+276
-6
lines changed

8 files changed

+276
-6
lines changed

README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,105 @@
2121

2222
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
2323
[![Build Status](https://travis-ci.com/apache/openwhisk-runtime-dotnet.svg?branch=master)](https://travis-ci.com/github/apache/openwhisk-runtime-dotnet)
24+
## Give it a try today
25+
26+
Create a C# project called Apache.OpenWhisk.Example.Dotnet:
27+
28+
```bash
29+
dotnet new classlib -n Apache.OpenWhisk.Example.Dotnet -lang "C#"
30+
cd Apache.OpenWhisk.Example.Dotnet
31+
```
32+
33+
Install the [Newtonsoft.Json](https://www.newtonsoft.com/json) NuGet package as follows:
34+
35+
```bash
36+
dotnet add package Newtonsoft.Json -v 12.0.1
37+
```
38+
39+
Now create a file called `Hello.cs` with the following content:
40+
41+
```csharp
42+
using System;
43+
using Newtonsoft.Json.Linq;
44+
45+
namespace Apache.OpenWhisk.Example.Dotnet
46+
{
47+
public class Hello
48+
{
49+
public JObject Main(JObject args)
50+
{
51+
string name = "stranger";
52+
if (args.ContainsKey("name")) {
53+
name = args["name"].ToString();
54+
}
55+
JObject message = new JObject();
56+
message.Add("greeting", new JValue($"Hello, {name}!"));
57+
return (message);
58+
}
59+
}
60+
}
61+
```
62+
Publish the project as follows:
63+
64+
```bash
65+
dotnet publish -c Release -o out
66+
```
67+
68+
Zip the published files as follows:
69+
70+
```bash
71+
cd out
72+
zip -r -0 helloDotNet.zip *
73+
```
74+
75+
Create the action
76+
77+
```bash
78+
wsk action update helloDotNet helloDotNet.zip --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main --kind dotnet:2.2
79+
```
80+
81+
For the return result, not only support `dictionary` but also support `array`
82+
83+
So a very simple `hello array` function would be:
84+
85+
```csharp
86+
using System;
87+
using Newtonsoft.Json.Linq;
88+
89+
namespace Apache.OpenWhisk.Tests.Dotnet
90+
{
91+
public class HelloArray
92+
{
93+
public JArray Main(JObject args)
94+
{
95+
JArray jarray = new JArray();
96+
jarray.Add("a");
97+
jarray.Add("b");
98+
return (jarray);
99+
}
100+
}
101+
}
102+
```
103+
104+
And support array result for sequence action as well, the first action's array result can be used as next action's input parameter.
105+
106+
So the function can be:
107+
108+
```csharp
109+
using System;
110+
using Newtonsoft.Json.Linq;
111+
112+
namespace Apache.OpenWhisk.Tests.Dotnet
113+
{
114+
public class HelloPassArrayParam
115+
{
116+
public JArray Main(JArray args)
117+
{
118+
return (args);
119+
}
120+
}
121+
}
122+
```
24123

25124
## Changelogs
26125

core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public async Task HandleRequest(HttpContext httpContext)
5454
JObject inputObject = string.IsNullOrEmpty(body) ? null : JObject.Parse(body);
5555

5656
JObject valObject = null;
57+
JArray valArray = null;
5758

5859
if (inputObject != null)
5960
{
@@ -76,18 +77,29 @@ await Console.Error.WriteLineAsync(
7677
}
7778
}
7879
}
80+
if (valObject == null) {
81+
valArray = inputObject["value"] as JArray;
82+
}
7983

8084
object owObject = _constructor.Invoke(new object[] { });
8185

8286
try
8387
{
84-
JObject output;
88+
JContainer output;
8589

8690
if(_awaitableMethod) {
87-
output = (JObject) await (dynamic) _method.Invoke(owObject, new object[] {valObject});
91+
if (valObject != null) {
92+
output = (JContainer) await (dynamic) _method.Invoke(owObject, new object[] {valObject});
93+
} else {
94+
output = (JContainer) await (dynamic) _method.Invoke(owObject, new object[] {valArray});
95+
}
8896
}
8997
else {
90-
output = (JObject) _method.Invoke(owObject, new object[] {valObject});
98+
if (valObject != null) {
99+
output = (JContainer) _method.Invoke(owObject, new object[] {valObject});
100+
} else {
101+
output = (JContainer) _method.Invoke(owObject, new object[] {valArray});
102+
}
91103
}
92104

93105
if (output == null)

core/dotnet3.1/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public async Task HandleRequest(HttpContext httpContext)
5454
JObject inputObject = string.IsNullOrEmpty(body) ? null : JObject.Parse(body);
5555

5656
JObject valObject = null;
57+
JArray valArray = null;
5758

5859
if (inputObject != null)
5960
{
@@ -75,19 +76,30 @@ await Console.Error.WriteLineAsync(
7576
$"Unable to set environment variable for the \"{token.Path}\" token.");
7677
}
7778
}
79+
if (valObject == null) {
80+
valArray = inputObject["value"] as JArray;
81+
}
7882
}
7983

8084
object owObject = _constructor.Invoke(new object[] { });
8185

8286
try
8387
{
84-
JObject output;
88+
JContainer output;
8589

8690
if(_awaitableMethod) {
87-
output = (JObject) await (dynamic) _method.Invoke(owObject, new object[] {valObject});
91+
if (valObject != null) {
92+
output = (JContainer) await (dynamic) _method.Invoke(owObject, new object[] {valObject});
93+
} else {
94+
output = (JContainer) await (dynamic) _method.Invoke(owObject, new object[] {valArray});
95+
}
8896
}
8997
else {
90-
output = (JObject) _method.Invoke(owObject, new object[] {valObject});
98+
if (valObject != null) {
99+
output = (JContainer) _method.Invoke(owObject, new object[] {valObject});
100+
} else {
101+
output = (JContainer) _method.Invoke(owObject, new object[] {valArray});
102+
}
91103
}
92104

93105
if (output == null)

tests/dotnetshared/HelloArray.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
using System;
19+
using Newtonsoft.Json.Linq;
20+
21+
namespace Apache.OpenWhisk.Tests.Dotnet
22+
{
23+
public class HelloArray
24+
{
25+
public JArray Main(JObject args)
26+
{
27+
JArray jarray = new JArray();
28+
jarray.Add("a");
29+
jarray.Add("b");
30+
return (jarray);
31+
}
32+
}
33+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
using System;
19+
using Newtonsoft.Json.Linq;
20+
21+
namespace Apache.OpenWhisk.Tests.Dotnet
22+
{
23+
public class HelloPassArrayParam
24+
{
25+
public JArray Main(JArray args)
26+
{
27+
return (args);
28+
}
29+
}
30+
}

tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,4 +231,32 @@ class DotNet2_2ActionContainerTests extends BasicActionRunnerTests with WskActor
231231
(o + e).toLowerCase should include("the action returned null")
232232
})
233233
}
234+
235+
it should "support return array result" in {
236+
val (out, err) = withActionContainer() { c =>
237+
val (initCode, _) =
238+
c.init(
239+
initPayload(functionb64, "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloArray::Main"))
240+
initCode should be(200)
241+
242+
val (runCode, runRes) = c.runForJsArray(runPayload(JsObject()))
243+
runCode should be(200)
244+
runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
245+
}
246+
}
247+
248+
it should "support array as input param" in {
249+
val (out, err) = withActionContainer() { c =>
250+
val (initCode, _) =
251+
c.init(
252+
initPayload(
253+
functionb64,
254+
"Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloPassArrayParam::Main"))
255+
initCode should be(200)
256+
257+
val (runCode, runRes) = c.runForJsArray(runPayload(JsArray(JsString("a"), JsString("b"))))
258+
runCode should be(200)
259+
runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
260+
}
261+
}
234262
}

tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,32 @@ class DotNet3_1ActionContainerTests extends BasicActionRunnerTests with WskActor
235235
(o + e).toLowerCase should include("the action returned null")
236236
})
237237
}
238+
239+
it should "support return array result" in {
240+
val (out, err) = withActionContainer() { c =>
241+
val (initCode, _) =
242+
c.init(
243+
initPayload(functionb64, "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloArray::Main"))
244+
initCode should be(200)
245+
246+
val (runCode, runRes) = c.runForJsArray(runPayload(JsObject()))
247+
runCode should be(200)
248+
runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
249+
}
250+
}
251+
252+
it should "support array as input param" in {
253+
val (out, err) = withActionContainer() { c =>
254+
val (initCode, _) =
255+
c.init(
256+
initPayload(
257+
functionb64,
258+
"Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloPassArrayParam::Main"))
259+
initCode should be(200)
260+
261+
val (runCode, runRes) = c.runForJsArray(runPayload(JsArray(JsString("a"), JsString("b"))))
262+
runCode should be(200)
263+
runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
264+
}
265+
}
238266
}

tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests_2_2.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,4 +235,32 @@ class DotNet3_1ActionContainerTests_2_2 extends BasicActionRunnerTests with WskA
235235
(o + e).toLowerCase should include("the action returned null")
236236
})
237237
}
238+
239+
it should "support return array result" in {
240+
val (out, err) = withActionContainer() { c =>
241+
val (initCode, _) =
242+
c.init(
243+
initPayload(functionb64, "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloArray::Main"))
244+
initCode should be(200)
245+
246+
val (runCode, runRes) = c.runForJsArray(runPayload(JsObject()))
247+
runCode should be(200)
248+
runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
249+
}
250+
}
251+
252+
it should "support array as input param" in {
253+
val (out, err) = withActionContainer() { c =>
254+
val (initCode, _) =
255+
c.init(
256+
initPayload(
257+
functionb64,
258+
"Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloPassArrayParam::Main"))
259+
initCode should be(200)
260+
261+
val (runCode, runRes) = c.runForJsArray(runPayload(JsArray(JsString("a"), JsString("b"))))
262+
runCode should be(200)
263+
runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
264+
}
265+
}
238266
}

0 commit comments

Comments
 (0)