From b2b6935717824d40cdfc73bd73c9981b60d7057f Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Mon, 15 Mar 2021 17:33:20 +0100 Subject: [PATCH] Implement corredor script exec through wf fn step --- automation/automation/corredor_handler.gen.go | 116 ++++++++++++++++++ automation/automation/corredor_handler.go | 85 +++++++++++++ automation/automation/corredor_handler.yaml | 13 ++ automation/service/service.go | 2 + 4 files changed, 216 insertions(+) create mode 100644 automation/automation/corredor_handler.gen.go create mode 100644 automation/automation/corredor_handler.go create mode 100644 automation/automation/corredor_handler.yaml diff --git a/automation/automation/corredor_handler.gen.go b/automation/automation/corredor_handler.gen.go new file mode 100644 index 000000000..9922491e6 --- /dev/null +++ b/automation/automation/corredor_handler.gen.go @@ -0,0 +1,116 @@ +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/corredor_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" +) + +var _ wfexec.ExecResponse + +type ( + corredorHandlerRegistry interface { + AddFunctions(ff ...*atypes.Function) + Type(ref string) expr.Type + } +) + +func (h corredorHandler) register() { + h.reg.AddFunctions( + h.Exec(), + ) +} + +type ( + corredorExecArgs struct { + hasScript bool + Script string + + hasArgs bool + Args interface{} + } + + corredorExecResults struct { + Results interface{} + } +) + +// Exec function Executes script in Corredor Automation server +// +// expects implementation of exec function: +// func (h corredorHandler) exec(ctx context.Context, args *corredorExecArgs) (results *corredorExecResults, err error) { +// return +// } +func (h corredorHandler) Exec() *atypes.Function { + return &atypes.Function{ + Ref: "corredorExec", + Kind: "function", + Labels: map[string]string(nil), + Meta: &atypes.FunctionMeta{ + Short: "Executes script in Corredor Automation server", + }, + + Parameters: []*atypes.Param{ + { + Name: "script", + Types: []string{"String"}, Required: true, + }, + { + Name: "args", + Types: []string{"Any"}, + }, + }, + + Results: []*atypes.Param{ + + { + Name: "results", + Types: []string{"Any"}, + }, + }, + + Handler: func(ctx context.Context, in *expr.Vars) (out *expr.Vars, err error) { + var ( + args = &corredorExecArgs{ + hasScript: in.Has("script"), + hasArgs: in.Has("args"), + } + ) + + if err = in.Decode(args); err != nil { + return + } + + var results *corredorExecResults + if results, err = h.exec(ctx, args); err != nil { + return + } + + out = &expr.Vars{} + + { + // converting results.Results (interface{}) to Any + var ( + tval expr.TypedValue + ) + + if tval, err = h.reg.Type("Any").Cast(results.Results); err != nil { + return + } else if err = expr.Assign(out, "results", tval); err != nil { + return + } + } + + return + }, + } +} diff --git a/automation/automation/corredor_handler.go b/automation/automation/corredor_handler.go new file mode 100644 index 000000000..c395a76e8 --- /dev/null +++ b/automation/automation/corredor_handler.go @@ -0,0 +1,85 @@ +package automation + +import ( + "context" + "encoding/json" + "github.com/cortezaproject/corteza-server/pkg/corredor" + "github.com/cortezaproject/corteza-server/pkg/eventbus" + "github.com/cortezaproject/corteza-server/system/service/event" + "github.com/spf13/cast" +) + +type ( + corredorHandler struct { + reg corredorHandlerRegistry + svc corredorServiceExecutor + } + + corredorServiceExecutor interface { + Exec(ctx context.Context, scriptName string, args corredor.ScriptArgs) (err error) + } + + scriptArgs struct { + payload map[string]interface{} + } +) + +func CorredorHandler(reg corredorHandlerRegistry, svc corredorServiceExecutor) *corredorHandler { + h := &corredorHandler{ + reg: reg, + svc: svc, + } + + h.register() + return h +} + +func (h corredorHandler) exec(ctx context.Context, args *corredorExecArgs) (r *corredorExecResults, err error) { + sArgs := makeScriptArgs(args.Args) + + if err = h.svc.Exec(ctx, args.Script, sArgs); err != nil { + return + } + + return &corredorExecResults{Results: sArgs.payload}, nil + +} + +func makeScriptArgs(in interface{}) *scriptArgs { + return &scriptArgs{ + payload: cast.ToStringMap(in), + } +} + +// mimic onManual event on system: + +func (scriptArgs) ResourceType() string { return event.SystemOnManual().ResourceType() } +func (scriptArgs) EventType() string { return event.SystemOnManual().EventType() } +func (scriptArgs) Match(eventbus.ConstraintMatcher) bool { return false } + +func (a *scriptArgs) Encode() (enc map[string][]byte, err error) { + enc = make(map[string][]byte) + for k, v := range a.payload { + enc[k], err = json.Marshal(v) + if err != nil { + return nil, err + } + } + + return +} + +func (a *scriptArgs) Decode(enc map[string][]byte) (err error) { + a.payload = make(map[string]interface{}) + + for k, v := range enc { + var aux interface{} + if err = json.Unmarshal(v, &aux); err != nil { + return err + } + + a.payload[k] = aux + } + + return +} diff --git a/automation/automation/corredor_handler.yaml b/automation/automation/corredor_handler.yaml new file mode 100644 index 000000000..a59a5549b --- /dev/null +++ b/automation/automation/corredor_handler.yaml @@ -0,0 +1,13 @@ +name: corredor + +functions: + exec: + kind: function + meta: + short: Executes script in Corredor Automation server + params: + script: { types: [ { wf: String } ], required: true } + args: { types: [ { wf: Any } ] } + results: + results: + wf: Any diff --git a/automation/service/service.go b/automation/service/service.go index 4fb0da430..9f259601c 100644 --- a/automation/service/service.go +++ b/automation/service/service.go @@ -4,6 +4,7 @@ import ( "context" "github.com/cortezaproject/corteza-server/automation/automation" "github.com/cortezaproject/corteza-server/pkg/actionlog" + "github.com/cortezaproject/corteza-server/pkg/corredor" "github.com/cortezaproject/corteza-server/pkg/expr" "github.com/cortezaproject/corteza-server/pkg/id" "github.com/cortezaproject/corteza-server/pkg/objstore" @@ -115,6 +116,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, c Config) automation.HttpRequestHandler(Registry()) automation.LogHandler(Registry()) automation.LoopHandler(Registry(), DefaultWorkflow.parser) + automation.CorredorHandler(Registry(), corredor.Service()) return }