diff --git a/.chloggen/avoid-internal-2.yaml b/.chloggen/avoid-internal-2.yaml new file mode 100644 index 00000000000..d52dab7c1d2 --- /dev/null +++ b/.chloggen/avoid-internal-2.yaml @@ -0,0 +1,20 @@ +# Use this changelog template to create an entry for release notes. + +# 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: options + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Avoid using private types in public APIs and also protect options to be implemented outside this module. + +# One or more tracking issues or pull requests related to the change +issues: [11054] + +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [api] diff --git a/config/confighttp/confighttp.go b/config/confighttp/confighttp.go index ec7c3197de9..4c38d3015a7 100644 --- a/config/confighttp/confighttp.go +++ b/config/confighttp/confighttp.go @@ -381,25 +381,33 @@ type toServerOptions struct { // ToServerOption is an option to change the behavior of the HTTP server // returned by ServerConfig.ToServer(). -type ToServerOption func(opts *toServerOptions) +type ToServerOption interface { + apply(*toServerOptions) +} + +type toServerOptionFunc func(*toServerOptions) + +func (of toServerOptionFunc) apply(e *toServerOptions) { + of(e) +} // WithErrorHandler overrides the HTTP error handler that gets invoked // when there is a failure inside httpContentDecompressor. func WithErrorHandler(e func(w http.ResponseWriter, r *http.Request, errorMsg string, statusCode int)) ToServerOption { - return func(opts *toServerOptions) { + return toServerOptionFunc(func(opts *toServerOptions) { opts.errHandler = e - } + }) } // WithDecoder provides support for additional decoders to be configured // by the caller. func WithDecoder(key string, dec func(body io.ReadCloser) (io.ReadCloser, error)) ToServerOption { - return func(opts *toServerOptions) { + return toServerOptionFunc(func(opts *toServerOptions) { if opts.decoders == nil { opts.decoders = map[string]func(body io.ReadCloser) (io.ReadCloser, error){} } opts.decoders[key] = dec - } + }) } // ToServer creates an http.Server from settings object. @@ -408,7 +416,7 @@ func (hss *ServerConfig) ToServer(_ context.Context, host component.Host, settin serverOpts := &toServerOptions{} for _, o := range opts { - o(serverOpts) + o.apply(serverOpts) } if hss.MaxRequestBodySize <= 0 { diff --git a/confmap/provider.go b/confmap/provider.go index 91d513fad37..daf508bf925 100644 --- a/confmap/provider.go +++ b/confmap/provider.go @@ -112,21 +112,29 @@ type retrievedSettings struct { } // RetrievedOption options to customize Retrieved values. -type RetrievedOption func(*retrievedSettings) +type RetrievedOption interface { + apply(*retrievedSettings) +} + +type retrievedOptionFunc func(*retrievedSettings) + +func (of retrievedOptionFunc) apply(e *retrievedSettings) { + of(e) +} // WithRetrievedClose overrides the default Retrieved.Close function. // The default Retrieved.Close function does nothing and always returns nil. func WithRetrievedClose(closeFunc CloseFunc) RetrievedOption { - return func(settings *retrievedSettings) { + return retrievedOptionFunc(func(settings *retrievedSettings) { settings.closeFunc = closeFunc - } + }) } func withStringRepresentation(stringRepresentation string) RetrievedOption { - return func(settings *retrievedSettings) { + return retrievedOptionFunc(func(settings *retrievedSettings) { settings.stringRepresentation = stringRepresentation settings.isSetString = true - } + }) } // NewRetrievedFromYAML returns a new Retrieved instance that contains the deserialized data from the yaml bytes. @@ -162,7 +170,7 @@ func NewRetrieved(rawConf any, opts ...RetrievedOption) (*Retrieved, error) { } set := retrievedSettings{} for _, opt := range opts { - opt(&set) + opt.apply(&set) } return &Retrieved{ rawConf: rawConf, diff --git a/consumer/consumer.go b/consumer/consumer.go index 64076655f20..b1b588a85c0 100644 --- a/consumer/consumer.go +++ b/consumer/consumer.go @@ -20,7 +20,7 @@ type Option = internal.Option // WithCapabilities overrides the default GetCapabilities function for a processor. // The default GetCapabilities function returns mutable capabilities. func WithCapabilities(capabilities Capabilities) Option { - return func(o *internal.BaseImpl) { + return internal.OptionFunc(func(o *internal.BaseImpl) { o.Cap = capabilities - } + }) } diff --git a/consumer/internal/consumer.go b/consumer/internal/consumer.go index 1f2b5683b22..45c90dd4341 100644 --- a/consumer/internal/consumer.go +++ b/consumer/internal/consumer.go @@ -22,7 +22,15 @@ type BaseImpl struct { } // Option to construct new consumers. -type Option func(*BaseImpl) +type Option interface { + apply(*BaseImpl) +} + +type OptionFunc func(*BaseImpl) + +func (of OptionFunc) apply(e *BaseImpl) { + of(e) +} // Capabilities returns the capabilities of the component func (bs BaseImpl) Capabilities() Capabilities { @@ -35,7 +43,7 @@ func NewBaseImpl(options ...Option) *BaseImpl { } for _, op := range options { - op(bs) + op.apply(bs) } return bs diff --git a/exporter/exporterhelper/common.go b/exporter/exporterhelper/common.go index 0a3238d3561..5b8a2a51767 100644 --- a/exporter/exporterhelper/common.go +++ b/exporter/exporterhelper/common.go @@ -44,53 +44,61 @@ func (b *baseRequestSender) setNextSender(nextSender requestSender) { type obsrepSenderFactory func(obsrep *obsReport) requestSender // Option apply changes to baseExporter. -type Option func(*baseExporter) error +type Option interface { + apply(*baseExporter) error +} + +type optionFunc func(*baseExporter) error + +func (of optionFunc) apply(e *baseExporter) error { + return of(e) +} // WithStart overrides the default Start function for an exporter. // The default start function does nothing and always returns nil. func WithStart(start component.StartFunc) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { o.StartFunc = start return nil - } + }) } // WithShutdown overrides the default Shutdown function for an exporter. // The default shutdown function does nothing and always returns nil. func WithShutdown(shutdown component.ShutdownFunc) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { o.ShutdownFunc = shutdown return nil - } + }) } -// WithTimeout overrides the default TimeoutConfig for an exporter. -// The default TimeoutConfig is 5 seconds. +// WithTimeout overrides the default TimeoutSettings for an exporter. +// The default TimeoutSettings is 5 seconds. func WithTimeout(timeoutConfig TimeoutConfig) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { o.timeoutSender.cfg = timeoutConfig return nil - } + }) } // WithRetry overrides the default configretry.BackOffConfig for an exporter. // The default configretry.BackOffConfig is to disable retries. func WithRetry(config configretry.BackOffConfig) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { if !config.Enabled { o.exportFailureMessage += " Try enabling retry_on_failure config option to retry on retryable errors." return nil } o.retrySender = newRetrySender(config, o.set) return nil - } + }) } // WithQueue overrides the default QueueConfig for an exporter. // The default QueueConfig is to disable queueing. // This option cannot be used with the new exporter helpers New[Traces|Metrics|Logs]RequestExporter. func WithQueue(config QueueConfig) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { if o.marshaler == nil || o.unmarshaler == nil { return fmt.Errorf("WithQueue option is not available for the new request exporters, use WithRequestQueue instead") } @@ -112,7 +120,7 @@ func WithQueue(config QueueConfig) Option { }) o.queueSender = newQueueSender(q, o.set, config.NumConsumers, o.exportFailureMessage, o.obsrep) return nil - } + }) } // WithRequestQueue enables queueing for an exporter. @@ -120,7 +128,7 @@ func WithQueue(config QueueConfig) Option { // Experimental: This API is at the early stage of development and may change without backward compatibility // until https://github.com/open-telemetry/opentelemetry-collector/issues/8122 is resolved. func WithRequestQueue(cfg exporterqueue.Config, queueFactory exporterqueue.Factory[Request]) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { if o.marshaler != nil || o.unmarshaler != nil { return fmt.Errorf("WithRequestQueue option must be used with the new request exporters only, use WithQueue instead") } @@ -131,25 +139,33 @@ func WithRequestQueue(cfg exporterqueue.Config, queueFactory exporterqueue.Facto o.queueCfg = cfg o.queueFactory = queueFactory return nil - } + }) } // WithCapabilities overrides the default Capabilities() function for a Consumer. // The default is non-mutable data. // TODO: Verify if we can change the default to be mutable as we do for processors. func WithCapabilities(capabilities consumer.Capabilities) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { o.consumerOptions = append(o.consumerOptions, consumer.WithCapabilities(capabilities)) return nil - } + }) } // BatcherOption apply changes to batcher sender. -type BatcherOption func(*batchSender) error +type BatcherOption interface { + apply(*batchSender) error +} + +type batcherOptionFunc func(*batchSender) error + +func (of batcherOptionFunc) apply(e *batchSender) error { + return of(e) +} // WithRequestBatchFuncs sets the functions for merging and splitting batches for an exporter built for custom request types. func WithRequestBatchFuncs(mf exporterbatcher.BatchMergeFunc[Request], msf exporterbatcher.BatchMergeSplitFunc[Request]) BatcherOption { - return func(bs *batchSender) error { + return batcherOptionFunc(func(bs *batchSender) error { if mf == nil || msf == nil { return fmt.Errorf("WithRequestBatchFuncs must be provided with non-nil functions") } @@ -159,7 +175,7 @@ func WithRequestBatchFuncs(mf exporterbatcher.BatchMergeFunc[Request], msf expor bs.mergeFunc = mf bs.mergeSplitFunc = msf return nil - } + }) } // WithBatcher enables batching for an exporter based on custom request types. @@ -168,39 +184,51 @@ func WithRequestBatchFuncs(mf exporterbatcher.BatchMergeFunc[Request], msf expor // This API is at the early stage of development and may change without backward compatibility // until https://github.com/open-telemetry/opentelemetry-collector/issues/8122 is resolved. func WithBatcher(cfg exporterbatcher.Config, opts ...BatcherOption) Option { - return func(o *baseExporter) error { - o.batcherCfg = cfg - o.batcherOpts = opts + return optionFunc(func(o *baseExporter) error { + if !cfg.Enabled { + return nil + } + + bs := newBatchSender(cfg, o.set, o.batchMergeFunc, o.batchMergeSplitfunc) + for _, opt := range opts { + if err := opt.apply(bs); err != nil { + return err + } + } + if bs.mergeFunc == nil || bs.mergeSplitFunc == nil { + return fmt.Errorf("WithRequestBatchFuncs must be provided for the batcher applied to the request-based exporters") + } + o.batchSender = bs return nil - } + }) } // withMarshaler is used to set the request marshaler for the new exporter helper. // It must be provided as the first option when creating a new exporter helper. func withMarshaler(marshaler exporterqueue.Marshaler[Request]) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { o.marshaler = marshaler return nil - } + }) } // withUnmarshaler is used to set the request unmarshaler for the new exporter helper. // It must be provided as the first option when creating a new exporter helper. func withUnmarshaler(unmarshaler exporterqueue.Unmarshaler[Request]) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { o.unmarshaler = unmarshaler return nil - } + }) } // withBatchFuncs is used to set the functions for merging and splitting batches for OLTP-based exporters. // It must be provided as the first option when creating a new exporter helper. func withBatchFuncs(mf exporterbatcher.BatchMergeFunc[Request], msf exporterbatcher.BatchMergeSplitFunc[Request]) Option { - return func(o *baseExporter) error { + return optionFunc(func(o *baseExporter) error { o.batchMergeFunc = mf o.batchMergeSplitfunc = msf return nil - } + }) } // baseExporter contains common fields between different exporter types. @@ -259,7 +287,7 @@ func newBaseExporter(set exporter.Settings, signal component.DataType, osf obsre } for _, op := range options { - err = multierr.Append(err, op(be)) + err = multierr.Append(err, op.apply(be)) } if err != nil { return nil, err @@ -268,7 +296,7 @@ func newBaseExporter(set exporter.Settings, signal component.DataType, osf obsre if be.batcherCfg.Enabled { bs := newBatchSender(be.batcherCfg, be.set, be.batchMergeFunc, be.batchMergeSplitfunc) for _, opt := range be.batcherOpts { - err = multierr.Append(err, opt(bs)) + err = multierr.Append(err, opt.apply(bs)) } if bs.mergeFunc == nil || bs.mergeSplitFunc == nil { err = multierr.Append(err, fmt.Errorf("WithRequestBatchFuncs must be provided for the batcher applied to the request-based exporters")) @@ -283,7 +311,7 @@ func newBaseExporter(set exporter.Settings, signal component.DataType, osf obsre } be.queueSender = newQueueSender(be.queueFactory(context.Background(), set, be.queueCfg), be.set, be.queueCfg.NumConsumers, be.exportFailureMessage, be.obsrep) for _, op := range options { - err = multierr.Append(err, op(be)) + err = multierr.Append(err, op.apply(be)) } } diff --git a/extension/auth/client.go b/extension/auth/client.go index d1855d8aece..03eba4ed336 100644 --- a/extension/auth/client.go +++ b/extension/auth/client.go @@ -26,7 +26,15 @@ type Client interface { } // ClientOption represents the possible options for NewClient. -type ClientOption func(*defaultClient) +type ClientOption interface { + apply(*defaultClient) +} + +type clientOptionFunc func(*defaultClient) + +func (of clientOptionFunc) apply(e *defaultClient) { + of(e) +} // ClientRoundTripperFunc specifies the function that returns a RoundTripper that can be used to authenticate HTTP requests. type ClientRoundTripperFunc func(base http.RoundTripper) (http.RoundTripper, error) @@ -58,33 +66,33 @@ type defaultClient struct { // WithClientStart overrides the default `Start` function for a component.Component. // The default always returns nil. func WithClientStart(startFunc component.StartFunc) ClientOption { - return func(o *defaultClient) { + return clientOptionFunc(func(o *defaultClient) { o.StartFunc = startFunc - } + }) } // WithClientShutdown overrides the default `Shutdown` function for a component.Component. // The default always returns nil. func WithClientShutdown(shutdownFunc component.ShutdownFunc) ClientOption { - return func(o *defaultClient) { + return clientOptionFunc(func(o *defaultClient) { o.ShutdownFunc = shutdownFunc - } + }) } // WithClientRoundTripper provides a `RoundTripper` function for this client authenticator. // The default round tripper is no-op. func WithClientRoundTripper(roundTripperFunc ClientRoundTripperFunc) ClientOption { - return func(o *defaultClient) { + return clientOptionFunc(func(o *defaultClient) { o.ClientRoundTripperFunc = roundTripperFunc - } + }) } // WithClientPerRPCCredentials provides a `PerRPCCredentials` function for this client authenticator. // There's no default. func WithClientPerRPCCredentials(perRPCCredentialsFunc ClientPerRPCCredentialsFunc) ClientOption { - return func(o *defaultClient) { + return clientOptionFunc(func(o *defaultClient) { o.ClientPerRPCCredentialsFunc = perRPCCredentialsFunc - } + }) } // NewClient returns a Client configured with the provided options. @@ -92,7 +100,7 @@ func NewClient(options ...ClientOption) Client { bc := &defaultClient{} for _, op := range options { - op(bc) + op.apply(bc) } return bc diff --git a/extension/auth/server.go b/extension/auth/server.go index 4fd3a550c01..256dc51ce9c 100644 --- a/extension/auth/server.go +++ b/extension/auth/server.go @@ -36,7 +36,15 @@ type defaultServer struct { } // ServerOption represents the possible options for NewServer. -type ServerOption func(*defaultServer) +type ServerOption interface { + apply(*defaultServer) +} + +type serverOptionFunc func(*defaultServer) + +func (of serverOptionFunc) apply(e *defaultServer) { + of(e) +} // ServerAuthenticateFunc defines the signature for the function responsible for performing the authentication based // on the given sources map. See Server.Authenticate. @@ -51,25 +59,25 @@ func (f ServerAuthenticateFunc) Authenticate(ctx context.Context, sources map[st // WithServerAuthenticate specifies which function to use to perform the authentication. func WithServerAuthenticate(authFunc ServerAuthenticateFunc) ServerOption { - return func(o *defaultServer) { + return serverOptionFunc(func(o *defaultServer) { o.ServerAuthenticateFunc = authFunc - } + }) } // WithServerStart overrides the default `Start` function for a component.Component. // The default always returns nil. func WithServerStart(startFunc component.StartFunc) ServerOption { - return func(o *defaultServer) { + return serverOptionFunc(func(o *defaultServer) { o.StartFunc = startFunc - } + }) } // WithServerShutdown overrides the default `Shutdown` function for a component.Component. // The default always returns nil. func WithServerShutdown(shutdownFunc component.ShutdownFunc) ServerOption { - return func(o *defaultServer) { + return serverOptionFunc(func(o *defaultServer) { o.ShutdownFunc = shutdownFunc - } + }) } // NewServer returns a Server configured with the provided options. @@ -77,7 +85,7 @@ func NewServer(options ...ServerOption) Server { bc := &defaultServer{} for _, op := range options { - op(bc) + op.apply(bc) } return bc diff --git a/processor/processorhelper/processor.go b/processor/processorhelper/processor.go index de0c00fb7d2..03d99b3375b 100644 --- a/processor/processorhelper/processor.go +++ b/processor/processorhelper/processor.go @@ -22,30 +22,38 @@ import ( var ErrSkipProcessingData = errors.New("sentinel error to skip processing data from the remainder of the pipeline") // Option apply changes to internalOptions. -type Option func(*baseSettings) +type Option interface { + apply(*baseSettings) +} + +type optionFunc func(*baseSettings) + +func (of optionFunc) apply(e *baseSettings) { + of(e) +} // WithStart overrides the default Start function for an processor. // The default shutdown function does nothing and always returns nil. func WithStart(start component.StartFunc) Option { - return func(o *baseSettings) { + return optionFunc(func(o *baseSettings) { o.StartFunc = start - } + }) } // WithShutdown overrides the default Shutdown function for an processor. // The default shutdown function does nothing and always returns nil. func WithShutdown(shutdown component.ShutdownFunc) Option { - return func(o *baseSettings) { + return optionFunc(func(o *baseSettings) { o.ShutdownFunc = shutdown - } + }) } // WithCapabilities overrides the default GetCapabilities function for an processor. // The default GetCapabilities function returns mutable capabilities. func WithCapabilities(capabilities consumer.Capabilities) Option { - return func(o *baseSettings) { + return optionFunc(func(o *baseSettings) { o.consumerOptions = append(o.consumerOptions, consumer.WithCapabilities(capabilities)) - } + }) } type baseSettings struct { @@ -62,7 +70,7 @@ func fromOptions(options []Option) *baseSettings { } for _, op := range options { - op(opts) + op.apply(opts) } return opts diff --git a/receiver/scraperhelper/scraper.go b/receiver/scraperhelper/scraper.go index b222f0bc339..5f84c025cec 100644 --- a/receiver/scraperhelper/scraper.go +++ b/receiver/scraperhelper/scraper.go @@ -30,20 +30,28 @@ type Scraper interface { } // ScraperOption apply changes to internal options. -type ScraperOption func(*baseScraper) +type ScraperOption interface { + apply(*baseScraper) +} + +type scraperOptionFunc func(*baseScraper) + +func (of scraperOptionFunc) apply(e *baseScraper) { + of(e) +} // WithStart sets the function that will be called on startup. func WithStart(start component.StartFunc) ScraperOption { - return func(o *baseScraper) { + return scraperOptionFunc(func(o *baseScraper) { o.StartFunc = start - } + }) } // WithShutdown sets the function that will be called on shutdown. func WithShutdown(shutdown component.ShutdownFunc) ScraperOption { - return func(o *baseScraper) { + return scraperOptionFunc(func(o *baseScraper) { o.ShutdownFunc = shutdown - } + }) } var _ Scraper = (*baseScraper)(nil) @@ -70,7 +78,7 @@ func NewScraper(t component.Type, scrape ScrapeFunc, options ...ScraperOption) ( id: component.NewID(t), } for _, op := range options { - op(bs) + op.apply(bs) } return bs, nil diff --git a/receiver/scraperhelper/scrapercontroller.go b/receiver/scraperhelper/scrapercontroller.go index 4b94ced6623..8767c608407 100644 --- a/receiver/scraperhelper/scrapercontroller.go +++ b/receiver/scraperhelper/scrapercontroller.go @@ -20,7 +20,15 @@ import ( ) // ScraperControllerOption apply changes to internal options. -type ScraperControllerOption func(*controller) +type ScraperControllerOption interface { + apply(*controller) +} + +type scraperControllerOptionFunc func(*controller) + +func (of scraperControllerOptionFunc) apply(e *controller) { + of(e) +} // AddScraper configures the provided scrape function to be called // with the specified options, and at the specified collection interval. @@ -28,18 +36,18 @@ type ScraperControllerOption func(*controller) // Observability information will be reported, and the scraped metrics // will be passed to the next consumer. func AddScraper(scraper Scraper) ScraperControllerOption { - return func(o *controller) { + return scraperControllerOptionFunc(func(o *controller) { o.scrapers = append(o.scrapers, scraper) - } + }) } // WithTickerChannel allows you to override the scraper controller's ticker // channel to specify when scrape is called. This is only expected to be // used by tests. func WithTickerChannel(tickerCh <-chan time.Time) ScraperControllerOption { - return func(o *controller) { + return scraperControllerOptionFunc(func(o *controller) { o.tickerCh = tickerCh - } + }) } type controller struct { @@ -98,7 +106,7 @@ func NewScraperControllerReceiver( } for _, op := range options { - op(sc) + op.apply(sc) } sc.obsScrapers = make([]*obsReport, len(sc.scrapers)) diff --git a/service/extensions/extensions.go b/service/extensions/extensions.go index 7cf4aaed6c6..fcefcb33f20 100644 --- a/service/extensions/extensions.go +++ b/service/extensions/extensions.go @@ -178,12 +178,20 @@ type Settings struct { Extensions builders.Extension } -type Option func(*Extensions) +type Option interface { + apply(*Extensions) +} + +type optionFunc func(*Extensions) + +func (of optionFunc) apply(e *Extensions) { + of(e) +} func WithReporter(reporter status.Reporter) Option { - return func(e *Extensions) { + return optionFunc(func(e *Extensions) { e.reporter = reporter - } + }) } // New creates a new Extensions from Config. @@ -197,7 +205,7 @@ func New(ctx context.Context, set Settings, cfg Config, options ...Option) (*Ext } for _, opt := range options { - opt(exts) + opt.apply(exts) } for _, extID := range cfg {