apache / openwhisk-runtime-dotnet Goto Github PK
View Code? Open in Web Editor NEWApache OpenWhisk Runtime .Net supports Apache OpenWhisk functions written in .Net languages
Home Page: https://openwhisk.apache.org/
License: Apache License 2.0
Apache OpenWhisk Runtime .Net supports Apache OpenWhisk functions written in .Net languages
Home Page: https://openwhisk.apache.org/
License: Apache License 2.0
I have a c# OpenWhisk Action:
using System;
using IHWhisk.Models;
using Newtonsoft.Json.Linq;
namespace IHWhisk
{
public class Hello
{
public JObject Main(JObject args)
{
var handian = new Handian();
string errorText = "";
try
{
using var db = new IHDbContext();
db.Handians.Add(handian);
db.SaveChanges();
}
catch (Exception e)
{
errorText = e.Message;
}
var message = new JObject();
message.Add("Content-Type", new JValue("application/json"));
message.Add("body", new JValue($"<p>Error: {errorText}</p>"));
return message;
}
}
}
which uses EF Core dependency injection to configure and access the database, like so:
using System;
using Microsoft.EntityFrameworkCore;
using IHWhisk.Models;
namespace IHWhisk
{
public class IHDbContext : DbContext
{
public DbSet<Handian> Handians { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder builder)
{
var connectionString = "Server=#.#.#.#;Database=ih;Port=5432;User Id=postgres;Password=supersecretpassword";
builder
.UseNpgsql(connectionString, o
=> o.EnableRetryOnFailure());
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.HasPostgresExtension("uuid-ossp")
.Entity<BaseEntity>(entity =>
{
entity.HasIndex("Discriminator");
entity.Property(p => p.Uuid)
.HasDefaultValueSql("uuid_generate_v4()"); // All IH entities get a postgres Uuid4
})
.Entity<Handian>(entity => { entity.Property<DateTime>(p => p.Birthday).HasDefaultValueSql("now()"); });
}
}
}
which when run inside my OpenWhisk installation fails with the error:
Error: Could not load file or assembly 'Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.3.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. Could not find or load a specific file. (0x80131621)
I test this Action locally by invoking it from a clean console app like so:
namespace WhiskTester
{
class Program
{
static void Main(string[] args)
{
var ihwhisk = new IHWhisk.Hello();
var callArgs = new JObject();
var result = ihwhisk.Main(callArgs);
Console.WriteLine(result);
}
}
}
It works when tested locally... a new record is written to the database as expected.
Things I've tried to resolve the issue:
Microsoft.Extensions.DependencyInjection.Abstractions, Version=3.1.2.0
At this point I've reached the edge of my knowledge and would be grateful for any advice or guidance you could offer.
Hey All, love openwhisk so far, I've got it running on a small 2-node vm cluster, using the helm chart, doing the examples in dotnet and having a good time so far, but noticing that I'm not getting any logs when I try wsk activation logs -l
or on any of my invokes - I'm trying to do the 'conductor' docs right now so I don't know if that would affect it, but when I try a Console.Writeline()
or Console.Out.Writeline()
I don't see anything in the logs - is there a correct way to write logs out?
Thanks,
Paul
Good morning OpenWhisk. I'm trying to hook up a test action to a Postgres database like so:
var conn = new NpgsqlConnection(connectionString);
var cmd = new NpgsqlCommand("INSERT INTO base_entity (name) VALUES ('danny')", conn);
cmd.ExecuteNonQuery();
I am getting this error message:
C:\Users\dmlod>wsk -i activation logs 7c5b1161098b41239b1161098b012371
2020-04-01T10:41:48.142980549Z stdout: at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
2020-04-01T10:41:48.143031669Z stdout: at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
2020-04-01T10:41:48.143036509Z stdout: at Apache.OpenWhisk.Runtime.Common.Run.HandleRequest(HttpContext httpContext) in /app/Apache.OpenWhisk.Runtime.Common/Run.cs:line 90
2020-04-01T10:41:48.175771203Z stderr: The action did not initialize or run as expected. Log data might be missing.
Connection string is verified ok. DB is operational. OpenWhisk will run the action if I comment out the 'ExecuteNonQuery' line.
Two questions:
Thank you for your time and I hope you're not too bored in quarantine.
Hello,
I'm running the tutorial off your README and seeing the following error:
wsk action create helloDotNet helloDotNet.zip --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main --kind dotnet:2.2
error: Unable to create action 'helloDotNet': The request content was malformed:
kind 'dotnet:2.2' not in Set(php:7.1, nodejs:8, swift:3, nodejs, blackbox, java, sequence, nodejs:6, python:3, python, python:2, swift, swift:3.1.1) (code 224)
Run 'wsk --help' for usage.
I've installed openwhisk on a local openshift cluster with no errors:
oc process -f https://git.io/vpnUR | oc create -f -
Any ideas? Thanks.
Hey everyone, I'm working on getting .net6.0 working and I'm not used to gradle unfortunately - when I run it in the openwhisk-runtime-dot as gradle build
I get an error about compileTestScala:
I'm running this on my ubuntu 18.04 WSL2 terminal.
my thought is that I need to get all the tests to run against the basic openwhisk repo, but when I run that I get lots of tests failing with initializationError
are there any docs around about how to get the tests to build/compile/pass for the basic openwhisk repo and then how to do so for a new runtime?
Do you have to have openwhisk running in standalone mode to have the gradle build pass?
Output of dotnet runtime's gradle build
> Task :tests:compileTestScala FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':tests:compileTestScala'.
> Could not resolve all files for configuration ':tests:testCompileClasspath'.
> Could not find org.apache.openwhisk:openwhisk-tests:1.0.0-SNAPSHOT.
Searched in the following locations:
- https://repo.maven.apache.org/maven2/org/apache/openwhisk/openwhisk-tests/1.0.0-SNAPSHOT/maven-metadata.xml
- https://repo.maven.apache.org/maven2/org/apache/openwhisk/openwhisk-tests/1.0.0-SNAPSHOT/openwhisk-tests-1.0.0-SNAPSHOT.pom
- https://repo.maven.apache.org/maven2/org/apache/openwhisk/openwhisk-tests/1.0.0-SNAPSHOT/openwhisk-tests-1.0.0-SNAPSHOT-tests.jar
- file:/home/paul42/.m2/repository/org/apache/openwhisk/openwhisk-tests/1.0.0-SNAPSHOT/maven-metadata.xml
- file:/home/paul42/.m2/repository/org/apache/openwhisk/openwhisk-tests/1.0.0-SNAPSHOT/openwhisk-tests-1.0.0-SNAPSHOT.pom
- file:/home/paul42/.m2/repository/org/apache/openwhisk/openwhisk-tests/1.0.0-SNAPSHOT/openwhisk-tests-1.0.0-SNAPSHOT-tests.jar
Required by:
project :tests
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 25s
26 actionable tasks: 25 executed, 1 up-to-date
lots of errors in the test file for the gradle build
in the openwhisk repo:
java.lang.AssertionError: could not determine openwhisk home
etc.
You’d need to ask ibm :)
As an Apache project we’d love the contribution, which you could then build and push to dockerhub and use independent of the ibm lifecycle.
Originally posted by @rabbah in #22 (comment)
Didn't know it was possible but 3.1 image from docker works fine with ibm functions.
Instead of:
ibmcloud fn action update {methodName} out.zip --kind dotnet:2.2 --main {namespaceName}::{namespaceName}.{className}::{methodName} --web true
Simply run:
ibmcloud fn action update {methodName} out.zip --docker openwhisk/action-dotnet-v3.1 --main {namespaceName}::{namespaceName}.{className}::{methodName} --web true
Just letting you know :)
When trying to use Confluent.Kafka in order to produce messages to kafka/event streams, we get the error :
Failed to load the librdkafka native library.
at Confluent.Kafka.Impl.LibRdKafka.Initialize(String userSpecifiedPath)
...
None of the librdkafka librairies packaged with Confluent.Kafka work with the current runtime
Is there a way to have one built-in the current runtime ?
Based on conversation in #34 and #50...
Problem:
OpenWhisk users creating .NET actions need to add a dependency on a 3rd party JSON library (currently Newtonsoft.Json as of the dotnet:3.1 runtime) because the contract between action and runtime provides the action main function with a JObject
via paramter and requires the main function to return a JObject
.
Consequences:
Potential solution:
Since the contract between runtimes and actions is really just an arbitrary map of data (as seen in the Node.js runtime instructions as https://github.com/apache/openwhisk/blob/master/docs/actions-nodejs.md where they just return { done: true }
and { message: 'my message' }
etc), use a map data structure for this contract. C# and other CLR languages supported by the .NET runtime like VB.NET have Dictionary
for that (https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.dictionary-2?view=net-5.0). If the map data structure type changes between runtimes, like moving from .NET Core 3.1 to .NET 6 for example, OpenWhisk users would be instructed via documentation for the new runtime to use a different type from the standard library of the language.
That way, all versions of the runtime and every action ever created for the runtime would not depend on things that need major version updates throughout the lifecycle of a runtime (like dotnet:3.1). The runtime would control the implementation of how JSON is handled. It could choose for example between different versions of Newtonsoft.Json or even other JSON libraries like System.Text.Json whenever it wants, with the runtime versions being updated without the action implementers ever having to worry about it.
Another thing that could be added to speed up large requests processing time.
Currently there is:
string body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();
JObject inputObject = string.IsNullOrEmpty(body) ? null : JObject.Parse(body);
It's fine for small requests but for big ones it will allocate a lot of memory and increase time to complete any function. While that code itself could be improved by reading from Stream directly using current JsonNet (more https://www.newtonsoft.com/json/help/html/Performance.htm in "Optimize Memory Usage") it would be great to somehow skip this process completely, pass httpContext.Request (instead of JObject) and let user do whatever he wants to. In addition to that instead of returning JObject that's converted to string
await httpContext.Response.WriteResponse(200, output.ToString());
(...)
await response.WriteAsync(content);
function could simply return string (or Stream like in AWS Lambda to be set for Response.Body)
So basically high performance mode, in the end function definition:
public async Task<string> Main(HttpRequest request)
Why is it important? I've just notice in Azure Functions it takes almost 2500ms to simply receive 1mb json. No idea what their sdk is doing exactly but that amount of overhead seems weird to me. They also use JsonNet.
With this feature I could use for ex. https://github.com/neuecc/Utf8Json to make part of my function in OpenWhisk run ~5 times faster and allocate ~20 times less memory :).
Edit
Did few tests:
Duration of empty function receiving 1mb request:
Azure (C# - most recent production version): 2400ms
Google/Firebase (javascript): 90-170ms
IBM/OpenWhisk (C# .NET Core 2.2): ~100ms
Seeing this I will definitely use IBM/OpenWhisk instead of Azure
Currently I don't think there is a way to return a Future from the .NET action, making it less convenient to write asynchronous functions.
Thanks for adding dotnet runtime to openwhisk.
I created action with sample code but sometimes errors occur when stress tests.
I debuged with console log and I found that "/run" was called before run(Run class) object is returned.
I fixed(moved) some codes and tested. Then no error occurred any more.
sechunOH#1
But I am not a dotnet programmer, so I'm not sure if the codes I fixed fits the dotnet grammar.
Is it okay if I make a pull request? can someone review it?
On 3.1, it's working fine on old 2.2 that ibm is using by default.
It should be possible to define method like this:
public Task<JObject> Main(JObject args)
That's very common definition in ASP.Net.
It's also the case in Amazon Lambdas and Azure Functions
If you are using .NET asynchronous programming, the return type can be Task and Task types and use async and await keywords.
At some point in the past we added support in OpenWhisk for init time parameters (these are “env” vars). See https://github.com/apache/openwhisk/blob/4babe39fd2dbcc900ccedb5a5e9561d301361205/tests/src/test/scala/actionContainers/BasicActionRunnerTests.scala#L125
For backward compatibility, runtimes weren’t required to implement this. The .net 3.1 runtime doesn’t override the required function so that behavior is skipped https://github.com/apache/openwhisk-runtime-dotnet/blob/master/tests/src/test/scala/actionContainers/DotNet3_1ActionContainerTests.scala
We should add this support to the runtime.
zip -r -0 helloDotNet.bin * should be zip -r -0 helloDotNet.zip *
cd out
zip -r -0 helloDotNet.bin *
wsk action update helloDotNet helloDotNet.bin --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main --kind dotnet:2.2
should be
cd out
zip -r -0 helloDotNet.zip *
wsk action update helloDotNet helloDotNet.zip --main Apache.OpenWhisk.Example.Dotnet::Apache.OpenWhisk.Example.Dotnet.Hello::Main --kind dotnet:2.2
If you invoke action updated with name *.bin will result:
{
"error": "code must be binary (zip file)."
}
Hi ,
I last time explored this repository for openwhish with dotnet core in December 18 when it was just evolved.
However , on IBM function i dont see dotnet core as supported runtime and also at https://openwhisk.apache.org/documentation.html in supported programming language section it is not updated.
Thus wanted to know if it is production ready or beat ready for production yet ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.