Skip to content
Snippets Groups Projects
pluginService.go 3.01 KiB
Newer Older
  • Learn to ignore specific revisions
  • package nucleus
    
    import (
    	"errors"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/event"
    	eventInterfaces "code.fbi.h-da.de/danet/gosdn/controller/interfaces/event"
    	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/plugin"
    	"code.fbi.h-da.de/danet/gosdn/controller/store"
    	"github.com/google/uuid"
    	hcplugin "github.com/hashicorp/go-plugin"
    	log "github.com/sirupsen/logrus"
    )
    
    const (
    	// PluginEventTopic is the used topic for plugin related entity changes.
    	PluginEventTopic = "plugin"
    )
    
    // PluginService provides a plugin service implementation.
    type PluginService struct {
    	pluginStore             plugin.Store
    	eventService            eventInterfaces.Service
    	createPluginFromStoreFn func(plugin.LoadedPlugin) (plugin.Plugin, error)
    }
    
    // NewPluginService creates a plugin service.
    func NewPluginService(pluginStore plugin.Store, eventService eventInterfaces.Service, createPluginFromStoreFn func(plugin.LoadedPlugin) (plugin.Plugin, error)) plugin.Service {
    	return &PluginService{
    		pluginStore:             pluginStore,
    		eventService:            eventService,
    		createPluginFromStoreFn: createPluginFromStoreFn,
    	}
    }
    
    // Get takes a Plugin's UUID or name and returns the Plugin.
    func (s *PluginService) Get(query store.Query) (plugin.Plugin, error) {
    	loadedPlugin, err := s.pluginStore.Get(query)
    	if err != nil {
    		return nil, err
    	}
    
    	plugin, err := s.createPluginFromStore(loadedPlugin)
    	if err != nil {
    		return nil, err
    	}
    
    	return plugin, nil
    }
    
    // GetAll returns all stored plugins.
    func (s *PluginService) GetAll() ([]plugin.Plugin, error) {
    	var plugins []plugin.Plugin
    
    	loadedPlugins, err := s.pluginStore.GetAll()
    	if err != nil {
    		return nil, err
    	}
    
    	for _, loadedPlugin := range loadedPlugins {
    		plugin, err := s.createPluginFromStore(loadedPlugin)
    		if err != nil {
    			return nil, err
    		}
    
    		plugins = append(plugins, plugin)
    	}
    
    	return plugins, nil
    }
    
    // Add adds a plugin to the plugin store.
    func (s *PluginService) Add(pluginToAdd plugin.Plugin) error {
    	err := s.pluginStore.Add(pluginToAdd)
    	if err != nil {
    		return err
    	}
    
    	if err := s.eventService.PublishEvent(PluginEventTopic, event.NewAddEvent(pluginToAdd.ID())); err != nil {
    		log.Error(err)
    	}
    
    	return nil
    }
    
    // Delete deletes a plugin from the plugin store.
    func (s *PluginService) Delete(pluginToDelete plugin.Plugin) error {
    	err := s.pluginStore.Delete(pluginToDelete)
    	if err != nil {
    		return err
    	}
    
    	// stop the plugin
    	pluginToDelete.GetClient().Kill()
    
    	if err := s.eventService.PublishEvent(PluginEventTopic, event.NewDeleteEvent(pluginToDelete.ID())); err != nil {
    		log.Error(err)
    	}
    
    	return nil
    }
    
    func (s *PluginService) createPluginFromStore(loadedPlugin plugin.LoadedPlugin) (plugin.Plugin, error) {
    	plugin, err := s.createPluginFromStoreFn(loadedPlugin)
    	if err != nil {
    		if errors.Is(err, hcplugin.ErrProcessNotFound) {
    			plugin, err = NewPlugin(uuid.MustParse(loadedPlugin.ID))
    			if err != nil {
    				return nil, err
    			}
    			err := s.pluginStore.Update(plugin)
    			if err != nil {
    				return nil, err
    			}
    		} else {
    			return nil, err
    		}
    	}
    
    	return plugin, nil
    }