Skip to content

Commit

Permalink
Refactored pipelines, errors
Browse files Browse the repository at this point in the history
  • Loading branch information
petergrlica committed Aug 26, 2021
1 parent 1bf4cbb commit 34aaad7
Show file tree
Hide file tree
Showing 28 changed files with 913 additions and 918 deletions.
4 changes: 2 additions & 2 deletions app/servers.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ func (app *CortezaApp) mountHttpRoutes(r chi.Router) {
r.Route("/federation", federationRest.MountRoutes)
}

// temp api gateway support
// API Gateway
{
apigw.Setup(options.Apigw(), service.DefaultLogger, service.DefaultStore)
r.Route("/gateway", apigw.Service().Router)
r.Route("/", apigw.Service().Router)
}

var fullpathDocs = options.CleanBase(ho.BaseUrl, ho.ApiBaseUrl, "docs")
Expand Down
19 changes: 19 additions & 0 deletions pkg/apigw/ctx/ctx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ctx

import (
"context"

"github.com/cortezaproject/corteza-server/pkg/apigw/types"
)

type ContextKey string

const ContextKeyScope ContextKey = "scope"

func ScopeToContext(ctx context.Context, s *types.Scp) context.Context {
return context.WithValue(ctx, ContextKeyScope, s)
}

func ScopeFromContext(ctx context.Context) *types.Scp {
return ctx.Value(ContextKeyScope).(*types.Scp)
}
26 changes: 26 additions & 0 deletions pkg/apigw/filter/filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package filter

import (
"github.com/cortezaproject/corteza-server/pkg/apigw/types"
)

const (
PreFilterWeight = iota
ProcesserWeight
PostFilterWeight
)

func FilterWeight(w int, t types.FilterKind) int {
mul := PreFilterWeight

switch t {
case types.PreFilter:
mul = PreFilterWeight
case types.Processer:
mul = ProcesserWeight
case types.PostFilter:
mul = PostFilterWeight
}

return mul*100 + w
}
96 changes: 28 additions & 68 deletions pkg/apigw/filter/postfilter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ package filter

import (
"bytes"
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"

"github.com/cortezaproject/corteza-server/pkg/apigw/types"
pe "github.com/cortezaproject/corteza-server/pkg/errors"
)

