You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by ni...@apache.org on 2022/08/16 07:26:00 UTC

[openwhisk-runtime-dotnet] branch master updated: Support array result include sequence action (#65)

This is an automated email from the ASF dual-hosted git repository.

ningyougang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-runtime-dotnet.git


The following commit(s) were added to refs/heads/master by this push:
     new 24995db  Support array result include sequence action (#65)
24995db is described below

commit 24995db0aea0c92b6ff6f56915205394e5c45771
Author: ningyougang <41...@qq.com>
AuthorDate: Tue Aug 16 15:25:56 2022 +0800

    Support array result include sequence action (#65)
    
    * Support array result
    
    * Add test case
    
    * Add another test case
    
    * Add document for support array result
---
 README.md                                          | 99 ++++++++++++++++++++++
 .../proxy/Apache.OpenWhisk.Runtime.Common/Run.cs   | 18 +++-
 .../proxy/Apache.OpenWhisk.Runtime.Common/Run.cs   | 18 +++-
 tests/dotnetshared/HelloArray.cs                   | 33 ++++++++
 tests/dotnetshared/HelloPassArrayParam.cs          | 30 +++++++
 .../DotNet2_2ActionContainerTests.scala            | 28 ++++++
 .../DotNet3_1ActionContainerTests.scala            | 28 ++++++
 .../DotNet3_1ActionContainerTests_2_2.scala        | 28 ++++++
 8 files changed, 276 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index 1100205..335e95a 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,105 @@
 
 [![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](http://www.apache.org/licenses/LICENSE-2.0)
 [![Build Status](https://travis-ci.com/apache/openwhisk-runtime-dotnet.svg?branch=master)](https://travis-ci.com/github/apache/openwhisk-runtime-dotnet)
+## Give it a try today
+
+Create a C# project called Apache.OpenWhisk.Example.Dotnet:
+
+```bash
+dotnet new classlib -n Apache.OpenWhisk.Example.Dotnet -lang "C#"
+cd Apache.OpenWhisk.Example.Dotnet
+```
+
+Install the [Newtonsoft.Json](https://www.newtonsoft.com/json) NuGet package as follows:
+
+```bash
+dotnet add package Newtonsoft.Json -v 12.0.1
+```
+
+Now create a file called `Hello.cs` with the following content:
+
+```csharp
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Apache.OpenWhisk.Example.Dotnet
+{
+    public class Hello
+    {
+        public JObject Main(JObject args)
+        {
+            string name = "stranger";
+            if (args.ContainsKey("name")) {
+                name = args["name"].ToString();
+            }
+            JObject message = new JObject();
+            message.Add("greeting", new JValue($"Hello, {name}!"));
+            return (message);
+        }
+    }
+}
+```
+Publish the project as follows:
+
+```bash
+dotnet publish -c Release -o out
+```
+
+Zip the published files as follows:
+
+```bash
+cd out
+zip -r -0 helloDotNet.zip *
+```
+
+Create the action
+
+```bash
+wsk action update helloDotNet helloDotNet.zip --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main --kind dotnet:2.2
+```
+
+For the return result, not only support `dictionary` but also support `array`
+
+So a very simple `hello array` function would be:
+
+```csharp
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Apache.OpenWhisk.Tests.Dotnet
+{
+    public class HelloArray
+    {
+        public JArray Main(JObject args)
+        {
+            JArray jarray = new JArray();
+            jarray.Add("a");
+            jarray.Add("b");
+            return (jarray);
+        }
+    }
+}
+```
+
+And support array result for sequence action as well, the first action's array result can be used as next action's input parameter.
+
+So the function can be:
+
+```csharp
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Apache.OpenWhisk.Tests.Dotnet
+{
+    public class HelloPassArrayParam
+    {
+        public JArray Main(JArray args)
+        {
+            return (args);
+        }
+    }
+}
+```
 
 ## Changelogs
 
diff --git a/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs b/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs
index 98551fe..d9c9df2 100644
--- a/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs
+++ b/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs
@@ -54,6 +54,7 @@ namespace Apache.OpenWhisk.Runtime.Common
                 JObject inputObject = string.IsNullOrEmpty(body) ? null : JObject.Parse(body);
 
                 JObject valObject = null;
+                JArray valArray = null;
 
                 if (inputObject != null)
                 {
@@ -76,18 +77,29 @@ namespace Apache.OpenWhisk.Runtime.Common
                         }
                     }
                 }
+                if (valObject == null) {
+                    valArray = inputObject["value"] as JArray;
+                }
 
                 object owObject = _constructor.Invoke(new object[] { });
 
                 try
                 {
-                    JObject output;
+                    JContainer output;
 
                     if(_awaitableMethod) {
-                        output = (JObject) await (dynamic) _method.Invoke(owObject, new object[] {valObject});
+                        if (valObject != null) {
+                            output = (JContainer) await (dynamic) _method.Invoke(owObject, new object[] {valObject});
+                        } else {
+                            output = (JContainer) await (dynamic) _method.Invoke(owObject, new object[] {valArray});
+                        }
                     }
                     else {
-                        output = (JObject) _method.Invoke(owObject, new object[] {valObject});
+                        if (valObject != null) {
+                            output = (JContainer) _method.Invoke(owObject, new object[] {valObject});
+                        } else {
+                            output = (JContainer) _method.Invoke(owObject, new object[] {valArray});
+                        }
                     }
 
                     if (output == null)
diff --git a/core/dotnet3.1/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs b/core/dotnet3.1/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs
index 98551fe..0ee99ce 100644
--- a/core/dotnet3.1/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs
+++ b/core/dotnet3.1/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs
@@ -54,6 +54,7 @@ namespace Apache.OpenWhisk.Runtime.Common
                 JObject inputObject = string.IsNullOrEmpty(body) ? null : JObject.Parse(body);
 
                 JObject valObject = null;
+                JArray valArray = null;
 
                 if (inputObject != null)
                 {
@@ -75,19 +76,30 @@ namespace Apache.OpenWhisk.Runtime.Common
                                 $"Unable to set environment variable for the \"{token.Path}\" token.");
                         }
                     }
+                    if (valObject == null) {
+                        valArray = inputObject["value"] as JArray;
+                    }
                 }
 
                 object owObject = _constructor.Invoke(new object[] { });
 
                 try
                 {
-                    JObject output;
+                    JContainer output;
 
                     if(_awaitableMethod) {
-                        output = (JObject) await (dynamic) _method.Invoke(owObject, new object[] {valObject});
+                        if (valObject != null) {
+                            output = (JContainer) await (dynamic) _method.Invoke(owObject, new object[] {valObject});
+                        } else {
+                            output = (JContainer) await (dynamic) _method.Invoke(owObject, new object[] {valArray});
+                        }
                     }
                     else {
-                        output = (JObject) _method.Invoke(owObject, new object[] {valObject});
+                        if (valObject != null) {
+                            output = (JContainer) _method.Invoke(owObject, new object[] {valObject});
+                        } else {
+                            output = (JContainer) _method.Invoke(owObject, new object[] {valArray});
+                        }
                     }
 
                     if (output == null)
diff --git a/tests/dotnetshared/HelloArray.cs b/tests/dotnetshared/HelloArray.cs
new file mode 100644
index 0000000..b9c7d22
--- /dev/null
+++ b/tests/dotnetshared/HelloArray.cs
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Apache.OpenWhisk.Tests.Dotnet
+{
+    public class HelloArray
+    {
+        public JArray Main(JObject args)
+        {
+            JArray jarray = new JArray();
+            jarray.Add("a");
+            jarray.Add("b");
+            return (jarray);
+        }
+    }
+}
diff --git a/tests/dotnetshared/HelloPassArrayParam.cs b/tests/dotnetshared/HelloPassArrayParam.cs
new file mode 100644
index 0000000..15458e2
--- /dev/null
+++ b/tests/dotnetshared/HelloPassArrayParam.cs
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using Newtonsoft.Json.Linq;
+
+namespace Apache.OpenWhisk.Tests.Dotnet
+{
+    public class HelloPassArrayParam
+    {
+        public JArray Main(JArray args)
+        {
+            return (args);
+        }
+    }
+}
diff --git a/tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala b/tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala
index 0a5b1b8..7a15249 100644
--- a/tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala
+++ b/tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala
@@ -231,4 +231,32 @@ class DotNet2_2ActionContainerTests extends BasicActionRunnerTests with WskActor
         (o + e).toLowerCase should include("the action returned null")
     })
   }
+
+  it should "support return array result" in {
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, _) =
+        c.init(
+          initPayload(functionb64, "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloArray::Main"))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.runForJsArray(runPayload(JsObject()))
+      runCode should be(200)
+      runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
+    }
+  }
+
+  it should "support array as input param" in {
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, _) =
+        c.init(
+          initPayload(
+            functionb64,
+            "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloPassArrayParam::Main"))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.runForJsArray(runPayload(JsArray(JsString("a"), JsString("b"))))
+      runCode should be(200)
+      runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
+    }
+  }
 }
