Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move everything from receiverhelper to component. #4891

Merged
merged 1 commit into from
Feb 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
- Deprecated `exporterhelper.WithMetrics` in favour of `component.WithMetricsExporter`
- Deprecated `exporterhelper.WithLogs` in favour of `component.WithLogsExporter`
- Deprecated `exporterhelper.NewFactory` in favour of `component.NewExporterFactory`
- Move helpers from receiverhelper to component (#4891)
- Deprecated `receiverhelper.CreateDefaultConfig` in favour of `component.ReceiverDefaultConfigFunc`
- Deprecated `receiverhelper.WithTraces` in favour of `component.WithTracesReceiver`
- Deprecated `receiverhelper.WithMetrics` in favour of `component.WithMetricsReceiver`
- Deprecated `receiverhelper.WithLogs` in favour of `component.WithLogsReceiver`
- Deprecated `receiverhelper.NewFactory` in favour of `component.NewReceiverFactory`

### 💡 Enhancements 💡

Expand Down
55 changes: 14 additions & 41 deletions component/componenttest/nop_receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/consumer"
"go.opentelemetry.io/collector/internal/internalinterface"
)

// NewNopReceiverCreateSettings returns a new nop settings for Create*Receiver functions.
Expand All @@ -35,57 +34,31 @@ type nopReceiverConfig struct {
config.ReceiverSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct
}

// nopReceiverFactory is factory for nopReceiver.
type nopReceiverFactory struct {
internalinterface.BaseInternal
}

var nopReceiverFactoryInstance = &nopReceiverFactory{}
var nopReceiverFactory = component.NewReceiverFactory(
"nop",
func() config.Receiver {
return &nopReceiverConfig{
ReceiverSettings: config.NewReceiverSettings(config.NewComponentID("nop")),
}
},
component.WithTracesReceiver(createTracesReceiver),
component.WithMetricsReceiver(createMetricsReceiver),
component.WithLogsReceiver(createLogsReceiver))

// NewNopReceiverFactory returns a component.ReceiverFactory that constructs nop receivers.
func NewNopReceiverFactory() component.ReceiverFactory {
return nopReceiverFactoryInstance
}

// Type gets the type of the Receiver config created by this factory.
func (f *nopReceiverFactory) Type() config.Type {
return config.NewComponentID("nop").Type()
}

// CreateDefaultConfig creates the default configuration for the Receiver.
func (f *nopReceiverFactory) CreateDefaultConfig() config.Receiver {
return &nopReceiverConfig{
ReceiverSettings: config.NewReceiverSettings(config.NewComponentID("nop")),
}
return nopReceiverFactory
}