type (
redirection struct {
types.FilterMeta

location *url.URL
status int

params struct {
HTTPStatus int `json:"status,string"`
Location string `json:"location"`
Expand All @@ -32,11 +36,6 @@ type (
defaultJsonResponse struct {
types.FilterMeta
}

errorHandler struct {
name string
args []string
}
)

func NewRedirection() (e *redirection) {
Expand All @@ -63,11 +62,7 @@ func NewRedirection() (e *redirection) {
}

func (h redirection) String() string {
return fmt.Sprintf("apigw function %s (%s)", h.Name, h.Label)
}

func (h redirection) Type() types.FilterKind {
return h.Kind
return fmt.Sprintf("apigw filter %s (%s)", h.Name, h.Label)
}

func (h redirection) Meta() types.FilterMeta {
Expand All @@ -78,61 +73,30 @@ func (h redirection) Weight() int {
return h.Wgt
}

func (f *redirection) Merge(params []byte) (types.Handler, error) {
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&f.params)
return f, err
}
func (h *redirection) Merge(params []byte) (types.Handler, error) {
err := json.NewDecoder(bytes.NewBuffer(params)).Decode(&h.params)

func (h redirection) Exec(ctx context.Context, scope *types.Scp) error {
loc, err := url.ParseRequestURI(h.params.Location)

if err != nil {
return fmt.Errorf("could not redirect: %s", err)
return nil, fmt.Errorf("could not validate parameters, invalid URL: %s", err)
}

status := h.params.HTTPStatus

if !checkStatus("redirect", status) {
return fmt.Errorf("could not redirect: wrong status %d", status)
if !checkStatus("redirect", h.params.HTTPStatus) {
return nil, fmt.Errorf("could not validate parameters, wrong status %d", h.params.HTTPStatus)
}

http.Redirect(scope.Writer(), scope.Request(), loc.String(), status)

return nil
}
h.location = loc
h.status = h.params.HTTPStatus

func NewErrorHandler(name string, args []string) (e *errorHandler) {
e = &errorHandler{
name: name,
args: args,
}

return
return h, err
}

func (pp errorHandler) Exec(ctx context.Context, scope *types.Scp, err error) {
type (
responseHelper struct {
ErrResponse struct {
Msg string `json:"msg"`
} `json:"error"`
}
)

resp := responseHelper{
ErrResponse: struct {
Msg string "json:\"msg\""
}{
Msg: err.Error(),
},
func (h redirection) Handler() types.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) error {
http.Redirect(rw, r, h.location.String(), h.status)
return nil
}

// set http status code
scope.Writer().WriteHeader(http.StatusInternalServerError)

// set body
json.NewEncoder(scope.Writer()).Encode(resp)

}

func NewDefaultJsonResponse() (e *defaultJsonResponse) {
Expand All @@ -146,32 +110,28 @@ func NewDefaultJsonResponse() (e *defaultJsonResponse) {
}

func (h defaultJsonResponse) String() string {
return fmt.Sprintf("apigw function %s (%s)", h.Name, h.Label)
}

func (h defaultJsonResponse) Type() types.FilterKind {
return h.Kind
return fmt.Sprintf("apigw filter %s (%s)", h.Name, h.Label)
}

func (h defaultJsonResponse) Meta() types.FilterMeta {
return h.FilterMeta
}

func (h defaultJsonResponse) Weight() int {
return h.Wgt
}

func (f *defaultJsonResponse) Merge(params []byte) (h types.Handler, err error) {
return f, err
}

func (h defaultJsonResponse) Exec(ctx context.Context, scope *types.Scp) (err error) {
scope.Writer().Header().Set("Content-Type", "application/json")
scope.Writer().WriteHeader(http.StatusAccepted)
func (h defaultJsonResponse) Handler() types.HandlerFunc {
return func(rw http.ResponseWriter, r *http.Request) error {
rw.Header().Set("Content-Type", "application/json")
rw.WriteHeader(http.StatusAccepted)

_, err = scope.Writer().Write([]byte(`{}`))
if _, err := rw.Write([]byte(`{}`)); err != nil {
return pe.Internal("could not write to body: (%v)", err)
}

return
return nil
}
}

func checkStatus(typ string, status int) bool {
Expand Down
71 changes: 44 additions & 27 deletions pkg/apigw/filter/postfilter_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package filter

import (
"context"
"net/http"
"net/http/httptest"
"testing"
Expand All @@ -10,12 +9,35 @@ import (
"github.com/stretchr/testify/require"
)

func Tesst_redirection(t *testing.T) {
func Test_redirectionMerge(t *testing.T) {
var (
tcc = []tf{
{
name: "url validation",
expr: `{"status":"301", "location": "invalid url"}`,
err: `could not validate parameters, invalid URL: parse "invalid url": invalid URI for request`,
},
{
name: "invalid redirection status",
expr: `{"status":"400", "location": "http://redire.ct/to"}`,
err: "could not validate parameters, wrong status 400",
},
}
)

for _, tc := range tcc {
t.Run(tc.name, testMerge(NewRedirection(), tc))
}
}

func Test_redirection(t *testing.T) {
type (
tf struct {
name string
expr string
err string
loc string
code int
}
)

Expand All @@ -24,52 +46,47 @@ func Tesst_redirection(t *testing.T) {
{
name: "simple redirection",
expr: `{"status":"302", "location": "http://redire.ct/to"}`,
loc: "http://redire.ct/to",
code: 302,
},
{
name: "permanent redirection",
expr: `{"status":"301", "location": "http://redire.ct/to"}`,
},
{
name: "url validation",
expr: `{"status":"301", "location": "invalid url"}`,
err: `could not redirect: parse "invalid url": invalid URI for request`,
},
{
name: "invalid redirection status",
expr: `{"status":"400", "location": "http://redire.ct/to"}`,
err: "could not redirect: wrong status 400",
loc: "http://redire.ct/to",
code: 301,
},
}
)

for _, tc := range tcc {
var (
ctx = context.Background()
)

t.Run(tc.name, func(t *testing.T) {
req := require.New(t)
var (
req = require.New(t)
r = httptest.NewRequest(http.MethodGet, "/foo", http.NoBody)
rc = httptest.NewRecorder()
)

r, err := http.NewRequest(http.MethodGet, "/foo", http.NoBody)
h := getHandler(NewRedirection())
h, err := h.Merge([]byte(tc.expr))

req.NoError(err)

rc := httptest.NewRecorder()
scope := &types.Scp{"request": r, "writer": rc}

h := NewRedirection()
h.Merge([]byte(tc.expr))

err = h.Exec(ctx, scope)
hn := h.Handler()
err = hn(rc, r)

if tc.err != "" {
req.EqualError(err, tc.err)
return
}

req.NoError(err)
req.Equal(h.params.Location, rc.Header().Get("Location"))
req.Equal(h.params.HTTPStatus, rc.Code)
req.Equal(tc.loc, rc.Header().Get("Location"))
req.Equal(tc.code, rc.Code)
})
}
}

// hackity hack
func getHandler(h types.Handler) types.Handler {
return h
}
Loading

0 comments on commit 34aaad7

Please sign in to comment.