Skip to content

Commit

Permalink
Merge pull request #76 from wepala/feature/WEOS-1131
Browse files Browse the repository at this point in the history
Feature/weos 1131, Feature/weos-1178
  • Loading branch information
akeemphilbert authored Feb 8, 2022
2 parents d82e22b + 2fc010d commit 22bb238
Show file tree
Hide file tree
Showing 20 changed files with 2,281 additions and 247 deletions.
631 changes: 601 additions & 30 deletions api.yaml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions controllers/rest/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ func (p *RESTAPI) Initialize(ctxt context.Context) error {
p.RegisterController("UpdateController", UpdateController)
p.RegisterController("ListController", ListController)
p.RegisterController("ViewController", ViewController)
p.RegisterController("DeleteController", DeleteController)
p.RegisterController("HealthCheck", HealthCheck)
p.RegisterController("CreateBatchController", CreateBatchController)
//register standard middleware
Expand All @@ -269,6 +270,7 @@ func (p *RESTAPI) Initialize(ctxt context.Context) error {
p.RegisterMiddleware("UpdateMiddleware", UpdateMiddleware)
p.RegisterMiddleware("ListMiddleware", ListMiddleware)
p.RegisterMiddleware("ViewMiddleware", ViewMiddleware)
p.RegisterMiddleware("DeleteMiddleware", DeleteMiddleware)
p.RegisterMiddleware("Recover", Recover)
//register standard operation initializers
p.RegisterOperationInitializer(ContextInitializer)
Expand Down Expand Up @@ -336,6 +338,7 @@ func (p *RESTAPI) Initialize(ctxt context.Context) error {
defaultCommandDispatcher.AddSubscriber(model.Create(context.Background(), nil, "", ""), model.CreateHandler)
defaultCommandDispatcher.AddSubscriber(model.CreateBatch(context.Background(), nil, ""), model.CreateBatchHandler)
defaultCommandDispatcher.AddSubscriber(model.Update(context.Background(), nil, ""), model.UpdateHandler)
defaultCommandDispatcher.AddSubscriber(model.Delete(context.Background(), "", ""), model.DeleteHandler)
p.RegisterCommandDispatcher("Default", defaultCommandDispatcher)
}

Expand Down
123 changes: 120 additions & 3 deletions controllers/rest/controller_standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,10 +549,127 @@ func ListController(api *RESTAPI, projection projections.Projection, commandDisp
}
}

func Delete(api *RESTAPI, projection projections.Projection, commandDispatcher model.CommandDispatcher, eventSource model.EventRepository, entityFactory model.EntityFactory) echo.HandlerFunc {
return func(context echo.Context) error {
//DeleteMiddleware delete entity
func DeleteMiddleware(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(ctxt echo.Context) error {
//look up the schema for the content type so that we could identify the rules
newContext := ctxt.Request().Context()
var weosID string
var sequenceNo string

return nil
if entityFactory != nil {
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)
return err
}
//getting etag from context
etagInterface := newContext.Value("If-Match")
if etagInterface != nil {
if etag, ok := etagInterface.(string); ok {
if etag != "" {
weosID, sequenceNo = SplitEtag(etag)
seq, err := strconv.Atoi(sequenceNo)
if err != nil {
return NewControllerError("unexpected error deleting content type. invalid sequence number", err, http.StatusBadRequest)
}
newContext = context.WithValue(newContext, weoscontext.WEOS_ID, weosID)
newContext = context.WithValue(newContext, weoscontext.SEQUENCE_NO, seq)
}
}
}

var err error
var identifiers []string
var result1 map[string]interface{}
var ok bool

//Uses the identifiers to pull the weosID, to be later used to get Seq NO
if etagInterface == nil {
//find entity based on identifiers specified
pks, _ := json.Marshal(entityFactory.Schema().Extensions["x-identifier"])
json.Unmarshal(pks, &identifiers)

if len(identifiers) == 0 {
identifiers = append(identifiers, "id")
}

primaryKeys := map[string]interface{}{}
for _, p := range identifiers {

ctxtIdentifier := newContext.Value(p)

primaryKeys[p] = ctxtIdentifier

}

if projection != nil {
result1, err = projection.GetByKey(newContext, entityFactory, primaryKeys)
if err != nil {
return err
}

}
weosID, ok = result1["weos_id"].(string)

if (len(result1) == 0) || !ok || weosID == "" {
return NewControllerError("No entity found", err, http.StatusNotFound)
} else if err != nil {
return NewControllerError(err.Error(), err, http.StatusBadRequest)
}
}

//Dispatch the actual delete to projecitons
err = commandDispatcher.Dispatch(newContext, model.Delete(newContext, entityFactory.Name(), weosID), eventSource, projection, api.EchoInstance().Logger)
if err != nil {
if errr, ok := err.(*model.DomainError); ok {
if strings.Contains(errr.Error(), "error deleting entity. This is a stale item") {
return NewControllerError(errr.Error(), err, http.StatusPreconditionFailed)
}
if strings.Contains(errr.Error(), "invalid:") {
return NewControllerError(errr.Error(), err, http.StatusUnprocessableEntity)
}
return NewControllerError(errr.Error(), err, http.StatusBadRequest)
} else {
return NewControllerError("unexpected error deleting content type", err, http.StatusBadRequest)
}
}
//Add response to context for controller
newContext = context.WithValue(newContext, weoscontext.WEOS_ID, weosID)
request := ctxt.Request().WithContext(newContext)
ctxt.SetRequest(request)
return next(ctxt)
}
}
}

//DeleteController handle delete
func DeleteController(api *RESTAPI, projection projections.Projection, commandDispatcher model.CommandDispatcher, eventSource model.EventRepository, entityFactory model.EntityFactory) echo.HandlerFunc {
return func(ctxt echo.Context) error {
newContext := ctxt.Request().Context()
if weosIDRaw := newContext.Value(weoscontext.WEOS_ID); weosIDRaw != nil {
if weosID, ok := weosIDRaw.(string); ok {
deleteEventSeq, err := eventSource.GetAggregateSequenceNumber(weosID)
if err != nil {
return NewControllerError("No delete event found", err, http.StatusNotFound)
}

etag := NewEtag(&model.ContentEntity{
AggregateRoot: model.AggregateRoot{
SequenceNo: deleteEventSeq,
BasicEntity: model.BasicEntity{ID: weosID},
},
})

ctxt.Response().Header().Set("Etag", etag)

return ctxt.JSON(http.StatusOK, "Deleted")
}
}

return ctxt.String(http.StatusBadRequest, "Item not deleted")
}
}

Expand Down
Loading

0 comments on commit 22bb238

Please sign in to comment.