3
0

Add ability to manually trigger record iterator via API

This commit is contained in:
Denis Arh
2020-03-26 15:30:01 +01:00
parent a3b1450e16
commit 6e5047bd22
6 changed files with 167 additions and 14 deletions
+16
View File
@@ -1073,6 +1073,22 @@
}
]
}
},
{
"name": "triggerScriptOnList",
"method": "POST",
"title": "Fire compose:record trigger",
"path": "/trigger",
"parameters": {
"post": [
{
"name": "script",
"type": "string",
"title": "Script to execute",
"required": true
}
]
}
}
]
},
+16
View File
@@ -364,6 +364,22 @@
}
]
}
},
{
"Name": "triggerScriptOnList",
"Method": "POST",
"Title": "Fire compose:record trigger",
"Path": "/trigger",
"Parameters": {
"post": [
{
"name": "script",
"required": true,
"title": "Script to execute",
"type": "string"
}
]
}
}
]
}
+37 -14
View File
@@ -43,24 +43,26 @@ type RecordAPI interface {
Delete(context.Context, *request.RecordDelete) (interface{}, error)
Upload(context.Context, *request.RecordUpload) (interface{}, error)
TriggerScript(context.Context, *request.RecordTriggerScript) (interface{}, error)
TriggerScriptOnList(context.Context, *request.RecordTriggerScriptOnList) (interface{}, error)
}
// HTTP API interface
type Record struct {
Report func(http.ResponseWriter, *http.Request)
List func(http.ResponseWriter, *http.Request)
ImportInit func(http.ResponseWriter, *http.Request)
ImportRun func(http.ResponseWriter, *http.Request)
ImportProgress func(http.ResponseWriter, *http.Request)
Export func(http.ResponseWriter, *http.Request)
Exec func(http.ResponseWriter, *http.Request)
Create func(http.ResponseWriter, *http.Request)
Read func(http.ResponseWriter, *http.Request)
Update func(http.ResponseWriter, *http.Request)
BulkDelete func(http.ResponseWriter, *http.Request)
Delete func(http.ResponseWriter, *http.Request)
Upload func(http.ResponseWriter, *http.Request)
TriggerScript func(http.ResponseWriter, *http.Request)
Report func(http.ResponseWriter, *http.Request)
List func(http.ResponseWriter, *http.Request)
ImportInit func(http.ResponseWriter, *http.Request)
ImportRun func(http.ResponseWriter, *http.Request)
ImportProgress func(http.ResponseWriter, *http.Request)
Export func(http.ResponseWriter, *http.Request)
Exec func(http.ResponseWriter, *http.Request)
Create func(http.ResponseWriter, *http.Request)
Read func(http.ResponseWriter, *http.Request)
Update func(http.ResponseWriter, *http.Request)
BulkDelete func(http.ResponseWriter, *http.Request)
Delete func(http.ResponseWriter, *http.Request)
Upload func(http.ResponseWriter, *http.Request)
TriggerScript func(http.ResponseWriter, *http.Request)
TriggerScriptOnList func(http.ResponseWriter, *http.Request)
}
func NewRecord(h RecordAPI) *Record {
@@ -345,6 +347,26 @@ func NewRecord(h RecordAPI) *Record {
resputil.JSON(w, value)
}
},
TriggerScriptOnList: func(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
params := request.NewRecordTriggerScriptOnList()
if err := params.Fill(r); err != nil {
logger.LogParamError("Record.TriggerScriptOnList", r, err)
resputil.JSON(w, err)
return
}
value, err := h.TriggerScriptOnList(r.Context(), params)
if err != nil {
logger.LogControllerError("Record.TriggerScriptOnList", r, err, params.Auditable())
resputil.JSON(w, err)
return
}
logger.LogControllerCall("Record.TriggerScriptOnList", r, params.Auditable())
if !serveHTTP(value, w, r) {
resputil.JSON(w, value)
}
},
}
}
@@ -365,5 +387,6 @@ func (h Record) MountRoutes(r chi.Router, middlewares ...func(http.Handler) http
r.Delete("/namespace/{namespaceID}/module/{moduleID}/record/{recordID}", h.Delete)
r.Post("/namespace/{namespaceID}/module/{moduleID}/record/attachment", h.Upload)
r.Post("/namespace/{namespaceID}/module/{moduleID}/record/{recordID}/trigger", h.TriggerScript)
r.Post("/namespace/{namespaceID}/module/{moduleID}/record/trigger", h.TriggerScriptOnList)
})
}
+21
View File
@@ -436,6 +436,27 @@ func (ctrl *Record) TriggerScript(ctx context.Context, r *request.RecordTriggerS
return ctrl.makePayload(ctx, module, record, err)
}
func (ctrl *Record) TriggerScriptOnList(ctx context.Context, r *request.RecordTriggerScriptOnList) (rsp interface{}, err error) {
//var (
// module *types.Module
// namespace *types.Namespace
//)
//
//if module, err = ctrl.module.With(ctx).FindByID(r.NamespaceID, r.ModuleID); err != nil {
// return
//}
//
//if namespace, err = ctrl.namespace.With(ctx).FindByID(r.NamespaceID); err != nil {
// return
//}
// @todo this does not need to be under /record ... where then?!?!
err = corredor.Service().ExecIterator(ctx, r.Script)
// Script can return modified record and we'll pass it on to the caller
return resputil.OK(), err
}
func (ctrl Record) makePayload(ctx context.Context, m *types.Module, r *types.Record, err error) (*recordPayload, error) {
if err != nil || r == nil {
return nil, err
+59
View File
@@ -923,3 +923,62 @@ func (r *RecordTriggerScript) Fill(req *http.Request) (err error) {
}
var _ RequestFiller = NewRecordTriggerScript()
// Record triggerScriptOnList request parameters
type RecordTriggerScriptOnList struct {
Script string
NamespaceID uint64 `json:",string"`
ModuleID uint64 `json:",string"`
}
func NewRecordTriggerScriptOnList() *RecordTriggerScriptOnList {
return &RecordTriggerScriptOnList{}
}
func (r RecordTriggerScriptOnList) Auditable() map[string]interface{} {
var out = map[string]interface{}{}
out["script"] = r.Script
out["namespaceID"] = r.NamespaceID
out["moduleID"] = r.ModuleID
return out
}
func (r *RecordTriggerScriptOnList) Fill(req *http.Request) (err error) {
if strings.ToLower(req.Header.Get("content-type")) == "application/json" {
err = json.NewDecoder(req.Body).Decode(r)
switch {
case err == io.EOF:
err = nil
case err != nil:
return errors.Wrap(err, "error parsing http request body")
}
}
if err = req.ParseForm(); err != nil {
return err
}
get := map[string]string{}
post := map[string]string{}
urlQuery := req.URL.Query()
for name, param := range urlQuery {
get[name] = string(param[0])
}
postVars := req.Form
for name, param := range postVars {
post[name] = string(param[0])
}
if val, ok := post["script"]; ok {
r.Script = val
}
r.NamespaceID = parseUInt64(chi.URLParam(req, "namespaceID"))
r.ModuleID = parseUInt64(chi.URLParam(req, "moduleID"))
return err
}
var _ RequestFiller = NewRecordTriggerScriptOnList()
+18
View File
@@ -651,6 +651,7 @@ Compose pages
| title | string | POST | Title | N/A | YES |
| handle | string | POST | Handle | N/A | NO |
| description | string | POST | Description | N/A | NO |
| weight | int | POST | Page tree weight | N/A | NO |
| visible | bool | POST | Visible in navigation | N/A | NO |
| blocks | sqlxTypes.JSONText | POST | Blocks JSON | N/A | NO |
@@ -827,6 +828,7 @@ Compose records
| `DELETE` | `/namespace/{namespaceID}/module/{moduleID}/record/{recordID}` | Delete record row from module section |
| `POST` | `/namespace/{namespaceID}/module/{moduleID}/record/attachment` | Uploads attachment and validates it against record field requirements |
| `POST` | `/namespace/{namespaceID}/module/{moduleID}/record/{recordID}/trigger` | Fire compose:record trigger |
| `POST` | `/namespace/{namespaceID}/module/{moduleID}/record/trigger` | Fire compose:record trigger |
## Generates report from module records
@@ -1069,6 +1071,22 @@ Compose records
| script | string | POST | Script to execute | N/A | YES |
| values | types.RecordValueSet | POST | Record values | N/A | YES |
## Fire compose:record trigger
#### Method
| URI | Protocol | Method | Authentication |
| --- | -------- | ------ | -------------- |
| `/namespace/{namespaceID}/module/{moduleID}/record/trigger` | HTTP/S | POST | |
#### Request parameters
| Parameter | Type | Method | Description | Default | Required? |
| --------- | ---- | ------ | ----------- | ------- | --------- |
| script | string | POST | Script to execute | N/A | YES |
| namespaceID | uint64 | PATH | Namespace ID | N/A | YES |
| moduleID | uint64 | PATH | Module ID | N/A | YES |
---