Skip to content

Commit

Permalink
Introduce service layer for workflow #2
Browse files Browse the repository at this point in the history
  • Loading branch information
alexblockfactory committed Feb 18, 2020
1 parent ba21a36 commit 252f5cf
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 81 deletions.
5 changes: 4 additions & 1 deletion main/handlers/externalnode/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ func ProbeExternalNodes(s *sys.System) {
err := healthCheck(node.HealthUrl())
if err != nil {
log.Printf("[nodeservice] removing external node err %s \n", err)
s.DB.Workflow.DeleteExternalNode(new(model.User), node.ID)
err = s.DB.Workflow.DeleteExternalNode(new(model.User), node.ID)
if err != nil {
log.Printf("[nodeservice] error on remivonf external node, err: %s", err.Error())
}
}
}
}
Expand Down
103 changes: 23 additions & 80 deletions main/handlers/workflow/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import (

"github.com/ProxeusApp/proxeus-core/storage/portable"

"github.com/ProxeusApp/proxeus-core/storage"
"github.com/ProxeusApp/proxeus-core/sys/workflow"

"github.com/labstack/echo"

"github.com/ProxeusApp/proxeus-core/storage"

"github.com/ProxeusApp/proxeus-core/main/handlers/api"

"github.com/ProxeusApp/proxeus-core/main/handlers/externalnode"
Expand Down Expand Up @@ -79,101 +78,50 @@ func UpdateHandler(e echo.Context) error {
return c.NoContent(http.StatusBadRequest)
}

item := &model.WorkflowItem{}
if err := c.Bind(&item); err != nil {
workflowItem := &model.WorkflowItem{}
if err := c.Bind(&workflowItem); err != nil {
//WorkflowItem.Price int overflow will return in bind error
log.Println("[workflowHandler][UpdateHandler] ", err.Error())
return c.String(http.StatusBadRequest, "unable to bind request")
}

item.ID = ID
if item.Price < 0 {
workflowItem.ID = ID
if workflowItem.Price < 0 {
return c.String(http.StatusBadRequest, "price should be 0 or higher")
}

user, err := userService.GetUser(sess)
if err != nil && user == nil {
return c.String(http.StatusBadRequest, "unable to get user")
}
if item.Price > 0 && user.EthereumAddr == "" {
if workflowItem.Price > 0 && user.EthereumAddr == "" {
return c.String(http.StatusBadRequest, "can not set price without eth addr")
}

if publish {
errs := map[string]interface{}{}
collectError := func(err error, node *workflow.Node) {
errs[node.ID] = struct {
Error string
Item interface{}
}{Error: err.Error(), Item: node}
}
//loop recursively and change permissions on all children
item.LoopNodes(nil, func(l *workflow.Looper, node *workflow.Node) bool {
if node.Type == "form" {
it, er := c.System().DB.Form.Get(sess, node.ID)
if er != nil {
collectError(er, node)
return true //continue
}
if !it.Published {
it.Published = true
er = c.System().DB.Form.Put(sess, it)
if er != nil {
collectError(er, node)
}
}
} else if node.Type == "template" {
it, er := c.System().DB.Template.Get(sess, node.ID)
if er != nil {
collectError(er, node)
return true //continue
}
if !it.Published {
it.Published = true
er = c.System().DB.Template.Put(sess, it)
if er != nil {
collectError(er, node)
}
}
} else if node.Type == "workflow" { // deep dive...
it, er := c.System().DB.Workflow.Get(sess, node.ID)
if er != nil {
collectError(er, node)
return true //continue
}
if !it.Published {
it.Published = true
er = c.System().DB.Workflow.Put(sess, it)
if er != nil {
collectError(er, node)
}
}
it.LoopNodes(l, nil)
}
return true //continue
})
errs := workflowService.Publish(sess, workflowItem)
if len(errs) > 0 {
return c.JSON(http.StatusMultiStatus, errs)
}
}

err = c.System().DB.Workflow.Put(sess, item)
err = workflowService.Put(sess, workflowItem)
if err != nil {
if err == model.ErrAuthorityMissing {
return c.NoContent(http.StatusUnauthorized)
}
return c.NoContent(http.StatusNotFound)
}

return c.JSON(http.StatusOK, item)
return c.JSON(http.StatusOK, workflowItem)
}

func DeleteHandler(e echo.Context) error {
c := e.(*www.Context)
ID := c.Param("ID")
sess := c.Session(false)
if sess != nil {
err := c.System().DB.Workflow.Delete(sess, ID)
err := workflowService.Delete(sess, ID)
if err != nil {
return c.String(http.StatusBadRequest, err.Error())
}
Expand All @@ -183,37 +131,32 @@ func DeleteHandler(e echo.Context) error {
}

func ListPublishedHandler(e echo.Context) error {
return listHandler(e.(*www.Context), true)
return listHandler(e.(*www.Context), true, e.QueryParam("c"), helpers.RequestOptions(e))
}

func ListHandler(e echo.Context) error {
return listHandler(e.(*www.Context), false)
return listHandler(e.(*www.Context), false, e.QueryParam("c"), helpers.RequestOptions(e))
}

func listHandler(c *www.Context, publishedOnly bool) error {
var sess model.Auth
if s := c.Session(false); s != nil {
sess = s
}
contains := c.QueryParam("c")
settings := helpers.RequestOptions(c)
var dat []*model.WorkflowItem
var err error

if publishedOnly {
dat, err = c.System().DB.Workflow.ListPublished(sess, contains, settings)
func listHandler(c *www.Context, published bool, contains string, settings storage.Options) error {
var (
err error
workflowItems []*model.WorkflowItem
)
if published {
workflowItems, err = workflowService.ListPublished(c.Session(false), contains, settings)
} else {
dat, err = c.System().DB.Workflow.List(sess, contains, settings)
workflowItems, err = workflowService.List(c.Session(false), contains, settings)
}

if err != nil {
if err == model.ErrAuthorityMissing {
log.Println("Can't list workflows: " + err.Error())
return c.NoContent(http.StatusUnauthorized)
}
return c.NoContent(http.StatusNotFound)
}
return c.JSON(http.StatusOK, dat)

return c.JSON(http.StatusOK, workflowItems)
}

func ListCustomNodeHandler(e echo.Context) error {
Expand Down
10 changes: 10 additions & 0 deletions service/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,23 @@ type (
func (me *baseService) paymentsDB() storage.WorkflowPaymentsIF {
return me.system.DB.WorkflowPayments
}

func (me *baseService) workflowDB() storage.WorkflowIF {
return me.system.DB.Workflow
}

func (me *baseService) userDB() storage.UserIF {
return me.system.DB.User
}

func (me *baseService) userDataDB() storage.UserDataIF {
return me.system.DB.UserData
}

func (me *baseService) formDB() storage.FormIF {
return me.system.DB.Form
}

func (me *baseService) templateDB() storage.TemplateIF {
return me.system.DB.Template
}
73 changes: 73 additions & 0 deletions service/workflowService.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ import (
"github.com/ProxeusApp/proxeus-core/storage"
"github.com/ProxeusApp/proxeus-core/sys"
"github.com/ProxeusApp/proxeus-core/sys/model"
"github.com/ProxeusApp/proxeus-core/sys/workflow"
)

type (
WorkflowService interface {
List(auth model.Auth, contains string, options storage.Options) ([]*model.WorkflowItem, error)
ListPublished(auth model.Auth, contains string, options storage.Options) ([]*model.WorkflowItem, error)
ListIds(auth model.Auth, contains string, options storage.Options) ([]string, error)
GetAndPopulateOwner(auth model.Auth, id string) (*model.WorkflowItem, error)
Get(auth model.Auth, id string) (*model.WorkflowItem, error)
Publish(auth model.Auth, wfItem *model.WorkflowItem) map[string]interface{}
Put(auth model.Auth, wfItem *model.WorkflowItem) error
Delete(auth model.Auth, id string) error
}

DefaultWorkflowService struct {
Expand All @@ -28,6 +33,10 @@ func (me *DefaultWorkflowService) List(auth model.Auth, contains string, options
return me.workflowDB().List(auth, contains, options)
}

func (me *DefaultWorkflowService) ListPublished(auth model.Auth, contains string, options storage.Options) ([]*model.WorkflowItem, error) {
return me.workflowDB().ListPublished(auth, contains, options)
}

func (me *DefaultWorkflowService) Get(auth model.Auth, id string) (*model.WorkflowItem, error) {
return me.workflowDB().Get(auth, id)
}
Expand Down Expand Up @@ -61,3 +70,67 @@ func (me *DefaultWorkflowService) ListIds(auth model.Auth, contains string, opti
}
return id, err
}

func (me *DefaultWorkflowService) Publish(auth model.Auth, wfItem *model.WorkflowItem) map[string]interface{} {
errs := map[string]interface{}{}
collectError := func(err error, node *workflow.Node) {
errs[node.ID] = struct {
Error string
Item interface{}
}{Error: err.Error(), Item: node}
}
//loop recursively and change permissions on all children
wfItem.LoopNodes(nil, func(l *workflow.Looper, node *workflow.Node) bool {
if node.Type == "form" {
it, er := me.formDB().Get(auth, node.ID)
if er != nil {
collectError(er, node)
return true //continue
}
if !it.Published {
it.Published = true
er = me.formDB().Put(auth, it)
if er != nil {
collectError(er, node)
}
}
} else if node.Type == "template" {
it, er := me.templateDB().Get(auth, node.ID)
if er != nil {
collectError(er, node)
return true //continue
}
if !it.Published {
it.Published = true
er = me.templateDB().Put(auth, it)
if er != nil {
collectError(er, node)
}
}
} else if node.Type == "workflow" { // deep dive...
it, er := me.workflowDB().Get(auth, node.ID)
if er != nil {
collectError(er, node)
return true //continue
}
if !it.Published {
it.Published = true
er = me.workflowDB().Put(auth, it)
if er != nil {
collectError(er, node)
}
}
it.LoopNodes(l, nil)
}
return true //continue
})
return errs
}

func (me *DefaultWorkflowService) Put(auth model.Auth, wfItem *model.WorkflowItem) error {
return me.workflowDB().Put(auth, wfItem)
}

func (me *DefaultWorkflowService) Delete(auth model.Auth, id string) error {
return me.workflowDB().Delete(auth, id)
}

0 comments on commit 252f5cf

Please sign in to comment.