Added registry, updated handlers
Updated modules Added function definition endpoint
This commit is contained in:
@@ -173,3 +173,16 @@ func (s *apigw) Init(ctx context.Context, route ...*route) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *apigw) Funcs(kind string) (list functionMetaList) {
|
||||
list = s.reg.All()
|
||||
|
||||
if kind != "" {
|
||||
list, _ = list.Filter(func(fm *functionMeta) (bool, error) {
|
||||
// return fm.
|
||||
return fm.Kind == kind, nil
|
||||
})
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,51 +2,56 @@ package apigw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/cortezaproject/corteza-server/pkg/wfexec"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
type (
|
||||
redirectExpediterArgs struct {
|
||||
Location string
|
||||
expediterRedirection struct{}
|
||||
|
||||
errorHandler struct {
|
||||
name string
|
||||
args []string
|
||||
weight int
|
||||
step int
|
||||
}
|
||||
)
|
||||
|
||||
func redirectExpediter(c context.Context, params *expr.Vars) wfHandler {
|
||||
var (
|
||||
clv = redirectExpediterArgs{}
|
||||
)
|
||||
|
||||
return func(c context.Context, er *wfexec.ExecRequest) (r wfexec.ExecResponse, err error) {
|
||||
params.Decode(&clv)
|
||||
spew.Dump("redirect expediter fn()", clv)
|
||||
e := er.Scope.GetValue()["envelope"]
|
||||
ee := e.Get().(envelope)
|
||||
|
||||
http.Redirect(ee.Writer, ee.Request, clv.Location, http.StatusTemporaryRedirect)
|
||||
|
||||
r = &expr.Vars{}
|
||||
return
|
||||
func (h expediterRedirection) Meta(f *types.Function) functionMeta {
|
||||
return functionMeta{
|
||||
Step: 3,
|
||||
Name: "expediterRedirection",
|
||||
Label: "Redirection expediter",
|
||||
Kind: "expediter",
|
||||
Weight: int(f.Weight),
|
||||
Params: f.Params,
|
||||
}
|
||||
}
|
||||
|
||||
func expediterErrorFn(c context.Context, er *wfexec.ExecRequest) (r wfexec.ExecResponse, err error) {
|
||||
// spew.Dump("expediter error fn()", er)
|
||||
func (h expediterRedirection) Handler() handlerFunc {
|
||||
return func(ctx context.Context, scope *scp, params map[string]interface{}, ff functionHandler) error {
|
||||
scope.writer.Header().Add(fmt.Sprintf("step_%d", ff.step), ff.name)
|
||||
http.Redirect(scope.writer, scope.req, params["location"].(string), http.StatusFound)
|
||||
|
||||
e := er.Scope.GetValue()["error"]
|
||||
values := er.Scope.GetValue()["writer"]
|
||||
|
||||
writer := values.Get()
|
||||
eValue := e.Get()
|
||||
|
||||
fmt.Fprintf(writer.(*httptest.ResponseRecorder), fmt.Sprintf(`{"msg": "%s"}`, eValue))
|
||||
writer.(*httptest.ResponseRecorder).Code = http.StatusBadGateway
|
||||
|
||||
r = &expr.Vars{}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (pp errorHandler) Exec(ctx context.Context, scope *scp, err error) {
|
||||
type (
|
||||
responseHelper struct {
|
||||
Msg string `json:"msg"`
|
||||
}
|
||||
)
|
||||
|
||||
resp := responseHelper{
|
||||
Msg: err.Error(),
|
||||
}
|
||||
spew.Dump("ERR in expediter", err, resp)
|
||||
|
||||
json.NewEncoder(scope.writer).Encode(resp)
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
)
|
||||
|
||||
type (
|
||||
functionMetaList []*functionMeta
|
||||
|
||||
Handler interface {
|
||||
Handler() handlerFunc
|
||||
Meta(f *types.Function) functionMeta
|
||||
@@ -15,12 +17,20 @@ type (
|
||||
handlerFunc func(context.Context, *scp, map[string]interface{}, functionHandler) error
|
||||
|
||||
functionMeta struct {
|
||||
step int
|
||||
weight int
|
||||
name string
|
||||
label string
|
||||
kind string
|
||||
params map[string]interface{}
|
||||
Step int `json:"step"`
|
||||
Weight int `json:"-"`
|
||||
Name string `json:"name"`
|
||||
Label string `json:"label"`
|
||||
Kind string `json:"kind"`
|
||||
Params map[string]interface{} `json:"-"`
|
||||
Args []*functionMetaArg `json:"params,omitempty"`
|
||||
}
|
||||
|
||||
functionMetaArg struct {
|
||||
Label string `json:"label"`
|
||||
Type string `json:"type"`
|
||||
Example string `json:"example"`
|
||||
Options map[string]interface{} `json:"options"`
|
||||
}
|
||||
|
||||
functionHandler struct {
|
||||
@@ -43,12 +53,12 @@ func (ff *functionHandler) SetHandler(h handlerFunc) {
|
||||
}
|
||||
|
||||
func (ff *functionHandler) Merge(ctx context.Context, p functionMeta) {
|
||||
ff.step = p.step
|
||||
ff.kind = p.kind
|
||||
ff.label = p.label
|
||||
ff.name = p.name
|
||||
ff.weight = p.weight
|
||||
ff.params = p.params
|
||||
ff.step = p.Step
|
||||
ff.kind = p.Kind
|
||||
ff.label = p.Label
|
||||
ff.name = p.Name
|
||||
ff.weight = p.Weight
|
||||
ff.params = p.Params
|
||||
}
|
||||
|
||||
func (ff functionHandler) Weight() int {
|
||||
@@ -56,3 +66,17 @@ func (ff functionHandler) Weight() int {
|
||||
// per step, we're doing something wrong
|
||||
return ff.step*1000 + ff.weight
|
||||
}
|
||||
|
||||
func (fm functionMetaList) Filter(f func(*functionMeta) (bool, error)) (out functionMetaList, err error) {
|
||||
var ok bool
|
||||
out = functionMetaList{}
|
||||
for i := range fm {
|
||||
if ok, err = f(fm[i]); err != nil {
|
||||
return
|
||||
} else if ok {
|
||||
out = append(out, fm[i])
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package apigw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/cortezaproject/corteza-server/pkg/wfexec"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
type (
|
||||
authenticationOriginMatcherArgs struct {
|
||||
Origin string
|
||||
}
|
||||
)
|
||||
|
||||
func authenticationOriginMatcher(c context.Context, params *expr.Vars) wfHandler {
|
||||
var (
|
||||
aomp = authenticationOriginMatcherArgs{}
|
||||
)
|
||||
|
||||
return func(c context.Context, er *wfexec.ExecRequest) (r wfexec.ExecResponse, err error) {
|
||||
|
||||
params.Decode(&aomp)
|
||||
spew.Dump("authentication origin matcher fn()", aomp)
|
||||
e := er.Scope.GetValue()["envelope"]
|
||||
ee := e.Get().(envelope)
|
||||
|
||||
origin := ee.Request.Header.Get("Origin")
|
||||
|
||||
spew.Dump("input, real", aomp.Origin, origin)
|
||||
|
||||
if aomp.Origin != origin {
|
||||
err = errors.New("origin fail")
|
||||
return
|
||||
}
|
||||
|
||||
r = &expr.Vars{}
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -3,53 +3,88 @@ package apigw
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/cortezaproject/corteza-server/pkg/wfexec"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/cortezaproject/corteza-server/pkg/eventbus"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
)
|
||||
|
||||
func formDataProcesserFn(c context.Context, er *wfexec.ExecRequest) (r wfexec.ExecResponse, err error) {
|
||||
type (
|
||||
formDataProcesserResponse struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
)
|
||||
type (
|
||||
dispatcher interface {
|
||||
Dispatch(ctx context.Context, ev eventbus.Event)
|
||||
}
|
||||
|
||||
spew.Dump("step processer fn()")
|
||||
processerWorkflow struct {
|
||||
d dispatcher
|
||||
}
|
||||
)
|
||||
|
||||
e := er.Scope.GetValue()["envelope"]
|
||||
ee := e.Get()
|
||||
|
||||
// ee.(envelope).Writer.WriteHeader(int(id))
|
||||
ee.(envelope).Writer.Write([]byte(`{"test":"foobar"}`))
|
||||
|
||||
e.Assign(ee)
|
||||
|
||||
// req := values.Get()
|
||||
// ww := wr.Get()
|
||||
// writer := ww.(http.ResponseWriter)
|
||||
|
||||
// formValue := req.(*http.Request).PostFormValue("name")
|
||||
|
||||
// resp := formDataProcesserResponse{
|
||||
// // Name: fmt.Sprintf("AA %s AA", formValue),
|
||||
// Name: "formValue",
|
||||
// }
|
||||
|
||||
// encoder := json.NewEncoder(writer)
|
||||
// encoder.Encode(resp)
|
||||
|
||||
// writer.(*httptest.ResponseRecorder).Header()["Content-Type"] = []string{"application/json"}
|
||||
// writer.Header().Set("Content-Type", "application/json3")
|
||||
|
||||
// spew.Dump(writer.(*httptest.ResponseRecorder).Header())
|
||||
// a, b := expr.NewKV(writer)
|
||||
// spew.Dump("Aaaaaaaaaaa", a)
|
||||
|
||||
vv := &expr.Vars{}
|
||||
// vv.Set("writer", writer)
|
||||
|
||||
r = vv
|
||||
|
||||
return
|
||||
func (h processerWorkflow) Meta(f *types.Function) functionMeta {
|
||||
return functionMeta{
|
||||
Step: 2,
|
||||
Name: "processerWorkflow",
|
||||
Label: "Workflow processer",
|
||||
Kind: "processer",
|
||||
Weight: int(f.Weight),
|
||||
Params: f.Params,
|
||||
Args: []*functionMetaArg{
|
||||
{
|
||||
Type: "workflow",
|
||||
Label: "workflow",
|
||||
Options: map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (h processerWorkflow) Handler() handlerFunc {
|
||||
return func(ctx context.Context, scope *scp, params map[string]interface{}, ff functionHandler) error {
|
||||
// h.d.Dispatch(c, event.ApiOnProcess(&envlp))
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// func formDataProcesserFn(c context.Context, er *wfexec.ExecRequest) (r wfexec.ExecResponse, err error) {
|
||||
// type (
|
||||
// formDataProcesserResponse struct {
|
||||
// Name string `json:"name"`
|
||||
// }
|
||||
// )
|
||||
|
||||
// spew.Dump("step processer fn()")
|
||||
|
||||
// e := er.Scope.GetValue()["envelope"]
|
||||
// ee := e.Get()
|
||||
|
||||
// // ee.(envelope).Writer.WriteHeader(int(id))
|
||||
// ee.(envelope).Writer.Write([]byte(`{"test":"foobar"}`))
|
||||
|
||||
// e.Assign(ee)
|
||||
|
||||
// // req := values.Get()
|
||||
// // ww := wr.Get()
|
||||
// // writer := ww.(http.ResponseWriter)
|
||||
|
||||
// // formValue := req.(*http.Request).PostFormValue("name")
|
||||
|
||||
// // resp := formDataProcesserResponse{
|
||||
// // // Name: fmt.Sprintf("AA %s AA", formValue),
|
||||
// // Name: "formValue",
|
||||
// // }
|
||||
|
||||
// // encoder := json.NewEncoder(writer)
|
||||
// // encoder.Encode(resp)
|
||||
|
||||
// // writer.(*httptest.ResponseRecorder).Header()["Content-Type"] = []string{"application/json"}
|
||||
// // writer.Header().Set("Content-Type", "application/json3")
|
||||
|
||||
// // spew.Dump(writer.(*httptest.ResponseRecorder).Header())
|
||||
// // a, b := expr.NewKV(writer)
|
||||
// // spew.Dump("Aaaaaaaaaaa", a)
|
||||
|
||||
// vv := &expr.Vars{}
|
||||
// // vv.Set("writer", writer)
|
||||
|
||||
// r = vv
|
||||
|
||||
// return
|
||||
// }
|
||||
|
||||
52
pkg/apigw/registry.go
Normal file
52
pkg/apigw/registry.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package apigw
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
)
|
||||
|
||||
type (
|
||||
registry struct {
|
||||
h map[string]Handler
|
||||
}
|
||||
)
|
||||
|
||||
func NewRegistry() *registry {
|
||||
return ®istry{
|
||||
h: map[string]Handler{},
|
||||
}
|
||||
}
|
||||
|
||||
func (r *registry) Add(n string, h Handler) {
|
||||
r.h[n] = h
|
||||
}
|
||||
|
||||
func (r *registry) Get(identifier string) (Handler, error) {
|
||||
var (
|
||||
ok bool
|
||||
f Handler
|
||||
)
|
||||
|
||||
if f, ok = r.h[identifier]; !ok {
|
||||
return nil, fmt.Errorf("could not get element from registry: %s", identifier)
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func (r *registry) All() (list functionMetaList) {
|
||||
for _, handler := range r.h {
|
||||
m := handler.Meta(&types.Function{})
|
||||
list = append(list, &m)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r *registry) Preload() {
|
||||
r.Add("verifierQueryParam", verifierQueryParam{})
|
||||
r.Add("verifierOrigin", verifierOrigin{})
|
||||
r.Add("expediterRedirection", expediterRedirection{})
|
||||
r.Add("processerWorkflow", processerWorkflow{})
|
||||
}
|
||||
@@ -3,62 +3,30 @@ package apigw
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/cortezaproject/corteza-server/pkg/logger"
|
||||
"github.com/cortezaproject/corteza-server/pkg/wfexec"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
type (
|
||||
route struct {
|
||||
ID uint64
|
||||
endpoint string
|
||||
method string
|
||||
graph *wfexec.Graph
|
||||
steps []wfexec.Step
|
||||
fns wfHandlerList
|
||||
|
||||
pipe *pl
|
||||
}
|
||||
)
|
||||
|
||||
func (r route) validate(req *http.Request) (err error) {
|
||||
// if req.Method != r.method {
|
||||
// err = errors.New("http method invalid")
|
||||
// }
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (r route) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
||||
if err := r.validate(req); err != nil {
|
||||
spew.Dump("ERR", err)
|
||||
return
|
||||
}
|
||||
var (
|
||||
ctx = context.Background()
|
||||
scope = scp{
|
||||
req: req,
|
||||
writer: w,
|
||||
}
|
||||
)
|
||||
|
||||
sess := wfexec.NewSession(context.Background(), r.graph, wfexec.SetLogger(logger.Default()), wfexec.SetHandler(func(ss wfexec.SessionStatus, s1 *wfexec.State, s2 *wfexec.Session) {
|
||||
// spew.Dump("event handler here!", ss)
|
||||
}))
|
||||
|
||||
scope := &expr.Vars{}
|
||||
|
||||
scope.Set("envelope", envelope{
|
||||
Request: req,
|
||||
Writer: w,
|
||||
})
|
||||
|
||||
if len(r.steps) == 0 {
|
||||
// dont serve, do what? return default response?
|
||||
return
|
||||
}
|
||||
|
||||
err := sess.Exec(context.Background(), r.steps[0], scope)
|
||||
|
||||
// if err != nil {
|
||||
// fmt.Fprintf(w, "no go, err on exec: %s", err)
|
||||
// return
|
||||
// }
|
||||
|
||||
err = sess.Wait(context.Background())
|
||||
err := r.pipe.Exec(ctx, &scope)
|
||||
|
||||
if err != nil {
|
||||
// log error
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
package apigw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/cortezaproject/corteza-server/pkg/wfexec"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
type (
|
||||
contentLengthValidatorArgs struct {
|
||||
Length int
|
||||
}
|
||||
)
|
||||
|
||||
func contentLengthValidator(c context.Context, params *expr.Vars) wfHandler {
|
||||
var (
|
||||
clv = contentLengthValidatorArgs{}
|
||||
)
|
||||
|
||||
return func(c context.Context, er *wfexec.ExecRequest) (r wfexec.ExecResponse, err error) {
|
||||
|
||||
params.Decode(&clv)
|
||||
spew.Dump("body size validator fn()", clv)
|
||||
e := er.Scope.GetValue()["envelope"]
|
||||
ee := e.Get().(envelope)
|
||||
|
||||
cl := ee.Request.ContentLength
|
||||
|
||||
if clv.Length < int(cl) {
|
||||
err = errors.New("content length overriden")
|
||||
return
|
||||
}
|
||||
|
||||
r = &expr.Vars{}
|
||||
return
|
||||
}
|
||||
}
|
||||
157
pkg/apigw/verifier.go
Normal file
157
pkg/apigw/verifier.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package apigw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/expr"
|
||||
"github.com/cortezaproject/corteza-server/system/types"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
type (
|
||||
verifierQueryParam struct{}
|
||||
verifierOrigin struct{}
|
||||
)
|
||||
|
||||
func (h verifierQueryParam) Meta(f *types.Function) functionMeta {
|
||||
return functionMeta{
|
||||
Step: 0,
|
||||
Name: "verifierQueryParam",
|
||||
Label: "Query parameters verifier",
|
||||
Kind: "verifier",
|
||||
Weight: int(f.Weight),
|
||||
Params: f.Params,
|
||||
Args: []*functionMetaArg{
|
||||
{
|
||||
Type: "expr",
|
||||
Label: "expr",
|
||||
Options: map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (h verifierOrigin) Meta(f *types.Function) functionMeta {
|
||||
return functionMeta{
|
||||
Step: 0,
|
||||
Name: "verifierOrigin",
|
||||
Label: "Origin verifier",
|
||||
Kind: "verifier",
|
||||
Weight: int(f.Weight),
|
||||
Params: f.Params,
|
||||
Args: []*functionMetaArg{
|
||||
{
|
||||
Type: "expr",
|
||||
Label: "expr",
|
||||
Options: map[string]interface{}{},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (h verifierQueryParam) Handler() handlerFunc {
|
||||
return func(ctx context.Context, scope *scp, params map[string]interface{}, ff functionHandler) error {
|
||||
for k := range ff.params {
|
||||
|
||||
v, ok := params[k]
|
||||
|
||||
if !ok {
|
||||
spew.Dump("not in params", k)
|
||||
continue
|
||||
}
|
||||
|
||||
vv := map[string]interface{}{}
|
||||
vals := scope.req.URL.Query()
|
||||
|
||||
for k, v := range vals {
|
||||
vv[k] = v[0]
|
||||
}
|
||||
|
||||
// get the request data and put it into vars
|
||||
out, err := expr.NewVars(vv)
|
||||
|
||||
if err != nil {
|
||||
// spew.Dump("ERR!", err)
|
||||
return err
|
||||
}
|
||||
|
||||
pp := expr.NewParser()
|
||||
tt, err := pp.Parse(v.(string))
|
||||
|
||||
if err != nil {
|
||||
// spew.Dump("ERR!", err)
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := tt.Test(ctx, out)
|
||||
|
||||
if err != nil {
|
||||
// spew.Dump("ERR!", err)
|
||||
return err
|
||||
}
|
||||
|
||||
spew.Dump("BBBB", b)
|
||||
|
||||
if !b {
|
||||
return fmt.Errorf("failed on step %d, function %s", ff.step, ff.name)
|
||||
}
|
||||
}
|
||||
|
||||
// testing
|
||||
scope.req.Header.Add(fmt.Sprintf("step_%d", ff.step), ff.name)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (h verifierOrigin) Handler() handlerFunc {
|
||||
return func(ctx context.Context, scope *scp, params map[string]interface{}, ff functionHandler) error {
|
||||
for k := range ff.params {
|
||||
v, ok := params[k]
|
||||
|
||||
if !ok {
|
||||
spew.Dump("not in params", k)
|
||||
continue
|
||||
}
|
||||
|
||||
vv := map[string]interface{}{
|
||||
"origin": scope.req.Header.Get("Origin"),
|
||||
}
|
||||
|
||||
// get the request data and put it into vars
|
||||
out, err := expr.NewVars(vv)
|
||||
|
||||
if err != nil {
|
||||
spew.Dump("ERR!", err)
|
||||
return err
|
||||
}
|
||||
|
||||
pp := expr.NewParser()
|
||||
tt, err := pp.Parse(v.(string))
|
||||
|
||||
if err != nil {
|
||||
spew.Dump("ERR!", err)
|
||||
return err
|
||||
}
|
||||
|
||||
b, err := tt.Test(ctx, out)
|
||||
|
||||
if err != nil {
|
||||
spew.Dump("ERR!", err)
|
||||
return err
|
||||
}
|
||||
|
||||
spew.Dump("BBBB", b)
|
||||
|
||||
if !b {
|
||||
return fmt.Errorf("failed on step %d, function %s", ff.step, ff.name)
|
||||
}
|
||||
}
|
||||
|
||||
// testing
|
||||
scope.req.Header.Add(fmt.Sprintf("step_%d", ff.step), ff.name)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user