79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
|
package plugins
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"github.com/baez90/inetmock/pkg/api"
|
||
|
"github.com/spf13/cobra"
|
||
|
"path/filepath"
|
||
|
"plugin"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
registry HandlerRegistry
|
||
|
)
|
||
|
|
||
|
type HandlerRegistry interface {
|
||
|
LoadPlugins(pluginsPath string) error
|
||
|
RegisterHandler(handlerName string, handlerProvider api.PluginInstanceFactory, subCommands ...*cobra.Command)
|
||
|
HandlerForName(handlerName string) (api.ProtocolHandler, bool)
|
||
|
PluginCommands() []*cobra.Command
|
||
|
}
|
||
|
|
||
|
type handlerRegistry struct {
|
||
|
handlers map[string]api.PluginInstanceFactory
|
||
|
pluginCommands []*cobra.Command
|
||
|
}
|
||
|
|
||
|
func (h handlerRegistry) PluginCommands() []*cobra.Command {
|
||
|
return h.pluginCommands
|
||
|
}
|
||
|
|
||
|
func (h *handlerRegistry) HandlerForName(handlerName string) (instance api.ProtocolHandler, ok bool) {
|
||
|
var provider api.PluginInstanceFactory
|
||
|
if provider, ok = h.handlers[handlerName]; ok {
|
||
|
instance = provider()
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (h *handlerRegistry) RegisterHandler(handlerName string, handlerProvider api.PluginInstanceFactory, subCommands ...*cobra.Command) {
|
||
|
if _, exists := h.handlers[handlerName]; exists {
|
||
|
panic(fmt.Sprintf("plugin %s already registered - there's something strange...in the neighborhood"))
|
||
|
}
|
||
|
h.handlers[handlerName] = handlerProvider
|
||
|
|
||
|
if len(subCommands) > 0 {
|
||
|
pluginCmds := &cobra.Command{
|
||
|
Use: handlerName,
|
||
|
}
|
||
|
pluginCmds.AddCommand(subCommands...)
|
||
|
h.pluginCommands = append(h.pluginCommands, pluginCmds)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (h *handlerRegistry) LoadPlugins(pluginsPath string) (err error) {
|
||
|
var plugins []string
|
||
|
if plugins, err = filepath.Glob(fmt.Sprintf("%s%c*.so", pluginsPath, filepath.Separator)); err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
for _, pluginSo := range plugins {
|
||
|
if _, err = plugin.Open(pluginSo); err != nil {
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
|
||
|
err = nil
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func Registry() HandlerRegistry {
|
||
|
return registry
|
||
|
}
|
||
|
|
||
|
func init() {
|
||
|
registry = &handlerRegistry{
|
||
|
handlers: make(map[string]api.PluginInstanceFactory),
|
||
|
}
|
||
|
}
|