Fission dotnet 2.0 env (#337)
Adding a new dotnet environment, supporting dotnet core 2.0. Project structure changed. Project.json was abandoned. Project.csproj is now used.
This commit is contained in:
committed by
Soam Vasani
parent
dc1ffa859d
commit
7bd3f20ad6
@@ -0,0 +1,9 @@
|
||||
FROM microsoft/dotnet:2.0-runtime
|
||||
|
||||
WORKDIR /fission-workdir
|
||||
COPY out .
|
||||
EXPOSE 8888
|
||||
|
||||
ENTRYPOINT ["dotnet"]
|
||||
|
||||
CMD ["fission-dotnet20.dll"]
|
||||
@@ -0,0 +1,82 @@
|
||||
using Fission.DotNetCore.Compiler;
|
||||
using Fission.DotNetCore.Api;
|
||||
using System.Collections.Generic;
|
||||
using Nancy;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace Fission.DotNetCore
|
||||
{
|
||||
public class ExecutorModule : NancyModule
|
||||
{
|
||||
#if DEBUG
|
||||
private const string CODE_PATH = "/tmp/func.cs";
|
||||
#else
|
||||
private const string CODE_PATH = "/userfunc/user";
|
||||
#endif
|
||||
private static Function _userFunc;
|
||||
private static Logger _logger = new Logger();
|
||||
|
||||
public ExecutorModule()
|
||||
{
|
||||
Post("/specialize", args => Specialize());
|
||||
Get("/", _ => Run());
|
||||
Post("/", _ => Run());
|
||||
Put("/", _ => Run());
|
||||
Head("/", _ => Run());
|
||||
Options("/", _ => Run());
|
||||
Delete("/", _ => Run());
|
||||
}
|
||||
|
||||
private object Specialize()
|
||||
{
|
||||
var errors = new List<string>();
|
||||
if (File.Exists(CODE_PATH))
|
||||
{
|
||||
var code = File.ReadAllText(CODE_PATH);
|
||||
_userFunc = FissionCompiler.Compile(code, out errors);
|
||||
if (_userFunc == null)
|
||||
{
|
||||
var errstr = string.Join(Environment.NewLine, errors);
|
||||
_logger.WriteError(errstr);
|
||||
var response = (Response)errstr;
|
||||
response.StatusCode = HttpStatusCode.InternalServerError;
|
||||
return response;
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
var errstr = $"Unable to locate code at '{CODE_PATH}'";
|
||||
_logger.WriteError(errstr);
|
||||
var response = (Response)errstr;
|
||||
response.StatusCode = HttpStatusCode.InternalServerError;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
private object Run()
|
||||
{
|
||||
if (_userFunc == null)
|
||||
{
|
||||
var response = (Response)"Generic container: no requests supported";
|
||||
response.StatusCode = HttpStatusCode.InternalServerError;
|
||||
return response;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return _userFunc.Invoke(FissionContext.Build(Request, new Logger()));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.WriteError(e.ToString());
|
||||
var response = (Response)e.Message;
|
||||
response.StatusCode = HttpStatusCode.BadRequest;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Emit;
|
||||
|
||||
namespace Fission.DotNetCore.Compiler
|
||||
{
|
||||
//adapted from this article http://www.tugberkugurlu.com/archive/compiling-c-sharp-code-into-memory-and-executing-it-with-roslyn
|
||||
class FissionCompiler
|
||||
{
|
||||
public static Function Compile(string code, out List<string> errors)
|
||||
{
|
||||
errors = new List<string>();
|
||||
|
||||
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
|
||||
|
||||
string assemblyName = Path.GetRandomFileName();
|
||||
|
||||
var coreDir = Directory.GetParent(typeof(Enumerable).GetTypeInfo().Assembly.Location);
|
||||
|
||||
List<MetadataReference> references = new List<MetadataReference>
|
||||
{
|
||||
MetadataReference.CreateFromFile(coreDir.FullName + Path.DirectorySeparatorChar + "mscorlib.dll"),
|
||||
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),
|
||||
MetadataReference.CreateFromFile(Assembly.GetEntryAssembly().Location),
|
||||
MetadataReference.CreateFromFile(typeof(System.Runtime.Serialization.Json.DataContractJsonSerializer).GetTypeInfo().Assembly.Location)
|
||||
};
|
||||
|
||||
foreach (var referencedAssembly in Assembly.GetEntryAssembly().GetReferencedAssemblies())
|
||||
{
|
||||
var assembly = Assembly.Load(referencedAssembly);
|
||||
references.Add(MetadataReference.CreateFromFile(assembly.Location));
|
||||
}
|
||||
|
||||
CSharpCompilation compilation = CSharpCompilation.Create(
|
||||
assemblyName,
|
||||
syntaxTrees: new[] { syntaxTree },
|
||||
references: references,
|
||||
options: new CSharpCompilationOptions(
|
||||
OutputKind.DynamicallyLinkedLibrary,
|
||||
optimizationLevel: OptimizationLevel.Release));
|
||||
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
EmitResult result = compilation.Emit(ms);
|
||||
|
||||
if (!result.Success)
|
||||
{
|
||||
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
|
||||
diagnostic.IsWarningAsError ||
|
||||
diagnostic.Severity == DiagnosticSeverity.Error).ToList();
|
||||
|
||||
foreach (Diagnostic diagnostic in failures)
|
||||
{
|
||||
errors.Add($"{diagnostic.Id}: {diagnostic.GetMessage()}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ms.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
|
||||
var type = assembly.GetType("FissionFunction");
|
||||
var info = type.GetMember("Execute").First() as MethodInfo;
|
||||
return new Function(assembly, type, info);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using Nancy;
|
||||
|
||||
namespace Fission.DotNetCore.Api
|
||||
{
|
||||
public class FissionContext
|
||||
{
|
||||
public FissionContext(Dictionary<string, object> args, Logger logger, FissionHttpRequest request)
|
||||
{
|
||||
if (args == null) throw new ArgumentNullException(nameof(args));
|
||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
Arguments = args;
|
||||
Logger = logger;
|
||||
Request = request;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> Arguments { get; private set; }
|
||||
|
||||
public FissionHttpRequest Request { get; private set; }
|
||||
|
||||
public Logger Logger { get; private set; }
|
||||
|
||||
public static FissionContext Build(Request request, Logger logger)
|
||||
{
|
||||
return new FissionContext(((DynamicDictionary)request.Query).ToDictionary(),
|
||||
logger,
|
||||
new FissionHttpRequest(request));
|
||||
}
|
||||
}
|
||||
|
||||
public class Logger
|
||||
{
|
||||
public void Write(Severity severity, string format, params object[] args)
|
||||
{
|
||||
Console.WriteLine($"{DateTime.Now.ToString("MM/dd/yy H:mm:ss zzz")} {severity}: " + format, args);
|
||||
}
|
||||
|
||||
public void WriteInfo(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Info, format, args);
|
||||
}
|
||||
|
||||
public void WriteWarning(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Warning, format, args);
|
||||
}
|
||||
|
||||
public void WriteError(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Error, format, args);
|
||||
}
|
||||
|
||||
public void WriteCritical(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Critical, format, args);
|
||||
}
|
||||
|
||||
public void WriteVerbose(string format, params object[] args)
|
||||
{
|
||||
Write(Severity.Verbose, format, args);
|
||||
}
|
||||
}
|
||||
|
||||
public enum Severity
|
||||
{
|
||||
Info,
|
||||
Warning,
|
||||
Error,
|
||||
Critical,
|
||||
Verbose
|
||||
}
|
||||
|
||||
public class FissionHttpRequest
|
||||
{
|
||||
private readonly Request _request;
|
||||
internal FissionHttpRequest(Request request)
|
||||
{
|
||||
if (request == null) throw new ArgumentNullException(nameof(request));
|
||||
_request = request;
|
||||
}
|
||||
|
||||
public Stream Body { get { return _request.Body; } }
|
||||
|
||||
public string BodyAsString()
|
||||
{
|
||||
int length = (int)_request.Body.Length;
|
||||
byte[] data = new byte[length];
|
||||
_request.Body.Read(data, 0, length);
|
||||
return Encoding.UTF8.GetString(data);
|
||||
}
|
||||
|
||||
public Dictionary<string, IEnumerable<string>> Headers
|
||||
{
|
||||
get
|
||||
{
|
||||
var headers = new Dictionary<string, IEnumerable<string>>();
|
||||
foreach (var kv in _request.Headers)
|
||||
{
|
||||
headers.Add(kv.Key, kv.Value);
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
|
||||
public X509Certificate Certificate { get { return _request.ClientCertificate; } }
|
||||
public string Url { get { return _request.Url.ToString(); } }
|
||||
public string Method { get { return _request.Method; } }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
namespace Fission.DotNetCore.Compiler
|
||||
{
|
||||
class Function
|
||||
{
|
||||
private readonly Assembly _assembly;
|
||||
private readonly Type _type;
|
||||
private readonly MethodInfo _info;
|
||||
|
||||
public Function(Assembly assembly, Type type, MethodInfo info)
|
||||
{
|
||||
if (info == null) throw new ArgumentNullException(nameof(info));
|
||||
if (assembly == null) throw new ArgumentNullException(nameof(assembly));
|
||||
if (type == null) throw new ArgumentNullException(nameof(type));
|
||||
_assembly = assembly;
|
||||
_type = type;
|
||||
_info = info;
|
||||
}
|
||||
|
||||
public object Invoke(FissionContext context)
|
||||
{
|
||||
return _info.Invoke(_assembly.CreateInstance(_type.FullName), new[] { context });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Nancy.Owin;
|
||||
|
||||
namespace Fission.DotNetCore
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseKestrel()
|
||||
.UseUrls("http://*:8888")
|
||||
.Configure(app => app.UseOwin(x => x.UseNancy()))
|
||||
.Build();
|
||||
host.Run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
# Fission: dotnet 2.0 C# Environment
|
||||
|
||||
This is a simple dotnet core 2.0 C# environment for Fission.
|
||||
|
||||
It's a Docker image containing the dotnet 2.0.0 runtime. The image
|
||||
uses Kestrel with Nancy to host the internal web server and uses
|
||||
Roslyn to compile the uploaded code.
|
||||
|
||||
The image supports compiling and running code with types defined in
|
||||
mscorlib and does not at present support other library references.
|
||||
One workaround for this would be to add the references to this project's
|
||||
project.json file and rebuild the container.
|
||||
|
||||
The environment works via convention where you create a C# class
|
||||
called FissionFunction which has a method named Execute taking a single
|
||||
parameter, a FissionContext object.
|
||||
|
||||
The FissionContext object gives access to the arguments and other items
|
||||
like logging. Please see FissionContext.cs for public API.
|
||||
|
||||
Example of simplest possible class to be executed:
|
||||
|
||||
```
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction {
|
||||
public string Execute(FissionContext context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Please see examples below.
|
||||
|
||||
## Rebuilding and pushing the image
|
||||
|
||||
To rebuild the image you need either a computer with dotnet core 2.0.0
|
||||
installed or else you will have to map the source directory into a
|
||||
container containing the dotnet core 2.0.0 environment.
|
||||
|
||||
### Locally installed Dotnet core 2.0.0
|
||||
|
||||
Simply move to the source directory in a terminal and run the ./build.sh script.
|
||||
|
||||
The script will restore dependencies, compile a release build and
|
||||
and build the container. If you need to change the name of the container
|
||||
simply change it in the script.
|
||||
|
||||
After the build finishes push the new image to a Docker registry using the
|
||||
standard procedure.
|
||||
|
||||
### Build in a container
|
||||
|
||||
Move to the directory containing the source and start the Docker container
|
||||
with dotnet and mount the current directory to a build location:
|
||||
|
||||
```
|
||||
docker run -it --rm -v $PWD:/build microsoft/dotnet
|
||||
```
|
||||
|
||||
Move to the build directory inside the container and restore the packages:
|
||||
|
||||
```
|
||||
cd /build
|
||||
dotnet restore
|
||||
log : Restoring packages for /source/project.json...
|
||||
log : Installing System.Net.WebSockets 4.0.0.
|
||||
log : Installing runtime.native.System.IO.Compression 4.1.0.
|
||||
...
|
||||
```
|
||||
|
||||
Compile and publish a release build of the source to the 'out' folder:
|
||||
|
||||
```
|
||||
dotnet publish -c Release -o out
|
||||
Publishing source for .NETCoreApp,Version
|
||||
...
|
||||
```
|
||||
Exit the build container and build the Docker container on the local host:
|
||||
|
||||
```
|
||||
exit
|
||||
docker build -t USER/dotnet20-env .
|
||||
```
|
||||
After the build finishes push the new image to a Docker registry using the
|
||||
standard procedure.
|
||||
|
||||
## Echo example
|
||||
|
||||
### Setup fission environment
|
||||
First you need to setup the fission according to your cluster setup as
|
||||
specified here: https://github.com/fission/fission
|
||||
|
||||
|
||||
### Create the class to run
|
||||
|
||||
Secondly you need to create a file /tmp/func.cs containing the following code:
|
||||
|
||||
```
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
context.Logger.WriteInfo("executing.. {0}", context.Arguments["text"]);
|
||||
return (string)context.Arguments["text"];
|
||||
}
|
||||
}
|
||||
```
|
||||
### Run the example
|
||||
|
||||
Lastly to run the example:
|
||||
|
||||
```
|
||||
$ fission env create --name dotnet --image fission/dotnet20-env
|
||||
|
||||
$ fission function create --name echo --env dotnet --code /tmp/func.cs
|
||||
|
||||
$ fission route create --method GET --url /echo --function echo
|
||||
|
||||
$ curl http://$FISSION_ROUTER/echo?text=hello%20world!
|
||||
hello world
|
||||
```
|
||||
|
||||
## Addition service example
|
||||
|
||||
### Setup fission environment
|
||||
First you need to setup the fission according to your cluster setup as
|
||||
specified here: https://github.com/fission/fission
|
||||
|
||||
|
||||
### Create the class to run
|
||||
|
||||
Secondly you need to create a file /tmp/func.cs containing the following code:
|
||||
|
||||
```
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
var x = Convert.ToInt32(context.Arguments["x"]);
|
||||
var y = Convert.ToInt32(context.Arguments["y"]);
|
||||
return (x+y).ToString();
|
||||
}
|
||||
}
|
||||
```
|
||||
### Run the example
|
||||
|
||||
Lastly to run the example:
|
||||
|
||||
```
|
||||
$ fission env create --name dotnet --image fission/dotnet20-env
|
||||
|
||||
$ fission function create --name addition --env dotnet --code /tmp/func.cs
|
||||
|
||||
$ fission route create --method GET --url /add --function addition
|
||||
|
||||
$ curl "http://$FISSION_ROUTER/add?x=30&y=12"
|
||||
42
|
||||
```
|
||||
|
||||
## Accessing http request information example
|
||||
|
||||
### Setup fission environment
|
||||
First you need to setup the fission according to your cluster setup as
|
||||
specified here: https://github.com/fission/fission
|
||||
|
||||
|
||||
### Create the class to run
|
||||
|
||||
Secondly you need to create a file /tmp/func.cs containing the following code:
|
||||
|
||||
```
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
var buffer = new System.Text.StringBuilder();
|
||||
foreach(var header in context.Request.Headers){
|
||||
buffer.AppendLine(header.Key);
|
||||
foreach(var item in header.Value){
|
||||
buffer.AppendLine($"\t{item}");
|
||||
}
|
||||
}
|
||||
buffer.AppendLine($"Url: {context.Request.Url}, method: {context.Request.Method}");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
### Run the example
|
||||
|
||||
Lastly to run the example:
|
||||
|
||||
```
|
||||
$ fission env create --name dotnet --image fission/dotnet20-env
|
||||
|
||||
$ fission function create --name httpinfo --env dotnet --code /tmp/func.cs
|
||||
|
||||
$ fission route create --method GET --url /http_info --function httpinfo
|
||||
|
||||
$ curl "http://$FISSION_ROUTER/http_info"
|
||||
Accept
|
||||
*/*;q=1
|
||||
Host
|
||||
fissionserver:8888
|
||||
User-Agent
|
||||
curl/7.47.0
|
||||
Url: http://fissionserver:8888, method: GET
|
||||
|
||||
```
|
||||
|
||||
## Accessing http request body example
|
||||
|
||||
### Setup fission environment
|
||||
First you need to setup the fission according to your cluster setup as
|
||||
specified here: https://github.com/fission/fission
|
||||
|
||||
|
||||
### Create the class to run
|
||||
|
||||
Secondly you need to create a file /tmp/func.cs containing the following code:
|
||||
|
||||
```
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context)
|
||||
{
|
||||
var person = Person.Deserialize(context.Request.Body);
|
||||
return $"Hello, my name is {person.Name} and I am {person.Age} years old.";
|
||||
}
|
||||
}
|
||||
|
||||
public class Person
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
|
||||
public static Person Deserialize(Stream json)
|
||||
{
|
||||
var serializer = new DataContractJsonSerializer(typeof(Person));
|
||||
return (Person)serializer.ReadObject(json);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
### Run the example
|
||||
|
||||
Lastly to run the example:
|
||||
|
||||
```
|
||||
$ fission env create --name dotnet --image fission/dotnet20-env
|
||||
|
||||
$ fission function create --name httpbody --env dotnet --code /tmp/func.cs
|
||||
|
||||
$ fission route create --method GET --url /http_body --function httpbody
|
||||
|
||||
$ curl -XPOST "http://$FISSION_ROUTER/http_body" -d '{ "Name":"Arthur", "Age":42}'
|
||||
Hello, my name is Arthur and I am 42 years old.
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Developing/debugging the enviroment locally
|
||||
|
||||
The easiest way to debug the environment is to open the directory in
|
||||
Visual Studio Code (VSCode) as that will setup debugger for you the
|
||||
first time.
|
||||
|
||||
Remember to install the excellent extension
|
||||
"C# for Visual Studio Code(powered by OmniSharp)" to get statement completion
|
||||
|
||||
The class ExecutorModule contain preprocessor directive overriding where
|
||||
the input code file should be found:
|
||||
|
||||
```
|
||||
#if DEBUG
|
||||
private const string CODE_PATH = "/tmp/func.cs";
|
||||
#else
|
||||
private const string CODE_PATH = "/userfunc/user";
|
||||
#endif
|
||||
```
|
||||
|
||||
So what you need to do is:
|
||||
1. Open the directory in VSCode.
|
||||
This will prompt restore of packages and query is debugger setup is needed. Accept both prompts.
|
||||
2. Press F5 to start the web server. Set breakpoints etc..
|
||||
3. Add a code file containing valid C# at /tmp/func.cs
|
||||
4. Specialize the service with curl via post
|
||||
```
|
||||
$ curl -XPOST http://localhost:8888/specialize
|
||||
```
|
||||
5. Call your function with curl
|
||||
```
|
||||
$ curl -XGET http://localhost:8888
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
dotnet restore
|
||||
dotnet publish -c Release -o out
|
||||
docker build -t fission/dotnet20-env .
|
||||
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.12
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "fission-dotnet20", "dotnet20\fission-dotnet20.csproj", "{3F044DE1-74E5-48F7-8D23-233C24AAA45C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{3F044DE1-74E5-48F7-8D23-233C24AAA45C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3F044DE1-74E5-48F7-8D23-233C24AAA45C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3F044DE1-74E5-48F7-8D23-233C24AAA45C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3F044DE1-74E5-48F7-8D23-233C24AAA45C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {272000F7-BBEC-4B61-8865-783EF7E5CEE9}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Owin" Version="2.0.0" />
|
||||
<PackageReference Include="Nancy" Version="2.0.0-clinteastwood" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="2.3.2" />
|
||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
<PackageReference Include="System.Runtime.Serialization.Json" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
var x = Convert.ToInt32(context.Arguments["x"]);
|
||||
var y = Convert.ToInt32(context.Arguments["y"]);
|
||||
return (x+y).ToString();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
context.Logger.WriteInfo("executing.. {0}", context.Arguments["text"]);
|
||||
return (string)context.Arguments["text"];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context)
|
||||
{
|
||||
return "Hello World!";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization.Json;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context)
|
||||
{
|
||||
var person = Person.Deserialize(context.Request.Body);
|
||||
return $"Hello, my name is {person.Name} and I am {person.Age} years old.";
|
||||
}
|
||||
}
|
||||
|
||||
public class Person
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
|
||||
public static Person Deserialize(Stream json)
|
||||
{
|
||||
var serializer = new DataContractJsonSerializer(typeof(Person));
|
||||
return (Person)serializer.ReadObject(json);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Fission.DotNetCore.Api;
|
||||
|
||||
public class FissionFunction
|
||||
{
|
||||
public string Execute(FissionContext context){
|
||||
var buffer = new System.Text.StringBuilder();
|
||||
foreach(var header in context.Request.Headers){
|
||||
buffer.AppendLine(header.Key);
|
||||
foreach(var item in header.Value){
|
||||
buffer.AppendLine($"\t{item}");
|
||||
}
|
||||
}
|
||||
buffer.AppendLine($"Url: {context.Request.Url}, method: {context.Request.Method}");
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user