From 04aac341126d6baba8d3cac0859a246a312bcf95 Mon Sep 17 00:00:00 2001 From: Justen Walker Date: Tue, 11 May 2021 22:38:49 -0400 Subject: [PATCH] feat: support context and out variables Support task definitions that optionally take a context and/or return a map of out variables to set --- README.md | 10 +- gw/run.go | 20 +- gw/task.go | 38 +++ gw/taskcontext/taskcontext.go | 18 +- internal/command/render.go | 48 ++- internal/command/render_test.go | 23 +- internal/command/testdata/main.golden | 41 ++- internal/parse/parse.go | 147 +++++++-- internal/parse/parse_test.go | 31 +- internal/parse/testdata/goodwill.go | 17 +- internal/parse/testdata/goodwill2.go | 24 +- internal/pb/context.pb.go | 309 +++++++++++------- internal/pb/context_grpc.pb.go | 72 ++++ .../goodwill/service/GrpcContextService.java | 44 ++- .../concord/goodwill/task/TaskCommon.java | 6 +- .../justen/concord/goodwill/task/v1/Task.java | 5 +- .../justen/concord/goodwill/task/v2/Task.java | 5 +- src/main/proto/context.proto | 6 + test/flow/goodwill.go | 35 +- 19 files changed, 677 insertions(+), 222 deletions(-) diff --git a/README.md b/README.md index ed7a248..dee36fd 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,19 @@ import ( "context" "go.justen.tech/goodwill/gw" + "go.justen.tech/goodwill/gw/value" ) // Each task is a function with the following signature // The function name should be capitalized +// Both the ctx context.Context arg and the map[string]value.Value return are optional +// and may be omitted from the method signature + // Default Task, Says Hello -func Default(ts *gw.Task) error { - _ = ts.Log(context.TODO(), "Hello, Goodwill!") - return nil +func Default(ctx context.Context, ts *gw.Task) (map[string]value.Value, error) { + _ = ts.Log(ctx, "Hello, Goodwill!") + return nil, nil } ``` diff --git a/gw/run.go b/gw/run.go index ea204a6..22a042b 100644 --- a/gw/run.go +++ b/gw/run.go @@ -4,6 +4,7 @@ package gw import ( + "context" "crypto/tls" "crypto/x509" "encoding/pem" @@ -31,8 +32,15 @@ const ( ErrNoGRPCAddr = Error("no grpc address provided") ) +var ranOnce bool + // Run a function -func Run(fn func(ts *Task) error) error { +func Run(ctx context.Context, tr TaskRunner) error { + // Guard to prevent task from executing this function + if ranOnce { + return Error("Run called more than once") + } + ranOnce = true var err error if os.Getenv(EnvMagicKey) != EnvMagicValue { return ErrNoMagicKey @@ -59,7 +67,15 @@ func Run(fn func(ts *Task) error) error { return fmt.Errorf("could not create context: %w", err) } defer c.Close() - return fn(c) + vars, err := tr.Run(ctx, c) + if err != nil { + return fmt.Errorf("task failed: %w", err) + } + err = c.Context().SetVariables(ctx, vars) + if err != nil { + return fmt.Errorf("failed to set output variables: %w", err) + } + return nil } func transportSecurity(opts []grpc.DialOption) ([]grpc.DialOption, error) { diff --git a/gw/task.go b/gw/task.go index 0b2bdbb..b061ac0 100644 --- a/gw/task.go +++ b/gw/task.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "go.justen.tech/goodwill/gw/jsonstore" + "go.justen.tech/goodwill/internal/pb" "go.justen.tech/goodwill/gw/config" "go.justen.tech/goodwill/gw/docker" @@ -46,6 +47,16 @@ type Task struct { conn *grpc.ClientConn } +type TaskRunner interface { + Run(ctx context.Context, ts *Task) (map[string]value.Value, error) +} + +type TaskRunnerFunc func(ctx context.Context, ts *Task) (map[string]value.Value, error) + +func (f TaskRunnerFunc) Run(ctx context.Context, ts *Task) (map[string]value.Value, error) { + return f(ctx, ts) +} + const ( logLineVar = "_goodwill_log_line" logLineCallExpr = `${log.call(` + logLineVar + `)}` @@ -97,6 +108,33 @@ func (c *Task) KV() *kv.Service { return kv.NewService(c.conn) } +func (c *Task) setResult(ctx context.Context, vars map[string]value.Value) error { + if len(vars) == 0 { + return nil + } + var variables pb.Variables + for key, val := range vars { + variable, err := newVariable(key, val) + if err != nil { + return fmt.Errorf("set result variable %q=%v failed: %w", key, val, err) + } + variables.Parameters = append(variables.Parameters, variable) + } + _, err := pb.NewContextServiceClient(c.conn).SetTaskResult(ctx, &variables) + return err +} + func (c *Task) Close() error { return c.conn.Close() } + +func newVariable(key string, val value.Value) (*pb.Variable, error) { + v, err := value.Marshal(val) + if err != nil { + return nil, err + } + return &pb.Variable{ + Name: key, + Value: v, + }, nil +} diff --git a/gw/taskcontext/taskcontext.go b/gw/taskcontext/taskcontext.go index 24fb559..287df23 100644 --- a/gw/taskcontext/taskcontext.go +++ b/gw/taskcontext/taskcontext.go @@ -31,6 +31,22 @@ func (c *Service) SetVariable(ctx context.Context, name string, value value.Valu return err } +func (c *Service) SetVariables(ctx context.Context, vars map[string]value.Value) error { + if len(vars) == 0 { + return nil + } + var variables pb.Variables + for key, val := range vars { + variable, err := newVariable(key, val) + if err != nil { + return fmt.Errorf("make variable %q=%v failed: %w", key, val, err) + } + variables.Parameters = append(variables.Parameters, variable) + } + _, err := c.client.SetVariables(ctx, &variables) + return err +} + // GetVariable gets the tasks variable to the given value func (c *Service) GetVariable(ctx context.Context, name string, out value.ValueOut) error { v, err := c.client.GetVariable(ctx, &pb.VariableName{Name: name}) @@ -69,7 +85,7 @@ func (c *Service) GetVariables(ctx context.Context) (map[string]interface{}, err // EvaluateParams evaluates the given expression, and returns the result into the output value. // The given map of parameters are set as variables before the expression is evaluated, // which approximates a parameterized query; allowing a safer expression evaluation compared to string concatenation. -func (c *Service) EvaluateParams(ctx context.Context, expr string, out value.ValueOut, params map[string]value.Value, ) error { +func (c *Service) EvaluateParams(ctx context.Context, expr string, out value.ValueOut, params map[string]value.Value) error { var parameters []*pb.Variable for key, val := range params { mv, err := value.Marshal(val) diff --git a/internal/command/render.go b/internal/command/render.go index 02fe2f3..608f303 100644 --- a/internal/command/render.go +++ b/internal/command/render.go @@ -11,6 +11,11 @@ import ( "strings" ) +const ( + gwPackage = "go.justen.tech/goodwill/gw" + valuePackage = "go.justen.tech/goodwill/gw/value" +) + func renderMain(w io.Writer, data ParsedData) error { file := NewFile("main") file.HeaderComment("+build goodwill") @@ -63,6 +68,23 @@ func renderMain(w io.Writer, data ParsedData) error { jenRunTask(fn), Return())) } + + mainCode = append(mainCode, + //ctx, cancel := context.WithCancel(context.Background()) + List(Id("ctx"), Id("cancel")).Op(":=").Qual("context", "WithCancel").Call(Qual("context", "Background").Call()), + //defer cancel() + Defer().Id("cancel").Call(), + //sigCh := make(chan signal.Signal) + Id("sigCh").Op(":=").Make(Id("chan").Qual("os", "Signal")), + //signal.Notify(sigCh, os.Interrupt) + Qual("os/signal", "Notify").Call(Id("sigCh"), Qual("os", "Interrupt")), + //go func() { + Go().Func().Params().Block( + // <-sigCh + Op("<-").Id("sigCh"), + // cancel() + Id("cancel").Call(), + ).Call()) //}() // switch strings.ToLower(funcName) { ... cases ... } mainCode = append(mainCode, Switch(Qual("strings", "ToLower").Call(Id("funcName"))).Block(funcSwitchCases...)) file.Func().Id("usage").Params().Block(usageCode...) @@ -75,7 +97,31 @@ func renderMain(w io.Writer, data ParsedData) error { } func jenRunTask(fn parse.TaskFunction) Code { - return Id("dieOnError").Call(Qual(parse.GwPackage, "Run").Call(Id(fn.Name))) + var block Code + if fn.Context { + // Func(ctx,ts) + block = Id(fn.Name).Call(Id("ctx"), Id("ts")) + } else { + // Func(ts) + block = Id(fn.Name).Call(Id("ts")) + } + if fn.OutVars { + // return Func(...) + block = Return(block) + } else { + // return nil, Func(...) + block = Return(Nil(), block) + } + // dieOnError(gw.Run(gw.TaskRunnerFunc(func(ctx context.Context, ts *gw.Task) (map[string]value.Value,error) {})) + return Id("dieOnError").Call(Qual(gwPackage, "Run").Call( + Id("ctx"), + Qual(gwPackage, "TaskRunnerFunc").Parens(Func().Params( + Id("ctx").Qual("context", "Context"), + Id("ts").Add(Op("*")).Qual(gwPackage, "Task"), + ).Params( + Map(String()).Qual(valuePackage, "Value"), + Id("error"), + ).Block(block)))) } func printlnStdErr(code ...Code) Code { diff --git a/internal/command/render_test.go b/internal/command/render_test.go index 9d918c8..24b2e7e 100644 --- a/internal/command/render_test.go +++ b/internal/command/render_test.go @@ -15,9 +15,26 @@ func TestRenderMain(t *testing.T) { g := goldie.New(t) err := renderMain(&buf, ParsedData{ Functions: []parse.TaskFunction{ - {Name: "Default", Doc: "Default Doc"}, - {Name: "Task1", Doc: "Task 1 Doc"}, - {Name: "Task2", Doc: "Task 2 Doc"}, + { + Name: "ContextFunc", + Doc: "ContextFunc takes a context and a task and returns an error", + Context: true, + }, + { + Name: "ContextOutFunc", + Doc: "ContextOutFunc takes a context and a task and returns output variables and an error", + Context: true, + OutVars: true, + }, + { + Name: "Func", + Doc: "Func only takes a task and returns an error", + }, + { + Name: "OutFunc", + Doc: "OutFunc takes a task and returns output variables and an error", + OutVars: true, + }, }, }) if err != nil { diff --git a/internal/command/testdata/main.golden b/internal/command/testdata/main.golden index 22355af..635e58e 100644 --- a/internal/command/testdata/main.golden +++ b/internal/command/testdata/main.golden @@ -3,9 +3,12 @@ package main import ( + "context" "fmt" gw "go.justen.tech/goodwill/gw" + value "go.justen.tech/goodwill/gw/value" "os" + "os/signal" "strings" ) @@ -18,9 +21,10 @@ func dieOnError(err error) { func usage() { fmt.Printf("Usage: %s FUNCTION\n", os.Args[0]) fmt.Println("Functions:") - fmt.Println("\tDefault\tDefault Doc") - fmt.Println("\tTask1\tTask 1 Doc") - fmt.Println("\tTask2\tTask 2 Doc") + fmt.Println("\tContextFunc\tContextFunc takes a context and a task and returns an error") + fmt.Println("\tContextOutFunc\tContextOutFunc takes a context and a task and returns output variables and an error") + fmt.Println("\tFunc\tFunc only takes a task and returns an error") + fmt.Println("\tOutFunc\tOutFunc takes a task and returns output variables and an error") os.Exit(128) } func main() { @@ -29,15 +33,34 @@ func main() { usage() } funcName := os.Args[1] + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + sigCh := make(chan os.Signal) + signal.Notify(sigCh, os.Interrupt) + go func() { + <-sigCh + cancel() + }() switch strings.ToLower(funcName) { - case "default": - dieOnError(gw.Run(Default)) + case "contextfunc": + dieOnError(gw.Run(ctx, gw.TaskRunnerFunc(func(ctx context.Context, ts *gw.Task) (map[string]value.Value, error) { + return nil, ContextFunc(ctx, ts) + }))) return - case "task1": - dieOnError(gw.Run(Task1)) + case "contextoutfunc": + dieOnError(gw.Run(ctx, gw.TaskRunnerFunc(func(ctx context.Context, ts *gw.Task) (map[string]value.Value, error) { + return ContextOutFunc(ctx, ts) + }))) return - case "task2": - dieOnError(gw.Run(Task2)) + case "func": + dieOnError(gw.Run(ctx, gw.TaskRunnerFunc(func(ctx context.Context, ts *gw.Task) (map[string]value.Value, error) { + return nil, Func(ts) + }))) + return + case "outfunc": + dieOnError(gw.Run(ctx, gw.TaskRunnerFunc(func(ctx context.Context, ts *gw.Task) (map[string]value.Value, error) { + return OutFunc(ts) + }))) return } fmt.Fprintln(os.Stderr, "Unknown function name:", funcName) diff --git a/internal/parse/parse.go b/internal/parse/parse.go index a7ef14b..26edd58 100644 --- a/internal/parse/parse.go +++ b/internal/parse/parse.go @@ -22,13 +22,25 @@ type PkgInfo struct { } type TaskFunction struct { - Name string - Doc string + Name string + Doc string + Context bool + OutVars bool } -const GwPackage = "go.justen.tech/goodwill/gw" -const TaskType = "Task" -const ErrorType = "error" +type ByName []TaskFunction + +func (fs ByName) Len() int { + return len(fs) +} + +func (fs ByName) Less(i, j int) bool { + return fs[i].Name < fs[j].Name +} + +func (fs ByName) Swap(i, j int) { + fs[i], fs[j] = fs[j], fs[i] +} func Package(path string, files []string) (*PkgInfo, error) { fset := token.NewFileSet() @@ -68,8 +80,7 @@ func Package(path string, files []string) (*PkgInfo, error) { } func TaskFunctions(path string, info *PkgInfo) ([]TaskFunction, error) { - var funcs []TaskFunction - funcNames := make(map[string]struct{}) + taskFuncs := make(map[string]TaskFunction) imports := make(map[string]string) for _, file := range info.AstPkg.Files { for _, is := range file.Imports { @@ -89,19 +100,18 @@ func TaskFunctions(path string, info *PkgInfo) ([]TaskFunction, error) { } for _, decl := range file.Decls { if fn, ok := decl.(*ast.FuncDecl); ok { - name, ok := flowFunctionName(imports, fn) + tf, ok := taskFunction(imports, fn) if ok { - funcNames[name] = struct{}{} + taskFuncs[tf.Name] = tf } } } } + var funcs []TaskFunction for _, f := range info.DocPkg.Funcs { - if _, ok := funcNames[f.Name]; ok { - funcs = append(funcs, TaskFunction{ - Name: f.Name, - Doc: oneLine(f.Doc), - }) + if tf, ok := taskFuncs[f.Name]; ok { + tf.Doc = oneLine(f.Doc) + funcs = append(funcs, tf) } } return funcs, nil @@ -119,34 +129,101 @@ func ident(node ast.Node) string { return id.Name } -func flowFunctionName(imports map[string]string, f *ast.FuncDecl) (string, bool) { - params := f.Type.Params - if len(params.List) != 1 { - return "", false +func taskFunction(imports map[string]string, f *ast.FuncDecl) (TaskFunction, bool) { + fi := &functionInspector{ + f: f, + imports: imports, + } + return fi.function() +} + +type functionInspector struct { + f *ast.FuncDecl + imports map[string]string +} + +func (i *functionInspector) function() (tf TaskFunction, ok bool) { + params := i.f.Type.Params.List + switch len(params) { + case 1: + if !i.isTaskType(params[0]) { + return + } + case 2: + if !i.isContextType(params[0]) { + return + } + tf.Context = true + if !i.isTaskType(params[1]) { + return + } + default: + return + } + returns := i.f.Type.Results.List + switch len(returns) { + case 1: + if !i.isErrType(returns[0]) { + return + } + case 2: + if !i.isOutVars(returns[0]) { + return + } + tf.OutVars = true + if !i.isErrType(returns[1]) { + return + } + default: + return } - p1 := params.List[0] - sexpr, ok := p1.Type.(*ast.StarExpr) + tf.Name = ident(i.f.Name) + return tf, true +} + +func (i *functionInspector) isTaskType(field *ast.Field) bool { + sexpr, ok := field.Type.(*ast.StarExpr) if !ok { - return "", false + return false } - selexpr, ok := sexpr.X.(*ast.SelectorExpr) + return i.isSelectorType(sexpr.X, "go.justen.tech/goodwill/gw", "Task") +} + +func (i *functionInspector) isSelectorType(expr ast.Expr, pkg string, name string) bool { + selexpr, ok := expr.(*ast.SelectorExpr) if !ok { - return "", false + return false } - if pkg := ident(selexpr.X); imports[pkg] != GwPackage { - return "", false + if p := ident(selexpr.X); i.imports[p] != pkg { + return false } - if ident(selexpr.Sel) != TaskType { - return "", false + if ident(selexpr.Sel) != name { + return false } - // return - returns := f.Type.Results - if len(returns.List) != 1 { - return "", false + return true + +} + +func (i *functionInspector) isErrType(field *ast.Field) bool { + return ident(field.Type) == "error" +} + +func (i *functionInspector) isOutVars(field *ast.Field) bool { + mtype, ok := field.Type.(*ast.MapType) + if !ok { + return false } - r1 := returns.List[0] - if ident(r1.Type) != ErrorType { - return "", false + // key is a string + ktype, ok := mtype.Key.(*ast.Ident) + if !ok { + return false + } + if ktype.Name != "string" { + return false } - return ident(f.Name), true + return i.isSelectorType(mtype.Value, "go.justen.tech/goodwill/gw/value", "Value") +} + +func (i *functionInspector) isContextType(field *ast.Field) bool { + return i.isSelectorType(field.Type, "context", "Context") } diff --git a/internal/parse/parse_test.go b/internal/parse/parse_test.go index 6381d4e..ee6f470 100644 --- a/internal/parse/parse_test.go +++ b/internal/parse/parse_test.go @@ -4,6 +4,7 @@ package parse import ( + "sort" "testing" ) @@ -12,11 +13,37 @@ func TestParse(t *testing.T) { if err != nil { t.Fatal(err) } + expected := []TaskFunction{ + { + Name: "ContextFunc", + Doc: "ContextFunc takes a context and a task and returns an error", + Context: true, + }, + { + Name: "ContextOutFunc", + Doc: "ContextOutFunc takes a context and a task and returns output variables and an error", + Context: true, + OutVars: true, + }, + { + Name: "Func", + Doc: "Func only takes a task and returns an error", + }, + { + Name: "OutFunc", + Doc: "OutFunc takes a task and returns output variables and an error", + OutVars: true, + }, + } + sort.Sort(ByName(expected)) ffs, err := TaskFunctions("./testdata", info) if err != nil { t.Fatal(err) } - for _, ff := range ffs { - t.Logf("> %s\n%s", ff.Doc, ff.Name) + sort.Sort(ByName(ffs)) + for i, ff := range ffs { + if expected[i] != ff { + t.Errorf("Expected Func %d to be %+v, got %+v", i, expected[i], ff) + } } } diff --git a/internal/parse/testdata/goodwill.go b/internal/parse/testdata/goodwill.go index 6830c33..6e6f75b 100644 --- a/internal/parse/testdata/goodwill.go +++ b/internal/parse/testdata/goodwill.go @@ -6,19 +6,16 @@ package main import ( - "context" - "fmt" "go.justen.tech/goodwill/gw" "go.justen.tech/goodwill/gw/value" ) -// PrintWorkDir prints the working directory -func PrintWorkDir(ts *gw.Task) error { - tc := ts.Context() - var value value.String - if err := tc.Evaluate(context.TODO(), "${workDir}", &value); err != nil { - return err - } - fmt.Println("workDir:", value) +// Func only takes a task and returns an error +func Func(ts *gw.Task) error { return nil } + +// OutFunc takes a task and returns output variables and an error +func OutFunc(ts *gw.Task) (map[string]value.Value, error) { + return nil, nil +} diff --git a/internal/parse/testdata/goodwill2.go b/internal/parse/testdata/goodwill2.go index 9117f99..f3a0d75 100644 --- a/internal/parse/testdata/goodwill2.go +++ b/internal/parse/testdata/goodwill2.go @@ -6,19 +6,19 @@ package main import ( - c2 "context" - "fmt" + "context" + + // This tests that aliases work when parsing gw2 "go.justen.tech/goodwill/gw" - "go.justen.tech/goodwill/gw/value" + val "go.justen.tech/goodwill/gw/value" ) -// PrintProcessID prints the concord process id -func PrintProcessID(ts *gw2.Task) error { - tc := ts.Context() - var value value.String - if err := tc.Evaluate(c2.TODO(), "${txId}", &value); err != nil { - return err - } - fmt.Println("Process ID:", value) +// ContextFunc takes a context and a task and returns an error +func ContextFunc(ctx context.Context, ts *gw2.Task) error { return nil -} \ No newline at end of file +} + +// ContextOutFunc takes a context and a task and returns output variables and an error +func ContextOutFunc(ctx context.Context, ts *gw2.Task) (map[string]val.Value, error) { + return nil, nil +} diff --git a/internal/pb/context.pb.go b/internal/pb/context.pb.go index a9082ea..b32aa72 100644 --- a/internal/pb/context.pb.go +++ b/internal/pb/context.pb.go @@ -138,6 +138,53 @@ func (*GetVariableNameParams) Descriptor() ([]byte, []int) { return file_context_proto_rawDescGZIP(), []int{2} } +type Variables struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Parameters []*Variable `protobuf:"bytes,1,rep,name=parameters,proto3" json:"parameters,omitempty"` +} + +func (x *Variables) Reset() { + *x = Variables{} + if protoimpl.UnsafeEnabled { + mi := &file_context_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Variables) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Variables) ProtoMessage() {} + +func (x *Variables) ProtoReflect() protoreflect.Message { + mi := &file_context_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Variables.ProtoReflect.Descriptor instead. +func (*Variables) Descriptor() ([]byte, []int) { + return file_context_proto_rawDescGZIP(), []int{3} +} + +func (x *Variables) GetParameters() []*Variable { + if x != nil { + return x.Parameters + } + return nil +} + type Value struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -149,7 +196,7 @@ type Value struct { func (x *Value) Reset() { *x = Value{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[3] + mi := &file_context_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -162,7 +209,7 @@ func (x *Value) String() string { func (*Value) ProtoMessage() {} func (x *Value) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[3] + mi := &file_context_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -175,7 +222,7 @@ func (x *Value) ProtoReflect() protoreflect.Message { // Deprecated: Use Value.ProtoReflect.Descriptor instead. func (*Value) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{3} + return file_context_proto_rawDescGZIP(), []int{4} } func (x *Value) GetValue() *anypb.Any { @@ -196,7 +243,7 @@ type MapValue struct { func (x *MapValue) Reset() { *x = MapValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[4] + mi := &file_context_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -209,7 +256,7 @@ func (x *MapValue) String() string { func (*MapValue) ProtoMessage() {} func (x *MapValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[4] + mi := &file_context_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -222,7 +269,7 @@ func (x *MapValue) ProtoReflect() protoreflect.Message { // Deprecated: Use MapValue.ProtoReflect.Descriptor instead. func (*MapValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{4} + return file_context_proto_rawDescGZIP(), []int{5} } func (x *MapValue) GetValue() map[string]*Value { @@ -243,7 +290,7 @@ type ListValue struct { func (x *ListValue) Reset() { *x = ListValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[5] + mi := &file_context_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -256,7 +303,7 @@ func (x *ListValue) String() string { func (*ListValue) ProtoMessage() {} func (x *ListValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[5] + mi := &file_context_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -269,7 +316,7 @@ func (x *ListValue) ProtoReflect() protoreflect.Message { // Deprecated: Use ListValue.ProtoReflect.Descriptor instead. func (*ListValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{5} + return file_context_proto_rawDescGZIP(), []int{6} } func (x *ListValue) GetValue() []*Value { @@ -290,7 +337,7 @@ type StringValue struct { func (x *StringValue) Reset() { *x = StringValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[6] + mi := &file_context_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -303,7 +350,7 @@ func (x *StringValue) String() string { func (*StringValue) ProtoMessage() {} func (x *StringValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[6] + mi := &file_context_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -316,7 +363,7 @@ func (x *StringValue) ProtoReflect() protoreflect.Message { // Deprecated: Use StringValue.ProtoReflect.Descriptor instead. func (*StringValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{6} + return file_context_proto_rawDescGZIP(), []int{7} } func (x *StringValue) GetValue() string { @@ -337,7 +384,7 @@ type IntValue struct { func (x *IntValue) Reset() { *x = IntValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[7] + mi := &file_context_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -350,7 +397,7 @@ func (x *IntValue) String() string { func (*IntValue) ProtoMessage() {} func (x *IntValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[7] + mi := &file_context_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -363,7 +410,7 @@ func (x *IntValue) ProtoReflect() protoreflect.Message { // Deprecated: Use IntValue.ProtoReflect.Descriptor instead. func (*IntValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{7} + return file_context_proto_rawDescGZIP(), []int{8} } func (x *IntValue) GetValue() int64 { @@ -384,7 +431,7 @@ type DoubleValue struct { func (x *DoubleValue) Reset() { *x = DoubleValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[8] + mi := &file_context_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -397,7 +444,7 @@ func (x *DoubleValue) String() string { func (*DoubleValue) ProtoMessage() {} func (x *DoubleValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[8] + mi := &file_context_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -410,7 +457,7 @@ func (x *DoubleValue) ProtoReflect() protoreflect.Message { // Deprecated: Use DoubleValue.ProtoReflect.Descriptor instead. func (*DoubleValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{8} + return file_context_proto_rawDescGZIP(), []int{9} } func (x *DoubleValue) GetValue() float64 { @@ -431,7 +478,7 @@ type BoolValue struct { func (x *BoolValue) Reset() { *x = BoolValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[9] + mi := &file_context_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -444,7 +491,7 @@ func (x *BoolValue) String() string { func (*BoolValue) ProtoMessage() {} func (x *BoolValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[9] + mi := &file_context_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -457,7 +504,7 @@ func (x *BoolValue) ProtoReflect() protoreflect.Message { // Deprecated: Use BoolValue.ProtoReflect.Descriptor instead. func (*BoolValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{9} + return file_context_proto_rawDescGZIP(), []int{10} } func (x *BoolValue) GetValue() bool { @@ -478,7 +525,7 @@ type TimeValue struct { func (x *TimeValue) Reset() { *x = TimeValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[10] + mi := &file_context_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -491,7 +538,7 @@ func (x *TimeValue) String() string { func (*TimeValue) ProtoMessage() {} func (x *TimeValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[10] + mi := &file_context_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -504,7 +551,7 @@ func (x *TimeValue) ProtoReflect() protoreflect.Message { // Deprecated: Use TimeValue.ProtoReflect.Descriptor instead. func (*TimeValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{10} + return file_context_proto_rawDescGZIP(), []int{11} } func (x *TimeValue) GetValue() int64 { @@ -523,7 +570,7 @@ type NullValue struct { func (x *NullValue) Reset() { *x = NullValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[11] + mi := &file_context_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -536,7 +583,7 @@ func (x *NullValue) String() string { func (*NullValue) ProtoMessage() {} func (x *NullValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[11] + mi := &file_context_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -549,7 +596,7 @@ func (x *NullValue) ProtoReflect() protoreflect.Message { // Deprecated: Use NullValue.ProtoReflect.Descriptor instead. func (*NullValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{11} + return file_context_proto_rawDescGZIP(), []int{12} } type JSONValue struct { @@ -564,7 +611,7 @@ type JSONValue struct { func (x *JSONValue) Reset() { *x = JSONValue{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[12] + mi := &file_context_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -577,7 +624,7 @@ func (x *JSONValue) String() string { func (*JSONValue) ProtoMessage() {} func (x *JSONValue) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[12] + mi := &file_context_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -590,7 +637,7 @@ func (x *JSONValue) ProtoReflect() protoreflect.Message { // Deprecated: Use JSONValue.ProtoReflect.Descriptor instead. func (*JSONValue) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{12} + return file_context_proto_rawDescGZIP(), []int{13} } func (x *JSONValue) GetClass() string { @@ -620,7 +667,7 @@ type EvaluateRequest struct { func (x *EvaluateRequest) Reset() { *x = EvaluateRequest{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[13] + mi := &file_context_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -633,7 +680,7 @@ func (x *EvaluateRequest) String() string { func (*EvaluateRequest) ProtoMessage() {} func (x *EvaluateRequest) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[13] + mi := &file_context_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -646,7 +693,7 @@ func (x *EvaluateRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use EvaluateRequest.ProtoReflect.Descriptor instead. func (*EvaluateRequest) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{13} + return file_context_proto_rawDescGZIP(), []int{14} } func (x *EvaluateRequest) GetExpression() string { @@ -681,7 +728,7 @@ type VariableName struct { func (x *VariableName) Reset() { *x = VariableName{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[14] + mi := &file_context_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -694,7 +741,7 @@ func (x *VariableName) String() string { func (*VariableName) ProtoMessage() {} func (x *VariableName) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[14] + mi := &file_context_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -707,7 +754,7 @@ func (x *VariableName) ProtoReflect() protoreflect.Message { // Deprecated: Use VariableName.ProtoReflect.Descriptor instead. func (*VariableName) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{14} + return file_context_proto_rawDescGZIP(), []int{15} } func (x *VariableName) GetName() string { @@ -728,7 +775,7 @@ type VariableNameList struct { func (x *VariableNameList) Reset() { *x = VariableNameList{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[15] + mi := &file_context_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -741,7 +788,7 @@ func (x *VariableNameList) String() string { func (*VariableNameList) ProtoMessage() {} func (x *VariableNameList) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[15] + mi := &file_context_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -754,7 +801,7 @@ func (x *VariableNameList) ProtoReflect() protoreflect.Message { // Deprecated: Use VariableNameList.ProtoReflect.Descriptor instead. func (*VariableNameList) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{15} + return file_context_proto_rawDescGZIP(), []int{16} } func (x *VariableNameList) GetName() []string { @@ -776,7 +823,7 @@ type Variable struct { func (x *Variable) Reset() { *x = Variable{} if protoimpl.UnsafeEnabled { - mi := &file_context_proto_msgTypes[16] + mi := &file_context_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -789,7 +836,7 @@ func (x *Variable) String() string { func (*Variable) ProtoMessage() {} func (x *Variable) ProtoReflect() protoreflect.Message { - mi := &file_context_proto_msgTypes[16] + mi := &file_context_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -802,7 +849,7 @@ func (x *Variable) ProtoReflect() protoreflect.Message { // Deprecated: Use Variable.ProtoReflect.Descriptor instead. func (*Variable) Descriptor() ([]byte, []int) { - return file_context_proto_rawDescGZIP(), []int{16} + return file_context_proto_rawDescGZIP(), []int{17} } func (x *Variable) GetName() string { @@ -829,7 +876,11 @@ var file_context_proto_rawDesc = []byte{ 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x13, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x33, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, + 0x6d, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0x3e, 0x0a, 0x09, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x0a, 0x70, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x22, 0x33, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x88, 0x01, @@ -876,7 +927,7 @@ var file_context_proto_rawDesc = []byte{ 0x62, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x32, 0xd4, 0x02, + 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x32, 0xd9, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x15, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, @@ -885,26 +936,34 @@ var file_context_proto_rawDesc = []byte{ 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x11, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x1a, 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x53, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x56, - 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x1e, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, - 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x1a, 0x19, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0c, 0x47, 0x65, 0x74, - 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x08, - 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x12, 0x18, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x00, 0x42, 0x56, 0x0a, 0x21, 0x74, 0x65, 0x63, 0x68, 0x2e, 0x6a, 0x75, 0x73, - 0x74, 0x65, 0x6e, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x6f, 0x72, 0x64, 0x2e, 0x67, 0x6f, 0x6f, 0x64, - 0x77, 0x69, 0x6c, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x42, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x23, 0x67, 0x6f, 0x2e, 0x6a, 0x75, 0x73, 0x74, - 0x65, 0x6e, 0x2e, 0x74, 0x65, 0x63, 0x68, 0x2f, 0x67, 0x6f, 0x6f, 0x64, 0x77, 0x69, 0x6c, 0x6c, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x0c, 0x53, 0x65, 0x74, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x12, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x78, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x1a, 0x1a, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x53, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, + 0x6c, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0d, 0x53, 0x65, + 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x2e, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x1a, + 0x1a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x53, 0x65, 0x74, 0x56, 0x61, 0x72, + 0x69, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x00, 0x12, 0x4f, 0x0a, + 0x10, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x12, 0x1e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x56, + 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, + 0x73, 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x22, 0x00, 0x12, 0x41, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x12, 0x1c, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x4d, 0x61, 0x70, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, + 0x00, 0x12, 0x36, 0x0a, 0x08, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, 0x12, 0x18, 0x2e, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x0e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, + 0x74, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x00, 0x42, 0x56, 0x0a, 0x21, 0x74, 0x65, 0x63, + 0x68, 0x2e, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x6e, 0x2e, 0x63, 0x6f, 0x6e, 0x63, 0x6f, 0x72, 0x64, + 0x2e, 0x67, 0x6f, 0x6f, 0x64, 0x77, 0x69, 0x6c, 0x6c, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x42, 0x0c, + 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x5a, 0x23, 0x67, 0x6f, + 0x2e, 0x6a, 0x75, 0x73, 0x74, 0x65, 0x6e, 0x2e, 0x74, 0x65, 0x63, 0x68, 0x2f, 0x67, 0x6f, 0x6f, + 0x64, 0x77, 0x69, 0x6c, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, + 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -919,50 +978,56 @@ func file_context_proto_rawDescGZIP() []byte { return file_context_proto_rawDescData } -var file_context_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_context_proto_msgTypes = make([]protoimpl.MessageInfo, 19) var file_context_proto_goTypes = []interface{}{ (*GetVariablesRequest)(nil), // 0: context.GetVariablesRequest (*SetVariableResult)(nil), // 1: context.SetVariableResult (*GetVariableNameParams)(nil), // 2: context.GetVariableNameParams - (*Value)(nil), // 3: context.Value - (*MapValue)(nil), // 4: context.MapValue - (*ListValue)(nil), // 5: context.ListValue - (*StringValue)(nil), // 6: context.StringValue - (*IntValue)(nil), // 7: context.IntValue - (*DoubleValue)(nil), // 8: context.DoubleValue - (*BoolValue)(nil), // 9: context.BoolValue - (*TimeValue)(nil), // 10: context.TimeValue - (*NullValue)(nil), // 11: context.NullValue - (*JSONValue)(nil), // 12: context.JSONValue - (*EvaluateRequest)(nil), // 13: context.EvaluateRequest - (*VariableName)(nil), // 14: context.VariableName - (*VariableNameList)(nil), // 15: context.VariableNameList - (*Variable)(nil), // 16: context.Variable - nil, // 17: context.MapValue.ValueEntry - (*anypb.Any)(nil), // 18: google.protobuf.Any + (*Variables)(nil), // 3: context.Variables + (*Value)(nil), // 4: context.Value + (*MapValue)(nil), // 5: context.MapValue + (*ListValue)(nil), // 6: context.ListValue + (*StringValue)(nil), // 7: context.StringValue + (*IntValue)(nil), // 8: context.IntValue + (*DoubleValue)(nil), // 9: context.DoubleValue + (*BoolValue)(nil), // 10: context.BoolValue + (*TimeValue)(nil), // 11: context.TimeValue + (*NullValue)(nil), // 12: context.NullValue + (*JSONValue)(nil), // 13: context.JSONValue + (*EvaluateRequest)(nil), // 14: context.EvaluateRequest + (*VariableName)(nil), // 15: context.VariableName + (*VariableNameList)(nil), // 16: context.VariableNameList + (*Variable)(nil), // 17: context.Variable + nil, // 18: context.MapValue.ValueEntry + (*anypb.Any)(nil), // 19: google.protobuf.Any } var file_context_proto_depIdxs = []int32{ - 18, // 0: context.Value.value:type_name -> google.protobuf.Any - 17, // 1: context.MapValue.value:type_name -> context.MapValue.ValueEntry - 3, // 2: context.ListValue.value:type_name -> context.Value - 16, // 3: context.EvaluateRequest.parameters:type_name -> context.Variable - 3, // 4: context.Variable.value:type_name -> context.Value - 3, // 5: context.MapValue.ValueEntry.value:type_name -> context.Value - 14, // 6: context.ContextService.GetVariable:input_type -> context.VariableName - 16, // 7: context.ContextService.SetVariable:input_type -> context.Variable - 2, // 8: context.ContextService.GetVariableNames:input_type -> context.GetVariableNameParams - 0, // 9: context.ContextService.GetVariables:input_type -> context.GetVariablesRequest - 13, // 10: context.ContextService.Evaluate:input_type -> context.EvaluateRequest - 3, // 11: context.ContextService.GetVariable:output_type -> context.Value - 1, // 12: context.ContextService.SetVariable:output_type -> context.SetVariableResult - 15, // 13: context.ContextService.GetVariableNames:output_type -> context.VariableNameList - 4, // 14: context.ContextService.GetVariables:output_type -> context.MapValue - 3, // 15: context.ContextService.Evaluate:output_type -> context.Value - 11, // [11:16] is the sub-list for method output_type - 6, // [6:11] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 17, // 0: context.Variables.parameters:type_name -> context.Variable + 19, // 1: context.Value.value:type_name -> google.protobuf.Any + 18, // 2: context.MapValue.value:type_name -> context.MapValue.ValueEntry + 4, // 3: context.ListValue.value:type_name -> context.Value + 17, // 4: context.EvaluateRequest.parameters:type_name -> context.Variable + 4, // 5: context.Variable.value:type_name -> context.Value + 4, // 6: context.MapValue.ValueEntry.value:type_name -> context.Value + 15, // 7: context.ContextService.GetVariable:input_type -> context.VariableName + 17, // 8: context.ContextService.SetVariable:input_type -> context.Variable + 3, // 9: context.ContextService.SetVariables:input_type -> context.Variables + 3, // 10: context.ContextService.SetTaskResult:input_type -> context.Variables + 2, // 11: context.ContextService.GetVariableNames:input_type -> context.GetVariableNameParams + 0, // 12: context.ContextService.GetVariables:input_type -> context.GetVariablesRequest + 14, // 13: context.ContextService.Evaluate:input_type -> context.EvaluateRequest + 4, // 14: context.ContextService.GetVariable:output_type -> context.Value + 1, // 15: context.ContextService.SetVariable:output_type -> context.SetVariableResult + 1, // 16: context.ContextService.SetVariables:output_type -> context.SetVariableResult + 1, // 17: context.ContextService.SetTaskResult:output_type -> context.SetVariableResult + 16, // 18: context.ContextService.GetVariableNames:output_type -> context.VariableNameList + 5, // 19: context.ContextService.GetVariables:output_type -> context.MapValue + 4, // 20: context.ContextService.Evaluate:output_type -> context.Value + 14, // [14:21] is the sub-list for method output_type + 7, // [7:14] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_context_proto_init() } @@ -1008,7 +1073,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Value); i { + switch v := v.(*Variables); i { case 0: return &v.state case 1: @@ -1020,7 +1085,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MapValue); i { + switch v := v.(*Value); i { case 0: return &v.state case 1: @@ -1032,7 +1097,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListValue); i { + switch v := v.(*MapValue); i { case 0: return &v.state case 1: @@ -1044,7 +1109,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StringValue); i { + switch v := v.(*ListValue); i { case 0: return &v.state case 1: @@ -1056,7 +1121,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*IntValue); i { + switch v := v.(*StringValue); i { case 0: return &v.state case 1: @@ -1068,7 +1133,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DoubleValue); i { + switch v := v.(*IntValue); i { case 0: return &v.state case 1: @@ -1080,7 +1145,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BoolValue); i { + switch v := v.(*DoubleValue); i { case 0: return &v.state case 1: @@ -1092,7 +1157,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*TimeValue); i { + switch v := v.(*BoolValue); i { case 0: return &v.state case 1: @@ -1104,7 +1169,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*NullValue); i { + switch v := v.(*TimeValue); i { case 0: return &v.state case 1: @@ -1116,7 +1181,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*JSONValue); i { + switch v := v.(*NullValue); i { case 0: return &v.state case 1: @@ -1128,7 +1193,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EvaluateRequest); i { + switch v := v.(*JSONValue); i { case 0: return &v.state case 1: @@ -1140,7 +1205,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VariableName); i { + switch v := v.(*EvaluateRequest); i { case 0: return &v.state case 1: @@ -1152,7 +1217,7 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VariableNameList); i { + switch v := v.(*VariableName); i { case 0: return &v.state case 1: @@ -1164,6 +1229,18 @@ func file_context_proto_init() { } } file_context_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*VariableNameList); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_context_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Variable); i { case 0: return &v.state @@ -1182,7 +1259,7 @@ func file_context_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_context_proto_rawDesc, NumEnums: 0, - NumMessages: 18, + NumMessages: 19, NumExtensions: 0, NumServices: 1, }, diff --git a/internal/pb/context_grpc.pb.go b/internal/pb/context_grpc.pb.go index dd89e28..a9f1eaa 100644 --- a/internal/pb/context_grpc.pb.go +++ b/internal/pb/context_grpc.pb.go @@ -20,6 +20,8 @@ const _ = grpc.SupportPackageIsVersion7 type ContextServiceClient interface { GetVariable(ctx context.Context, in *VariableName, opts ...grpc.CallOption) (*Value, error) SetVariable(ctx context.Context, in *Variable, opts ...grpc.CallOption) (*SetVariableResult, error) + SetVariables(ctx context.Context, in *Variables, opts ...grpc.CallOption) (*SetVariableResult, error) + SetTaskResult(ctx context.Context, in *Variables, opts ...grpc.CallOption) (*SetVariableResult, error) GetVariableNames(ctx context.Context, in *GetVariableNameParams, opts ...grpc.CallOption) (*VariableNameList, error) GetVariables(ctx context.Context, in *GetVariablesRequest, opts ...grpc.CallOption) (*MapValue, error) Evaluate(ctx context.Context, in *EvaluateRequest, opts ...grpc.CallOption) (*Value, error) @@ -51,6 +53,24 @@ func (c *contextServiceClient) SetVariable(ctx context.Context, in *Variable, op return out, nil } +func (c *contextServiceClient) SetVariables(ctx context.Context, in *Variables, opts ...grpc.CallOption) (*SetVariableResult, error) { + out := new(SetVariableResult) + err := c.cc.Invoke(ctx, "/context.ContextService/SetVariables", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *contextServiceClient) SetTaskResult(ctx context.Context, in *Variables, opts ...grpc.CallOption) (*SetVariableResult, error) { + out := new(SetVariableResult) + err := c.cc.Invoke(ctx, "/context.ContextService/SetTaskResult", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *contextServiceClient) GetVariableNames(ctx context.Context, in *GetVariableNameParams, opts ...grpc.CallOption) (*VariableNameList, error) { out := new(VariableNameList) err := c.cc.Invoke(ctx, "/context.ContextService/GetVariableNames", in, out, opts...) @@ -84,6 +104,8 @@ func (c *contextServiceClient) Evaluate(ctx context.Context, in *EvaluateRequest type ContextServiceServer interface { GetVariable(context.Context, *VariableName) (*Value, error) SetVariable(context.Context, *Variable) (*SetVariableResult, error) + SetVariables(context.Context, *Variables) (*SetVariableResult, error) + SetTaskResult(context.Context, *Variables) (*SetVariableResult, error) GetVariableNames(context.Context, *GetVariableNameParams) (*VariableNameList, error) GetVariables(context.Context, *GetVariablesRequest) (*MapValue, error) Evaluate(context.Context, *EvaluateRequest) (*Value, error) @@ -100,6 +122,12 @@ func (UnimplementedContextServiceServer) GetVariable(context.Context, *VariableN func (UnimplementedContextServiceServer) SetVariable(context.Context, *Variable) (*SetVariableResult, error) { return nil, status.Errorf(codes.Unimplemented, "method SetVariable not implemented") } +func (UnimplementedContextServiceServer) SetVariables(context.Context, *Variables) (*SetVariableResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetVariables not implemented") +} +func (UnimplementedContextServiceServer) SetTaskResult(context.Context, *Variables) (*SetVariableResult, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetTaskResult not implemented") +} func (UnimplementedContextServiceServer) GetVariableNames(context.Context, *GetVariableNameParams) (*VariableNameList, error) { return nil, status.Errorf(codes.Unimplemented, "method GetVariableNames not implemented") } @@ -158,6 +186,42 @@ func _ContextService_SetVariable_Handler(srv interface{}, ctx context.Context, d return interceptor(ctx, in, info, handler) } +func _ContextService_SetVariables_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Variables) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ContextServiceServer).SetVariables(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/context.ContextService/SetVariables", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ContextServiceServer).SetVariables(ctx, req.(*Variables)) + } + return interceptor(ctx, in, info, handler) +} + +func _ContextService_SetTaskResult_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Variables) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ContextServiceServer).SetTaskResult(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/context.ContextService/SetTaskResult", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ContextServiceServer).SetTaskResult(ctx, req.(*Variables)) + } + return interceptor(ctx, in, info, handler) +} + func _ContextService_GetVariableNames_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(GetVariableNameParams) if err := dec(in); err != nil { @@ -227,6 +291,14 @@ var ContextService_ServiceDesc = grpc.ServiceDesc{ MethodName: "SetVariable", Handler: _ContextService_SetVariable_Handler, }, + { + MethodName: "SetVariables", + Handler: _ContextService_SetVariables_Handler, + }, + { + MethodName: "SetTaskResult", + Handler: _ContextService_SetTaskResult_Handler, + }, { MethodName: "GetVariableNames", Handler: _ContextService_GetVariableNames_Handler, diff --git a/src/main/java/tech/justen/concord/goodwill/service/GrpcContextService.java b/src/main/java/tech/justen/concord/goodwill/service/GrpcContextService.java index 253fe6b..b5d2ba7 100644 --- a/src/main/java/tech/justen/concord/goodwill/service/GrpcContextService.java +++ b/src/main/java/tech/justen/concord/goodwill/service/GrpcContextService.java @@ -10,18 +10,18 @@ import tech.justen.concord.goodwill.grpc.ContextProto.*; import tech.justen.concord.goodwill.grpc.ContextServiceGrpc; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class GrpcContextService extends ContextServiceGrpc.ContextServiceImplBase { private static final Logger log = LoggerFactory.getLogger(GrpcContextService.class); private final ContextService executionService; - public GrpcContextService(ContextService executionService) { + private final Map taskResultMap; + + public GrpcContextService(ContextService executionService, Map result) { this.executionService = executionService; + this.taskResultMap = result; } @Override @@ -50,6 +50,40 @@ public void setVariable(Variable request, StreamObserver resp } } + @Override + public void setVariables(Variables request, StreamObserver responseObserver) { + for (Variable var : request.getParametersList()) { + String name = var.getName(); + try { + Object obj = GrpcUtils.fromAny(var.getValue().getValue()); + this.executionService.setVariable(name, obj); + } catch (Exception ex) { + log.error(String.format("GrpcExecutionService: setVariables %s failed", name), ex); + responseObserver.onError(GrpcUtils.toStatusException(ex)); + return; + } + } + responseObserver.onNext(SetVariableResult.newBuilder().build()); + responseObserver.onCompleted(); + } + + @Override + public void setTaskResult(Variables request, StreamObserver responseObserver) { + for (Variable var : request.getParametersList()) { + String name = var.getName(); + try { + Object obj = GrpcUtils.fromAny(var.getValue().getValue()); + this.taskResultMap.put(name, obj); + } catch (Exception ex) { + log.error(String.format("GrpcExecutionService: setTaskResult %s failed", name), ex); + responseObserver.onError(GrpcUtils.toStatusException(ex)); + return; + } + } + responseObserver.onNext(SetVariableResult.newBuilder().build()); + responseObserver.onCompleted(); + } + @Override public void getVariableNames(GetVariableNameParams request, StreamObserver responseObserver) { try { diff --git a/src/main/java/tech/justen/concord/goodwill/task/TaskCommon.java b/src/main/java/tech/justen/concord/goodwill/task/TaskCommon.java index a605ed9..10a8a66 100644 --- a/src/main/java/tech/justen/concord/goodwill/task/TaskCommon.java +++ b/src/main/java/tech/justen/concord/goodwill/task/TaskCommon.java @@ -170,7 +170,7 @@ public String compileOnHost() throws java.lang.Exception { return out.toString(); } - public void execute() throws java.lang.Exception { + public Map execute() throws java.lang.Exception { Path workDir = config.workingDirectory(); File goodwillDir = new File(workDir.toString(), params.getBuildDirectory()); goodwillDir.mkdir(); @@ -199,6 +199,7 @@ public void execute() throws java.lang.Exception { File certFile = new File(goodwillDir, "client.crt"); File keyFile = new File(goodwillDir, "client.key"); ca.generatePKI(caFile, certFile, keyFile); + Map taskResult = new HashMap<>(); try { ApiClient apiClient = apiClientFactory.create(apiClientConfig); int port = 0; @@ -212,7 +213,7 @@ public void execute() throws java.lang.Exception { .useTransportSecurity(caCert, caKey) .addService(new GrpcDockerService(dockerService)) .addService(new GrpcConfigService(apiClientConfig, config)) - .addService(new GrpcContextService(contextService)) + .addService(new GrpcContextService(contextService, taskResult)) .addService(new GrpcSecretService(config, secretService, apiClient)) .addService(new GrpcLockService(lockService)) .build(); @@ -256,6 +257,7 @@ public void execute() throws java.lang.Exception { server.shutdown(); } } + return taskResult; } private int randomPort() { diff --git a/src/main/java/tech/justen/concord/goodwill/task/v1/Task.java b/src/main/java/tech/justen/concord/goodwill/task/v1/Task.java index b61bc51..ea0eadb 100644 --- a/src/main/java/tech/justen/concord/goodwill/task/v1/Task.java +++ b/src/main/java/tech/justen/concord/goodwill/task/v1/Task.java @@ -71,7 +71,10 @@ public void execute(Context ctx) throws java.lang.Exception { executor, config, apiClientFactory); - common.execute(); + Map result = common.execute(); + for (Map.Entry e : result.entrySet()) { + ctx.setVariable(e.getKey(), e.getValue()); + } } private String defaultString(Context ctx, String key) { diff --git a/src/main/java/tech/justen/concord/goodwill/task/v2/Task.java b/src/main/java/tech/justen/concord/goodwill/task/v2/Task.java index 7d35cbb..fd44178 100644 --- a/src/main/java/tech/justen/concord/goodwill/task/v2/Task.java +++ b/src/main/java/tech/justen/concord/goodwill/task/v2/Task.java @@ -13,6 +13,7 @@ import javax.inject.Inject; import javax.inject.Named; +import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -56,8 +57,8 @@ public TaskResult execute(Variables input) throws Exception { executor, config, apiClientFactory); - common.execute(); - return TaskResult.of(true); + Map result = common.execute(); + return TaskResult.of(true).values(result); } private String defaultString(Variables input, String key) { diff --git a/src/main/proto/context.proto b/src/main/proto/context.proto index 368ece6..a35ad03 100644 --- a/src/main/proto/context.proto +++ b/src/main/proto/context.proto @@ -14,6 +14,8 @@ package context; service ContextService { rpc GetVariable(VariableName) returns (Value) {} rpc SetVariable(Variable) returns (SetVariableResult) {} + rpc SetVariables(Variables) returns (SetVariableResult) {} + rpc SetTaskResult(Variables) returns (SetVariableResult) {} rpc GetVariableNames(GetVariableNameParams) returns (VariableNameList) {} rpc GetVariables(GetVariablesRequest) returns (MapValue) {} rpc Evaluate(EvaluateRequest) returns (Value) {} @@ -23,6 +25,10 @@ message GetVariablesRequest {} message SetVariableResult {} message GetVariableNameParams {} +message Variables { + repeated Variable parameters = 1; +} + message Value { google.protobuf.Any value = 1; } diff --git a/test/flow/goodwill.go b/test/flow/goodwill.go index fedb44e..4ca677b 100644 --- a/test/flow/goodwill.go +++ b/test/flow/goodwill.go @@ -18,9 +18,7 @@ import ( ) // Default is a flow that prints the working directory -func Default(ts *gw.Task) error { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute*2) - defer cancel() +func Default(ctx context.Context, ts *gw.Task) error { fmt.Println("====== Get Task Config") cfg, err := ts.Config().Configuration(ctx) if err != nil { @@ -32,38 +30,39 @@ func Default(ts *gw.Task) error { } // SetVariables gets and sets variables -func SetVariables(ts *gw.Task) error { - ctx, cancel := context.WithTimeout(context.Background(), time.Minute*2) - defer cancel() - var value value.Time +func SetVariables(ctx context.Context, ts *gw.Task) (map[string]value.Value, error) { + var t value.Time tc := ts.Context() fmt.Println("====== Evaluate Expression") - if err := tc.Evaluate(ctx, "${datetime.current()}", &value); err != nil { - return fmt.Errorf("evaluate expression failed: %w", err) + if err := tc.Evaluate(ctx, "${datetime.current()}", &t); err != nil { + return nil, fmt.Errorf("evaluate expression failed: %w", err) } - fmt.Printf("datetime.current: %v\n", value.Format(time.RFC3339Nano)) + fmt.Printf("datetime.current: %v\n", t.Format(time.RFC3339Nano)) fmt.Println("====== Set/Get Variables") - fmt.Println("Set timeStamp:", value) - if err := tc.SetVariable(ctx, "timeStamp", value); err != nil { - return fmt.Errorf("set timeStamp var failed: %w", err) + fmt.Println("Set timeStamp:", t) + if err := tc.SetVariable(ctx, "timeStamp", t); err != nil { + return nil, fmt.Errorf("set timeStamp var failed: %w", err) } fmt.Println("Get timeStamp") - if err := tc.GetVariable(ctx, "timeStamp", &value); err != nil { - return fmt.Errorf("get timeStamp var failed: %w", err) + if err := tc.GetVariable(ctx, "timeStamp", &t); err != nil { + return nil, fmt.Errorf("get timeStamp var failed: %w", err) } - fmt.Printf("timeStamp: %v\n", value.Format(time.RFC3339Nano)) + fmt.Printf("timeStamp: %v\n", t.Format(time.RFC3339Nano)) fmt.Println("====== Dump Variables") vars, err := tc.GetVariables(ctx) if err != nil { - return fmt.Errorf("ger variables failed: %w", err) + return nil, fmt.Errorf("ger variables failed: %w", err) } fmt.Println("Variables:") for k, v := range vars { fmt.Println(k, "=", v) } - return nil + return map[string]value.Value{ + "foo": value.String("bar"), + "baz": value.Int64(1000), + }, nil } // Crypto does crypto operations on secrets