diff --git a/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests.scala b/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests.scala
index 8436252..dc9ee90 100644
--- a/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests.scala
+++ b/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests.scala
@@ -235,4 +235,32 @@ class DotNet3_1ActionContainerTests extends BasicActionRunnerTests with WskActor
         (o + e).toLowerCase should include("the action returned null")
     })
   }
+
+  it should "support return array result" in {
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, _) =
+        c.init(
+          initPayload(functionb64, "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloArray::Main"))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.runForJsArray(runPayload(JsObject()))
+      runCode should be(200)
+      runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
+    }
+  }
+
+  it should "support array as input param" in {
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, _) =
+        c.init(
+          initPayload(
+            functionb64,
+            "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloPassArrayParam::Main"))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.runForJsArray(runPayload(JsArray(JsString("a"), JsString("b"))))
+      runCode should be(200)
+      runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
+    }
+  }
 }
diff --git a/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests_2_2.scala b/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests_2_2.scala
index 6a8db7f..b3c9a99 100644
--- a/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests_2_2.scala
+++ b/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests_2_2.scala
@@ -235,4 +235,32 @@ class DotNet3_1ActionContainerTests_2_2 extends BasicActionRunnerTests with WskA
         (o + e).toLowerCase should include("the action returned null")
     })
   }
+
+  it should "support return array result" in {
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, _) =
+        c.init(
+          initPayload(functionb64, "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloArray::Main"))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.runForJsArray(runPayload(JsObject()))
+      runCode should be(200)
+      runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
+    }
+  }
+
+  it should "support array as input param" in {
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, _) =
+        c.init(
+          initPayload(
+            functionb64,
+            "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.HelloPassArrayParam::Main"))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.runForJsArray(runPayload(JsArray(JsString("a"), JsString("b"))))
+      runCode should be(200)
+      runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
+    }
+  }
 }