From 2195bbc09d54fe5df7440c057fcc5a328a99624d Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Mon, 13 Jul 2020 21:32:06 -0700 Subject: [PATCH] Add helper component to reduce boilerplate (#1334) Signed-off-by: Bogdan Drutu --- receiver/hostmetricsreceiver/factory.go | 145 ++++++++---------- receiver/hostmetricsreceiver/factory_test.go | 6 +- receiver/jaegerreceiver/config_test.go | 4 +- receiver/jaegerreceiver/factory.go | 126 +++++++-------- receiver/jaegerreceiver/factory_test.go | 38 ++--- .../jaegerreceiver/trace_receiver_test.go | 2 +- receiver/otlpreceiver/config_test.go | 4 +- receiver/otlpreceiver/factory.go | 104 ++++++------- receiver/otlpreceiver/factory_test.go | 8 +- receiver/otlpreceiver/otlp_test.go | 17 +- receiver/receiverhelper/factory.go | 121 +++++++++++++++ receiver/receiverhelper/factory_test.go | 81 ++++++++++ service/defaultcomponents/defaults.go | 4 +- service/defaultcomponents/defaults_test.go | 121 ++++++++------- testbed/testbed/receivers.go | 4 +- 15 files changed, 476 insertions(+), 309 deletions(-) create mode 100644 receiver/receiverhelper/factory.go create mode 100644 receiver/receiverhelper/factory_test.go diff --git a/receiver/hostmetricsreceiver/factory.go b/receiver/hostmetricsreceiver/factory.go index 95b97db412d1..6f59c1ab066c 100644 --- a/receiver/hostmetricsreceiver/factory.go +++ b/receiver/hostmetricsreceiver/factory.go @@ -23,7 +23,6 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/configerror" "go.opentelemetry.io/collector/config/configmodels" "go.opentelemetry.io/collector/consumer" "go.opentelemetry.io/collector/receiver/hostmetricsreceiver/internal" @@ -36,6 +35,7 @@ import ( "go.opentelemetry.io/collector/receiver/hostmetricsreceiver/internal/scraper/processesscraper" "go.opentelemetry.io/collector/receiver/hostmetricsreceiver/internal/scraper/processscraper" "go.opentelemetry.io/collector/receiver/hostmetricsreceiver/internal/scraper/swapscraper" + "go.opentelemetry.io/collector/receiver/receiverhelper" ) // This file implements Factory for HostMetrics receiver. @@ -46,99 +46,93 @@ const ( scrapersKey = "scrapers" ) -// Factory is the Factory for receiver. -type Factory struct { - scraperFactories map[string]internal.ScraperFactory - resourceScraperFactories map[string]internal.ResourceScraperFactory -} +var ( + scraperFactories = map[string]internal.ScraperFactory{ + cpuscraper.TypeStr: &cpuscraper.Factory{}, + diskscraper.TypeStr: &diskscraper.Factory{}, + loadscraper.TypeStr: &loadscraper.Factory{}, + filesystemscraper.TypeStr: &filesystemscraper.Factory{}, + memoryscraper.TypeStr: &memoryscraper.Factory{}, + networkscraper.TypeStr: &networkscraper.Factory{}, + processesscraper.TypeStr: &processesscraper.Factory{}, + swapscraper.TypeStr: &swapscraper.Factory{}, + } -// NewFactory creates a new factory for host metrics receiver. -func NewFactory() *Factory { - return &Factory{ - scraperFactories: map[string]internal.ScraperFactory{ - cpuscraper.TypeStr: &cpuscraper.Factory{}, - diskscraper.TypeStr: &diskscraper.Factory{}, - loadscraper.TypeStr: &loadscraper.Factory{}, - filesystemscraper.TypeStr: &filesystemscraper.Factory{}, - memoryscraper.TypeStr: &memoryscraper.Factory{}, - networkscraper.TypeStr: &networkscraper.Factory{}, - processesscraper.TypeStr: &processesscraper.Factory{}, - swapscraper.TypeStr: &swapscraper.Factory{}, - }, - resourceScraperFactories: map[string]internal.ResourceScraperFactory{ - processscraper.TypeStr: &processscraper.Factory{}, - }, + resourceScraperFactories = map[string]internal.ResourceScraperFactory{ + processscraper.TypeStr: &processscraper.Factory{}, } -} +) -// Type returns the type of the Receiver config created by this Factory. -func (f *Factory) Type() configmodels.Type { - return typeStr +// NewFactory creates a new factory for host metrics receiver. +func NewFactory() component.ReceiverFactory { + return receiverhelper.NewFactory( + typeStr, + createDefaultConfig, + receiverhelper.WithMetricsReceiver(createMetricsReceiver), + receiverhelper.WithCustomUnmarshaler(customUnmarshaler)) } -// CustomUnmarshaler returns custom unmarshaler for this config. -func (f *Factory) CustomUnmarshaler() component.CustomUnmarshaler { - return func(componentViperSection *viper.Viper, intoCfg interface{}) error { +// customUnmarshaler returns custom unmarshaler for this config. +func customUnmarshaler(componentViperSection *viper.Viper, intoCfg interface{}) error { - // load the non-dynamic config normally + // load the non-dynamic config normally - err := componentViperSection.Unmarshal(intoCfg) - if err != nil { - return err - } - - cfg, ok := intoCfg.(*Config) - if !ok { - return fmt.Errorf("config type not hostmetrics.Config") - } + err := componentViperSection.Unmarshal(intoCfg) + if err != nil { + return err + } - if cfg.CollectionInterval <= 0 { - return fmt.Errorf("collection_interval must be a positive duration") - } + cfg, ok := intoCfg.(*Config) + if !ok { + return fmt.Errorf("config type not hostmetrics.Config") + } - // dynamically load the individual collector configs based on the key name + if cfg.CollectionInterval <= 0 { + return fmt.Errorf("collection_interval must be a positive duration") + } - cfg.Scrapers = map[string]internal.Config{} + // dynamically load the individual collector configs based on the key name - scrapersViperSection := config.ViperSub(componentViperSection, scrapersKey) - if scrapersViperSection == nil || len(scrapersViperSection.AllKeys()) == 0 { - return fmt.Errorf("must specify at least one scraper when using hostmetrics receiver") - } + cfg.Scrapers = map[string]internal.Config{} - for key := range componentViperSection.GetStringMap(scrapersKey) { - factory, ok := f.getScraperFactory(key) - if !ok { - return fmt.Errorf("invalid scraper key: %s", key) - } + scrapersViperSection := config.ViperSub(componentViperSection, scrapersKey) + if scrapersViperSection == nil || len(scrapersViperSection.AllKeys()) == 0 { + return fmt.Errorf("must specify at least one scraper when using hostmetrics receiver") + } - collectorCfg := factory.CreateDefaultConfig() - collectorViperSection := config.ViperSub(scrapersViperSection, key) - err := collectorViperSection.UnmarshalExact(collectorCfg) - if err != nil { - return fmt.Errorf("error reading settings for scraper type %q: %v", key, err) - } + for key := range componentViperSection.GetStringMap(scrapersKey) { + factory, ok := getScraperFactory(key) + if !ok { + return fmt.Errorf("invalid scraper key: %s", key) + } - cfg.Scrapers[key] = collectorCfg + collectorCfg := factory.CreateDefaultConfig() + collectorViperSection := config.ViperSub(scrapersViperSection, key) + err := collectorViperSection.UnmarshalExact(collectorCfg) + if err != nil { + return fmt.Errorf("error reading settings for scraper type %q: %v", key, err) } - return nil + cfg.Scrapers[key] = collectorCfg } + + return nil } -func (f *Factory) getScraperFactory(key string) (internal.BaseFactory, bool) { - if factory, ok := f.scraperFactories[key]; ok { +func getScraperFactory(key string) (internal.BaseFactory, bool) { + if factory, ok := scraperFactories[key]; ok { return factory, true } - if factory, ok := f.resourceScraperFactories[key]; ok { + if factory, ok := resourceScraperFactories[key]; ok { return factory, true } return nil, false } -// CreateDefaultConfig creates the default configuration for receiver. -func (f *Factory) CreateDefaultConfig() configmodels.Receiver { +// createDefaultConfig creates the default configuration for receiver. +func createDefaultConfig() configmodels.Receiver { return &Config{ ReceiverSettings: configmodels.ReceiverSettings{ TypeVal: typeStr, @@ -148,27 +142,16 @@ func (f *Factory) CreateDefaultConfig() configmodels.Receiver { } } -// CreateTraceReceiver returns error as trace receiver is not applicable to host metrics receiver. -func (f *Factory) CreateTraceReceiver( - ctx context.Context, - params component.ReceiverCreateParams, - cfg configmodels.Receiver, - consumer consumer.TraceConsumer, -) (component.TraceReceiver, error) { - // Host Metrics does not support traces - return nil, configerror.ErrDataTypeIsNotSupported -} - -// CreateMetricsReceiver creates a metrics receiver based on provided config. -func (f *Factory) CreateMetricsReceiver( +// createMetricsReceiver creates a metrics receiver based on provided config. +func createMetricsReceiver( ctx context.Context, params component.ReceiverCreateParams, cfg configmodels.Receiver, consumer consumer.MetricsConsumer, ) (component.MetricsReceiver, error) { - config := cfg.(*Config) + oCfg := cfg.(*Config) - hmr, err := newHostMetricsReceiver(ctx, params.Logger, config, f.scraperFactories, f.resourceScraperFactories, consumer) + hmr, err := newHostMetricsReceiver(ctx, params.Logger, oCfg, scraperFactories, resourceScraperFactories, consumer) if err != nil { return nil, err } diff --git a/receiver/hostmetricsreceiver/factory_test.go b/receiver/hostmetricsreceiver/factory_test.go index 5f4a85458629..eb4d756a3e95 100644 --- a/receiver/hostmetricsreceiver/factory_test.go +++ b/receiver/hostmetricsreceiver/factory_test.go @@ -31,14 +31,14 @@ import ( var creationParams = component.ReceiverCreateParams{Logger: zap.NewNop()} func TestCreateDefaultConfig(t *testing.T) { - factory := &Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() assert.NotNil(t, cfg, "failed to create default config") assert.NoError(t, configcheck.ValidateConfig(cfg)) } func TestCreateReceiver(t *testing.T) { - factory := &Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() tReceiver, err := factory.CreateTraceReceiver(context.Background(), creationParams, cfg, nil) @@ -55,7 +55,7 @@ func TestCreateReceiver(t *testing.T) { func TestCreateReceiver_ScraperKeyConfigError(t *testing.T) { const errorKey string = "error" - factory := &Factory{} + factory := NewFactory() cfg := &Config{Scrapers: map[string]internal.Config{errorKey: &mockConfig{}}} _, err := factory.CreateMetricsReceiver(context.Background(), creationParams, cfg, nil) diff --git a/receiver/jaegerreceiver/config_test.go b/receiver/jaegerreceiver/config_test.go index 743fac55eb8c..7ed1dc9487e6 100644 --- a/receiver/jaegerreceiver/config_test.go +++ b/receiver/jaegerreceiver/config_test.go @@ -34,7 +34,7 @@ func TestLoadConfig(t *testing.T) { factories, err := config.ExampleComponents() assert.NoError(t, err) - factory := &Factory{} + factory := NewFactory() factories.Receivers[typeStr] = factory cfg, err := config.LoadConfigFile(t, path.Join(".", "testdata", "config.yaml"), factories) @@ -154,7 +154,7 @@ func TestFailedLoadConfig(t *testing.T) { factories, err := config.ExampleComponents() assert.NoError(t, err) - factory := &Factory{} + factory := NewFactory() factories.Receivers[typeStr] = factory _, err = config.LoadConfigFile(t, path.Join(".", "testdata", "bad_typo_default_proto_config.yaml"), factories) assert.EqualError(t, err, "error reading settings for receiver type \"jaeger\": unknown protocols in the Jaeger receiver") diff --git a/receiver/jaegerreceiver/factory.go b/receiver/jaegerreceiver/factory.go index 5fdafa52c03e..fbe45bf7a518 100644 --- a/receiver/jaegerreceiver/factory.go +++ b/receiver/jaegerreceiver/factory.go @@ -25,13 +25,13 @@ import ( "github.com/spf13/viper" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config/configerror" "go.opentelemetry.io/collector/config/configgrpc" "go.opentelemetry.io/collector/config/confighttp" "go.opentelemetry.io/collector/config/configmodels" "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/config/configprotocol" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/receiver/receiverhelper" ) const ( @@ -52,74 +52,68 @@ const ( defaultAgentRemoteSamplingHTTPPort = 5778 ) -// Factory is the factory for Jaeger receiver. -type Factory struct { +func NewFactory() component.ReceiverFactory { + return receiverhelper.NewFactory( + typeStr, + createDefaultConfig, + receiverhelper.WithTraceReceiver(createTraceReceiver), + receiverhelper.WithCustomUnmarshaler(customUnmarshaler)) } -// Type gets the type of the Receiver config created by this factory. -func (f *Factory) Type() configmodels.Type { - return typeStr -} - -// CustomUnmarshaler is used to add defaults for named but empty protocols -func (f *Factory) CustomUnmarshaler() component.CustomUnmarshaler { - return func(componentViperSection *viper.Viper, intoCfg interface{}) error { - if componentViperSection == nil || len(componentViperSection.AllKeys()) == 0 { - return fmt.Errorf("empty config for Jaeger receiver") - } +// customUnmarshaler is used to add defaults for named but empty protocols +func customUnmarshaler(componentViperSection *viper.Viper, intoCfg interface{}) error { + if componentViperSection == nil || len(componentViperSection.AllKeys()) == 0 { + return fmt.Errorf("empty config for Jaeger receiver") + } - componentViperSection.SetConfigType("yaml") + componentViperSection.SetConfigType("yaml") - // UnmarshalExact will not set struct properties to nil even if no key is provided, - // so set the protocol structs to nil where the keys were omitted. - err := componentViperSection.UnmarshalExact(intoCfg) - if err != nil { - return err - } + // UnmarshalExact will not set struct properties to nil even if no key is provided, + // so set the protocol structs to nil where the keys were omitted. + err := componentViperSection.UnmarshalExact(intoCfg) + if err != nil { + return err + } - receiverCfg, ok := intoCfg.(*Config) - if !ok { - return fmt.Errorf("config type not *jaegerreceiver.Config") - } + receiverCfg := intoCfg.(*Config) - protocols := componentViperSection.GetStringMap(protocolsFieldName) - if len(protocols) == 0 { - return fmt.Errorf("must specify at least one protocol when using the Jaeger receiver") - } + protocols := componentViperSection.GetStringMap(protocolsFieldName) + if len(protocols) == 0 { + return fmt.Errorf("must specify at least one protocol when using the Jaeger receiver") + } - knownProtocols := 0 - if _, ok := protocols[protoGRPC]; !ok { - receiverCfg.GRPC = nil - } else { - knownProtocols++ - } - if _, ok := protocols[protoThriftHTTP]; !ok { - receiverCfg.ThriftHTTP = nil - } else { - knownProtocols++ - } - if _, ok := protocols[protoThriftBinary]; !ok { - receiverCfg.ThriftBinary = nil - } else { - knownProtocols++ - } - if _, ok := protocols[protoThriftCompact]; !ok { - receiverCfg.ThriftCompact = nil - } else { - knownProtocols++ - } - // UnmarshalExact will ignore empty entries like a protocol with no values, so if a typo happened - // in the protocol that is intended to be enabled will not be enabled. So check if the protocols - // include only known protocols. - if len(protocols) != knownProtocols { - return fmt.Errorf("unknown protocols in the Jaeger receiver") - } - return nil + knownProtocols := 0 + if _, ok := protocols[protoGRPC]; !ok { + receiverCfg.GRPC = nil + } else { + knownProtocols++ + } + if _, ok := protocols[protoThriftHTTP]; !ok { + receiverCfg.ThriftHTTP = nil + } else { + knownProtocols++ } + if _, ok := protocols[protoThriftBinary]; !ok { + receiverCfg.ThriftBinary = nil + } else { + knownProtocols++ + } + if _, ok := protocols[protoThriftCompact]; !ok { + receiverCfg.ThriftCompact = nil + } else { + knownProtocols++ + } + // UnmarshalExact will ignore empty entries like a protocol with no values, so if a typo happened + // in the protocol that is intended to be enabled will not be enabled. So check if the protocols + // include only known protocols. + if len(protocols) != knownProtocols { + return fmt.Errorf("unknown protocols in the Jaeger receiver") + } + return nil } // CreateDefaultConfig creates the default configuration for Jaeger receiver. -func (f *Factory) CreateDefaultConfig() configmodels.Receiver { +func createDefaultConfig() configmodels.Receiver { return &Config{ ReceiverSettings: configmodels.ReceiverSettings{ TypeVal: typeStr, @@ -145,9 +139,9 @@ func (f *Factory) CreateDefaultConfig() configmodels.Receiver { } } -// CreateTraceReceiver creates a trace receiver based on provided config. -func (f *Factory) CreateTraceReceiver( - ctx context.Context, +// createTraceReceiver creates a trace receiver based on provided config. +func createTraceReceiver( + _ context.Context, params component.ReceiverCreateParams, cfg configmodels.Receiver, nextConsumer consumer.TraceConsumer, @@ -241,16 +235,6 @@ func (f *Factory) CreateTraceReceiver( return New(rCfg.Name(), &config, nextConsumer, params) } -// CreateMetricsReceiver creates a metrics receiver based on provided config. -func (f *Factory) CreateMetricsReceiver( - _ context.Context, - _ component.ReceiverCreateParams, - _ configmodels.Receiver, - _ consumer.MetricsConsumer, -) (component.MetricsReceiver, error) { - return nil, configerror.ErrDataTypeIsNotSupported -} - // extract the port number from string in "address:port" format. If the // port number cannot be extracted returns an error. func extractPortFromEndpoint(endpoint string) (int, error) { diff --git a/receiver/jaegerreceiver/factory_test.go b/receiver/jaegerreceiver/factory_test.go index f64203a6d438..982f56e09912 100644 --- a/receiver/jaegerreceiver/factory_test.go +++ b/receiver/jaegerreceiver/factory_test.go @@ -34,20 +34,20 @@ import ( ) func TestTypeStr(t *testing.T) { - factory := Factory{} + factory := NewFactory() assert.Equal(t, "jaeger", string(factory.Type())) } func TestCreateDefaultConfig(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() assert.NotNil(t, cfg, "failed to create default config") assert.NoError(t, configcheck.ValidateConfig(cfg)) } func TestCreateReceiver(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() // have to enable at least one protocol for the jaeger receiver to be created cfg.(*Config).Protocols.GRPC = &configgrpc.GRPCServerSettings{ @@ -68,7 +68,7 @@ func TestCreateReceiver(t *testing.T) { // default ports retrieved from https://www.jaegertracing.io/docs/1.16/deployment/ func TestCreateDefaultGRPCEndpoint(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.GRPC = &configgrpc.GRPCServerSettings{ @@ -85,7 +85,7 @@ func TestCreateDefaultGRPCEndpoint(t *testing.T) { } func TestCreateTLSGPRCEndpoint(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.GRPC = &configgrpc.GRPCServerSettings{ @@ -107,7 +107,7 @@ func TestCreateTLSGPRCEndpoint(t *testing.T) { } func TestCreateInvalidHTTPEndpoint(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.ThriftHTTP = &confighttp.HTTPServerSettings{ @@ -121,7 +121,7 @@ func TestCreateInvalidHTTPEndpoint(t *testing.T) { } func TestCreateInvalidThriftBinaryEndpoint(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.ThriftBinary = &configprotocol.ProtocolServerSettings{ @@ -135,7 +135,7 @@ func TestCreateInvalidThriftBinaryEndpoint(t *testing.T) { } func TestCreateInvalidThriftCompactEndpoint(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.ThriftCompact = &configprotocol.ProtocolServerSettings{ @@ -149,7 +149,7 @@ func TestCreateInvalidThriftCompactEndpoint(t *testing.T) { } func TestDefaultAgentRemoteSamplingEndpointAndPort(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() rCfg := cfg.(*Config) @@ -166,7 +166,7 @@ func TestDefaultAgentRemoteSamplingEndpointAndPort(t *testing.T) { } func TestAgentRemoteSamplingEndpoint(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() rCfg := cfg.(*Config) @@ -188,7 +188,7 @@ func TestAgentRemoteSamplingEndpoint(t *testing.T) { } func TestCreateNoPort(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.ThriftHTTP = &confighttp.HTTPServerSettings{ @@ -200,7 +200,7 @@ func TestCreateNoPort(t *testing.T) { } func TestCreateLargePort(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.ThriftHTTP = &confighttp.HTTPServerSettings{ @@ -212,7 +212,7 @@ func TestCreateLargePort(t *testing.T) { } func TestCreateInvalidHost(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.GRPC = &configgrpc.GRPCServerSettings{ @@ -228,7 +228,7 @@ func TestCreateInvalidHost(t *testing.T) { } func TestCreateNoProtocols(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols = Protocols{} @@ -238,7 +238,7 @@ func TestCreateNoProtocols(t *testing.T) { } func TestThriftBinaryBadPort(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.ThriftBinary = &configprotocol.ProtocolServerSettings{ @@ -250,7 +250,7 @@ func TestThriftBinaryBadPort(t *testing.T) { } func TestThriftCompactBadPort(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() cfg.(*Config).Protocols.ThriftCompact = &configprotocol.ProtocolServerSettings{ @@ -263,7 +263,7 @@ func TestThriftCompactBadPort(t *testing.T) { } func TestRemoteSamplingConfigPropagation(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() rCfg := cfg.(*Config) @@ -293,7 +293,7 @@ func TestRemoteSamplingConfigPropagation(t *testing.T) { } func TestRemoteSamplingFileRequiresGRPC(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() rCfg := cfg.(*Config) @@ -312,7 +312,7 @@ func TestRemoteSamplingFileRequiresGRPC(t *testing.T) { } func TestCustomUnmarshalErrors(t *testing.T) { - factory := Factory{} + factory := NewFactory() f := factory.CustomUnmarshaler() assert.NotNil(t, f, "custom unmarshal function should not be nil") diff --git a/receiver/jaegerreceiver/trace_receiver_test.go b/receiver/jaegerreceiver/trace_receiver_test.go index ebf6e9469ab6..431eabda275f 100644 --- a/receiver/jaegerreceiver/trace_receiver_test.go +++ b/receiver/jaegerreceiver/trace_receiver_test.go @@ -574,7 +574,7 @@ func TestSamplingStrategiesMutualTLS(t *testing.T) { port, err := randomAvailablePort() require.NoError(t, err) hostEndpoint := fmt.Sprintf("localhost:%d", port) - factory := &Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig().(*Config) cfg.RemoteSampling = &RemoteSamplingConfig{ GRPCClientSettings: configgrpc.GRPCClientSettings{ diff --git a/receiver/otlpreceiver/config_test.go b/receiver/otlpreceiver/config_test.go index 675ccd7efdeb..88f145507e8d 100644 --- a/receiver/otlpreceiver/config_test.go +++ b/receiver/otlpreceiver/config_test.go @@ -34,7 +34,7 @@ func TestLoadConfig(t *testing.T) { factories, err := config.ExampleComponents() assert.NoError(t, err) - factory := &Factory{} + factory := NewFactory() factories.Receivers[typeStr] = factory cfg, err := config.LoadConfigFile(t, path.Join(".", "testdata", "config.yaml"), factories) @@ -201,7 +201,7 @@ func TestFailedLoadConfig(t *testing.T) { factories, err := config.ExampleComponents() assert.NoError(t, err) - factory := &Factory{} + factory := NewFactory() factories.Receivers[typeStr] = factory _, err = config.LoadConfigFile(t, path.Join(".", "testdata", "typo_default_proto_config.yaml"), factories) assert.EqualError(t, err, `error reading settings for receiver type "otlp": unknown protocols in the OTLP receiver`) diff --git a/receiver/otlpreceiver/factory.go b/receiver/otlpreceiver/factory.go index 0ee55a5f7f22..32927176ad7d 100644 --- a/receiver/otlpreceiver/factory.go +++ b/receiver/otlpreceiver/factory.go @@ -26,6 +26,7 @@ import ( "go.opentelemetry.io/collector/config/configmodels" "go.opentelemetry.io/collector/config/confignet" "go.opentelemetry.io/collector/consumer" + "go.opentelemetry.io/collector/receiver/receiverhelper" ) const ( @@ -38,17 +39,17 @@ const ( protocolsFieldName = "protocols" ) -// Factory is the Factory for receiver. -type Factory struct { +func NewFactory() component.ReceiverFactory { + return receiverhelper.NewFactory( + typeStr, + createDefaultConfig, + receiverhelper.WithTraceReceiver(createTraceReceiver), + receiverhelper.WithMetricsReceiver(createMetricsReceiver), + receiverhelper.WithCustomUnmarshaler(customUnmarshaler)) } -// Type gets the type of the Receiver config created by this Factory. -func (f *Factory) Type() configmodels.Type { - return typeStr -} - -// CreateDefaultConfig creates the default configuration for receiver. -func (f *Factory) CreateDefaultConfig() configmodels.Receiver { +// createDefaultConfig creates the default configuration for receiver. +func createDefaultConfig() configmodels.Receiver { return &Config{ ReceiverSettings: configmodels.ReceiverSettings{ TypeVal: typeStr, @@ -70,61 +71,56 @@ func (f *Factory) CreateDefaultConfig() configmodels.Receiver { } } -// CustomUnmarshaler is used to add defaults for named but empty protocols -func (f *Factory) CustomUnmarshaler() component.CustomUnmarshaler { - return func(componentViperSection *viper.Viper, intoCfg interface{}) error { - if componentViperSection == nil || len(componentViperSection.AllKeys()) == 0 { - return fmt.Errorf("empty config for OTLP receiver") - } - // first load the config normally - err := componentViperSection.UnmarshalExact(intoCfg) - if err != nil { - return err - } - receiverCfg, ok := intoCfg.(*Config) - if !ok { - return fmt.Errorf("config type not *otlpreceiver.Config") - } - - // next manually search for protocols in viper, if a protocol is not present it means it is disable. - protocols := componentViperSection.GetStringMap(protocolsFieldName) - - // UnmarshalExact will ignore empty entries like a protocol with no values, so if a typo happened - // in the protocol that is intended to be enabled will not be enabled. So check if the protocols - // include only known protocols. - knownProtocols := 0 - if _, ok := protocols[protoGRPC]; !ok { - receiverCfg.GRPC = nil - } else { - knownProtocols++ - } +// customUnmarshaler is used to add defaults for named but empty protocols +func customUnmarshaler(componentViperSection *viper.Viper, intoCfg interface{}) error { + if componentViperSection == nil || len(componentViperSection.AllKeys()) == 0 { + return fmt.Errorf("empty config for OTLP receiver") + } + // first load the config normally + err := componentViperSection.UnmarshalExact(intoCfg) + if err != nil { + return err + } - if _, ok := protocols[protoHTTP]; !ok { - receiverCfg.HTTP = nil - } else { - knownProtocols++ - } + receiverCfg := intoCfg.(*Config) + // next manually search for protocols in viper, if a protocol is not present it means it is disable. + protocols := componentViperSection.GetStringMap(protocolsFieldName) + + // UnmarshalExact will ignore empty entries like a protocol with no values, so if a typo happened + // in the protocol that is intended to be enabled will not be enabled. So check if the protocols + // include only known protocols. + knownProtocols := 0 + if _, ok := protocols[protoGRPC]; !ok { + receiverCfg.GRPC = nil + } else { + knownProtocols++ + } - if len(protocols) != knownProtocols { - return fmt.Errorf("unknown protocols in the OTLP receiver") - } + if _, ok := protocols[protoHTTP]; !ok { + receiverCfg.HTTP = nil + } else { + knownProtocols++ + } - if receiverCfg.GRPC == nil && receiverCfg.HTTP == nil { - return fmt.Errorf("must specify at least one protocol when using the OTLP receiver") - } + if len(protocols) != knownProtocols { + return fmt.Errorf("unknown protocols in the OTLP receiver") + } - return nil + if receiverCfg.GRPC == nil && receiverCfg.HTTP == nil { + return fmt.Errorf("must specify at least one protocol when using the OTLP receiver") } + + return nil } // CreateTraceReceiver creates a trace receiver based on provided config. -func (f *Factory) CreateTraceReceiver( +func createTraceReceiver( ctx context.Context, _ component.ReceiverCreateParams, cfg configmodels.Receiver, nextConsumer consumer.TraceConsumer, ) (component.TraceReceiver, error) { - r, err := f.createReceiver(cfg) + r, err := createReceiver(cfg) if err != nil { return nil, err } @@ -135,13 +131,13 @@ func (f *Factory) CreateTraceReceiver( } // CreateMetricsReceiver creates a metrics receiver based on provided config. -func (f *Factory) CreateMetricsReceiver( +func createMetricsReceiver( ctx context.Context, _ component.ReceiverCreateParams, cfg configmodels.Receiver, consumer consumer.MetricsConsumer, ) (component.MetricsReceiver, error) { - r, err := f.createReceiver(cfg) + r, err := createReceiver(cfg) if err != nil { return nil, err } @@ -151,7 +147,7 @@ func (f *Factory) CreateMetricsReceiver( return r, nil } -func (f *Factory) createReceiver(cfg configmodels.Receiver) (*Receiver, error) { +func createReceiver(cfg configmodels.Receiver) (*Receiver, error) { rCfg := cfg.(*Config) // There must be one receiver for both metrics and traces. We maintain a map of diff --git a/receiver/otlpreceiver/factory_test.go b/receiver/otlpreceiver/factory_test.go index 1ade48d1f40d..d54cbd973cea 100644 --- a/receiver/otlpreceiver/factory_test.go +++ b/receiver/otlpreceiver/factory_test.go @@ -34,14 +34,14 @@ import ( ) func TestCreateDefaultConfig(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() assert.NotNil(t, cfg, "failed to create default config") assert.NoError(t, configcheck.ValidateConfig(cfg)) } func TestCreateReceiver(t *testing.T) { - factory := Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig() config := cfg.(*Config) @@ -59,7 +59,7 @@ func TestCreateReceiver(t *testing.T) { } func TestCreateTraceReceiver(t *testing.T) { - factory := Factory{} + factory := NewFactory() defaultReceiverSettings := configmodels.ReceiverSettings{ TypeVal: typeStr, NameVal: typeStr, @@ -144,7 +144,7 @@ func TestCreateTraceReceiver(t *testing.T) { } func TestCreateMetricReceiver(t *testing.T) { - factory := Factory{} + factory := NewFactory() defaultReceiverSettings := configmodels.ReceiverSettings{ TypeVal: typeStr, NameVal: typeStr, diff --git a/receiver/otlpreceiver/otlp_test.go b/receiver/otlpreceiver/otlp_test.go index ba0d809ed31a..0d4d469e4683 100644 --- a/receiver/otlpreceiver/otlp_test.go +++ b/receiver/otlpreceiver/otlp_test.go @@ -409,8 +409,7 @@ func TestGRPCInvalidTLSCredentials(t *testing.T) { } // TLS is resolved during Creation of the receiver for GRPC. - factory := &Factory{} - _, err := factory.createReceiver(cfg) + _, err := createReceiver(cfg) assert.EqualError(t, err, `failed to load TLS config: for auth via TLS, either both certificate and key must be supplied, or neither`) } @@ -433,13 +432,13 @@ func TestHTTPInvalidTLSCredentials(t *testing.T) { } // TLS is resolved during Start for HTTP. - r := newReceiver(t, &Factory{}, cfg, new(exportertest.SinkTraceExporter), new(exportertest.SinkMetricsExporter)) + r := newReceiver(t, NewFactory(), cfg, new(exportertest.SinkTraceExporter), new(exportertest.SinkMetricsExporter)) assert.EqualError(t, r.Start(context.Background(), componenttest.NewNopHost()), `failed to load TLS config: for auth via TLS, either both certificate and key must be supplied, or neither`) } func newGRPCReceiver(t *testing.T, name string, endpoint string, tc consumer.TraceConsumer, mc consumer.MetricsConsumer) *Receiver { - factory := &Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig().(*Config) cfg.SetName(name) cfg.GRPC.NetAddr.Endpoint = endpoint @@ -448,7 +447,7 @@ func newGRPCReceiver(t *testing.T, name string, endpoint string, tc consumer.Tra } func newHTTPReceiver(t *testing.T, name string, endpoint string, tc consumer.TraceConsumer, mc consumer.MetricsConsumer) *Receiver { - factory := &Factory{} + factory := NewFactory() cfg := factory.CreateDefaultConfig().(*Config) cfg.SetName(name) cfg.HTTP.Endpoint = endpoint @@ -456,17 +455,17 @@ func newHTTPReceiver(t *testing.T, name string, endpoint string, tc consumer.Tra return newReceiver(t, factory, cfg, tc, mc) } -func newReceiver(t *testing.T, factory *Factory, cfg *Config, tc consumer.TraceConsumer, mc consumer.MetricsConsumer) *Receiver { - r, err := factory.createReceiver(cfg) +func newReceiver(t *testing.T, factory component.ReceiverFactory, cfg *Config, tc consumer.TraceConsumer, mc consumer.MetricsConsumer) *Receiver { + r, err := createReceiver(cfg) require.NoError(t, err) if tc != nil { params := component.ReceiverCreateParams{} - _, err = factory.CreateTraceReceiver(context.Background(), params, cfg, tc) + _, err := factory.CreateTraceReceiver(context.Background(), params, cfg, tc) require.NoError(t, err) } if mc != nil { params := component.ReceiverCreateParams{} - _, err = factory.CreateMetricsReceiver(context.Background(), params, cfg, mc) + _, err := factory.CreateMetricsReceiver(context.Background(), params, cfg, mc) require.NoError(t, err) } return r diff --git a/receiver/receiverhelper/factory.go b/receiver/receiverhelper/factory.go new file mode 100644 index 000000000000..e4637f0a708f --- /dev/null +++ b/receiver/receiverhelper/factory.go @@ -0,0 +1,121 @@ +// Copyright 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 receiverhelper + +import ( + "context" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configerror" + "go.opentelemetry.io/collector/config/configmodels" + "go.opentelemetry.io/collector/consumer" +) + +// FactoryOption apply changes to ReceiverOptions. +type FactoryOption func(o *factory) + +// WithCustomUnmarshaler overrides the default "not available" CustomUnmarshaler. +func WithCustomUnmarshaler(customUnmarshaler component.CustomUnmarshaler) FactoryOption { + return func(o *factory) { + o.customUnmarshaler = customUnmarshaler + } +} + +// WithTraceReceiver overrides the default "error not supported" implementation for CreateTraceReceiver. +func WithTraceReceiver(createTraceReceiver CreateTraceReceiver) FactoryOption { + return func(o *factory) { + o.createTraceReceiver = createTraceReceiver + } +} + +// WithTraceReceiver overrides the default "error not supported" implementation for CreateMetricsReceiver. +func WithMetricsReceiver(createMetricsReceiver CreateMetricsReceiver) FactoryOption { + return func(o *factory) { + o.createMetricsReceiver = createMetricsReceiver + } +} + +// CreateDefaultConfig is the equivalent of component.ReceiverFactory.CreateDefaultConfig() +type CreateDefaultConfig func() configmodels.Receiver + +// CreateTraceReceiver is the equivalent of component.ReceiverFactory.CreateTraceReceiver() +type CreateTraceReceiver func(ctx context.Context, params component.ReceiverCreateParams, config configmodels.Receiver, nextConsumer consumer.TraceConsumer) (component.TraceReceiver, error) + +// CreateMetricsReceiver is the equivalent of component.ReceiverFactory.CreateMetricsReceiver() +type CreateMetricsReceiver func(ctx context.Context, params component.ReceiverCreateParams, config configmodels.Receiver, nextConsumer consumer.MetricsConsumer) (component.MetricsReceiver, error) + +// factory is the factory for Jaeger gRPC exporter. +type factory struct { + cfgType configmodels.Type + customUnmarshaler component.CustomUnmarshaler + createDefaultConfig CreateDefaultConfig + createTraceReceiver CreateTraceReceiver + createMetricsReceiver CreateMetricsReceiver +} + +// NewFactory returns a component.ReceiverFactory that only supports all types. +func NewFactory( + cfgType configmodels.Type, + createDefaultConfig CreateDefaultConfig, + options ...FactoryOption) component.ReceiverFactory { + f := &factory{ + cfgType: cfgType, + createDefaultConfig: createDefaultConfig, + } + for _, opt := range options { + opt(f) + } + return f +} + +// Type gets the type of the Receiver config created by this factory. +func (f *factory) Type() configmodels.Type { + return f.cfgType +} + +// CustomUnmarshaler returns a custom unmarshaler for the configuration or nil if +// there is no need for custom unmarshaling. +func (f *factory) CustomUnmarshaler() component.CustomUnmarshaler { + return f.customUnmarshaler +} + +// CreateDefaultConfig creates the default configuration for receiver. +func (f *factory) CreateDefaultConfig() configmodels.Receiver { + return f.createDefaultConfig() +} + +// CreateTraceReceiver creates a component.TraceReceiver based on this config. +func (f *factory) CreateTraceReceiver( + ctx context.Context, + params component.ReceiverCreateParams, + cfg configmodels.Receiver, + nextConsumer consumer.TraceConsumer) (component.TraceReceiver, error) { + if f.createTraceReceiver != nil { + return f.createTraceReceiver(ctx, params, cfg, nextConsumer) + } + return nil, configerror.ErrDataTypeIsNotSupported +} + +// CreateMetricsReceiver creates a consumer.MetricsConsumer based on this config. +func (f *factory) CreateMetricsReceiver( + ctx context.Context, + params component.ReceiverCreateParams, + cfg configmodels.Receiver, + nextConsumer consumer.MetricsConsumer) (component.MetricsReceiver, error) { + if f.createMetricsReceiver != nil { + return f.createMetricsReceiver(ctx, params, cfg, nextConsumer) + } + return nil, configerror.ErrDataTypeIsNotSupported +} diff --git a/receiver/receiverhelper/factory_test.go b/receiver/receiverhelper/factory_test.go new file mode 100644 index 000000000000..2f11a76f3094 --- /dev/null +++ b/receiver/receiverhelper/factory_test.go @@ -0,0 +1,81 @@ +// Copyright 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 receiverhelper + +import ( + "context" + "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configmodels" + "go.opentelemetry.io/collector/consumer" +) + +const typeStr = "test" + +var defaultCfg = &configmodels.ReceiverSettings{ + TypeVal: typeStr, + NameVal: typeStr, +} + +func TestNewFactory(t *testing.T) { + factory := NewFactory( + typeStr, + defaultConfig) + assert.EqualValues(t, typeStr, factory.Type()) + assert.EqualValues(t, defaultCfg, factory.CreateDefaultConfig()) + assert.Nil(t, factory.CustomUnmarshaler()) + _, err := factory.CreateTraceReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil) + assert.Error(t, err) + _, err = factory.CreateMetricsReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil) + assert.Error(t, err) +} + +func TestNewFactory_WithConstructors(t *testing.T) { + factory := NewFactory( + typeStr, + defaultConfig, + WithTraceReceiver(createTraceReceiver), + WithMetricsReceiver(createMetricsReceiver), + WithCustomUnmarshaler(customUnmarshaler)) + assert.EqualValues(t, typeStr, factory.Type()) + assert.EqualValues(t, defaultCfg, factory.CreateDefaultConfig()) + assert.NotNil(t, factory.CustomUnmarshaler()) + tr, err := factory.CreateTraceReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil) + assert.NoError(t, err) + assert.EqualValues(t, component.TraceReceiver(nil), tr) + mr, err := factory.CreateMetricsReceiver(context.Background(), component.ReceiverCreateParams{}, defaultCfg, nil) + assert.NoError(t, err) + assert.EqualValues(t, component.MetricsReceiver(nil), mr) +} + +func defaultConfig() configmodels.Receiver { + return defaultCfg +} + +func createTraceReceiver(context.Context, component.ReceiverCreateParams, configmodels.Receiver, consumer.TraceConsumer) (component.TraceReceiver, error) { + return nil, nil +} + +func createMetricsReceiver(context.Context, component.ReceiverCreateParams, configmodels.Receiver, consumer.MetricsConsumer) (component.MetricsReceiver, error) { + return nil, nil +} + +func customUnmarshaler(*viper.Viper, interface{}) error { + return nil +} diff --git a/service/defaultcomponents/defaults.go b/service/defaultcomponents/defaults.go index 16fef55d9918..b3d63c065fd7 100644 --- a/service/defaultcomponents/defaults.go +++ b/service/defaultcomponents/defaults.go @@ -64,11 +64,11 @@ func Components() ( } receivers, err := component.MakeReceiverFactoryMap( - &jaegerreceiver.Factory{}, + jaegerreceiver.NewFactory(), &zipkinreceiver.Factory{}, &prometheusreceiver.Factory{}, &opencensusreceiver.Factory{}, - &otlpreceiver.Factory{}, + otlpreceiver.NewFactory(), hostmetricsreceiver.NewFactory(), ) if err != nil { diff --git a/service/defaultcomponents/defaults_test.go b/service/defaultcomponents/defaults_test.go index ff9ffbd87b65..de2b68051e19 100644 --- a/service/defaultcomponents/defaults_test.go +++ b/service/defaultcomponents/defaults_test.go @@ -20,75 +20,78 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configmodels" - "go.opentelemetry.io/collector/exporter/fileexporter" - "go.opentelemetry.io/collector/exporter/jaegerexporter" - "go.opentelemetry.io/collector/exporter/loggingexporter" - "go.opentelemetry.io/collector/exporter/opencensusexporter" - "go.opentelemetry.io/collector/exporter/otlpexporter" - "go.opentelemetry.io/collector/exporter/prometheusexporter" - "go.opentelemetry.io/collector/exporter/zipkinexporter" - "go.opentelemetry.io/collector/extension/healthcheckextension" - "go.opentelemetry.io/collector/extension/pprofextension" - "go.opentelemetry.io/collector/extension/zpagesextension" - "go.opentelemetry.io/collector/processor/attributesprocessor" - "go.opentelemetry.io/collector/processor/batchprocessor" - "go.opentelemetry.io/collector/processor/filterprocessor" - "go.opentelemetry.io/collector/processor/memorylimiter" - "go.opentelemetry.io/collector/processor/queuedprocessor" - "go.opentelemetry.io/collector/processor/resourceprocessor" - "go.opentelemetry.io/collector/processor/samplingprocessor/probabilisticsamplerprocessor" - "go.opentelemetry.io/collector/processor/samplingprocessor/tailsamplingprocessor" - "go.opentelemetry.io/collector/processor/spanprocessor" - "go.opentelemetry.io/collector/receiver/hostmetricsreceiver" - "go.opentelemetry.io/collector/receiver/jaegerreceiver" - "go.opentelemetry.io/collector/receiver/opencensusreceiver" - "go.opentelemetry.io/collector/receiver/otlpreceiver" - "go.opentelemetry.io/collector/receiver/prometheusreceiver" - "go.opentelemetry.io/collector/receiver/zipkinreceiver" ) func TestDefaultComponents(t *testing.T) { - expectedExtensions := map[configmodels.Type]component.ExtensionFactory{ - "health_check": &healthcheckextension.Factory{}, - "pprof": &pprofextension.Factory{}, - "zpages": &zpagesextension.Factory{}, + expectedExtensions := []configmodels.Type{ + "health_check", + "pprof", + "zpages", } - expectedReceivers := map[configmodels.Type]component.ReceiverFactoryBase{ - "jaeger": &jaegerreceiver.Factory{}, - "zipkin": &zipkinreceiver.Factory{}, - "prometheus": &prometheusreceiver.Factory{}, - "opencensus": &opencensusreceiver.Factory{}, - "otlp": &otlpreceiver.Factory{}, - "hostmetrics": hostmetricsreceiver.NewFactory(), + expectedReceivers := []configmodels.Type{ + "jaeger", + "zipkin", + "prometheus", + "opencensus", + "otlp", + "hostmetrics", } - expectedProcessors := map[configmodels.Type]component.ProcessorFactoryBase{ - "attributes": &attributesprocessor.Factory{}, - "resource": &resourceprocessor.Factory{}, - "queued_retry": &queuedprocessor.Factory{}, - "batch": &batchprocessor.Factory{}, - "memory_limiter": &memorylimiter.Factory{}, - "tail_sampling": &tailsamplingprocessor.Factory{}, - "probabilistic_sampler": &probabilisticsamplerprocessor.Factory{}, - "span": &spanprocessor.Factory{}, - "filter": &filterprocessor.Factory{}, + expectedProcessors := []configmodels.Type{ + "attributes", + "resource", + "queued_retry", + "batch", + "memory_limiter", + "tail_sampling", + "probabilistic_sampler", + "span", + "filter", } - expectedExporters := map[configmodels.Type]component.ExporterFactoryBase{ - "opencensus": &opencensusexporter.Factory{}, - "prometheus": &prometheusexporter.Factory{}, - "logging": &loggingexporter.Factory{}, - "zipkin": &zipkinexporter.Factory{}, - "jaeger": &jaegerexporter.Factory{}, - "file": &fileexporter.Factory{}, - "otlp": &otlpexporter.Factory{}, + expectedExporters := []configmodels.Type{ + "opencensus", + "prometheus", + "logging", + "zipkin", + "jaeger", + "file", + "otlp", } factories, err := Components() assert.NoError(t, err) - assert.Equal(t, expectedExtensions, factories.Extensions) - assert.Equal(t, expectedReceivers, factories.Receivers) - assert.Equal(t, expectedProcessors, factories.Processors) - assert.Equal(t, expectedExporters, factories.Exporters) + + exts := factories.Extensions + assert.Equal(t, len(expectedExtensions), len(exts)) + for _, k := range expectedExtensions { + v, ok := exts[k] + assert.True(t, ok) + assert.Equal(t, k, v.Type()) + } + + recvs := factories.Receivers + assert.Equal(t, len(expectedReceivers), len(recvs)) + for _, k := range expectedReceivers { + v, ok := recvs[k] + require.True(t, ok) + assert.Equal(t, k, v.Type()) + } + + procs := factories.Processors + assert.Equal(t, len(expectedProcessors), len(procs)) + for _, k := range expectedProcessors { + v, ok := procs[k] + require.True(t, ok) + assert.Equal(t, k, v.Type()) + } + + exps := factories.Exporters + assert.Equal(t, len(expectedExporters), len(exps)) + for _, k := range expectedExporters { + v, ok := exps[k] + require.True(t, ok) + assert.Equal(t, k, v.Type()) + } } diff --git a/testbed/testbed/receivers.go b/testbed/testbed/receivers.go index 98184ba3cbde..e17b772311e3 100644 --- a/testbed/testbed/receivers.go +++ b/testbed/testbed/receivers.go @@ -145,7 +145,7 @@ func NewJaegerDataReceiver(port int) *JaegerDataReceiver { } func (jr *JaegerDataReceiver) Start(tc *MockTraceConsumer, _ *MockMetricConsumer) error { - factory := jaegerreceiver.Factory{} + factory := jaegerreceiver.NewFactory() cfg := factory.CreateDefaultConfig().(*jaegerreceiver.Config) cfg.SetName(jr.ProtocolName()) cfg.Protocols.GRPC = &configgrpc.GRPCServerSettings{ @@ -196,7 +196,7 @@ func NewOTLPDataReceiver(port int) *OTLPDataReceiver { } func (or *OTLPDataReceiver) Start(tc *MockTraceConsumer, mc *MockMetricConsumer) error { - factory := otlpreceiver.Factory{} + factory := otlpreceiver.NewFactory() cfg := factory.CreateDefaultConfig().(*otlpreceiver.Config) cfg.SetName(or.ProtocolName()) cfg.GRPC.NetAddr = confignet.NetAddr{Endpoint: fmt.Sprintf("localhost:%d", or.Port), Transport: "tcp"}