// CreateTracesReceiver implements component.ReceiverFactory interface.
func (f *nopReceiverFactory) CreateTracesReceiver(
_ context.Context,
_ component.ReceiverCreateSettings,
_ config.Receiver,
_ consumer.Traces,
) (component.TracesReceiver, error) {
func createTracesReceiver(context.Context, component.ReceiverCreateSettings, config.Receiver, consumer.Traces) (component.TracesReceiver, error) {
return nopReceiverInstance, nil
}

// CreateMetricsReceiver implements component.ReceiverFactory interface.
func (f *nopReceiverFactory) CreateMetricsReceiver(
_ context.Context,
_ component.ReceiverCreateSettings,
_ config.Receiver,
_ consumer.Metrics,
) (component.MetricsReceiver, error) {
func createMetricsReceiver(context.Context, component.ReceiverCreateSettings, config.Receiver, consumer.Metrics) (component.MetricsReceiver, error) {
return nopReceiverInstance, nil
}

// CreateLogsReceiver implements component.ReceiverFactory interface.
func (f *nopReceiverFactory) CreateLogsReceiver(
_ context.Context,
_ component.ReceiverCreateSettings,
_ config.Receiver,
_ consumer.Logs,
) (component.LogsReceiver, error) {
func createLogsReceiver(context.Context, component.ReceiverCreateSettings, config.Receiver, consumer.Logs) (component.LogsReceiver, error) {
return nopReceiverInstance, nil
}

Expand Down
38 changes: 38 additions & 0 deletions component/factories_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,44 @@ func TestMakeExtensionFactoryMap(t *testing.T) {
}
}

func TestMakeReceiverFactoryMap(t *testing.T) {
type testCase struct {
name string
in []ReceiverFactory
out map[config.Type]ReceiverFactory
}

p1 := NewReceiverFactory("p1", nil)
p2 := NewReceiverFactory("p2", nil)
testCases := []testCase{
{
name: "different names",
in: []ReceiverFactory{p1, p2},
out: map[config.Type]ReceiverFactory{
p1.Type(): p1,
p2.Type(): p2,
},
},
{
name: "same name",
in: []ReceiverFactory{p1, p2, NewReceiverFactory("p1", nil)},
},
}

for i := range testCases {
tt := testCases[i]
t.Run(tt.name, func(t *testing.T) {
out, err := MakeReceiverFactoryMap(tt.in...)
if tt.out == nil {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.Equal(t, tt.out, out)
})
}
}

func TestMakeProcessorFactoryMap(t *testing.T) {
type testCase struct {
name string
Expand Down
112 changes: 109 additions & 3 deletions component/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ package component // import "go.opentelemetry.io/collector/component"
import (
"context"

"go.opentelemetry.io/collector/component/componenterror"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/consumer"
"go.opentelemetry.io/collector/internal/internalinterface"
)

// Receiver allows the collector to receive metrics, traces and logs.
Expand Down Expand Up @@ -97,11 +99,10 @@ type ReceiverCreateSettings struct {
BuildInfo BuildInfo
}

// ReceiverFactory can create TracesReceiver, MetricsReceiver and
// and LogsReceiver. This is the new preferred factory type to create receivers.
// ReceiverFactory is factory interface for receivers.
//
// This interface cannot be directly implemented. Implementations must
// use the receiverhelper.NewFactory to implement it.
// use the NewReceiverFactory to implement it.
type ReceiverFactory interface {
Factory

Expand Down Expand Up @@ -132,3 +133,108 @@ type ReceiverFactory interface {
CreateLogsReceiver(ctx context.Context, set ReceiverCreateSettings,
cfg config.Receiver, nextConsumer consumer.Logs) (LogsReceiver, error)
}

// ReceiverFactoryOption apply changes to ReceiverOptions.
type ReceiverFactoryOption func(o *receiverFactory)

// ReceiverCreateDefaultConfigFunc is the equivalent of ReceiverFactory.CreateDefaultConfig().
type ReceiverCreateDefaultConfigFunc func() config.Receiver

// CreateDefaultConfig implements ReceiverFactory.CreateDefaultConfig().
func (f ReceiverCreateDefaultConfigFunc) CreateDefaultConfig() config.Receiver {
return f()
}

// CreateTracesReceiverFunc is the equivalent of ReceiverFactory.CreateTracesReceiver().
type CreateTracesReceiverFunc func(context.Context, ReceiverCreateSettings, config.Receiver, consumer.Traces) (TracesReceiver, error)

// CreateTracesReceiver implements ReceiverFactory.CreateTracesReceiver().
func (f CreateTracesReceiverFunc) CreateTracesReceiver(
ctx context.Context,
set ReceiverCreateSettings,
cfg config.Receiver,
nextConsumer consumer.Traces) (TracesReceiver, error) {
if f == nil {
return nil, componenterror.ErrDataTypeIsNotSupported
}
return f(ctx, set, cfg, nextConsumer)
}

// CreateMetricsReceiverFunc is the equivalent of ReceiverFactory.CreateMetricsReceiver().
type CreateMetricsReceiverFunc func(context.Context, ReceiverCreateSettings, config.Receiver, consumer.Metrics) (MetricsReceiver, error)

// CreateMetricsReceiver implements ReceiverFactory.CreateMetricsReceiver().
func (f CreateMetricsReceiverFunc) CreateMetricsReceiver(
ctx context.Context,
set ReceiverCreateSettings,
cfg config.Receiver,
nextConsumer consumer.Metrics,
) (MetricsReceiver, error) {
if f == nil {
return nil, componenterror.ErrDataTypeIsNotSupported
}
return f(ctx, set, cfg, nextConsumer)
}

// CreateLogsReceiverFunc is the equivalent of ReceiverFactory.CreateLogsReceiver().
type CreateLogsReceiverFunc func(context.Context, ReceiverCreateSettings, config.Receiver, consumer.Logs) (LogsReceiver, error)

// CreateLogsReceiver implements ReceiverFactory.CreateLogsReceiver().
func (f CreateLogsReceiverFunc) CreateLogsReceiver(
ctx context.Context,
set ReceiverCreateSettings,
cfg config.Receiver,
nextConsumer consumer.Logs,
) (LogsReceiver, error) {
if f == nil {
return nil, componenterror.ErrDataTypeIsNotSupported
}
return f(ctx, set, cfg, nextConsumer)
}

type receiverFactory struct {
internalinterface.BaseInternal
cfgType config.Type
ReceiverCreateDefaultConfigFunc
CreateTracesReceiverFunc
CreateMetricsReceiverFunc
CreateLogsReceiverFunc
}

// WithTracesReceiver overrides the default "error not supported" implementation for CreateTracesReceiver.
func WithTracesReceiver(createTracesReceiver CreateTracesReceiverFunc) ReceiverFactoryOption {
return func(o *receiverFactory) {
o.CreateTracesReceiverFunc = createTracesReceiver
}
}

// WithMetricsReceiver overrides the default "error not supported" implementation for CreateMetricsReceiver.
func WithMetricsReceiver(createMetricsReceiver CreateMetricsReceiverFunc) ReceiverFactoryOption {
return func(o *receiverFactory) {
o.CreateMetricsReceiverFunc = createMetricsReceiver
}
}

// WithLogsReceiver overrides the default "error not supported" implementation for CreateLogsReceiver.
func WithLogsReceiver(createLogsReceiver CreateLogsReceiverFunc) ReceiverFactoryOption {
return func(o *receiverFactory) {
o.CreateLogsReceiverFunc = createLogsReceiver
}
}

// NewReceiverFactory returns a ReceiverFactory.
func NewReceiverFactory(cfgType config.Type, createDefaultConfig ReceiverCreateDefaultConfigFunc, options ...ReceiverFactoryOption) ReceiverFactory {
f := &receiverFactory{
cfgType: cfgType,
ReceiverCreateDefaultConfigFunc: createDefaultConfig,
}
for _, opt := range options {
opt(f)
}
return f
}

// Type returns the type of the Receiver created by this ReceiverFactory.
func (f *receiverFactory) Type() config.Type {
return f.cfgType
}
82 changes: 44 additions & 38 deletions component/receiver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,55 +15,61 @@
package component

import (
"context"
"testing"

"github.com/stretchr/testify/assert"

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

type TestReceiverFactory struct {
ReceiverFactory
name config.Type
func TestNewReceiverFactory(t *testing.T) {
const typeStr = "test"
defaultCfg := config.NewReceiverSettings(config.NewComponentID(typeStr))
factory := NewReceiverFactory(
typeStr,
func() config.Receiver { return &defaultCfg })
assert.EqualValues(t, typeStr, factory.Type())
assert.EqualValues(t, &defaultCfg, factory.CreateDefaultConfig())
_, err := factory.CreateTracesReceiver(context.Background(), ReceiverCreateSettings{}, &defaultCfg, nil)
assert.Error(t, err)
_, err = factory.CreateMetricsReceiver(context.Background(), ReceiverCreateSettings{}, &defaultCfg, nil)
assert.Error(t, err)
_, err = factory.CreateLogsReceiver(context.Background(), ReceiverCreateSettings{}, &defaultCfg, nil)
assert.Error(t, err)
}

// Type gets the type of the Receiver config created by this factory.
func (f *TestReceiverFactory) Type() config.Type {
return f.name
func TestNewReceiverFactory_WithOptions(t *testing.T) {
const typeStr = "test"
defaultCfg := config.NewReceiverSettings(config.NewComponentID(typeStr))
factory := NewReceiverFactory(
typeStr,
func() config.Receiver { return &defaultCfg },
WithTracesReceiver(createTracesReceiver),
WithMetricsReceiver(createMetricsReceiver),
WithLogsReceiver(createLogsReceiver))
assert.EqualValues(t, typeStr, factory.Type())
assert.EqualValues(t, &defaultCfg, factory.CreateDefaultConfig())

_, err := factory.CreateTracesReceiver(context.Background(), ReceiverCreateSettings{}, &defaultCfg, nil)
assert.NoError(t, err)

_, err = factory.CreateMetricsReceiver(context.Background(), ReceiverCreateSettings{}, &defaultCfg, nil)
assert.NoError(t, err)

_, err = factory.CreateLogsReceiver(context.Background(), ReceiverCreateSettings{}, &defaultCfg, nil)
assert.NoError(t, err)
}

func TestBuildReceivers(t *testing.T) {
type testCase struct {
in []ReceiverFactory
out map[config.Type]ReceiverFactory
}
func createTracesReceiver(context.Context, ReceiverCreateSettings, config.Receiver, consumer.Traces) (TracesReceiver, error) {
return nil, nil
}

testCases := []testCase{
{
in: []ReceiverFactory{
&TestReceiverFactory{name: "e1"},
&TestReceiverFactory{name: "e2"},
},
out: map[config.Type]ReceiverFactory{
"e1": &TestReceiverFactory{name: "e1"},
"e2": &TestReceiverFactory{name: "e2"},
},
},
{
in: []ReceiverFactory{
&TestReceiverFactory{name: "e1"},
&TestReceiverFactory{name: "e1"},
},
},
}
func createMetricsReceiver(context.Context, ReceiverCreateSettings, config.Receiver, consumer.Metrics) (MetricsReceiver, error) {
return nil, nil
}

for _, c := range testCases {
out, err := MakeReceiverFactoryMap(c.in...)
if c.out == nil {
assert.Error(t, err)
continue
}
assert.NoError(t, err)
assert.Equal(t, c.out, out)
}
func createLogsReceiver(context.Context, ReceiverCreateSettings, config.Receiver, consumer.Logs) (LogsReceiver, error) {
return nil, nil
}
Loading