diff --git a/.chloggen/connector-factory.yaml b/.chloggen/connector-factory.yaml new file mode 100755 index 00000000000..033ddb91a39 --- /dev/null +++ b/.chloggen/connector-factory.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: connector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add connector factory + +# One or more tracking issues or pull requests related to the change +issues: [6611] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/component/config.go b/component/config.go index a7ed0efc637..84aa94dcb6a 100644 --- a/component/config.go +++ b/component/config.go @@ -28,6 +28,14 @@ type Config interface { privateConfig() } +// CreateDefaultConfigFunc is the equivalent of Factory.CreateDefaultConfig(). +type CreateDefaultConfigFunc func() Config + +// CreateDefaultConfig implements Factory.CreateDefaultConfig(). +func (f CreateDefaultConfigFunc) CreateDefaultConfig() Config { + return f() +} + // As interface types are only used for static typing, a common idiom to find the reflection Type // for an interface type Foo is to use a *Foo value. var configValidatorType = reflect.TypeOf((*ConfigValidator)(nil)).Elem() diff --git a/connector/connector.go b/connector/connector.go index 9c172e47bd2..749e30ce70a 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -35,3 +35,61 @@ type CreateSettings struct { // BuildInfo can be used by components for informational purposes BuildInfo component.BuildInfo } + +// Factory is factory interface for connectors. +// +// This interface cannot be directly implemented. Implementations must +// use the NewFactory to implement it. +type Factory interface { + component.Factory + + // CreateDefaultConfig creates the default configuration for the Connector. + // This method can be called multiple times depending on the pipeline + // configuration and should not cause side-effects that prevent the creation + // of multiple instances of the Connector. + // The object returned by this method needs to pass the checks implemented by + // 'configtest.CheckConfigStruct'. It is recommended to have these checks in the + // tests of any implementation of the Factory interface. + CreateDefaultConfig() component.Config +} + +// FactoryOption applies changes to Factory. +type FactoryOption interface { + // apply applies the option. + apply(o *factory) +} + +var _ FactoryOption = (*factoryOptionFunc)(nil) + +// factoryOptionFunc is an FactoryOption created through a function. +type factoryOptionFunc func(*factory) + +func (f factoryOptionFunc) apply(o *factory) { + f(o) +} + +// factory implements Factory. +type factory struct { + component.Factory + cfgType component.Type + component.CreateDefaultConfigFunc +} + +var _ Factory = (*factory)(nil) + +// Type returns the type of component. +func (f *factory) Type() component.Type { + return f.cfgType +} + +// NewFactory returns a Factory. +func NewFactory(cfgType component.Type, createDefaultConfig component.CreateDefaultConfigFunc, options ...FactoryOption) Factory { + f := &factory{ + cfgType: cfgType, + CreateDefaultConfigFunc: createDefaultConfig, + } + for _, opt := range options { + opt.apply(f) + } + return f +} diff --git a/connector/connector_test.go b/connector/connector_test.go new file mode 100644 index 00000000000..97d0f9763c9 --- /dev/null +++ b/connector/connector_test.go @@ -0,0 +1,34 @@ +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package connector // import "go.opentelemetry.io/collector/connector" + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config" +) + +func TestNewFactory_NoOptions(t *testing.T) { + const typeStr = "test" + defaultCfg := config.NewConnectorSettings(component.NewID(typeStr)) + factory := NewFactory( + typeStr, + func() component.Config { return &defaultCfg }) + assert.EqualValues(t, typeStr, factory.Type()) + assert.EqualValues(t, &defaultCfg, factory.CreateDefaultConfig()) +}