Package / arch (push) Canceled after 0s
Package / user (push) Canceled after 0s
Package / deb (push) Canceled after 0s
Package / freebsd (push) Canceled after 0s
Package / image (push) Canceled after 0s
Test / test (push) Canceled after 0s
Test / e2e (push) Canceled after 0s
134 lines
3.3 KiB
Go
134 lines
3.3 KiB
Go
// Package plugin maps each source and sink type to the constructor its
|
|
// package registers in init; a type without a row in config's catalogue is
|
|
// refused.
|
|
package plugin
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"github.com/lixenwraith/logwisp/internal/config"
|
|
"github.com/lixenwraith/logwisp/internal/session"
|
|
"github.com/lixenwraith/logwisp/internal/sink"
|
|
"github.com/lixenwraith/logwisp/internal/source"
|
|
|
|
"github.com/lixenwraith/log"
|
|
)
|
|
|
|
// SourceFactory creates source instances
|
|
type SourceFactory func(
|
|
id string,
|
|
configMap map[string]any,
|
|
logger *log.Logger,
|
|
sessions *session.Proxy,
|
|
) (source.Source, error)
|
|
|
|
// SinkFactory creates sink instances
|
|
type SinkFactory func(
|
|
id string,
|
|
configMap map[string]any,
|
|
logger *log.Logger,
|
|
sessions *session.Proxy,
|
|
) (sink.Sink, error)
|
|
|
|
// registry encapsulates all plugin factories with lazy initialization
|
|
type registry struct {
|
|
sourceFactories map[string]SourceFactory
|
|
sinkFactories map[string]SinkFactory
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
var (
|
|
globalRegistry *registry
|
|
once sync.Once
|
|
)
|
|
|
|
// getRegistry returns the singleton registry, initializing on first access
|
|
func getRegistry() *registry {
|
|
once.Do(func() {
|
|
globalRegistry = ®istry{
|
|
sourceFactories: make(map[string]SourceFactory),
|
|
sinkFactories: make(map[string]SinkFactory),
|
|
}
|
|
})
|
|
return globalRegistry
|
|
}
|
|
|
|
// RegisterSource registers a source factory function for a type the
|
|
// catalogue (config.LookupPlugin) has a row for
|
|
func RegisterSource(name string, constructor SourceFactory) error {
|
|
if _, ok := config.LookupPlugin("source", name); !ok {
|
|
return fmt.Errorf("source type %s has no catalogue row", name)
|
|
}
|
|
r := getRegistry()
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
if _, exists := r.sourceFactories[name]; exists {
|
|
return fmt.Errorf("source type %s already registered", name)
|
|
}
|
|
r.sourceFactories[name] = constructor
|
|
return nil
|
|
}
|
|
|
|
// RegisterSink registers a sink factory function for a type the catalogue
|
|
// has a row for
|
|
func RegisterSink(name string, constructor SinkFactory) error {
|
|
if _, ok := config.LookupPlugin("sink", name); !ok {
|
|
return fmt.Errorf("sink type %s has no catalogue row", name)
|
|
}
|
|
r := getRegistry()
|
|
r.mu.Lock()
|
|
defer r.mu.Unlock()
|
|
|
|
if _, exists := r.sinkFactories[name]; exists {
|
|
return fmt.Errorf("sink type %s already registered", name)
|
|
}
|
|
r.sinkFactories[name] = constructor
|
|
return nil
|
|
}
|
|
|
|
// GetSource retrieves a source factory function
|
|
func GetSource(name string) (SourceFactory, bool) {
|
|
r := getRegistry()
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
constructor, exists := r.sourceFactories[name]
|
|
return constructor, exists
|
|
}
|
|
|
|
// GetSink retrieves a sink factory function
|
|
func GetSink(name string) (SinkFactory, bool) {
|
|
r := getRegistry()
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
constructor, exists := r.sinkFactories[name]
|
|
return constructor, exists
|
|
}
|
|
|
|
// ListSources returns all registered source types
|
|
func ListSources() []string {
|
|
r := getRegistry()
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
types := make([]string, 0, len(r.sourceFactories))
|
|
for t := range r.sourceFactories {
|
|
types = append(types, t)
|
|
}
|
|
return types
|
|
}
|
|
|
|
// ListSinks returns all registered sink types
|
|
func ListSinks() []string {
|
|
r := getRegistry()
|
|
r.mu.RLock()
|
|
defer r.mu.RUnlock()
|
|
|
|
types := make([]string, 0, len(r.sinkFactories))
|
|
for t := range r.sinkFactories {
|
|
types = append(types, t)
|
|
}
|
|
return types
|
|
}
|