aicra/driver/plugin.go

118 lines
2.6 KiB
Go

package driver
import (
"fmt"
"path/filepath"
"plugin"
)
// 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 :
//
// type Controller interface {
// Get(d i.Arguments, r *i.Response) i.Response
// Post(d i.Arguments, r *i.Response) i.Response
// Put(d i.Arguments, r *i.Response) i.Response
// Delete(d i.Arguments, r *i.Response) i.Response
// }
//
// The controllers are exported by calling the 'Export() Controller' method
type Plugin struct{}
// Name returns the driver name
func (d Plugin) Name() string { return "plugin" }
// Path returns the universal path from the source path
func (d Plugin) Path(_root, _folder, _src string) string {
return filepath.Dir(_src)
}
// Source returns the source path from the universal path
func (d Plugin) Source(_root, _folder, _path string) string {
return filepath.Join(_root, _folder, _path, "main.go")
}
// Build returns the build path from the universal path
func (d Plugin) Build(_root, _folder, _path string) string {
if _path == "" {
return fmt.Sprintf("%s", filepath.Join(_root, ".build", _folder, "ROOT.so"))
}
return fmt.Sprintf("%s.so", filepath.Join(_root, ".build", _folder, _path))
}
// Compiled returns whether the driver has to be build
func (d Plugin) Compiled() bool { return true }
// LoadController returns a new Controller
func (d *Plugin) LoadController(_path string) (Controller, error) {
/* 1. Try to load plugin */
p, err := plugin.Open(_path)
if err != nil {
return nil, err
}
/* 2. Try to extract exported field */
m, err := p.Lookup("Export")
if err != nil {
return nil, err
}
exporter, ok := m.(func() Controller)
if !ok {
return nil, err
}
/* 3. Controller */
return exporter(), nil
}
// LoadMiddleware returns a new Middleware
func (d *Plugin) LoadMiddleware(_path string) (Middleware, error) {
/* 1. Try to load plugin */
p, err := plugin.Open(_path)
if err != nil {
return nil, err
}
/* 2. Try to extract exported field */
m, err := p.Lookup("Export")
if err != nil {
return nil, err
}
exporter, ok := m.(func() Middleware)
if !ok {
return nil, err
}
return exporter(), nil
}
// LoadChecker returns a new Checker
func (d *Plugin) LoadChecker(_path string) (Checker, error) {
/* 1. Try to load plugin */
p, err := plugin.Open(_path)
if err != nil {
return nil, err
}
/* 2. Try to extract exported field */
m, err := p.Lookup("Export")
if err != nil {
return nil, err
}
exporter, ok := m.(func() Checker)
if !ok {
return nil, err
}
return exporter(), nil
}