Skip to content

Commit

Permalink
Refactor ConfigValidator
Browse files Browse the repository at this point in the history
Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
  • Loading branch information
bogdandrutu committed Mar 30, 2021
1 parent 2c17034 commit 63e28c8
Show file tree
Hide file tree
Showing 14 changed files with 44 additions and 56 deletions.
1 change: 1 addition & 0 deletions component/componenttest/nop_receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ func (f *nopReceiverFactory) Type() config.Type {
return "nop"
}

// TODO: Consider to remove this or move it to configtest.
type NopConfig struct {
config.ReceiverSettings
}
Expand Down
20 changes: 13 additions & 7 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ func (cfg *Config) Validate() error {
return errMissingReceivers
}

// Validate the receiver configuration.
for recv, recvCfg := range cfg.Receivers {
if err := recvCfg.Validate(); err != nil {
return fmt.Errorf("receiver %s has invalid configuration: %w", recv, err)
}
}

// Currently there is no default exporter enabled.
// The configuration must specify at least one exporter to be valid.
if len(cfg.Exporters) == 0 {
Expand Down Expand Up @@ -108,13 +115,6 @@ func (cfg *Config) validateServicePipelines() error {
if cfg.Receivers[ref] == nil {
return fmt.Errorf("pipeline %q references receiver %q which does not exist", pipeline.Name, ref)
}

// Validate the receiver configuration by the custom configuration validator
recCfg := cfg.Receivers[ref]
if err := recCfg.Validate(); err != nil {
return fmt.Errorf("pipeline %q references receiver %q which has invalid configuration with error: %v", pipeline.Name, ref, err)
}

}

// Validate pipeline processor name references
Expand Down Expand Up @@ -160,6 +160,12 @@ type NamedEntity interface {
SetName(name string)
}

// Validator defines the interface for the configuration validation.
type Validator interface {
// Validate validates the configuration and returns an error if invalid.
Validate() error
}

// DataType is the data type that is supported for collection. We currently support
// collecting metrics, traces and logs, this can expand in the future.
type DataType string
Expand Down
8 changes: 4 additions & 4 deletions config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ import (
"github.com/stretchr/testify/assert"
)

type NopConfig struct {
type nopConfig struct {
ReceiverSettings
}

func (nc *NopConfig) Validate() error {
func (nc *nopConfig) Validate() error {
if nc.TypeVal != "nop" {
return fmt.Errorf("invalid receiver config")
}
Expand Down Expand Up @@ -134,7 +134,7 @@ func TestConfigValidate(t *testing.T) {
name: "invalid-receiver-config",
cfgFn: func() *Config {
cfg := generateConfig()
cfg.Receivers["nop"] = &NopConfig{
cfg.Receivers["nop"] = &nopConfig{
ReceiverSettings: ReceiverSettings{
TypeVal: "invalid_rec_type",
},
Expand All @@ -156,7 +156,7 @@ func TestConfigValidate(t *testing.T) {
func generateConfig() *Config {
return &Config{
Receivers: map[string]Receiver{
"nop": &NopConfig{
"nop": &nopConfig{
ReceiverSettings: ReceiverSettings{
TypeVal: "nop",
},
Expand Down
19 changes: 2 additions & 17 deletions config/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,12 @@ package config

// Receiver is the configuration of a receiver. Specific receivers must implement this
// interface and will typically embed ReceiverSettings struct or a struct that extends it.
// Embedded CustomConfigOptions will force each receiver to implement Validate() function
// Embedded Validator will force each receiver to implement Validate() function
type Receiver interface {
NamedEntity
CustomConfigOptions
Validator
}

// CustomConfigOptions defines the interfaces for configuration customization options
// Different custom interfaces can be added like CustomConfigValidator and any other interface.
type CustomConfigOptions interface {
CustomConfigValidator
}

// CustomConfigValidator defines the interface for the custom configuration validation on each component
type CustomConfigValidator interface {
Validate() error
}

// CustomValidator is a function that runs the customized validation
// on component level configuration.
type CustomValidator func() error

// Receivers is a map of names to Receivers.
type Receivers map[string]Receiver

Expand Down
2 changes: 1 addition & 1 deletion receiver/hostmetricsreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Config struct {
Scrapers map[string]internal.Config `mapstructure:"-"`
}

var _ config.CustomConfigOptions = (*Config)(nil)
var _ config.Receiver = (*Config)(nil)

// Validate checks the receiver configuration is valid
func (cfg *Config) Validate() error {
Expand Down
2 changes: 1 addition & 1 deletion receiver/jaegerreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ type Config struct {
RemoteSampling *RemoteSamplingConfig `mapstructure:"remote_sampling"`
}

var _ config.CustomConfigOptions = (*Config)(nil)
var _ config.Receiver = (*Config)(nil)

// Validate checks the receiver configuration is valid
func (cfg *Config) Validate() error {
Expand Down
2 changes: 1 addition & 1 deletion receiver/kafkareceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type Config struct {
Authentication kafkaexporter.Authentication `mapstructure:"auth"`
}

var _ config.CustomConfigOptions = (*Config)(nil)
var _ config.Receiver = (*Config)(nil)

// Validate checks the receiver configuration is valid
func (cfg *Config) Validate() error {
Expand Down
2 changes: 1 addition & 1 deletion receiver/opencensusreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (cfg *Config) buildOptions() ([]ocOption, error) {
return opts, nil
}

var _ config.CustomConfigOptions = (*Config)(nil)
var _ config.Receiver = (*Config)(nil)

// Validate checks the receiver configuration is valid
func (cfg *Config) Validate() error {
Expand Down
2 changes: 1 addition & 1 deletion receiver/otlpreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ type Config struct {
Protocols `mapstructure:"protocols"`
}

var _ config.CustomConfigOptions = (*Config)(nil)
var _ config.Receiver = (*Config)(nil)

// Validate checks the receiver configuration is valid
func (cfg *Config) Validate() error {
Expand Down
18 changes: 9 additions & 9 deletions receiver/prometheusreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,27 @@ package prometheusreceiver
import (
"time"

"github.com/prometheus/prometheus/config"
promconfig "github.com/prometheus/prometheus/config"

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

// Config defines configuration for Prometheus receiver.
type Config struct {
config2.ReceiverSettings `mapstructure:",squash"`
PrometheusConfig *config.Config `mapstructure:"-"`
BufferPeriod time.Duration `mapstructure:"buffer_period"`
BufferCount int `mapstructure:"buffer_count"`
UseStartTimeMetric bool `mapstructure:"use_start_time_metric"`
StartTimeMetricRegex string `mapstructure:"start_time_metric_regex"`
config.ReceiverSettings `mapstructure:",squash"`
PrometheusConfig *promconfig.Config `mapstructure:"-"`
BufferPeriod time.Duration `mapstructure:"buffer_period"`
BufferCount int `mapstructure:"buffer_count"`
UseStartTimeMetric bool `mapstructure:"use_start_time_metric"`
StartTimeMetricRegex string `mapstructure:"start_time_metric_regex"`

// ConfigPlaceholder is just an entry to make the configuration pass a check
// that requires that all keys present in the config actually exist on the
// structure, ie.: it will error if an unknown key is present.
ConfigPlaceholder interface{} `mapstructure:"config"`
}

var _ config2.CustomConfigOptions = (*Config)(nil)
var _ config.Receiver = (*Config)(nil)

// Validate checks the receiver configuration is valid
func (cfg *Config) Validate() error {
Expand Down
12 changes: 6 additions & 6 deletions receiver/receiverhelper/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ func TestNewFactory(t *testing.T) {
assert.EqualValues(t, defaultCfg, factory.CreateDefaultConfig())
_, ok := factory.(component.ConfigUnmarshaler)
assert.False(t, ok)
_, err := factory.CreateTracesReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil)
_, err := factory.CreateTracesReceiver(context.Background(), component.ReceiverCreateParams{}, factory.CreateDefaultConfig(), nil)
assert.Error(t, err)
_, err = factory.CreateMetricsReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil)
_, err = factory.CreateMetricsReceiver(context.Background(), component.ReceiverCreateParams{}, factory.CreateDefaultConfig(), nil)
assert.Error(t, err)
_, err = factory.CreateLogsReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil)
_, err = factory.CreateLogsReceiver(context.Background(), component.ReceiverCreateParams{}, factory.CreateDefaultConfig(), nil)
assert.Error(t, err)
}

Expand All @@ -68,13 +68,13 @@ func TestNewFactory_WithConstructors(t *testing.T) {
assert.True(t, ok)
assert.Equal(t, errors.New("my error"), fu.Unmarshal(nil, nil))

_, err := factory.CreateTracesReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil)
_, err := factory.CreateTracesReceiver(context.Background(), component.ReceiverCreateParams{}, factory.CreateDefaultConfig(), nil)
assert.NoError(t, err)

_, err = factory.CreateMetricsReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil)
_, err = factory.CreateMetricsReceiver(context.Background(), component.ReceiverCreateParams{}, factory.CreateDefaultConfig(), nil)
assert.NoError(t, err)

_, err = factory.CreateLogsReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil)
_, err = factory.CreateLogsReceiver(context.Background(), component.ReceiverCreateParams{}, factory.CreateDefaultConfig(), nil)
assert.NoError(t, err)
}

Expand Down
4 changes: 1 addition & 3 deletions receiver/zipkinreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ type Config struct {
// If enabled the zipkin receiver will attempt to parse string tags/binary annotations into int/bool/float.
// Disabled by default
ParseStringTags bool `mapstructure:"parse_string_tags"`

config.CustomConfigOptions
}

var _ config.CustomConfigOptions = (*Config)(nil)
var _ config.Receiver = (*Config)(nil)

// Validate checks the receiver configuration is valid
func (cfg *Config) Validate() error {
Expand Down
2 changes: 1 addition & 1 deletion service/internal/builder/factories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"context"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/component/componenttest"
componenttest "go.opentelemetry.io/collector/component/componenttest"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/exporter/exporterhelper"
"go.opentelemetry.io/collector/extension/extensionhelper"
Expand Down
6 changes: 2 additions & 4 deletions service/internal/builder/receivers_builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,7 @@ func TestBuildReceivers_BuildCustom(t *testing.T) {

func TestBuildReceivers_StartAll(t *testing.T) {
receivers := make(Receivers)
rcvCfg := &componenttest.NopConfig{}

rcvCfg := &testcomponents.ExampleReceiver{}
receiver := &testcomponents.ExampleReceiverProducer{}

receivers[rcvCfg] = &builtReceiver{
Expand All @@ -279,8 +278,7 @@ func TestBuildReceivers_StartAll(t *testing.T) {

func TestBuildReceivers_StopAll(t *testing.T) {
receivers := make(Receivers)
rcvCfg := &componenttest.NopConfig{}

rcvCfg := &testcomponents.ExampleReceiver{}
receiver := &testcomponents.ExampleReceiverProducer{}

receivers[rcvCfg] = &builtReceiver{
Expand Down

0 comments on commit 63e28c8

Please sign in to comment.