Skip to content

Commit 9b96e80

Browse files
authored
Init json quickstart updates (#50)
Newtonsoft.Json update Init decompression now in-memory Async examples
1 parent 20daaa8 commit 9b96e80

7 files changed

Lines changed: 126 additions & 32 deletions

File tree

core/dotnet2.2/QUICKSTART.md

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,20 @@
1919

2020
# Quick .NET Core 2.2 Action
2121

22-
A .NET Core action is a .NET Core class library with a method called `Main` that has the exact signature as follows:
22+
A .NET Core action is a .NET Core class library with a method called `Main` or `MainAsync` that has the exact signature as follows:
23+
24+
Synchronous:
2325

2426
```csharp
2527
public Newtonsoft.Json.Linq.JObject Main(Newtonsoft.Json.Linq.JObject);
2628
```
2729

30+
Asynchronous:
31+
32+
```csharp
33+
public async System.Threading.Tasks.Task<Newtonsoft.Json.Linq.JObject> MainAsync(Newtonsoft.Json.Linq.JObject);
34+
```
35+
2836
In order to compile, test and archive .NET Core projects, you must have the [.NET Core SDK](https://www.microsoft.com/net/download) installed locally and the environment variable `DOTNET_HOME` set to the location where the `dotnet` executable can be found.
2937

3038
For example, create a C# project called `Apache.OpenWhisk.Example.Dotnet`:
@@ -37,11 +45,13 @@ cd Apache.OpenWhisk.Example.Dotnet
3745
Install the [Newtonsoft.Json](https://www.newtonsoft.com/json) NuGet package as follows:
3846

3947
```bash
40-
dotnet add package Newtonsoft.Json -v 12.0.2
48+
dotnet add package Newtonsoft.Json -v 13.0.1
4149
```
4250

4351
Now create a file called `Hello.cs` with the following content:
4452

53+
Synchronous example:
54+
4555
```csharp
4656
using System;
4757
using Newtonsoft.Json.Linq;
@@ -64,6 +74,32 @@ namespace Apache.OpenWhisk.Example.Dotnet
6474
}
6575
```
6676

77+
Asynchronous example:
78+
79+
```csharp
80+
using System;
81+
using Newtonsoft.Json.Linq;
82+
using System.Threading.Tasks;
83+
84+
namespace Apache.OpenWhisk.Example.Dotnet
85+
{
86+
public class Hello
87+
{
88+
public async Task<JObject> MainAsync(JObject args)
89+
{
90+
await Task.Delay(10); // Just do a delay to have an async/await process occur.
91+
string name = "stranger";
92+
if (args.ContainsKey("name")) {
93+
name = args["name"].ToString();
94+
}
95+
JObject message = new JObject();
96+
message.Add("greeting", new JValue($"Hello, {name}!"));
97+
return (message);
98+
}
99+
}
100+
}
101+
```
102+
67103
Publish the project as follows:
68104

69105
```bash
@@ -79,17 +115,27 @@ zip -r -0 helloDotNet.zip *
79115

80116
You need to specify the name of the function handler using `--main` argument.
81117
The value for `main` needs to be in the following format:
82-
`{Assembly}::{Class Full Name}::{Method}`, e.q.,
83-
`Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main`
118+
`{Assembly}::{Class Full Name}::{Method}`, e.q.:
119+
120+
+ Synchronous: `Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main`
121+
+ Asynchronous: `Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::MainAsync`
84122

85123
## Create the .NET Core Action
86124

87125
To use on a deployment of OpenWhisk that contains the runtime as a kind:
88126

127+
Synchronous:
128+
89129
```bash
90130
wsk action update helloDotNet helloDotNet.zip --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main --kind dotnet:2.2
91131
```
92132

133+
Asynchronous:
134+
135+
```bash
136+
wsk action update helloDotNet helloDotNet.zip --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::MainAsync --kind dotnet:2.2
137+
```
138+
93139
## Invoke the .NET Core Action
94140

95141
Action invocation is the same for .NET Core actions as it is for Swift and JavaScript actions:
@@ -150,7 +196,7 @@ Install dependencies from the root directory on $OPENWHISK_HOME repository
150196
```bash
151197
pushd $OPENWHISK_HOME
152198
./gradlew install
153-
podd $OPENWHISK_HOME
199+
popd
154200
```
155201

156202
Using gradle to run all tests

core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Apache.OpenWhisk.Runtime.Common.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
<Version>2.2.0</Version>
2929
</PackageReference>
3030
<PackageReference Include="Newtonsoft.Json">
31-
<Version>12.0.2</Version>
31+
<Version>13.0.1</Version>
3232
</PackageReference>
3333
</ItemGroup>
3434

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
using System;
1919
using System.IO;
20+
using System.IO.Compression;
2021
using System.Reflection;
2122
using System.Threading;
2223
using System.Threading.Tasks;
@@ -88,23 +89,23 @@ public async Task<Run> HandleRequest(HttpContext httpContext)
8889
return (null);
8990
}
9091

91-
string base64Zip = message["code"].ToString();
9292
string tempPath = Path.Combine(Environment.CurrentDirectory, Guid.NewGuid().ToString());
93-
string tempFile = Path.GetTempFileName();
94-
await File.WriteAllBytesAsync(tempFile, Convert.FromBase64String(base64Zip));
93+
string base64Zip = message["code"].ToString();
9594
try
9695
{
97-
System.IO.Compression.ZipFile.ExtractToDirectory(tempFile, tempPath);
96+
using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(base64Zip)))
97+
{
98+
using (ZipArchive archive = new ZipArchive(stream))
99+
{
100+
archive.ExtractToDirectory(tempPath);
101+
}
102+
}
98103
}
99104
catch (Exception)
100105
{
101106
await httpContext.Response.WriteError("Unable to decompress package.");
102107
return (null);
103108
}
104-
finally
105-
{
106-
File.Delete(tempFile);
107-
}
108109

109110
Environment.CurrentDirectory = tempPath;
110111

core/dotnet3.1/QUICKSTART.md

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,20 @@
1919

2020
# Quick .NET Core 3.1 Action
2121

22-
A .NET Core action is a .NET Core class library with a method called `Main` that has the exact signature as follows:
22+
A .NET Core action is a .NET Core class library with a method called `Main` or `MainAsync` that has the exact signature as follows:
23+
24+
Synchronous:
2325

2426
```csharp
2527
public Newtonsoft.Json.Linq.JObject Main(Newtonsoft.Json.Linq.JObject);
2628
```
2729

30+
Asynchronous:
31+
32+
```csharp
33+
public async System.Threading.Tasks.Task<Newtonsoft.Json.Linq.JObject> MainAsync(Newtonsoft.Json.Linq.JObject);
34+
```
35+
2836
In order to compile, test and archive .NET Core projects, you must have the [.NET Core SDK](https://www.microsoft.com/net/download) installed locally and the environment variable `DOTNET_HOME` set to the location where the `dotnet` executable can be found.
2937

3038
For example, create a C# project called `Apache.OpenWhisk.Example.Dotnet`:
@@ -37,11 +45,13 @@ cd Apache.OpenWhisk.Example.Dotnet
3745
Install the [Newtonsoft.Json](https://www.newtonsoft.com/json) NuGet package as follows:
3846

3947
```bash
40-
dotnet add package Newtonsoft.Json -v 12.0.2
48+
dotnet add package Newtonsoft.Json -v 13.0.1
4149
```
4250

4351
Now create a file called `Hello.cs` with the following content:
4452

53+
Synchronous example:
54+
4555
```csharp
4656
using System;
4757
using Newtonsoft.Json.Linq;
@@ -64,6 +74,32 @@ namespace Apache.OpenWhisk.Example.Dotnet
6474
}
6575
```
6676

77+
Asynchronous example:
78+
79+
```csharp
80+
using System;
81+
using Newtonsoft.Json.Linq;
82+
using System.Threading.Tasks;
83+
84+
namespace Apache.OpenWhisk.Example.Dotnet
85+
{
86+
public class Hello
87+
{
88+
public async Task<JObject> MainAsync(JObject args)
89+
{
90+
await Task.Delay(10); // Just do a delay to have an async/await process occur.
91+
string name = "stranger";
92+
if (args.ContainsKey("name")) {
93+
name = args["name"].ToString();
94+
}
95+
JObject message = new JObject();
96+
message.Add("greeting", new JValue($"Hello, {name}!"));
97+
return (message);
98+
}
99+
}
100+
}
101+
```
102+
67103
Publish the project as follows:
68104

69105
```bash
@@ -79,17 +115,27 @@ zip -r -0 helloDotNet.zip *
79115

80116
You need to specify the name of the function handler using `--main` argument.
81117
The value for `main` needs to be in the following format:
82-
`{Assembly}::{Class Full Name}::{Method}`, e.q.,
83-
`Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main`
118+
`{Assembly}::{Class Full Name}::{Method}`, e.q.:
119+
120+
+ Synchronous: `Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main`
121+
+ Asynchronous: `Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::MainAsync`
84122

85123
## Create the .NET Core Action
86124

87125
To use on a deployment of OpenWhisk that contains the runtime as a kind:
88126

127+
Synchronous:
128+
89129
```bash
90130
wsk action update helloDotNet helloDotNet.zip --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main --kind dotnet:3.1
91131
```
92132

133+
Asynchronous:
134+
135+
```bash
136+
wsk action update helloDotNet helloDotNet.zip --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::MainAsync --kind dotnet:3.1
137+
```
138+
93139
## Invoke the .NET Core Action
94140

95141
Action invocation is the same for .NET Core actions as it is for Swift and JavaScript actions:
@@ -150,7 +196,7 @@ Install dependencies from the root directory on $OPENWHISK_HOME repository
150196
```bash
151197
pushd $OPENWHISK_HOME
152198
./gradlew install
153-
podd $OPENWHISK_HOME
199+
popd
154200
```
155201

156202
Using gradle to run all tests

core/dotnet3.1/proxy/Apache.OpenWhisk.Runtime.Common/Apache.OpenWhisk.Runtime.Common.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
<ItemGroup>
2828
<PackageReference Include="Newtonsoft.Json">
29-
<Version>12.0.3</Version>
29+
<Version>13.0.1</Version>
3030
</PackageReference>
3131
</ItemGroup>
3232

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
using System;
1919
using System.IO;
20+
using System.IO.Compression;
2021
using System.Reflection;
2122
using System.Threading;
2223
using System.Threading.Tasks;
@@ -89,23 +90,23 @@ public async Task<Run> HandleRequest(HttpContext httpContext)
8990
return (null);
9091
}
9192

92-
string base64Zip = message["code"].ToString();
9393
string tempPath = Path.Combine(Environment.CurrentDirectory, Guid.NewGuid().ToString());
94-
string tempFile = Path.GetTempFileName();
95-
await File.WriteAllBytesAsync(tempFile, Convert.FromBase64String(base64Zip));
94+
string base64Zip = message["code"].ToString();
9695
try
9796
{
98-
System.IO.Compression.ZipFile.ExtractToDirectory(tempFile, tempPath);
97+
using (MemoryStream stream = new MemoryStream(Convert.FromBase64String(base64Zip)))
98+
{
99+
using (ZipArchive archive = new ZipArchive(stream))
100+
{
101+
archive.ExtractToDirectory(tempPath);
102+
}
103+
}
99104
}
100105
catch (Exception)
101106
{
102107
await httpContext.Response.WriteError("Unable to decompress package.");
103108
return (null);
104109
}
105-
finally
106-
{
107-
File.Delete(tempFile);
108-
}
109110

110111
Environment.CurrentDirectory = tempPath;
111112

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ class DotNet3_1ActionContainerTests_2_2 extends BasicActionRunnerTests with WskA
4747
TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.Environment::Main")
4848
}
4949

50-
override val testEnvParameters = {
51-
TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.Init::Main")
52-
}
53-
5450
override val testEcho = {
5551
TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.AltEcho::Main")
5652
}
5753

54+
override val testEnvParameters = {
55+
TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.Init::Main")
56+
}
57+
5858
val testEchoNoWrite = {
5959
TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.Echo::MainAsync")
6060
}

0 commit comments

Comments
 (0)