diff --git a/driver/import.go b/driver/import.go new file mode 100644 index 0000000..f8b715c --- /dev/null +++ b/driver/import.go @@ -0,0 +1,113 @@ +package driver + +import ( + "errors" + "fmt" + e "git.xdrm.io/go/aicra/err" + "git.xdrm.io/go/aicra/response" + "net/http" + "plugin" + "strings" +) + +// Name returns the driver name +func (d *Import) Name() string { return "import" } + +// RegisterController registers a new controller +func (d *Import) RegisterController(_path string, _controller Controller) error { + + // 1. init controllers if not already + if d.Controllers == nil { + d.Controllers = make(map[string]Controller) + } + + // 2. fail if no controller + if _controller == nil { + return errors.New("nil controller") + } + + // 3. Fail on invalid path + if len(_path) < 1 || _path[0] != '/' { + return errors.New("invalid controller path") + } + + // 4. Store controller + d.Controllers[_path] = _controller + return nil + +} + +// RegisterMiddleware registers a new controller +func (d *Import) RegisterMiddlware(_path string, _middleware Middleware) error { + + // 1. init imddlewares if not already + if d.Middlewares == nil { + d.Middlewares = make(map[string]Middleware) + } + + // 2. fail if no imddleware + if _middleware == nil { + return errors.New("nil imddleware") + } + + // 3. Fail on invalid path + if len(_path) < 1 || _path[0] != '/' { + return errors.New("invalid imddleware path") + } + + // 4. Store imddleware + d.Middlewares[_path] = _middleware + return nil + +} + +// RunController implements the Driver interface +func (d *Import) RunController(_path []string, _method string) (func(response.Arguments) response.Response, err.Error) { + + /* (1) Build controller path */ + path := strings.Join(_path, "-") + + /* (2) Check if controller exists */ + controller, ok := d.Controllers[path] + if !ok { + return nil, e.UncallableController + } + + /* (3) Format method */ + method := strings.ToLower(_method) + + /* (4) Return method according to method */ + switch method { + case "GET": + return controller.Get, e.Success + case "POST": + return controller.Post, e.Success + case "PUT": + return controller.Put, e.Success + case "DELETE": + return controller.Delete, e.Success + default: + return nil, e.UncallableMethod + } + + return nil, e.UncallableController +} + +// LoadMiddleware returns a new middleware function; it must be a +// valid and existing folder/filename file with the .so extension +func (d *Import) LoadMiddleware(_path string) (func(http.Request, *[]string), error) { + + /* (1) Check plugin name */ + if len(_path) < 1 { + return nil, errors.New("middleware name must not be empty") + } + + /* (2) Check if middleware exists */ + middleware, ok := d.Middlewares[_path] + if !ok { + return nil, errors.New("middleware not found") + } + + /* (3) Return middleware */ + return mware, nil +} diff --git a/driver/types.go b/driver/types.go index 4212fd5..61aeb0a 100644 --- a/driver/types.go +++ b/driver/types.go @@ -25,6 +25,46 @@ type Driver interface { // - the a/b/c controller executable must be named /controller/a/b/c type Generic struct{} +// Controller is the interface that controller implementation must follow +// it is used by the 'Import' driver +type Controller interface { + Get(d response.Arguments) response.Response + Post(d response.Arguments) response.Response + Put(d response.Arguments) response.Response + Delete(d response.Arguments) response.Response +} + +// Middleware is the interface that middleware implementation must follow +// it is used by the 'Import' driver +type Middleware interface { + Inspect(http.Request, *[]string) +} + +// Import tells the aicra instance to use the import driver to load controller/middleware executables +// +// It will compile imported with the following interface : +// +// type Controller interface { +// Get(d response.Arguments) response.Response +// Post(d response.Arguments) response.Response +// Put(d response.Arguments) response.Response +// Delete(d response.Arguments) response.Response +// } +// +// CONTROLLER FILE STRUCTURE +// -------------- +// - the root (/) controller executable must be named /controller/ROOT.go +// - the a/b/c controller executable must be named /controller/a/b/c.go +// +// COMPILATION +// ----------- +// The controllers/middlewares are imported and instanciated inside the main function, they are +// thus compiled with the main binary file +type Import struct { + Controllers map[string]Controller + Middlewares map[string]Middleware +} + // Plugin tells the aicra instance to use the plugin driver to load controller/middleware executables // // It will load go .so plugins with the following interface :