github.com/Jeffail/benthos/v3@v3.65.0/internal/bundle/outputs.go (about) 1 package bundle 2 3 import ( 4 "fmt" 5 "sort" 6 7 "github.com/Jeffail/benthos/v3/internal/docs" 8 "github.com/Jeffail/benthos/v3/lib/output" 9 "github.com/Jeffail/benthos/v3/lib/types" 10 ) 11 12 // AllOutputs is a set containing every single output that has been imported. 13 var AllOutputs = &OutputSet{ 14 specs: map[string]outputSpec{}, 15 } 16 17 //------------------------------------------------------------------------------ 18 19 // OutputAdd adds a new output to this environment by providing a constructor 20 // and documentation. 21 func (e *Environment) OutputAdd(constructor OutputConstructor, spec docs.ComponentSpec) error { 22 return e.outputs.Add(constructor, spec) 23 } 24 25 // OutputInit attempts to initialise a output from a config. 26 func (e *Environment) OutputInit( 27 conf output.Config, 28 mgr NewManagement, 29 pipelines ...types.PipelineConstructorFunc, 30 ) (types.Output, error) { 31 return e.outputs.Init(conf, mgr, pipelines...) 32 } 33 34 // OutputDocs returns a slice of output specs, which document each method. 35 func (e *Environment) OutputDocs() []docs.ComponentSpec { 36 return e.outputs.Docs() 37 } 38 39 //------------------------------------------------------------------------------ 40 41 // OutputConstructorFromSimple provides a way to define an output constructor 42 // without manually initializing processors of the config. 43 func OutputConstructorFromSimple(fn func(output.Config, NewManagement) (output.Type, error)) OutputConstructor { 44 return func(c output.Config, nm NewManagement, pcf ...types.PipelineConstructorFunc) (output.Type, error) { 45 o, err := fn(c, nm) 46 if err != nil { 47 return nil, fmt.Errorf("failed to create output '%v': %w", c.Type, err) 48 } 49 pcf = output.AppendProcessorsFromConfig(c, nm, nm.Logger(), nm.Metrics(), pcf...) 50 return output.WrapWithPipelines(o, pcf...) 51 } 52 } 53 54 //------------------------------------------------------------------------------ 55 56 // OutputConstructor constructs an output component. 57 type OutputConstructor func(output.Config, NewManagement, ...types.PipelineConstructorFunc) (output.Type, error) 58 59 type outputSpec struct { 60 constructor OutputConstructor 61 spec docs.ComponentSpec 62 } 63 64 // OutputSet contains an explicit set of outputs available to a Benthos service. 65 type OutputSet struct { 66 specs map[string]outputSpec 67 } 68 69 // Add a new output to this set by providing a spec (name, documentation, and 70 // constructor). 71 func (s *OutputSet) Add(constructor OutputConstructor, spec docs.ComponentSpec) error { 72 if s.specs == nil { 73 s.specs = map[string]outputSpec{} 74 } 75 s.specs[spec.Name] = outputSpec{ 76 constructor: constructor, 77 spec: spec, 78 } 79 docs.RegisterDocs(spec) 80 return nil 81 } 82 83 // Init attempts to initialise an output from a config. 84 func (s *OutputSet) Init( 85 conf output.Config, 86 mgr NewManagement, 87 pipelines ...types.PipelineConstructorFunc, 88 ) (types.Output, error) { 89 spec, exists := s.specs[conf.Type] 90 if !exists { 91 // TODO: V4 Remove this 92 if ctor, exists := output.GetDeprecatedPlugin(conf.Type); exists { 93 return ctor(conf, mgr, mgr.Logger(), mgr.Metrics(), pipelines...) 94 } 95 return nil, types.ErrInvalidOutputType 96 } 97 return spec.constructor(conf, mgr, pipelines...) 98 } 99 100 // Docs returns a slice of output specs, which document each method. 101 func (s *OutputSet) Docs() []docs.ComponentSpec { 102 var docs []docs.ComponentSpec 103 for _, v := range s.specs { 104 docs = append(docs, v.spec) 105 } 106 sort.Slice(docs, func(i, j int) bool { 107 return docs[i].Name < docs[j].Name 108 }) 109 return docs 110 } 111 112 // DocsFor returns the documentation for a given component name, returns a 113 // boolean indicating whether the component name exists. 114 func (s *OutputSet) DocsFor(name string) (docs.ComponentSpec, bool) { 115 c, ok := s.specs[name] 116 if !ok { 117 return docs.ComponentSpec{}, false 118 } 119 return c.spec, true 120 }