Added jsenv support to workflows

This commit is contained in:
Peter Grlica
2021-08-12 09:05:59 +02:00
parent 84598a8a52
commit e0f6cc5553
5 changed files with 277 additions and 2 deletions
+175
View File
@@ -0,0 +1,175 @@
package automation
// This file is auto-generated.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
// Definitions file that controls how this file is generated:
// automation/automation/jsenv_handler.yaml
import (
"context"
atypes "github.com/cortezaproject/corteza-server/automation/types"
"github.com/cortezaproject/corteza-server/pkg/expr"
"github.com/cortezaproject/corteza-server/pkg/wfexec"
"io"
)
var _ wfexec.ExecResponse
type (
jsenvHandlerRegistry interface {
AddFunctions(ff ...*atypes.Function)
Type(ref string) expr.Type
}
)
func (h jsenvHandler) register() {
h.reg.AddFunctions(
h.Execute(),
)
}
type (
jsenvExecuteArgs struct {
hasScope bool
Scope interface{}
scopeAny interface{}
scopeString string
scopeStream io.Reader
hasSource bool
Source string
}
jsenvExecuteResults struct {
ResultString string
ResultInt int64
ResultAny interface{}
}
)
func (a jsenvExecuteArgs) GetScope() (bool, interface{}, string, io.Reader) {
return a.hasScope, a.scopeAny, a.scopeString, a.scopeStream
}
// Execute function Process arbitrary data in jsenv
//
// expects implementation of execute function:
// func (h jsenvHandler) execute(ctx context.Context, args *jsenvExecuteArgs) (results *jsenvExecuteResults, err error) {
// return
// }
func (h jsenvHandler) Execute() *atypes.Function {
return &atypes.Function{
Ref: "jsenvExecute",
Kind: "function",
Labels: map[string]string(nil),
Meta: &atypes.FunctionMeta{
Short: "Process arbitrary data in jsenv",
},
Parameters: []*atypes.Param{
{
Name: "scope",
Types: []string{"Any", "String", "Reader"}, Required: true,
},
{
Name: "source",
Types: []string{"String"}, Required: true,
},
},
Results: []*atypes.Param{
{
Name: "resultString",
Types: []string{"String"},
},
{
Name: "resultInt",
Types: []string{"Integer"},
},
{
Name: "resultAny",
Types: []string{"Any"},
},
},
Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) {
var (
args = &jsenvExecuteArgs{
hasScope: in.Has("scope"),
hasSource: in.Has("source"),
}
)
if err = in.Decode(args); err != nil {
return
}
// Converting Scope argument
if args.hasScope {
aux := expr.Must(expr.Select(in, "scope"))
switch aux.Type() {
case h.reg.Type("Any").Type():
args.scopeAny = aux.Get().(interface{})
case h.reg.Type("String").Type():
args.scopeString = aux.Get().(string)
case h.reg.Type("Reader").Type():
args.scopeStream = aux.Get().(io.Reader)
}
}
var results *jsenvExecuteResults
if results, err = h.execute(ctx, args); err != nil {
return
}
out = &expr.Vars{}
{
// converting results.ResultString (string) to String
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("String").Cast(results.ResultString); err != nil {
return
} else if err = expr.Assign(out, "resultString", tval); err != nil {
return
}
}
{
// converting results.ResultInt (int64) to Integer
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("Integer").Cast(results.ResultInt); err != nil {
return
} else if err = expr.Assign(out, "resultInt", tval); err != nil {
return
}
}
{
// converting results.ResultAny (interface{}) to Any
var (
tval expr.TypedValue
)
if tval, err = h.reg.Type("Any").Cast(results.ResultAny); err != nil {
return
} else if err = expr.Assign(out, "resultAny", tval); err != nil {
return
}
}
return
},
}
}
+73
View File
@@ -0,0 +1,73 @@
package automation
import (
"context"
"fmt"
"github.com/cortezaproject/corteza-server/pkg/jsenv"
)
type (
jsenvHandler struct {
reg queueHandlerRegistry
}
)
func JsenvHandler(reg queueHandlerRegistry) *jsenvHandler {
h := &jsenvHandler{
reg: reg,
}
h.register()
return h
}
func (h jsenvHandler) execute(ctx context.Context, args *jsenvExecuteArgs) (res *jsenvExecuteResults, err error) {
res = &jsenvExecuteResults{}
if !args.hasSource {
err = fmt.Errorf("could not process payload, function missing")
return
}
if !args.hasScope {
err = fmt.Errorf("could not process payload, scope missing")
return
}
// call jsenv, feed it function and expect a result
tr := jsenv.NewTransformer(jsenv.LoaderJS, jsenv.TargetNoop)
vm := jsenv.New(tr)
fn, err := vm.RegisterFunction(args.Source)
if err != nil {
err = fmt.Errorf("could not register jsenv function: %s", err)
return
}
out, err := fn.Exec(vm.New(args.scopeString))
if err != nil {
err = fmt.Errorf("could not exec jsenv function: %s", err)
return
}
switch vv := out.(type) {
// this one should go out once the ResultAny
// is mainly used
case uint64, int64:
res.ResultInt = int64(vv.(uint64))
// this one should go out once the ResultAny
// is mainly used
case string:
res.ResultString = string(vv)
default:
res.ResultAny = vv
}
return
}
+25
View File
@@ -0,0 +1,25 @@
imports:
- io
functions:
execute:
meta:
short: Process arbitrary data in jsenv
params:
scope:
required: true
types:
- { wf: Any }
- { wf: String, suffix: String }
- { wf: Reader, suffix: Stream }
source:
required: true
types:
- { wf: String }
results:
resultString:
wf: String
resultInt:
wf: Integer
resultAny:
wf: Any
+3 -2
View File
@@ -1,10 +1,11 @@
package service
import (
"github.com/cortezaproject/corteza-server/automation/types"
"github.com/cortezaproject/corteza-server/pkg/expr"
"sort"
"sync"
"github.com/cortezaproject/corteza-server/automation/types"
"github.com/cortezaproject/corteza-server/pkg/expr"
)
type (
+1
View File
@@ -120,6 +120,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, ws websock
automation.HttpRequestHandler(Registry())
automation.LogHandler(Registry())
automation.QueueHandler(Registry())
automation.JsenvHandler(Registry())
automation.LoopHandler(Registry(), DefaultWorkflow.parser)
automation.CorredorHandler(Registry(), corredor.Service())
automation.EmailHandler(Registry())