Skip to content

Commit

Permalink
Merge branch 'dev' into feature/WEOS-1342
Browse files Browse the repository at this point in the history
# Conflicts:
#	controllers/rest/middleware_context_test.go
  • Loading branch information
shaniah868 committed Mar 8, 2022
2 parents dd0b206 + 03c17df commit 0d6ff00
Show file tree
Hide file tree
Showing 13 changed files with 442 additions and 159 deletions.
25 changes: 8 additions & 17 deletions api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ x-weos-config:
- RequestID
- Recover
- ZapLogger
- LogLevel
components:
schemas:
Category:
Expand Down Expand Up @@ -206,6 +207,10 @@ paths:
post:
operationId: Add Blog
summary: Create Blog
x-middleware:
- Recover
- ZapLogger
- LogLevel
requestBody:
description: Blog info that is submitted
required: true
Expand Down Expand Up @@ -258,24 +263,10 @@ paths:
required: false
description: query string
x-context:
filters:
- field: status
_filters:
- field: active
operator: eq
values:
- Active
- field: lastUpdated
operator: between
values:
- 2021-12-17 15:46:00
- 2021-12-18 15:46:00
- field: categories
operator: in
values:
- Technology
- Javascript
sorts:
- field: title
order: asc
value: true
page: 1
limit: 10
responses:
Expand Down
2 changes: 2 additions & 0 deletions controllers/rest/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ func (p *RESTAPI) Initialize(ctxt context.Context) error {
//register standard global initializers
p.RegisterGlobalInitializer(Security)
p.RegisterMiddleware("DefaultResponseMiddleware", DefaultResponseMiddleware)
p.RegisterMiddleware("LogLevel", LogLevel)
p.RegisterMiddleware("ZapLogger", ZapLogger)
//register standard operation initializers
p.RegisterOperationInitializer(ContextInitializer)
p.RegisterOperationInitializer(EntityFactoryInitializer)
Expand Down
88 changes: 75 additions & 13 deletions controllers/rest/controller_standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"errors"
"fmt"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/labstack/gommon/log"
logs "github.com/wepala/weos/log"
"net/http"
"strconv"
"strings"
Expand All @@ -31,7 +33,7 @@ func CreateMiddleware(api *RESTAPI, projection projections.Projection, commandDi
newContext = context.WithValue(newContext, weoscontext.ENTITY_FACTORY, entityFactory)
} else {
err := errors.New("entity factory must be set")
api.EchoInstance().Logger.Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
ctxt.Logger().Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
return err
}
payload := weoscontext.GetPayload(newContext)
Expand All @@ -49,7 +51,7 @@ func CreateMiddleware(api *RESTAPI, projection projections.Projection, commandDi
weosID = ksuid.New().String()
}

err := commandDispatcher.Dispatch(newContext, model.Create(newContext, payload, entityFactory.Name(), weosID), eventSource, projection, api.EchoInstance().Logger)
err := commandDispatcher.Dispatch(newContext, model.Create(newContext, payload, entityFactory.Name(), weosID), eventSource, projection, ctxt.Logger())
if err != nil {
if errr, ok := err.(*model.DomainError); ok {
return NewControllerError(errr.Error(), err, http.StatusBadRequest)
Expand Down Expand Up @@ -100,12 +102,12 @@ func CreateBatchMiddleware(api *RESTAPI, projection projections.Projection, comm
newContext = context.WithValue(newContext, weoscontext.ENTITY_FACTORY, entityFactory)
} else {
err := errors.New("entity factory must be set")
api.EchoInstance().Logger.Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
ctxt.Logger().Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
return err
}
payload := weoscontext.GetPayload(newContext)

err := commandDispatcher.Dispatch(newContext, model.CreateBatch(newContext, payload, entityFactory.Name()), eventSource, projection, api.EchoInstance().Logger)
err := commandDispatcher.Dispatch(newContext, model.CreateBatch(newContext, payload, entityFactory.Name()), eventSource, projection, ctxt.Logger())
if err != nil {
if errr, ok := err.(*model.DomainError); ok {
return NewControllerError(errr.Error(), err, http.StatusBadRequest)
Expand Down Expand Up @@ -135,7 +137,7 @@ func UpdateMiddleware(api *RESTAPI, projection projections.Projection, commandDi
newContext = context.WithValue(newContext, weoscontext.ENTITY_FACTORY, entityFactory)
} else {
err := errors.New("entity factory must be set")
api.EchoInstance().Logger.Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
ctxt.Logger().Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
return err
}
var weosID string
Expand All @@ -160,9 +162,9 @@ func UpdateMiddleware(api *RESTAPI, projection projections.Projection, commandDi
}
}

err = commandDispatcher.Dispatch(newContext, model.Update(newContext, payload, entityFactory.Name()), eventSource, projection, api.EchoInstance().Logger)
err = commandDispatcher.Dispatch(newContext, model.Update(newContext, payload, entityFactory.Name()), eventSource, projection, ctxt.Logger())
if err != nil {
api.e.Logger.Errorf("error persisting entity '%s'", err)
ctxt.Logger().Errorf("error persisting entity '%s'", err)
if errr, ok := err.(*model.DomainError); ok {
if strings.Contains(errr.Error(), "error updating entity. This is a stale item") {
return NewControllerError(errr.Error(), err, http.StatusPreconditionFailed)
Expand Down Expand Up @@ -302,7 +304,7 @@ func ViewMiddleware(api *RESTAPI, projection projections.Projection, commandDisp
return func(ctxt echo.Context) error {
if entityFactory == nil {
err := errors.New("entity factory must be set")
api.EchoInstance().Logger.Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
ctxt.Logger().Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
return err
}
pks, _ := json.Marshal(entityFactory.Schema().Extensions[IdentifierExtension])
Expand Down Expand Up @@ -435,7 +437,7 @@ func ViewController(api *RESTAPI, projection projections.Projection, commandDisp
}
if entityFactory == nil {
err = errors.New("entity factory must be set")
api.EchoInstance().Logger.Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
ctxt.Logger().Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
return err
}

Expand Down Expand Up @@ -474,7 +476,7 @@ func ListMiddleware(api *RESTAPI, projection projections.Projection, commandDisp
newContext := ctxt.Request().Context()
if entityFactory == nil {
err := errors.New("entity factory must be set")
api.EchoInstance().Logger.Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
ctxt.Logger().Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
return NewControllerError(err.Error(), nil, http.StatusBadRequest)
}
//gets the filter, limit and page from context
Expand Down Expand Up @@ -556,7 +558,7 @@ func DeleteMiddleware(api *RESTAPI, projection projections.Projection, commandDi
newContext = context.WithValue(newContext, weoscontext.ENTITY_FACTORY, entityFactory)
} else {
err := errors.New("entity factory must be set")
api.EchoInstance().Logger.Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
ctxt.Logger().Errorf("no entity factory detected for '%s'", ctxt.Request().RequestURI)
return err
}
//getting etag from context
Expand Down Expand Up @@ -616,7 +618,7 @@ func DeleteMiddleware(api *RESTAPI, projection projections.Projection, commandDi
}

//Dispatch the actual delete to projecitons
err = commandDispatcher.Dispatch(newContext, model.Delete(newContext, entityFactory.Name(), weosID), eventSource, projection, api.EchoInstance().Logger)
err = commandDispatcher.Dispatch(newContext, model.Delete(newContext, entityFactory.Name(), weosID), eventSource, projection, ctxt.Logger())
if err != nil {
if errr, ok := err.(*model.DomainError); ok {
if strings.Contains(errr.Error(), "error deleting entity. This is a stale item") {
Expand Down Expand Up @@ -757,7 +759,7 @@ func DefaultResponseController(api *RESTAPI, projection projections.Projection,
newContext := context.Request().Context()
value := newContext.Value("resp")
if value == nil {
return NewControllerError("unexpected error all responses were parsed, nothing was found", nil, http.StatusBadRequest)
return nil
}
return value.(error)
}
Expand Down Expand Up @@ -869,3 +871,63 @@ func OpenIDMiddleware(api *RESTAPI, projection projections.Projection, commandDi
}
}
}

func LogLevel(api *RESTAPI, projection projections.Projection, commandDispatcher model.CommandDispatcher, eventSource model.EventRepository, entityFactory model.EntityFactory, path *openapi3.PathItem, operation *openapi3.Operation) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
newContext := c.Request().Context()
req := c.Request()
res := c.Response()
level := req.Header.Get(weoscontext.HeaderXLogLevel)
if level == "" {
level = "error"
}

res.Header().Set(weoscontext.HeaderXLogLevel, level)

//Set the log.level in context based on what is passed into the header
switch level {
case "debug":
c.Logger().SetLevel(log.DEBUG)
case "info":
c.Logger().SetLevel(log.INFO)
case "warn":
c.Logger().SetLevel(log.WARN)
case "error":
c.Logger().SetLevel(log.ERROR)
}

//Sets the logger on the application object
if api.Config == nil {
api.Config = &APIConfig{}
}

if api.Config.Log == nil {
api.Config.Log = &model.LogConfig{}
}

api.Config.Log.Level = level

//Assigns the log level to context
newContext = context.WithValue(newContext, weoscontext.HeaderXLogLevel, level)
request := c.Request().WithContext(newContext)
c.SetRequest(request)
return next(c)
}
}
}

//ZapLogger switch to using ZapLogger
func ZapLogger(api *RESTAPI, projection projections.Projection, commandDispatcher model.CommandDispatcher, eventSource model.EventRepository, entityFactory model.EntityFactory, path *openapi3.PathItem, operation *openapi3.Operation) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
//setting the default logger in the context as zap with the default mode being error
zapLogger, err := logs.NewZap("error")
if err != nil {
c.Logger().Errorf("Unexpected error setting the context logger : %s", err)
}
c.SetLogger(zapLogger)
return next(c)
}
}
}
12 changes: 12 additions & 0 deletions controllers/rest/controller_standard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ func TestStandardControllers_CreateBatch(t *testing.T) {
NameFunc: func() string {
return "Blog"
},
SchemaFunc: func() *openapi3.Schema {
return swagger.Components.Schemas["Blog"].Value
},
}

t.Run("basic batch create based on simple content type", func(t *testing.T) {
Expand Down Expand Up @@ -1392,6 +1395,9 @@ func TestStandardControllers_FormUrlEncoded_Create(t *testing.T) {
NameFunc: func() string {
return "Blog"
},
SchemaFunc: func() *openapi3.Schema {
return swagger.Components.Schemas["Blog"].Value
},
}
eventRepository := &EventRepositoryMock{}

Expand Down Expand Up @@ -1551,6 +1557,9 @@ func TestStandardControllers_FormData_Create(t *testing.T) {
NameFunc: func() string {
return "Blog"
},
SchemaFunc: func() *openapi3.Schema {
return swagger.Components.Schemas["Blog"].Value
},
}

t.Run("basic create based on multipart/form-data content type", func(t *testing.T) {
Expand Down Expand Up @@ -1717,6 +1726,9 @@ func TestStandardControllers_DeleteEtag(t *testing.T) {
NameFunc: func() string {
return "Blog"
},
SchemaFunc: func() *openapi3.Schema {
return swagger.Components.Schemas["Blog"].Value
},
}
resp := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodDelete, "/blogs/"+weosId, nil)
Expand Down
8 changes: 5 additions & 3 deletions controllers/rest/fixtures/blog.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,10 @@ paths:
required: false
description: query string
x-context:
filters:
_filters:
- field: status
operator: eq
values:
value:
- Active
- field: lastUpdated
operator: between
Expand All @@ -289,7 +289,7 @@ paths:
values:
- Technology
- Javascript
sorts:
_sorts:
- field: title
order: asc
page: 1
Expand Down Expand Up @@ -355,6 +355,8 @@ paths:
schema:
type: number
format: double
x-context:
id: 2
summary: Get Blog by id
operationId: Get Blog
responses:
Expand Down
Loading

0 comments on commit 0d6ff00

Please sign in to comment.