Skip to content

Commit

Permalink
Deprecate factory unmarshaler interface
Browse files Browse the repository at this point in the history
  • Loading branch information
mx-psi committed Apr 2, 2021
1 parent eec8600 commit e33c788
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 11 deletions.
22 changes: 22 additions & 0 deletions component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package component
import (
"context"

"github.com/spf13/viper"

"go.opentelemetry.io/collector/config"
)

Expand Down Expand Up @@ -76,3 +78,23 @@ type Factory interface {
// Type gets the type of the component created by this factory.
Type() config.Type
}

// DeprecatedUnmarshaler interface is a deprecated optional interface that if implemented by a Factory,
// the configuration loading system will use to unmarshal the config.
// Use config.Unmarshal instead.
type DeprecatedUnmarshaler interface {
// Unmarshal is a function that un-marshals a viper data into a config struct in a custom way.
// componentViperSection *viper.Viper
// The config for this specific component. May be nil or empty if no config available.
// intoCfg interface{}
// An empty interface wrapping a pointer to the config struct to unmarshal into.
Unmarshal(componentViperSection *viper.Viper, intoCfg interface{}) error
}

// CustomUnmarshaler is a function that un-marshals a viper data into a config struct
// in a custom way.
// componentViperSection *viper.Viper
// The config for this specific component. May be nil or empty if no config available.
// intoCfg interface{}
// An empty interface wrapping a pointer to the config struct to unmarshal into.
type CustomUnmarshaler func(componentViperSection *viper.Viper, intoCfg interface{}) error
22 changes: 18 additions & 4 deletions config/configparser/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ func loadExtensions(exts map[string]interface{}, factories map[config.Type]compo

// Now that the default config struct is created we can Unmarshal into it
// and it will apply user-defined config on top of the default.
if err := unmarshal(componentConfig, extensionCfg); err != nil {
unm := unmarshaler(factory)
if err := unm(componentConfig, extensionCfg); err != nil {
return nil, errorUnmarshalError(extensionsKeyName, fullName, err)
}

Expand Down Expand Up @@ -280,7 +281,8 @@ func LoadReceiver(componentConfig *config.Parser, fullName string, factory compo

// Now that the default config struct is created we can Unmarshal into it
// and it will apply user-defined config on top of the default.
if err := unmarshal(componentConfig, receiverCfg); err != nil {
unm := unmarshaler(factory)
if err := unm(componentConfig, receiverCfg); err != nil {
return nil, errorUnmarshalError(receiversKeyName, fullName, err)
}

Expand Down Expand Up @@ -352,7 +354,8 @@ func loadExporters(exps map[string]interface{}, factories map[config.Type]compon

// Now that the default config struct is created we can Unmarshal into it
// and it will apply user-defined config on top of the default.
if err := unmarshal(componentConfig, exporterCfg); err != nil {
unm := unmarshaler(factory)
if err := unm(componentConfig, exporterCfg); err != nil {
return nil, errorUnmarshalError(exportersKeyName, fullName, err)
}

Expand Down Expand Up @@ -394,7 +397,8 @@ func loadProcessors(procs map[string]interface{}, factories map[config.Type]comp

// Now that the default config struct is created we can Unmarshal into it
// and it will apply user-defined config on top of the default.
if err := unmarshal(componentConfig, processorCfg); err != nil {
unm := unmarshaler(factory)
if err := unm(componentConfig, processorCfg); err != nil {
return nil, errorUnmarshalError(processorsKeyName, fullName, err)
}

Expand Down Expand Up @@ -536,3 +540,13 @@ func unmarshal(componentSection *config.Parser, intoCfg interface{}) error {

return componentSection.UnmarshalExact(intoCfg)
}

// unmarshaler returns an unmarshaling function. It should be removed when deprecatedUnmarshaler is removed.
func unmarshaler(factory component.Factory) func(componentViperSection *config.Parser, intoCfg interface{}) error {
if fu, ok := factory.(component.DeprecatedUnmarshaler); ok {
return func(componentParser *config.Parser, intoCfg interface{}) error {
return fu.Unmarshal(componentParser.Viper(), intoCfg)
}
}
return unmarshal
}
29 changes: 28 additions & 1 deletion exporter/exporterhelper/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package exporterhelper
import (
"context"

"github.com/spf13/viper"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/configerror"
Expand All @@ -39,6 +41,7 @@ type CreateLogsExporter func(context.Context, component.ExporterCreateParams, co

type factory struct {
cfgType config.Type
customUnmarshaler component.CustomUnmarshaler
createDefaultConfig CreateDefaultConfig
createTracesExporter CreateTracesExporter
createMetricsExporter CreateMetricsExporter
Expand Down Expand Up @@ -66,6 +69,13 @@ func WithLogs(createLogsExporter CreateLogsExporter) FactoryOption {
}
}

// WithCustomUnmarshaler implements component.DeprecatedUnmarshaler.
func WithCustomUnmarshaler(customUnmarshaler component.CustomUnmarshaler) FactoryOption {
return func(o *factory) {
o.customUnmarshaler = customUnmarshaler
}
}

// NewFactory returns a component.ExporterFactory.
func NewFactory(
cfgType config.Type,
Expand All @@ -78,7 +88,13 @@ func NewFactory(
for _, opt := range options {
opt(f)
}
return f
var ret component.ExporterFactory
if f.customUnmarshaler != nil {
ret = &factoryWithUnmarshaler{f}
} else {
ret = f
}
return ret
}

// Type gets the type of the Exporter config created by this factory.
Expand Down Expand Up @@ -124,3 +140,14 @@ func (f *factory) CreateLogsExporter(
}
return nil, configerror.ErrDataTypeIsNotSupported
}

var _ component.DeprecatedUnmarshaler = (*factoryWithUnmarshaler)(nil)

type factoryWithUnmarshaler struct {
*factory
}

// Unmarshal un-marshals the config using the provided custom unmarshaler.
func (f *factoryWithUnmarshaler) Unmarshal(componentViperSection *viper.Viper, intoCfg interface{}) error {
return f.customUnmarshaler(componentViperSection, intoCfg)
}
15 changes: 14 additions & 1 deletion exporter/exporterhelper/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ package exporterhelper

import (
"context"
"errors"
"testing"

"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"go.uber.org/zap"

Expand Down Expand Up @@ -51,6 +53,8 @@ func TestNewFactory(t *testing.T) {
defaultConfig)
assert.EqualValues(t, typeStr, factory.Type())
assert.EqualValues(t, defaultCfg, factory.CreateDefaultConfig())
_, ok := factory.(component.DeprecatedUnmarshaler)
assert.False(t, ok)
_, err := factory.CreateTracesExporter(context.Background(), component.ExporterCreateParams{Logger: zap.NewNop()}, defaultCfg)
assert.Equal(t, configerror.ErrDataTypeIsNotSupported, err)
_, err = factory.CreateMetricsExporter(context.Background(), component.ExporterCreateParams{Logger: zap.NewNop()}, defaultCfg)
Expand All @@ -65,10 +69,15 @@ func TestNewFactory_WithConstructors(t *testing.T) {
defaultConfig,
WithTraces(createTraceExporter),
WithMetrics(createMetricsExporter),
WithLogs(createLogsExporter))
WithLogs(createLogsExporter),
WithCustomUnmarshaler(customUnmarshaler))
assert.EqualValues(t, typeStr, factory.Type())
assert.EqualValues(t, defaultCfg, factory.CreateDefaultConfig())

fu, ok := factory.(component.DeprecatedUnmarshaler)
assert.True(t, ok)
assert.Equal(t, errors.New("my error"), fu.Unmarshal(nil, nil))

te, err := factory.CreateTracesExporter(context.Background(), component.ExporterCreateParams{Logger: zap.NewNop()}, defaultCfg)
assert.NoError(t, err)
assert.Same(t, nopTracesExporter, te)
Expand Down Expand Up @@ -97,3 +106,7 @@ func createMetricsExporter(context.Context, component.ExporterCreateParams, conf
func createLogsExporter(context.Context, component.ExporterCreateParams, config.Exporter) (component.LogsExporter, error) {
return nopLogsExporter, nil
}

func customUnmarshaler(*viper.Viper, interface{}) error {
return errors.New("my error")
}
29 changes: 28 additions & 1 deletion extension/extensionhelper/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package extensionhelper
import (
"context"

"github.com/spf13/viper"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
)
Expand All @@ -32,10 +34,18 @@ type CreateServiceExtension func(context.Context, component.ExtensionCreateParam

type factory struct {
cfgType config.Type
customUnmarshaler component.CustomUnmarshaler
createDefaultConfig CreateDefaultConfig
createServiceExtension CreateServiceExtension
}

// WithCustomUnmarshaler implements component.DeprecatedUnmarshaler.
func WithCustomUnmarshaler(customUnmarshaler component.CustomUnmarshaler) FactoryOption {
return func(o *factory) {
o.customUnmarshaler = customUnmarshaler
}
}

// NewFactory returns a component.ExtensionFactory.
func NewFactory(
cfgType config.Type,
Expand All @@ -50,7 +60,13 @@ func NewFactory(
for _, opt := range options {
opt(f)
}
return f
var ret component.ExtensionFactory
if f.customUnmarshaler != nil {
ret = &factoryWithUnmarshaler{f}
} else {
ret = f
}
return ret
}

// Type gets the type of the Extension config created by this factory.
Expand All @@ -70,3 +86,14 @@ func (f *factory) CreateExtension(
cfg config.Extension) (component.Extension, error) {
return f.createServiceExtension(ctx, params, cfg)
}

var _ component.DeprecatedUnmarshaler = (*factoryWithUnmarshaler)(nil)

type factoryWithUnmarshaler struct {
*factory
}

// Unmarshal un-marshals the config using the provided custom unmarshaler.
func (f *factoryWithUnmarshaler) Unmarshal(componentViperSection *viper.Viper, intoCfg interface{}) error {
return f.customUnmarshaler(componentViperSection, intoCfg)
}
24 changes: 24 additions & 0 deletions extension/extensionhelper/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ package extensionhelper

import (
"context"
"errors"
"testing"

"github.com/spf13/viper"
"github.com/stretchr/testify/assert"

"go.opentelemetry.io/collector/component"
Expand Down Expand Up @@ -46,6 +48,24 @@ func TestNewFactory(t *testing.T) {
assert.Same(t, nopExtensionInstance, ext)
}

func TestNewFactory_WithConstructors(t *testing.T) {
factory := NewFactory(
typeStr,
defaultConfig,
createExtension,
WithCustomUnmarshaler(customUnmarshaler))
assert.EqualValues(t, typeStr, factory.Type())
assert.EqualValues(t, defaultCfg, factory.CreateDefaultConfig())

fu, ok := factory.(component.DeprecatedUnmarshaler)
assert.True(t, ok)
assert.Equal(t, errors.New("my error"), fu.Unmarshal(nil, nil))

ext, err := factory.CreateExtension(context.Background(), component.ExtensionCreateParams{}, defaultCfg)
assert.NoError(t, err)
assert.Same(t, nopExtensionInstance, ext)
}

func defaultConfig() config.Extension {
return defaultCfg
}
Expand All @@ -54,6 +74,10 @@ func createExtension(context.Context, component.ExtensionCreateParams, config.Ex
return nopExtensionInstance, nil
}

func customUnmarshaler(*viper.Viper, interface{}) error {
return errors.New("my error")
}

type nopExtension struct {
}

Expand Down
29 changes: 28 additions & 1 deletion processor/processorhelper/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ package processorhelper
import (
"context"

"github.com/spf13/viper"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/configerror"
Expand All @@ -40,12 +42,20 @@ type CreateLogsProcessor func(context.Context, component.ProcessorCreateParams,

type factory struct {
cfgType config.Type
customUnmarshaler component.CustomUnmarshaler
createDefaultConfig CreateDefaultConfig
createTraceProcessor CreateTraceProcessor
createMetricsProcessor CreateMetricsProcessor
createLogsProcessor CreateLogsProcessor
}

// WithCustomUnmarshaler implements component.DeprecatedUnmarshaler.
func WithCustomUnmarshaler(customUnmarshaler component.CustomUnmarshaler) FactoryOption {
return func(o *factory) {
o.customUnmarshaler = customUnmarshaler
}
}

// WithTraces overrides the default "error not supported" implementation for CreateTraceProcessor.
func WithTraces(createTraceProcessor CreateTraceProcessor) FactoryOption {
return func(o *factory) {
Expand Down Expand Up @@ -79,7 +89,13 @@ func NewFactory(
for _, opt := range options {
opt(f)
}
return f
var ret component.ProcessorFactory
if f.customUnmarshaler != nil {
ret = &factoryWithUnmarshaler{f}
} else {
ret = f
}
return ret
}

// Type gets the type of the Processor config created by this factory.
Expand Down Expand Up @@ -130,3 +146,14 @@ func (f *factory) CreateLogsProcessor(
}
return nil, configerror.ErrDataTypeIsNotSupported
}

var _ component.DeprecatedUnmarshaler = (*factoryWithUnmarshaler)(nil)

type factoryWithUnmarshaler struct {
*factory
}

// Unmarshal un-marshals the config using the provided custom unmarshaler.
func (f *factoryWithUnmarshaler) Unmarshal(componentViperSection *viper.Viper, intoCfg interface{}) error {
return f.customUnmarshaler(componentViperSection, intoCfg)
}
Loading

0 comments on commit e33c788

Please sign in to comment.