2018-09-27 12:11:48 +00:00
|
|
|
package driver
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
2018-09-28 06:04:36 +00:00
|
|
|
e "git.xdrm.io/go/aicra/err"
|
2018-09-27 12:11:48 +00:00
|
|
|
"git.xdrm.io/go/aicra/response"
|
2018-09-28 09:08:44 +00:00
|
|
|
"net/http"
|
2018-09-27 12:11:48 +00:00
|
|
|
"os/exec"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2018-09-28 08:54:13 +00:00
|
|
|
// RunController implements the Driver interface
|
|
|
|
func (d *Generic) RunController(_path []string, _method string) (func(response.Arguments) response.Response, e.Error) {
|
2018-09-27 12:11:48 +00:00
|
|
|
|
|
|
|
/* (1) Build controller path */
|
|
|
|
path := strings.Join(_path, "-")
|
|
|
|
if len(path) == 0 {
|
|
|
|
path = fmt.Sprintf("./controller/ROOT")
|
|
|
|
} else {
|
|
|
|
path = fmt.Sprintf("./controller/%s", path)
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (2) Format method */
|
|
|
|
method := strings.ToUpper(_method)
|
|
|
|
|
|
|
|
return func(d response.Arguments) response.Response {
|
|
|
|
|
|
|
|
res := response.New()
|
|
|
|
|
|
|
|
/* (1) Prepare stdin data */
|
|
|
|
d["_HTTP_METHOD_"] = method
|
2018-09-28 06:04:36 +00:00
|
|
|
stdin, err := json.Marshal(d)
|
|
|
|
if err != nil {
|
|
|
|
res.Err = e.UncallableController
|
2018-09-27 12:11:48 +00:00
|
|
|
return *res
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (2) Try to load command with <stdin> -> stdout */
|
|
|
|
cmd := exec.Command(path, string(stdin))
|
|
|
|
|
2018-09-28 06:04:36 +00:00
|
|
|
stdout, err := cmd.Output()
|
|
|
|
if err != nil {
|
|
|
|
res.Err = e.UncallableController
|
2018-09-27 12:11:48 +00:00
|
|
|
return *res
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (3) Get output json */
|
2018-09-27 12:33:03 +00:00
|
|
|
var outputI interface{}
|
2018-09-28 06:04:36 +00:00
|
|
|
err = json.Unmarshal(stdout, &outputI)
|
|
|
|
if err != nil {
|
|
|
|
res.Err = e.UncallableController
|
2018-09-27 12:33:03 +00:00
|
|
|
return *res
|
|
|
|
}
|
|
|
|
|
|
|
|
output, ok := outputI.(map[string]interface{})
|
|
|
|
if !ok {
|
2018-09-28 06:04:36 +00:00
|
|
|
res.Err = e.UncallableController
|
2018-09-27 12:33:03 +00:00
|
|
|
return *res
|
|
|
|
}
|
2018-09-27 12:11:48 +00:00
|
|
|
|
2018-09-28 06:04:36 +00:00
|
|
|
res.Err = e.Success
|
2018-09-27 12:11:48 +00:00
|
|
|
|
|
|
|
// extract error (success by default or on error)
|
|
|
|
if outErr, ok := output["error"]; ok {
|
2018-09-27 12:33:03 +00:00
|
|
|
errCode, ok := outErr.(float64)
|
2018-09-27 12:11:48 +00:00
|
|
|
if ok {
|
2018-09-28 06:10:41 +00:00
|
|
|
res.Err = e.Error{Code: int(errCode), Reason: "unknown reason", Arguments: nil}
|
2018-09-27 12:11:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
delete(output, "error")
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (4) fill response */
|
|
|
|
for k, v := range output {
|
|
|
|
res.Set(k, v)
|
|
|
|
}
|
|
|
|
|
|
|
|
return *res
|
|
|
|
|
2018-09-28 06:04:36 +00:00
|
|
|
}, e.Success
|
2018-09-27 12:11:48 +00:00
|
|
|
}
|
2018-09-28 09:08:44 +00:00
|
|
|
|
|
|
|
// LoadMiddleware returns a new middleware function; it must be a
|
|
|
|
// valid and existing folder/filename file
|
|
|
|
func (d *Generic) LoadMiddleware(_path string) (func(http.Request, *[]string), error) {
|
|
|
|
|
|
|
|
/* (1) Check plugin name */
|
|
|
|
if len(_path) < 1 {
|
|
|
|
return nil, fmt.Errorf("Middleware name must not be empty")
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (2) Create method + error */
|
|
|
|
return func(_req http.Request, _scope *[]string) {
|
|
|
|
|
|
|
|
/* (1) Prepare stdin data */
|
|
|
|
stdin, err := json.Marshal(_scope)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (2) Try to load command with <stdin> -> stdout */
|
|
|
|
cmd := exec.Command(_path, string(stdin))
|
|
|
|
|
|
|
|
stdout, err := cmd.Output()
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (3) Get output json */
|
|
|
|
var outputI interface{}
|
|
|
|
err = json.Unmarshal(stdout, &outputI)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
output, ok := outputI.(map[string]interface{})
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// extract 'scope' (empty by default or error)
|
|
|
|
scopeOut, ok := output["scope"]
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
scope, ok := scopeOut.([]string)
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
*_scope = append(*_scope, scope...)
|
|
|
|
|
|
|
|
}, nil
|
|
|
|
|
|
|
|
}
|