From 3356863030edd81a2ff2e3b0ae80b9759dcd9e2a Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Tue, 31 May 2022 10:51:24 -0700 Subject: [PATCH] Move config.Map to its own package which does not depend on any component concept (#5237) Signed-off-by: Bogdan Drutu --- CHANGELOG.md | 16 +++- config/common.go | 11 ++- config/configtest/configtest.go | 16 +--- config/experimental/configsource/component.go | 4 +- config/exporter.go | 7 +- config/extension.go | 7 +- config/internal/configsource/manager.go | 26 +++--- config/internal/configsource/manager_test.go | 38 ++++----- .../expandmapconverter/deprecated.go | 22 +++++ .../deprecated.go | 22 +++++ .../mapprovider/envmapprovider/deprecated.go | 22 +++++ .../mapprovider/filemapprovider/deprecated.go | 22 +++++ .../mapprovider/yamlmapprovider/deprecated.go | 22 +++++ config/moved_configmap.go | 60 ++++++++++++++ config/processor.go | 7 +- config/receiver.go | 7 +- {config => confmap}/README.md | 34 ++++---- config/configmap.go => confmap/confmap.go | 44 +++++----- .../confmap_test.go | 30 +++---- confmap/confmaptest/configtest.go | 31 +++++++ confmap/confmaptest/configtest_test.go | 34 ++++++++ confmap/confmaptest/doc.go | 16 ++++ confmap/confmaptest/testdata/simple.yaml | 1 + .../mapconverter.go => confmap/converter.go | 10 +-- .../converter/expandconverter}/expand.go | 14 ++-- .../converter/expandconverter}/expand_test.go | 26 +++--- .../testdata/default-config.yaml | 0 .../testdata/expand-escaped-env.yaml | 0 .../testdata/expand-with-all-env.yaml | 0 .../testdata/expand-with-no-env.yaml | 0 .../testdata/expand-with-partial-env.yaml | 0 .../properties.go | 12 +-- .../properties_test.go | 28 +++---- config/mapprovider.go => confmap/provider.go | 26 +++--- .../provider/envprovider}/mapprovider.go | 24 +++--- .../provider/envprovider}/mapprovider_test.go | 6 +- .../provider/fileprovider}/mapprovider.go | 26 +++--- .../fileprovider}/mapprovider_test.go | 8 +- .../testdata/default-config.yaml | 0 .../fileprovider}/testdata/invalid-yaml.yaml | 0 .../provider/yamlprovider}/mapprovider.go | 24 +++--- .../yamlprovider}/mapprovider_test.go | 2 +- .../provider_test.go | 14 ++-- {config => confmap}/testdata/basic_types.yaml | 0 {config => confmap}/testdata/config.yaml | 0 .../testdata/embedded_keys.yaml | 0 receiver/otlpreceiver/config.go | 7 +- service/collector_test.go | 8 +- service/collector_windows.go | 6 +- service/command.go | 6 +- service/config_provider.go | 32 ++++---- .../configunmarshaler/defaultunmarshaler.go | 17 ++-- .../defaultunmarshaler_test.go | 6 +- service/mapresolver.go | 58 +++++++------- service/mapresolver_test.go | 80 +++++++++---------- service/service_test.go | 6 +- service/servicetest/configprovider.go | 6 +- 57 files changed, 613 insertions(+), 338 deletions(-) create mode 100644 config/mapconverter/expandmapconverter/deprecated.go create mode 100644 config/mapconverter/overwritepropertiesmapconverter/deprecated.go create mode 100644 config/mapprovider/envmapprovider/deprecated.go create mode 100644 config/mapprovider/filemapprovider/deprecated.go create mode 100644 config/mapprovider/yamlmapprovider/deprecated.go create mode 100644 config/moved_configmap.go rename {config => confmap}/README.md (74%) rename config/configmap.go => confmap/confmap.go (86%) rename config/configmap_test.go => confmap/confmap_test.go (90%) create mode 100644 confmap/confmaptest/configtest.go create mode 100644 confmap/confmaptest/configtest_test.go create mode 100644 confmap/confmaptest/doc.go create mode 100644 confmap/confmaptest/testdata/simple.yaml rename config/mapconverter.go => confmap/converter.go (70%) rename {config/mapconverter/expandmapconverter => confmap/converter/expandconverter}/expand.go (78%) rename {config/mapconverter/expandmapconverter => confmap/converter/expandconverter}/expand_test.go (79%) rename {config/mapconverter/expandmapconverter => confmap/converter/expandconverter}/testdata/default-config.yaml (100%) rename {config/mapconverter/expandmapconverter => confmap/converter/expandconverter}/testdata/expand-escaped-env.yaml (100%) rename {config/mapconverter/expandmapconverter => confmap/converter/expandconverter}/testdata/expand-with-all-env.yaml (100%) rename {config/mapconverter/expandmapconverter => confmap/converter/expandconverter}/testdata/expand-with-no-env.yaml (100%) rename {config/mapconverter/expandmapconverter => confmap/converter/expandconverter}/testdata/expand-with-partial-env.yaml (100%) rename {config/mapconverter/overwritepropertiesmapconverter => confmap/converter/overwritepropertiesconverter}/properties.go (78%) rename {config/mapconverter/overwritepropertiesmapconverter => confmap/converter/overwritepropertiesconverter}/properties_test.go (59%) rename config/mapprovider.go => confmap/provider.go (87%) rename {config/mapprovider/envmapprovider => confmap/provider/envprovider}/mapprovider.go (57%) rename {config/mapprovider/envmapprovider => confmap/provider/envprovider}/mapprovider_test.go (93%) rename {config/mapprovider/filemapprovider => confmap/provider/fileprovider}/mapprovider.go (65%) rename {config/mapprovider/filemapprovider => confmap/provider/fileprovider}/mapprovider_test.go (93%) rename {config/mapprovider/filemapprovider => confmap/provider/fileprovider}/testdata/default-config.yaml (100%) rename {config/mapprovider/filemapprovider => confmap/provider/fileprovider}/testdata/invalid-yaml.yaml (100%) rename {config/mapprovider/yamlmapprovider => confmap/provider/yamlprovider}/mapprovider.go (60%) rename {config/mapprovider/yamlmapprovider => confmap/provider/yamlprovider}/mapprovider_test.go (99%) rename config/mapprovider_test.go => confmap/provider_test.go (80%) rename {config => confmap}/testdata/basic_types.yaml (100%) rename {config => confmap}/testdata/config.yaml (100%) rename {config => confmap}/testdata/embedded_keys.yaml (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91ab9818678..c57588c059a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,24 @@ ### πŸ›‘ Breaking changes πŸ›‘ - Remove deprecated `componenterror` package. (#5420) -- Remove deprecated config.MapConverterFunc. (#5419) +- Remove deprecated `config.MapConverterFunc`. (#5419) ### 🚩 Deprecations 🚩 +- Move `config.Map` to its own package `confmap` which does not depend on any component concept (#5237) + - `config.Map` -> `confmap.ConfMap` + - `config.MapProvider` -> `confmap.Provider` + - `config.Received` -> `confmap.Received` + - `config.CloseFunc` -> `confmap.CloseFunc` + - `config.ChangeEvent` -> `confmap.ChangeEvent` + - `config.MapConverter` -> `confmap.Converter` + - Package `envmapprovider` -> `envprovider` + - Package `filemapprovider` -> `fileprovider` + - Package `yamlmapprovider` -> `yamlprovider` + - Package `expandmapconverter` -> `expandconverter` + - Package `filemapprovider` -> `fileprovider` + - Package `overwritepropertiesmapconverter` -> `overwritepropertiesconverter` + ### πŸ’‘ Enhancements πŸ’‘ ### 🧰 Bug fixes 🧰 diff --git a/config/common.go b/config/common.go index 408fda6a1f1..4a5cf245bec 100644 --- a/config/common.go +++ b/config/common.go @@ -13,6 +13,9 @@ // limitations under the License. package config // import "go.opentelemetry.io/collector/config" +import ( + "go.opentelemetry.io/collector/confmap" +) // Type is the component type as it is used in the config. type Type string @@ -26,9 +29,9 @@ type validatable interface { // Unmarshallable defines an optional interface for custom configuration unmarshaling. // A configuration struct can implement this interface to override the default unmarshaling. type Unmarshallable interface { - // Unmarshal is a function that unmarshals a config.Map into the unmarshable struct in a custom way. - // The config.Map for this specific component may be nil or empty if no config available. - Unmarshal(component *Map) error + // Unmarshal is a function that unmarshals a confmap.Conf into the unmarshable struct in a custom way. + // The confmap.Conf for this specific component may be nil or empty if no config available. + Unmarshal(component *confmap.Conf) error } // DataType is a special Type that represents the data types supported by the collector. We currently support @@ -47,7 +50,7 @@ const ( LogsDataType DataType = "logs" ) -func unmarshal(componentSection *Map, intoCfg interface{}) error { +func unmarshal(componentSection *confmap.Conf, intoCfg interface{}) error { if cu, ok := intoCfg.(Unmarshallable); ok { return cu.Unmarshal(componentSection) } diff --git a/config/configtest/configtest.go b/config/configtest/configtest.go index 99189b7708c..3b6fd73ce07 100644 --- a/config/configtest/configtest.go +++ b/config/configtest/configtest.go @@ -15,7 +15,6 @@ package configtest // import "go.opentelemetry.io/collector/config/configtest" import ( - "context" "fmt" "reflect" "regexp" @@ -23,22 +22,15 @@ import ( "go.uber.org/multierr" - "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/mapprovider/filemapprovider" + "go.opentelemetry.io/collector/confmap/confmaptest" ) +// Deprecated: [v0.53.0] use confmaptest.LoadConf +var LoadConfigMap = confmaptest.LoadConf + // The regular expression for valid config field tag. var configFieldTagRegExp = regexp.MustCompile("^[a-z0-9][a-z0-9_]*$") -// LoadConfigMap loads a config.Map from file, and does NOT validate the configuration. -func LoadConfigMap(fileName string) (*config.Map, error) { - ret, err := filemapprovider.New().Retrieve(context.Background(), "file:"+fileName, nil) - if err != nil { - return nil, err - } - return ret.AsMap() -} - // CheckConfigStruct enforces that given configuration object is following the patterns // used by the collector. This ensures consistency between different implementations // of components and extensions. It is recommended for implementers of components diff --git a/config/experimental/configsource/component.go b/config/experimental/configsource/component.go index 9bb7945e569..459684675fc 100644 --- a/config/experimental/configsource/component.go +++ b/config/experimental/configsource/component.go @@ -18,7 +18,7 @@ import ( "context" "errors" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) // ErrSessionClosed is returned by WatchForUpdate functions when its parent Session @@ -54,7 +54,7 @@ type ConfigSource interface { // // The selector is a string that is required on all invocations, the params are optional. Each // implementation handles the generic params according to their requirements. - Retrieve(ctx context.Context, selector string, paramsConfigMap *config.Map) (Retrieved, error) + Retrieve(ctx context.Context, selector string, paramsConfigMap *confmap.Conf) (Retrieved, error) // Close signals that the configuration for which it was used to retrieve values is no longer in use // and the object should close and release any watchers that it may have created. diff --git a/config/exporter.go b/config/exporter.go index c13c7db2837..c6e6e8d3836 100644 --- a/config/exporter.go +++ b/config/exporter.go @@ -13,6 +13,9 @@ // limitations under the License. package config // import "go.opentelemetry.io/collector/config" +import ( + "go.opentelemetry.io/collector/confmap" +) // Exporter is the configuration of a component.Exporter. Specific extensions must implement // this interface and must embed ExporterSettings struct or a struct that extends it. @@ -26,8 +29,8 @@ type Exporter interface { // UnmarshalExporter helper function to unmarshal an Exporter config. // It checks if the config implements Unmarshallable and uses that if available, // otherwise uses Map.UnmarshalExact, erroring if a field is nonexistent. -func UnmarshalExporter(cfgMap *Map, cfg Exporter) error { - return unmarshal(cfgMap, cfg) +func UnmarshalExporter(conf *confmap.Conf, cfg Exporter) error { + return unmarshal(conf, cfg) } // ExporterSettings defines common settings for a component.Exporter configuration. diff --git a/config/extension.go b/config/extension.go index 24f6cac7d24..7df771b1eac 100644 --- a/config/extension.go +++ b/config/extension.go @@ -13,6 +13,9 @@ // limitations under the License. package config // import "go.opentelemetry.io/collector/config" +import ( + "go.opentelemetry.io/collector/confmap" +) // Extension is the configuration of a component.Extension. Specific extensions must implement // this interface and must embed ExtensionSettings struct or a struct that extends it. @@ -26,8 +29,8 @@ type Extension interface { // UnmarshalExtension helper function to unmarshal an Extension config. // It checks if the config implements Unmarshallable and uses that if available, // otherwise uses Map.UnmarshalExact, erroring if a field is nonexistent. -func UnmarshalExtension(cfgMap *Map, cfg Extension) error { - return unmarshal(cfgMap, cfg) +func UnmarshalExtension(conf *confmap.Conf, cfg Extension) error { + return unmarshal(conf, cfg) } // ExtensionSettings defines common settings for a component.Extension configuration. diff --git a/config/internal/configsource/manager.go b/config/internal/configsource/manager.go index 8faae06e7e1..5e3aea8ac2a 100644 --- a/config/internal/configsource/manager.go +++ b/config/internal/configsource/manager.go @@ -27,8 +27,8 @@ import ( "go.uber.org/multierr" "gopkg.in/yaml.v3" - "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/experimental/configsource" + "go.opentelemetry.io/collector/confmap" ) const ( @@ -181,7 +181,7 @@ type Manager struct { // NewManager creates a new instance of a Manager to be used to inject data from // ConfigSource objects into a configuration and watch for updates on the injected // data. -func NewManager(_ *config.Map) (*Manager, error) { +func NewManager(_ *confmap.Conf) (*Manager, error) { // TODO: Config sources should be extracted for the config itself, need Factories for that. return &Manager{ @@ -190,18 +190,18 @@ func NewManager(_ *config.Map) (*Manager, error) { }, nil } -// Resolve inspects the given config.Map and resolves all config sources referenced -// in the configuration, returning a config.Map in which all env vars and config sources on +// Resolve inspects the given confmap.Conf and resolves all config sources referenced +// in the configuration, returning a confmap.Conf in which all env vars and config sources on // the given input config map are resolved to actual literal values of the env vars or config sources. // This method must be called only once per lifetime of a Manager object. -func (m *Manager) Resolve(ctx context.Context, configMap *config.Map) (*config.Map, error) { - res := config.NewMap() +func (m *Manager) Resolve(ctx context.Context, configMap *confmap.Conf) (*confmap.Conf, error) { + res := confmap.New() allKeys := configMap.AllKeys() for _, k := range allKeys { if strings.HasPrefix(k, configSourcesKey) { // Remove everything under the config_sources section. The `config_sources` section // is read when loading the config sources used in the configuration, but it is not - // part of the resulting configuration returned via *config.Map. + // part of the resulting configuration returned via *confmap.Conf. continue } @@ -285,7 +285,7 @@ func (m *Manager) Close(ctx context.Context) error { // parseConfigValue takes the value of a "config node" and process it recursively. The processing consists // in transforming invocations of config sources and/or environment variables into literal data that can be -// used directly from a `config.Map` object. +// used directly from a `confmap.Conf` object. func (m *Manager) parseConfigValue(ctx context.Context, value interface{}) (interface{}, error) { switch v := value.(type) { case string: @@ -509,11 +509,11 @@ func newErrUnknownConfigSource(cfgSrcName string) error { // parseCfgSrcInvocation parses the original string in the configuration that has a config source // retrieve operation and return its "logical components": the config source name, the selector, and -// a config.Map to be used in this invocation of the config source. See Test_parseCfgSrcInvocation +// a confmap.Conf to be used in this invocation of the config source. See Test_parseCfgSrcInvocation // for some examples of input and output. // The caller should check for error explicitly since it is possible for the // other values to have been partially set. -func parseCfgSrcInvocation(s string) (cfgSrcName, selector string, paramsConfigMap *config.Map, err error) { +func parseCfgSrcInvocation(s string) (cfgSrcName, selector string, paramsConfigMap *confmap.Conf, err error) { parts := strings.SplitN(s, string(configSourceNameDelimChar), 2) if len(parts) != 2 { err = fmt.Errorf("invalid config source syntax at %q, it must have at least the config source name and a selector", s) @@ -534,7 +534,7 @@ func parseCfgSrcInvocation(s string) (cfgSrcName, selector string, paramsConfigM if err = yaml.Unmarshal([]byte(parts[1]), &data); err != nil { return } - paramsConfigMap = config.NewMapFromStringMap(data) + paramsConfigMap = confmap.NewFromStringMap(data) } default: @@ -556,7 +556,7 @@ func parseCfgSrcInvocation(s string) (cfgSrcName, selector string, paramsConfigM return cfgSrcName, selector, paramsConfigMap, err } -func parseParamsAsURLQuery(s string) (*config.Map, error) { +func parseParamsAsURLQuery(s string) (*confmap.Conf, error) { values, err := url.ParseQuery(s) if err != nil { return nil, err @@ -587,7 +587,7 @@ func parseParamsAsURLQuery(s string) (*config.Map, error) { params[k] = elemSlice } } - return config.NewMapFromStringMap(params), err + return confmap.NewFromStringMap(params), err } // osExpandEnv replicate the internal behavior of os.ExpandEnv when handling env diff --git a/config/internal/configsource/manager_test.go b/config/internal/configsource/manager_test.go index 477deb61c99..0e21132aa4b 100644 --- a/config/internal/configsource/manager_test.go +++ b/config/internal/configsource/manager_test.go @@ -24,9 +24,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/configtest" "go.opentelemetry.io/collector/config/experimental/configsource" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/confmaptest" ) func TestConfigSourceManager_Simple(t *testing.T) { @@ -52,7 +52,7 @@ func TestConfigSourceManager_Simple(t *testing.T) { }, } - cp := config.NewMapFromStringMap(originalCfg) + cp := confmap.NewFromStringMap(originalCfg) res, err := manager.Resolve(ctx, cp) require.NoError(t, err) @@ -85,7 +85,7 @@ func TestConfigSourceManager_ResolveRemoveConfigSourceSection(t *testing.T) { "tstcfgsrc": &testConfigSource{}, }) - res, err := manager.Resolve(context.Background(), config.NewMapFromStringMap(cfg)) + res, err := manager.Resolve(context.Background(), confmap.NewFromStringMap(cfg)) require.NoError(t, err) require.NotNil(t, res) @@ -125,7 +125,7 @@ func TestConfigSourceManager_ResolveErrors(t *testing.T) { t.Run(tt.name, func(t *testing.T) { manager := newManager(tt.configSourceMap) - res, err := manager.Resolve(ctx, config.NewMapFromStringMap(tt.config)) + res, err := manager.Resolve(ctx, confmap.NewFromStringMap(tt.config)) require.Error(t, err) require.Nil(t, res) require.NoError(t, manager.Close(ctx)) @@ -161,11 +161,11 @@ map: }) file := filepath.Join("testdata", "yaml_injection.yaml") - cp, err := configtest.LoadConfigMap(file) + cp, err := confmaptest.LoadConf(file) require.NoError(t, err) expectedFile := filepath.Join("testdata", "yaml_injection_expected.yaml") - expectedConfigMap, err := configtest.LoadConfigMap(expectedFile) + expectedConfigMap, err := confmaptest.LoadConf(expectedFile) require.NoError(t, err) expectedCfg := expectedConfigMap.ToStringMap() @@ -190,11 +190,11 @@ func TestConfigSourceManager_ArraysAndMaps(t *testing.T) { }) file := filepath.Join("testdata", "arrays_and_maps.yaml") - cp, err := configtest.LoadConfigMap(file) + cp, err := confmaptest.LoadConf(file) require.NoError(t, err) expectedFile := filepath.Join("testdata", "arrays_and_maps_expected.yaml") - expectedConfigMap, err := configtest.LoadConfigMap(expectedFile) + expectedConfigMap, err := confmaptest.LoadConf(expectedFile) require.NoError(t, err) res, err := manager.Resolve(ctx, cp) @@ -230,7 +230,7 @@ func TestConfigSourceManager_ParamsHandling(t *testing.T) { } // Set OnRetrieve to check if the parameters were parsed as expected. - tstCfgSrc.OnRetrieve = func(ctx context.Context, selector string, paramsConfigMap *config.Map) error { + tstCfgSrc.OnRetrieve = func(ctx context.Context, selector string, paramsConfigMap *confmap.Conf) error { paramsValue := (interface{})(nil) if paramsConfigMap != nil { paramsValue = paramsConfigMap.ToStringMap() @@ -244,11 +244,11 @@ func TestConfigSourceManager_ParamsHandling(t *testing.T) { }) file := filepath.Join("testdata", "params_handling.yaml") - cp, err := configtest.LoadConfigMap(file) + cp, err := confmaptest.LoadConf(file) require.NoError(t, err) expectedFile := filepath.Join("testdata", "params_handling_expected.yaml") - expectedConfigMap, err := configtest.LoadConfigMap(expectedFile) + expectedConfigMap, err := confmaptest.LoadConf(expectedFile) require.NoError(t, err) res, err := manager.Resolve(ctx, cp) @@ -280,7 +280,7 @@ func TestConfigSourceManager_WatchForUpdate(t *testing.T) { }, } - cp := config.NewMapFromStringMap(originalCfg) + cp := confmap.NewFromStringMap(originalCfg) _, err := manager.Resolve(ctx, cp) require.NoError(t, err) @@ -334,7 +334,7 @@ func TestConfigSourceManager_MultipleWatchForUpdate(t *testing.T) { }, } - cp := config.NewMapFromStringMap(originalCfg) + cp := confmap.NewFromStringMap(originalCfg) _, err := manager.Resolve(ctx, cp) require.NoError(t, err) @@ -368,7 +368,7 @@ func TestConfigSourceManager_EnvVarHandling(t *testing.T) { } // Intercept "params_key" and create an entry with the params themselves. - tstCfgSrc.OnRetrieve = func(ctx context.Context, selector string, paramsConfigMap *config.Map) error { + tstCfgSrc.OnRetrieve = func(ctx context.Context, selector string, paramsConfigMap *confmap.Conf) error { if selector == "params_key" { tstCfgSrc.ValueMap[selector] = valueEntry{Value: paramsConfigMap.ToStringMap()} } @@ -380,11 +380,11 @@ func TestConfigSourceManager_EnvVarHandling(t *testing.T) { }) file := filepath.Join("testdata", "envvar_cfgsrc_mix.yaml") - cp, err := configtest.LoadConfigMap(file) + cp, err := confmaptest.LoadConf(file) require.NoError(t, err) expectedFile := filepath.Join("testdata", "envvar_cfgsrc_mix_expected.yaml") - expectedConfigMap, err := configtest.LoadConfigMap(expectedFile) + expectedConfigMap, err := confmaptest.LoadConf(expectedFile) require.NoError(t, err) res, err := manager.Resolve(ctx, cp) @@ -633,7 +633,7 @@ type testConfigSource struct { ErrOnRetrieve error ErrOnClose error - OnRetrieve func(ctx context.Context, selector string, paramsConfigMap *config.Map) error + OnRetrieve func(ctx context.Context, selector string, paramsConfigMap *confmap.Conf) error } type valueEntry struct { @@ -643,7 +643,7 @@ type valueEntry struct { var _ configsource.ConfigSource = (*testConfigSource)(nil) -func (t *testConfigSource) Retrieve(ctx context.Context, selector string, paramsConfigMap *config.Map) (configsource.Retrieved, error) { +func (t *testConfigSource) Retrieve(ctx context.Context, selector string, paramsConfigMap *confmap.Conf) (configsource.Retrieved, error) { if t.OnRetrieve != nil { if err := t.OnRetrieve(ctx, selector, paramsConfigMap); err != nil { return nil, err diff --git a/config/mapconverter/expandmapconverter/deprecated.go b/config/mapconverter/expandmapconverter/deprecated.go new file mode 100644 index 00000000000..52ffe174237 --- /dev/null +++ b/config/mapconverter/expandmapconverter/deprecated.go @@ -0,0 +1,22 @@ +// Copyright The 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 expandconverter // import "go.opentelemetry.io/collector/config/mapconverter/expandmapconverter" + +import ( + "go.opentelemetry.io/collector/confmap/converter/expandconverter" +) + +// Deprecated: [v0.53.0] use expandconverter.New +var New = expandconverter.New diff --git a/config/mapconverter/overwritepropertiesmapconverter/deprecated.go b/config/mapconverter/overwritepropertiesmapconverter/deprecated.go new file mode 100644 index 00000000000..6bed7dda431 --- /dev/null +++ b/config/mapconverter/overwritepropertiesmapconverter/deprecated.go @@ -0,0 +1,22 @@ +// Copyright The 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 overwritepropertiesmapconverter // import "go.opentelemetry.io/collector/config/mapconverter/overwritepropertiesmapconverter" + +import ( + "go.opentelemetry.io/collector/confmap/converter/overwritepropertiesconverter" +) + +// Deprecated: [v0.53.0] use overwritepropertiesconverter.New +var New = overwritepropertiesconverter.New diff --git a/config/mapprovider/envmapprovider/deprecated.go b/config/mapprovider/envmapprovider/deprecated.go new file mode 100644 index 00000000000..5ccd7b75df2 --- /dev/null +++ b/config/mapprovider/envmapprovider/deprecated.go @@ -0,0 +1,22 @@ +// Copyright The 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 envmapprovider // import "go.opentelemetry.io/collector/config/mapprovider/envmapprovider" + +import ( + "go.opentelemetry.io/collector/confmap/provider/envprovider" +) + +// Deprecated: [v0.53.0] use envprovider.New +var New = envprovider.New diff --git a/config/mapprovider/filemapprovider/deprecated.go b/config/mapprovider/filemapprovider/deprecated.go new file mode 100644 index 00000000000..cf1ba0ea27f --- /dev/null +++ b/config/mapprovider/filemapprovider/deprecated.go @@ -0,0 +1,22 @@ +// Copyright The 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 filemapprovider // import "go.opentelemetry.io/collector/config/mapprovider/filemapprovider" + +import ( + "go.opentelemetry.io/collector/confmap/provider/fileprovider" +) + +// Deprecated: [v0.53.0] use fileprovider.New +var New = fileprovider.New diff --git a/config/mapprovider/yamlmapprovider/deprecated.go b/config/mapprovider/yamlmapprovider/deprecated.go new file mode 100644 index 00000000000..0d4a14d6f20 --- /dev/null +++ b/config/mapprovider/yamlmapprovider/deprecated.go @@ -0,0 +1,22 @@ +// Copyright The 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 yamlmapprovider // import "go.opentelemetry.io/collector/config/mapprovider/yamlmapprovider" + +import ( + "go.opentelemetry.io/collector/confmap/provider/yamlprovider" +) + +// Deprecated: [v0.53.0] use yamlprovider.New +var New = yamlprovider.New diff --git a/config/moved_configmap.go b/config/moved_configmap.go new file mode 100644 index 00000000000..f65b8d5b825 --- /dev/null +++ b/config/moved_configmap.go @@ -0,0 +1,60 @@ +// Copyright The 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 config // import "go.opentelemetry.io/collector/config" + +import ( + "go.opentelemetry.io/collector/confmap" +) + +const ( + // Deprecated: [v0.53.0] use confmap.KeyDelimiter + KeyDelimiter = confmap.KeyDelimiter +) + +// Deprecated: [v0.53.0] use confmap.Converter +type MapConverter = confmap.Converter + +// Deprecated: [v0.53.0] use confmap.Conf +type Map = confmap.Conf + +// Deprecated: [v0.53.0] use confmap.New +var NewMap = confmap.New + +// Deprecated: [v0.53.0] use confmap.NewFromStringMap +var NewMapFromStringMap = confmap.NewFromStringMap + +// Deprecated: [v0.53.0] use confmap.Provider +type MapProvider = confmap.Provider + +// Deprecated: [v0.53.0] use confmap.Retrieved +type Retrieved = confmap.Retrieved + +// Deprecated: [v0.53.0] use confmap.RetrievedOption +type RetrievedOption = confmap.RetrievedOption + +// Deprecated: [v0.53.0] use confmap.NewRetrievedFromMap +var WithRetrievedClose = confmap.WithRetrievedClose + +// Deprecated: [v0.53.0] use confmap.NewRetrievedFromMap +var NewRetrievedFromMap = confmap.NewRetrievedFromMap + +// Deprecated: [v0.53.0] use confmap.WatcherFunc +type WatcherFunc = confmap.WatcherFunc + +// Deprecated: [v0.53.0] use confmap.CloseFunc +type CloseFunc = confmap.CloseFunc + +// Deprecated: [v0.53.0] use confmap.ChangeEvent +type ChangeEvent = confmap.ChangeEvent diff --git a/config/processor.go b/config/processor.go index bde13f68736..ba0a52aa2a6 100644 --- a/config/processor.go +++ b/config/processor.go @@ -13,6 +13,9 @@ // limitations under the License. package config // import "go.opentelemetry.io/collector/config" +import ( + "go.opentelemetry.io/collector/confmap" +) // Processor is the configuration of a component.Processor. Specific extensions must implement // this interface and must embed ProcessorSettings struct or a struct that extends it. @@ -26,8 +29,8 @@ type Processor interface { // UnmarshalProcessor helper function to unmarshal a Processor config. // It checks if the config implements Unmarshallable and uses that if available, // otherwise uses Map.UnmarshalExact, erroring if a field is nonexistent. -func UnmarshalProcessor(cfgMap *Map, cfg Processor) error { - return unmarshal(cfgMap, cfg) +func UnmarshalProcessor(conf *confmap.Conf, cfg Processor) error { + return unmarshal(conf, cfg) } // ProcessorSettings defines common settings for a component.Processor configuration. diff --git a/config/receiver.go b/config/receiver.go index 6974efbc46b..4080d2df572 100644 --- a/config/receiver.go +++ b/config/receiver.go @@ -13,6 +13,9 @@ // limitations under the License. package config // import "go.opentelemetry.io/collector/config" +import ( + "go.opentelemetry.io/collector/confmap" +) // Receiver is the configuration of a component.Receiver. Specific extensions must implement // this interface and must embed ReceiverSettings struct or a struct that extends it. @@ -26,8 +29,8 @@ type Receiver interface { // UnmarshalReceiver helper function to unmarshal a Receiver config. // It checks if the config implements Unmarshallable and uses that if available, // otherwise uses Map.UnmarshalExact, erroring if a field is nonexistent. -func UnmarshalReceiver(cfgMap *Map, cfg Receiver) error { - return unmarshal(cfgMap, cfg) +func UnmarshalReceiver(conf *confmap.Conf, cfg Receiver) error { + return unmarshal(conf, cfg) } // ReceiverSettings defines common settings for a component.Receiver configuration. diff --git a/config/README.md b/confmap/README.md similarity index 74% rename from config/README.md rename to confmap/README.md index b2d94829160..6a40ed10a87 100644 --- a/config/README.md +++ b/confmap/README.md @@ -3,39 +3,39 @@ This document is work in progress, some concepts are not yet available (e.g. MapResolver is a private concept in the service for the moment). -## Map +## ConfMap -The [Map](configmap.go) represents the raw configuration for a service (e.g. OpenTelemetry Collector). +The [ConfMap](confmap.go) represents the raw configuration for a service (e.g. OpenTelemetry Collector). -## MapProvider +## Provider -The [MapProvider](mapprovider.go) provides configuration, and allows to watch/monitor for changes. Any `MapProvider` +The [Provider](provider.go) provides configuration, and allows to watch/monitor for changes. Any `Provider` has a `` associated with it, and will provide configs for `configURI` that follow the ":" format. This format is compatible with the URI definition (see [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986)). -The `` MUST be always included in the `configURI`. The scheme for any `MapProvider` MUST be at least 2 +The `` MUST be always included in the `configURI`. The scheme for any `Provider` MUST be at least 2 characters long to avoid conflicting with a driver-letter identifier as specified in [file URI syntax](https://tools.ietf.org/id/draft-kerwin-file-scheme-07.html#syntax). -## MapConverter +## Converter -The [MapConverter](mapconverter.go) allows implementing conversion logic for the provided configuration. One of the most +The [Converter](converter.go) allows implementing conversion logic for the provided configuration. One of the most common use-case is to migrate/transform the configuration after a backwards incompatible change. ## MapResolver -The `MapResolver` handles the use of multiple [MapProviders](#mapprovider) and [MapConverters](#mapconverter) +The `MapResolver` handles the use of multiple [Providers](#provider) and [Converters](#converter) simplifying configuration parsing, monitoring for updates, and the overall life-cycle of the used config providers. The `MapResolver` provides two main functionalities: [Configuration Resolving](#configuration-resolving) and [Watching for Updates](#watching-for-updates). ### Configuration Resolving -The `MapResolver` receives as input a set of `MapProviders`, a list of `MapConverters`, and a list of configuration identifier +The `MapResolver` receives as input a set of `Providers`, a list of `Converters`, and a list of configuration identifier `configURI` that will be used to generate the resulting, or effective, configuration in the form of a `config.Map`, -that can be used by code that is oblivious to the usage of `MapProviders` and `MapConverters`. +that can be used by code that is oblivious to the usage of `Providers` and `Converters`. ```terminal - MapResolver MapProvider + MapResolver Provider β”‚ β”‚ Resolve β”‚ β”‚ ────────────────►│ β”‚ @@ -49,12 +49,12 @@ that can be used by code that is oblivious to the usage of `MapProviders` and `M β”‚ β”‚ β”‚Merge β”‚ β”‚ β”‚β—„β”€β”€β”˜ β”‚ └─ β”‚ β”‚ - β”‚ MapConverter β”‚ + β”‚ Converter β”‚ β”‚ β”‚ β”‚ β”Œβ”€ β”‚ Convert β”‚ β”‚ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Ίβ”‚ β”‚ - foreach β”‚ β”‚ β”‚ β”‚ - MapConverter β”‚ │◄──────────────── β”‚ + foreach β”‚ β”‚ β”‚ β”‚ + Converter β”‚ │◄──────────────── β”‚ └─ β”‚ β”‚ β”‚ β”‚ ◄───────────────── β”‚ @@ -70,10 +70,10 @@ The `Resolve` method proceeds in the following steps: ### Watching for Updates After the configuration was processed, the `MapResolver` can be used as a single point to watch for updates in the -configuration retrieved via the `MapProvider` used to retrieve the β€œinitial” configuration and to generate the β€œeffective” one. +configuration retrieved via the `Provider` used to retrieve the β€œinitial” configuration and to generate the β€œeffective” one. ```terminal - MapResolver MapProvider + MapResolver Provider β”‚ β”‚ Watch β”‚ β”‚ ───────────►│ β”‚ @@ -86,4 +86,4 @@ configuration retrieved via the `MapProvider` used to retrieve the β€œinitial” ◄──────────── β”‚ ``` -The `MapResolver` does that by passing an `onChange` func to each `MapProvider.Retrieve` call and capturing all watch events. +The `MapResolver` does that by passing an `onChange` func to each `Provider.Retrieve` call and capturing all watch events. diff --git a/config/configmap.go b/confmap/confmap.go similarity index 86% rename from config/configmap.go rename to confmap/confmap.go index 1253f1512cd..2296e05c118 100644 --- a/config/configmap.go +++ b/confmap/confmap.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package config // import "go.opentelemetry.io/collector/config" +package confmap // import "go.opentelemetry.io/collector/confmap" import ( "encoding" @@ -30,34 +30,34 @@ const ( KeyDelimiter = "::" ) -// NewMap creates a new empty config.Map instance. -func NewMap() *Map { - return &Map{k: koanf.New(KeyDelimiter)} +// New creates a new empty confmap.Conf instance. +func New() *Conf { + return &Conf{k: koanf.New(KeyDelimiter)} } -// NewMapFromStringMap creates a config.Map from a map[string]interface{}. -func NewMapFromStringMap(data map[string]interface{}) *Map { - p := NewMap() +// NewFromStringMap creates a confmap.Conf from a map[string]interface{}. +func NewFromStringMap(data map[string]interface{}) *Conf { + p := New() // Cannot return error because the koanf instance is empty. _ = p.k.Load(confmap.Provider(data, KeyDelimiter), nil) return p } -// Map represents the raw configuration map for the OpenTelemetry Collector. -// The config.Map can be unmarshalled into the Collector's config using the "configunmarshaler" package. -type Map struct { +// Conf represents the raw configuration map for the OpenTelemetry Collector. +// The confmap.Conf can be unmarshalled into the Collector's config using the "service" package. +type Conf struct { k *koanf.Koanf } // AllKeys returns all keys holding a value, regardless of where they are set. // Nested keys are returned with a KeyDelimiter separator. -func (l *Map) AllKeys() []string { +func (l *Conf) AllKeys() []string { return l.k.Keys() } // Unmarshal unmarshalls the config into a struct. // Tags on the fields of the structure must be properly set. -func (l *Map) Unmarshal(rawVal interface{}) error { +func (l *Conf) Unmarshal(rawVal interface{}) error { decoder, err := mapstructure.NewDecoder(decoderConfig(rawVal)) if err != nil { return err @@ -66,7 +66,7 @@ func (l *Map) Unmarshal(rawVal interface{}) error { } // UnmarshalExact unmarshalls the config into a struct, erroring if a field is nonexistent. -func (l *Map) UnmarshalExact(rawVal interface{}) error { +func (l *Conf) UnmarshalExact(rawVal interface{}) error { dc := decoderConfig(rawVal) dc.ErrorUnused = true decoder, err := mapstructure.NewDecoder(dc) @@ -77,12 +77,12 @@ func (l *Map) UnmarshalExact(rawVal interface{}) error { } // Get can retrieve any value given the key to use. -func (l *Map) Get(key string) interface{} { +func (l *Conf) Get(key string) interface{} { return l.k.Get(key) } // Set sets the value for the key. -func (l *Map) Set(key string, value interface{}) { +func (l *Conf) Set(key string, value interface{}) { // koanf doesn't offer a direct setting mechanism so merging is required. merged := koanf.New(KeyDelimiter) _ = merged.Load(confmap.Provider(map[string]interface{}{key: value}, KeyDelimiter), nil) @@ -92,34 +92,34 @@ func (l *Map) Set(key string, value interface{}) { // IsSet checks to see if the key has been set in any of the data locations. // IsSet is case-insensitive for a key. -func (l *Map) IsSet(key string) bool { +func (l *Conf) IsSet(key string) bool { return l.k.Exists(key) } // Merge merges the input given configuration into the existing config. // Note that the given map may be modified. -func (l *Map) Merge(in *Map) error { +func (l *Conf) Merge(in *Conf) error { return l.k.Merge(in.k) } -// Sub returns new Map instance representing a sub-config of this instance. +// Sub returns new Conf instance representing a sub-config of this instance. // It returns an error is the sub-config is not a map[string]interface{} (use Get()), and an empty Map if none exists. -func (l *Map) Sub(key string) (*Map, error) { +func (l *Conf) Sub(key string) (*Conf, error) { // Code inspired by the koanf "Cut" func, but returns an error instead of empty map for unsupported sub-config type. data := l.Get(key) if data == nil { - return NewMap(), nil + return New(), nil } if v, ok := data.(map[string]interface{}); ok { - return NewMapFromStringMap(v), nil + return NewFromStringMap(v), nil } return nil, fmt.Errorf("unexpected sub-config value kind for key:%s value:%v kind:%v)", key, data, reflect.TypeOf(data).Kind()) } // ToStringMap creates a map[string]interface{} from a Parser. -func (l *Map) ToStringMap() map[string]interface{} { +func (l *Conf) ToStringMap() map[string]interface{} { return maps.Unflatten(l.k.All(), KeyDelimiter) } diff --git a/config/configmap_test.go b/confmap/confmap_test.go similarity index 90% rename from config/configmap_test.go rename to confmap/confmap_test.go index 000e7665e31..74ce5d10704 100644 --- a/config/configmap_test.go +++ b/confmap/confmap_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package config +package confmap import ( "errors" @@ -28,7 +28,7 @@ import ( ) func TestToStringMap_WithSet(t *testing.T) { - parser := NewMap() + parser := New() parser.Set("key::embedded", int64(123)) assert.Equal(t, map[string]interface{}{"key": map[string]interface{}{"embedded": int64(123)}}, parser.ToStringMap()) } @@ -111,8 +111,8 @@ func TestToStringMap(t *testing.T) { } } -// newMapFromFile creates a new config.Map by reading the given file. -func newMapFromFile(fileName string) (*Map, error) { +// newMapFromFile creates a new confmap.Conf by reading the given file. +func newMapFromFile(fileName string) (*Conf, error) { content, err := ioutil.ReadFile(filepath.Clean(fileName)) if err != nil { return nil, fmt.Errorf("unable to read the file %v: %w", fileName, err) @@ -123,7 +123,7 @@ func newMapFromFile(fileName string) (*Map, error) { return nil, fmt.Errorf("unable to parse yaml: %w", err) } - return NewMapFromStringMap(data), nil + return NewFromStringMap(data), nil } func TestExpandNilStructPointersHookFunc(t *testing.T) { @@ -134,10 +134,10 @@ func TestExpandNilStructPointersHookFunc(t *testing.T) { "struct": nil, }, } - cfgMap := NewMapFromStringMap(stringMap) + conf := NewFromStringMap(stringMap) cfg := &TestConfig{} assert.Nil(t, cfg.Struct) - assert.NoError(t, cfgMap.UnmarshalExact(cfg)) + assert.NoError(t, conf.UnmarshalExact(cfg)) assert.Nil(t, cfg.Boolean) // assert.False(t, *cfg.Boolean) assert.Nil(t, cfg.Struct) @@ -154,7 +154,7 @@ func TestExpandNilStructPointersHookFuncDefaultNotNilConfigNil(t *testing.T) { "struct": nil, }, } - cfgMap := NewMapFromStringMap(stringMap) + conf := NewFromStringMap(stringMap) varBool := true s1 := &Struct{Name: "s1"} s2 := &Struct{Name: "s2"} @@ -163,7 +163,7 @@ func TestExpandNilStructPointersHookFuncDefaultNotNilConfigNil(t *testing.T) { Struct: s1, MapStruct: map[string]*Struct{"struct": s2}, } - assert.NoError(t, cfgMap.UnmarshalExact(cfg)) + assert.NoError(t, conf.UnmarshalExact(cfg)) assert.NotNil(t, cfg.Boolean) assert.True(t, *cfg.Boolean) assert.NotNil(t, cfg.Struct) @@ -205,9 +205,9 @@ func TestMapKeyStringToMapKeyTextUnmarshalerHookFunc(t *testing.T) { "string": "this is a string", }, } - cfgMap := NewMapFromStringMap(stringMap) + conf := NewFromStringMap(stringMap) cfg := &TestIDConfig{} - assert.NoError(t, cfgMap.UnmarshalExact(cfg)) + assert.NoError(t, conf.UnmarshalExact(cfg)) assert.True(t, cfg.Boolean) assert.Equal(t, map[TestID]string{"string": "this is a string"}, cfg.Map) } @@ -220,9 +220,9 @@ func TestMapKeyStringToMapKeyTextUnmarshalerHookFuncDuplicateID(t *testing.T) { "string_": "this is another string", }, } - cfgMap := NewMapFromStringMap(stringMap) + conf := NewFromStringMap(stringMap) cfg := &TestIDConfig{} - assert.Error(t, cfgMap.UnmarshalExact(cfg)) + assert.Error(t, conf.UnmarshalExact(cfg)) } func TestMapKeyStringToMapKeyTextUnmarshalerHookFuncErrorUnmarshal(t *testing.T) { @@ -232,7 +232,7 @@ func TestMapKeyStringToMapKeyTextUnmarshalerHookFuncErrorUnmarshal(t *testing.T) "error": "this is a string", }, } - cfgMap := NewMapFromStringMap(stringMap) + conf := NewFromStringMap(stringMap) cfg := &TestIDConfig{} - assert.Error(t, cfgMap.UnmarshalExact(cfg)) + assert.Error(t, conf.UnmarshalExact(cfg)) } diff --git a/confmap/confmaptest/configtest.go b/confmap/confmaptest/configtest.go new file mode 100644 index 00000000000..198909aa7a0 --- /dev/null +++ b/confmap/confmaptest/configtest.go @@ -0,0 +1,31 @@ +// Copyright The 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 confmaptest // import "go.opentelemetry.io/collector/confmap/confmaptest" + +import ( + "context" + + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" +) + +// LoadConf loads a confmap.Conf from file, and does NOT validate the configuration. +func LoadConf(fileName string) (*confmap.Conf, error) { + ret, err := fileprovider.New().Retrieve(context.Background(), "file:"+fileName, nil) + if err != nil { + return nil, err + } + return ret.AsMap() +} diff --git a/confmap/confmaptest/configtest_test.go b/confmap/confmaptest/configtest_test.go new file mode 100644 index 00000000000..ae1e592dec1 --- /dev/null +++ b/confmap/confmaptest/configtest_test.go @@ -0,0 +1,34 @@ +// Copyright The 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 confmaptest + +import ( + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestLoadConfigMap_FileNotFound(t *testing.T) { + _, err := LoadConf("file/not/found") + assert.Error(t, err) +} + +func TestLoadConfigMap(t *testing.T) { + cfg, err := LoadConf(filepath.Join("testdata", "simple.yaml")) + require.NoError(t, err) + assert.Equal(t, map[string]interface{}{"floating": 3.14}, cfg.ToStringMap()) +} diff --git a/confmap/confmaptest/doc.go b/confmap/confmaptest/doc.go new file mode 100644 index 00000000000..47e5938b427 --- /dev/null +++ b/confmap/confmaptest/doc.go @@ -0,0 +1,16 @@ +// Copyright The 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 confmaptest helps loading confmap.Conf to test packages implementing using the configuration. +package confmaptest // import "go.opentelemetry.io/collector/confmap/confmaptest" diff --git a/confmap/confmaptest/testdata/simple.yaml b/confmap/confmaptest/testdata/simple.yaml new file mode 100644 index 00000000000..116d9c5f15b --- /dev/null +++ b/confmap/confmaptest/testdata/simple.yaml @@ -0,0 +1 @@ +floating: 3.14 diff --git a/config/mapconverter.go b/confmap/converter.go similarity index 70% rename from config/mapconverter.go rename to confmap/converter.go index 3337a640f5d..74ba0933566 100644 --- a/config/mapconverter.go +++ b/confmap/converter.go @@ -12,15 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -package config // import "go.opentelemetry.io/collector/config" +package confmap // import "go.opentelemetry.io/collector/confmap" import ( "context" ) -// MapConverter is a converter interface for the config.Map that allows distributions +// Converter is a converter interface for the confmap.Conf that allows distributions // (in the future components as well) to build backwards compatible config converters. -type MapConverter interface { - // Convert applies the conversion logic to the given "cfgMap". - Convert(ctx context.Context, cfgMap *Map) error +type Converter interface { + // Convert applies the conversion logic to the given "conf". + Convert(ctx context.Context, conf *Conf) error } diff --git a/config/mapconverter/expandmapconverter/expand.go b/confmap/converter/expandconverter/expand.go similarity index 78% rename from config/mapconverter/expandmapconverter/expand.go rename to confmap/converter/expandconverter/expand.go index 44d6398e7f7..b6670d09c82 100644 --- a/config/mapconverter/expandmapconverter/expand.go +++ b/confmap/converter/expandconverter/expand.go @@ -12,27 +12,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -package expandmapconverter // import "go.opentelemetry.io/collector/config/mapconverter/expandmapconverter" +package expandconverter // import "go.opentelemetry.io/collector/confmap/converter/expandconverter" import ( "context" "os" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) type converter struct{} -// New returns a config.MapConverter, that expands all environment variables for a given config.Map. +// New returns a confmap.Converter, that expands all environment variables for a given confmap.Conf. // // Notice: This API is experimental. -func New() config.MapConverter { +func New() confmap.Converter { return converter{} } -func (converter) Convert(_ context.Context, cfgMap *config.Map) error { - for _, k := range cfgMap.AllKeys() { - cfgMap.Set(k, expandStringValues(cfgMap.Get(k))) +func (converter) Convert(_ context.Context, conf *confmap.Conf) error { + for _, k := range conf.AllKeys() { + conf.Set(k, expandStringValues(conf.Get(k))) } return nil } diff --git a/config/mapconverter/expandmapconverter/expand_test.go b/confmap/converter/expandconverter/expand_test.go similarity index 79% rename from config/mapconverter/expandmapconverter/expand_test.go rename to confmap/converter/expandconverter/expand_test.go index 7697d10df49..65fb24e653c 100644 --- a/config/mapconverter/expandmapconverter/expand_test.go +++ b/confmap/converter/expandconverter/expand_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package expandmapconverter +package expandconverter import ( "context" @@ -22,8 +22,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/configtest" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/confmaptest" ) func TestNewExpandConverter(t *testing.T) { @@ -47,17 +47,17 @@ func TestNewExpandConverter(t *testing.T) { t.Setenv("EXTRA_LIST_VALUE_1", valueExtraListElement+"_1") t.Setenv("EXTRA_LIST_VALUE_2", valueExtraListElement+"_2") - expectedCfgMap, errExpected := configtest.LoadConfigMap(filepath.Join("testdata", "expand-with-no-env.yaml")) + expectedCfgMap, errExpected := confmaptest.LoadConf(filepath.Join("testdata", "expand-with-no-env.yaml")) require.NoError(t, errExpected, "Unable to get expected config") for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - cfgMap, err := configtest.LoadConfigMap(filepath.Join("testdata", test.name)) + conf, err := confmaptest.LoadConf(filepath.Join("testdata", test.name)) require.NoError(t, err, "Unable to get config") // Test that expanded configs are the same with the simple config with no env vars. - require.NoError(t, New().Convert(context.Background(), cfgMap)) - assert.Equal(t, expectedCfgMap.ToStringMap(), cfgMap.ToStringMap()) + require.NoError(t, New().Convert(context.Background(), conf)) + assert.Equal(t, expectedCfgMap.ToStringMap(), conf.ToStringMap()) }) } } @@ -66,7 +66,7 @@ func TestNewExpandConverter_EscapedMaps(t *testing.T) { const receiverExtraMapValue = "some map value" t.Setenv("MAP_VALUE", receiverExtraMapValue) - cfgMap := config.NewMapFromStringMap( + conf := confmap.NewFromStringMap( map[string]interface{}{ "test_string_map": map[string]interface{}{ "recv": "$MAP_VALUE", @@ -75,7 +75,7 @@ func TestNewExpandConverter_EscapedMaps(t *testing.T) { "recv": "$MAP_VALUE", }}, ) - require.NoError(t, New().Convert(context.Background(), cfgMap)) + require.NoError(t, New().Convert(context.Background(), conf)) expectedMap := map[string]interface{}{ "test_string_map": map[string]interface{}{ @@ -84,7 +84,7 @@ func TestNewExpandConverter_EscapedMaps(t *testing.T) { "test_interface_map": map[string]interface{}{ "recv": receiverExtraMapValue, }} - assert.Equal(t, expectedMap, cfgMap.ToStringMap()) + assert.Equal(t, expectedMap, conf.ToStringMap()) } func TestNewExpandConverter_EscapedEnvVars(t *testing.T) { @@ -92,7 +92,7 @@ func TestNewExpandConverter_EscapedEnvVars(t *testing.T) { t.Setenv("MAP_VALUE_2", receiverExtraMapValue) // Retrieve the config - cfgMap, err := configtest.LoadConfigMap(filepath.Join("testdata", "expand-escaped-env.yaml")) + conf, err := confmaptest.LoadConf(filepath.Join("testdata", "expand-escaped-env.yaml")) require.NoError(t, err, "Unable to get config") expectedMap := map[string]interface{}{ @@ -112,6 +112,6 @@ func TestNewExpandConverter_EscapedEnvVars(t *testing.T) { // escaped $ alone "recv.7": "$", }} - require.NoError(t, New().Convert(context.Background(), cfgMap)) - assert.Equal(t, expectedMap, cfgMap.ToStringMap()) + require.NoError(t, New().Convert(context.Background(), conf)) + assert.Equal(t, expectedMap, conf.ToStringMap()) } diff --git a/config/mapconverter/expandmapconverter/testdata/default-config.yaml b/confmap/converter/expandconverter/testdata/default-config.yaml similarity index 100% rename from config/mapconverter/expandmapconverter/testdata/default-config.yaml rename to confmap/converter/expandconverter/testdata/default-config.yaml diff --git a/config/mapconverter/expandmapconverter/testdata/expand-escaped-env.yaml b/confmap/converter/expandconverter/testdata/expand-escaped-env.yaml similarity index 100% rename from config/mapconverter/expandmapconverter/testdata/expand-escaped-env.yaml rename to confmap/converter/expandconverter/testdata/expand-escaped-env.yaml diff --git a/config/mapconverter/expandmapconverter/testdata/expand-with-all-env.yaml b/confmap/converter/expandconverter/testdata/expand-with-all-env.yaml similarity index 100% rename from config/mapconverter/expandmapconverter/testdata/expand-with-all-env.yaml rename to confmap/converter/expandconverter/testdata/expand-with-all-env.yaml diff --git a/config/mapconverter/expandmapconverter/testdata/expand-with-no-env.yaml b/confmap/converter/expandconverter/testdata/expand-with-no-env.yaml similarity index 100% rename from config/mapconverter/expandmapconverter/testdata/expand-with-no-env.yaml rename to confmap/converter/expandconverter/testdata/expand-with-no-env.yaml diff --git a/config/mapconverter/expandmapconverter/testdata/expand-with-partial-env.yaml b/confmap/converter/expandconverter/testdata/expand-with-partial-env.yaml similarity index 100% rename from config/mapconverter/expandmapconverter/testdata/expand-with-partial-env.yaml rename to confmap/converter/expandconverter/testdata/expand-with-partial-env.yaml diff --git a/config/mapconverter/overwritepropertiesmapconverter/properties.go b/confmap/converter/overwritepropertiesconverter/properties.go similarity index 78% rename from config/mapconverter/overwritepropertiesmapconverter/properties.go rename to confmap/converter/overwritepropertiesconverter/properties.go index 152dab4ce63..71f5532dd79 100644 --- a/config/mapconverter/overwritepropertiesmapconverter/properties.go +++ b/confmap/converter/overwritepropertiesconverter/properties.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package overwritepropertiesmapconverter // import "go.opentelemetry.io/collector/config/mapconverter/overwritepropertiesmapconverter" +package overwritepropertiesconverter // import "go.opentelemetry.io/collector/confmap/converter/overwritepropertiesconverter" import ( "bytes" @@ -22,24 +22,24 @@ import ( "github.com/knadh/koanf/maps" "github.com/magiconair/properties" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) type converter struct { properties []string } -// New returns a config.MapConverter, that overrides all the given properties into the +// New returns a confmap.Converter, that overrides all the given properties into the // input map. // // Properties must follow the Java properties format, key-value list separated by equal sign with a "." // as key delimiter. // ["processors.batch.timeout=2s", "processors.batch/foo.timeout=3s"] -func New(properties []string) config.MapConverter { +func New(properties []string) confmap.Converter { return &converter{properties: properties} } -func (c *converter) Convert(_ context.Context, cfgMap *config.Map) error { +func (c *converter) Convert(_ context.Context, conf *confmap.Conf) error { if len(c.properties) == 0 { return nil } @@ -65,5 +65,5 @@ func (c *converter) Convert(_ context.Context, cfgMap *config.Map) error { } prop := maps.Unflatten(parsed, ".") - return cfgMap.Merge(config.NewMapFromStringMap(prop)) + return conf.Merge(confmap.NewFromStringMap(prop)) } diff --git a/config/mapconverter/overwritepropertiesmapconverter/properties_test.go b/confmap/converter/overwritepropertiesconverter/properties_test.go similarity index 59% rename from config/mapconverter/overwritepropertiesmapconverter/properties_test.go rename to confmap/converter/overwritepropertiesconverter/properties_test.go index 1ab2e7daf15..363868c833b 100644 --- a/config/mapconverter/overwritepropertiesmapconverter/properties_test.go +++ b/confmap/converter/overwritepropertiesconverter/properties_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package overwritepropertiesmapconverter +package overwritepropertiesconverter import ( "context" @@ -21,14 +21,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) func TestOverwritePropertiesConverter_Empty(t *testing.T) { pmp := New(nil) - cfgMap := config.NewMapFromStringMap(map[string]interface{}{"foo": "bar"}) - assert.NoError(t, pmp.Convert(context.Background(), cfgMap)) - assert.Equal(t, map[string]interface{}{"foo": "bar"}, cfgMap.ToStringMap()) + conf := confmap.NewFromStringMap(map[string]interface{}{"foo": "bar"}) + assert.NoError(t, pmp.Convert(context.Background(), conf)) + assert.Equal(t, map[string]interface{}{"foo": "bar"}, conf.ToStringMap()) } func TestOverwritePropertiesConverter(t *testing.T) { @@ -40,18 +40,18 @@ func TestOverwritePropertiesConverter(t *testing.T) { } pmp := New(props) - cfgMap := config.NewMap() - require.NoError(t, pmp.Convert(context.Background(), cfgMap)) - keys := cfgMap.AllKeys() + conf := confmap.New() + require.NoError(t, pmp.Convert(context.Background(), conf)) + keys := conf.AllKeys() assert.Len(t, keys, 4) - assert.Equal(t, "2s", cfgMap.Get("processors::batch::timeout")) - assert.Equal(t, "3s", cfgMap.Get("processors::batch/foo::timeout")) - assert.Equal(t, "foo:9200,foo2:9200", cfgMap.Get("exporters::kafka::brokers")) - assert.Equal(t, "localhost:1818", cfgMap.Get("receivers::otlp::protocols::grpc::endpoint")) + assert.Equal(t, "2s", conf.Get("processors::batch::timeout")) + assert.Equal(t, "3s", conf.Get("processors::batch/foo::timeout")) + assert.Equal(t, "foo:9200,foo2:9200", conf.Get("exporters::kafka::brokers")) + assert.Equal(t, "localhost:1818", conf.Get("receivers::otlp::protocols::grpc::endpoint")) } func TestOverwritePropertiesConverter_InvalidProperty(t *testing.T) { pmp := New([]string{"=2s"}) - cfgMap := config.NewMap() - assert.Error(t, pmp.Convert(context.Background(), cfgMap)) + conf := confmap.New() + assert.Error(t, pmp.Convert(context.Background(), conf)) } diff --git a/config/mapprovider.go b/confmap/provider.go similarity index 87% rename from config/mapprovider.go rename to confmap/provider.go index e6a9884014f..879cb401f3b 100644 --- a/config/mapprovider.go +++ b/confmap/provider.go @@ -12,28 +12,28 @@ // See the License for the specific language governing permissions and // limitations under the License. -package config // import "go.opentelemetry.io/collector/config" +package confmap // import "go.opentelemetry.io/collector/confmap" import ( "context" ) -// MapProvider is an interface that helps to retrieve a config map and watch for any +// Provider is an interface that helps to retrieve a config map and watch for any // changes to the config map. Implementations may load the config from a file, // a database or any other source. // // The typical usage is the following: // -// r, err := mapProvider.Retrieve("file:/path/to/config") +// r, err := provider.Retrieve("file:/path/to/config") // // Use r.Map; wait for watcher to be called. // r.Close() -// r, err = mapProvider.Retrieve("file:/path/to/config") +// r, err = provider.Retrieve("file:/path/to/config") // // Use r.Map; wait for watcher to be called. // r.Close() // // repeat retrieve/wait/close cycle until it is time to shut down the Collector process. // // ... -// mapProvider.Shutdown() -type MapProvider interface { +// provider.Shutdown() +type Provider interface { // Retrieve goes to the configuration source and retrieves the selected data which // contains the value to be injected in the configuration and the corresponding watcher that // will be used to monitor for updates of the retrieved value. @@ -81,7 +81,7 @@ type ChangeEvent struct { // Retrieved holds the result of a call to the Retrieve method of a Provider object. type Retrieved struct { - cfgMap *Map + conf *Conf closeFunc CloseFunc } @@ -101,24 +101,24 @@ func WithRetrievedClose(closeFunc CloseFunc) RetrievedOption { } // NewRetrievedFromMap returns a new Retrieved instance that contains a Map data. -// * cfgMap the Map that will be merged to the given map in the MergeTo. +// * conf the Map that will be merged to the given map in the MergeTo. // * CloseFunc specifies a function to be invoked when the configuration for which it was // used to retrieve values is no longer in use and should close and release any watchers // that it may have created. -func NewRetrievedFromMap(cfgMap *Map, opts ...RetrievedOption) Retrieved { +func NewRetrievedFromMap(conf *Conf, opts ...RetrievedOption) Retrieved { set := retrievedSettings{} for _, opt := range opts { opt(&set) } - return Retrieved{cfgMap: cfgMap, closeFunc: set.closeFunc} + return Retrieved{conf: conf, closeFunc: set.closeFunc} } // AsMap returns the retrieved configuration parsed as a Map. -func (r Retrieved) AsMap() (*Map, error) { - return r.cfgMap, nil +func (r Retrieved) AsMap() (*Conf, error) { + return r.conf, nil } -// Close and release any watchers that MapProvider.Retrieve may have created. +// Close and release any watchers that Provider.Retrieve may have created. // // Should block until all resources are closed, and guarantee that `onChange` is not // going to be called after it returns except when `ctx` is cancelled. diff --git a/config/mapprovider/envmapprovider/mapprovider.go b/confmap/provider/envprovider/mapprovider.go similarity index 57% rename from config/mapprovider/envmapprovider/mapprovider.go rename to confmap/provider/envprovider/mapprovider.go index db405c75058..58ba6de5493 100644 --- a/config/mapprovider/envmapprovider/mapprovider.go +++ b/confmap/provider/envprovider/mapprovider.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package envmapprovider // import "go.opentelemetry.io/collector/config/mapprovider/envmapprovider" +package envprovider // import "go.opentelemetry.io/collector/confmap/provider/envprovider" import ( "context" @@ -22,39 +22,39 @@ import ( "gopkg.in/yaml.v3" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) const schemeName = "env" -type mapProvider struct{} +type provider struct{} -// New returns a new config.MapProvider that reads the configuration from the given environment variable. +// New returns a new confmap.Provider that reads the configuration from the given environment variable. // // This Provider supports "env" scheme, and can be called with a selector: // `env:NAME_OF_ENVIRONMENT_VARIABLE` -func New() config.MapProvider { - return &mapProvider{} +func New() confmap.Provider { + return &provider{} } -func (emp *mapProvider) Retrieve(_ context.Context, uri string, _ config.WatcherFunc) (config.Retrieved, error) { +func (emp *provider) Retrieve(_ context.Context, uri string, _ confmap.WatcherFunc) (confmap.Retrieved, error) { if !strings.HasPrefix(uri, schemeName+":") { - return config.Retrieved{}, fmt.Errorf("%v uri is not supported by %v provider", uri, schemeName) + return confmap.Retrieved{}, fmt.Errorf("%v uri is not supported by %v provider", uri, schemeName) } content := os.Getenv(uri[len(schemeName)+1:]) var data map[string]interface{} if err := yaml.Unmarshal([]byte(content), &data); err != nil { - return config.Retrieved{}, fmt.Errorf("unable to parse yaml: %w", err) + return confmap.Retrieved{}, fmt.Errorf("unable to parse yaml: %w", err) } - return config.NewRetrievedFromMap(config.NewMapFromStringMap(data)), nil + return confmap.NewRetrievedFromMap(confmap.NewFromStringMap(data)), nil } -func (*mapProvider) Scheme() string { +func (*provider) Scheme() string { return schemeName } -func (*mapProvider) Shutdown(context.Context) error { +func (*provider) Shutdown(context.Context) error { return nil } diff --git a/config/mapprovider/envmapprovider/mapprovider_test.go b/confmap/provider/envprovider/mapprovider_test.go similarity index 93% rename from config/mapprovider/envmapprovider/mapprovider_test.go rename to confmap/provider/envprovider/mapprovider_test.go index 90dded2c245..269f4b82a1c 100644 --- a/config/mapprovider/envmapprovider/mapprovider_test.go +++ b/confmap/provider/envprovider/mapprovider_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package envmapprovider +package envprovider import ( "context" @@ -21,7 +21,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) const envSchemePrefix = schemeName + ":" @@ -68,7 +68,7 @@ func TestEnv(t *testing.T) { require.NoError(t, err) retMap, err := ret.AsMap() assert.NoError(t, err) - expectedMap := config.NewMapFromStringMap(map[string]interface{}{ + expectedMap := confmap.NewFromStringMap(map[string]interface{}{ "processors::batch": nil, "exporters::otlp::endpoint": "localhost:4317", }) diff --git a/config/mapprovider/filemapprovider/mapprovider.go b/confmap/provider/fileprovider/mapprovider.go similarity index 65% rename from config/mapprovider/filemapprovider/mapprovider.go rename to confmap/provider/fileprovider/mapprovider.go index a9185e266ef..9c9079ef856 100644 --- a/config/mapprovider/filemapprovider/mapprovider.go +++ b/confmap/provider/fileprovider/mapprovider.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package filemapprovider // import "go.opentelemetry.io/collector/config/mapprovider/filemapprovider" +package fileprovider // import "go.opentelemetry.io/collector/confmap/provider/fileprovider" import ( "context" @@ -23,14 +23,14 @@ import ( "gopkg.in/yaml.v3" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) const schemeName = "file" -type mapProvider struct{} +type provider struct{} -// New returns a new config.MapProvider that reads the configuration from a file. +// New returns a new confmap.Provider that reads the configuration from a file. // // This Provider supports "file" scheme, and can be called with a "uri" that follows: // file-uri = "file:" local-path @@ -43,33 +43,33 @@ type mapProvider struct{} // `file:/path/to/file` - absolute path (unix, windows) // `file:c:/path/to/file` - absolute path including drive-letter (windows) // `file:c:\path\to\file` - absolute path including drive-letter (windows) -func New() config.MapProvider { - return &mapProvider{} +func New() confmap.Provider { + return &provider{} } -func (fmp *mapProvider) Retrieve(_ context.Context, uri string, _ config.WatcherFunc) (config.Retrieved, error) { +func (fmp *provider) Retrieve(_ context.Context, uri string, _ confmap.WatcherFunc) (confmap.Retrieved, error) { if !strings.HasPrefix(uri, schemeName+":") { - return config.Retrieved{}, fmt.Errorf("%v uri is not supported by %v provider", uri, schemeName) + return confmap.Retrieved{}, fmt.Errorf("%v uri is not supported by %v provider", uri, schemeName) } // Clean the path before using it. content, err := ioutil.ReadFile(filepath.Clean(uri[len(schemeName)+1:])) if err != nil { - return config.Retrieved{}, fmt.Errorf("unable to read the file %v: %w", uri, err) + return confmap.Retrieved{}, fmt.Errorf("unable to read the file %v: %w", uri, err) } var data map[string]interface{} if err = yaml.Unmarshal(content, &data); err != nil { - return config.Retrieved{}, fmt.Errorf("unable to parse yaml: %w", err) + return confmap.Retrieved{}, fmt.Errorf("unable to parse yaml: %w", err) } - return config.NewRetrievedFromMap(config.NewMapFromStringMap(data)), nil + return confmap.NewRetrievedFromMap(confmap.NewFromStringMap(data)), nil } -func (*mapProvider) Scheme() string { +func (*provider) Scheme() string { return schemeName } -func (*mapProvider) Shutdown(context.Context) error { +func (*provider) Shutdown(context.Context) error { return nil } diff --git a/config/mapprovider/filemapprovider/mapprovider_test.go b/confmap/provider/fileprovider/mapprovider_test.go similarity index 93% rename from config/mapprovider/filemapprovider/mapprovider_test.go rename to confmap/provider/fileprovider/mapprovider_test.go index 443ee7972cc..8c5b3fa87be 100644 --- a/config/mapprovider/filemapprovider/mapprovider_test.go +++ b/confmap/provider/fileprovider/mapprovider_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package filemapprovider +package fileprovider import ( "context" @@ -23,7 +23,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) const fileSchemePrefix = schemeName + ":" @@ -66,7 +66,7 @@ func TestRelativePath(t *testing.T) { require.NoError(t, err) retMap, err := ret.AsMap() assert.NoError(t, err) - expectedMap := config.NewMapFromStringMap(map[string]interface{}{ + expectedMap := confmap.NewFromStringMap(map[string]interface{}{ "processors::batch": nil, "exporters::otlp::endpoint": "localhost:4317", }) @@ -80,7 +80,7 @@ func TestAbsolutePath(t *testing.T) { require.NoError(t, err) retMap, err := ret.AsMap() assert.NoError(t, err) - expectedMap := config.NewMapFromStringMap(map[string]interface{}{ + expectedMap := confmap.NewFromStringMap(map[string]interface{}{ "processors::batch": nil, "exporters::otlp::endpoint": "localhost:4317", }) diff --git a/config/mapprovider/filemapprovider/testdata/default-config.yaml b/confmap/provider/fileprovider/testdata/default-config.yaml similarity index 100% rename from config/mapprovider/filemapprovider/testdata/default-config.yaml rename to confmap/provider/fileprovider/testdata/default-config.yaml diff --git a/config/mapprovider/filemapprovider/testdata/invalid-yaml.yaml b/confmap/provider/fileprovider/testdata/invalid-yaml.yaml similarity index 100% rename from config/mapprovider/filemapprovider/testdata/invalid-yaml.yaml rename to confmap/provider/fileprovider/testdata/invalid-yaml.yaml diff --git a/config/mapprovider/yamlmapprovider/mapprovider.go b/confmap/provider/yamlprovider/mapprovider.go similarity index 60% rename from config/mapprovider/yamlmapprovider/mapprovider.go rename to confmap/provider/yamlprovider/mapprovider.go index f11a94c72e8..aed8b9afbc7 100644 --- a/config/mapprovider/yamlmapprovider/mapprovider.go +++ b/confmap/provider/yamlprovider/mapprovider.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package yamlmapprovider // import "go.opentelemetry.io/collector/config/mapprovider/yamlmapprovider" +package yamlprovider // import "go.opentelemetry.io/collector/confmap/provider/yamlprovider" import ( "context" @@ -21,14 +21,14 @@ import ( "gopkg.in/yaml.v3" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" ) const schemeName = "yaml" -type mapProvider struct{} +type provider struct{} -// New returns a new config.MapProvider that allows to provide yaml bytes. +// New returns a new confmap.Provider that allows to provide yaml bytes. // // This Provider supports "yaml" scheme, and can be called with a "uri" that follows: // bytes-uri = "yaml:" yaml-bytes @@ -36,27 +36,27 @@ type mapProvider struct{} // Examples: // `yaml:processors::batch::timeout: 2s` // `yaml:processors::batch/foo::timeout: 3s` -func New() config.MapProvider { - return &mapProvider{} +func New() confmap.Provider { + return &provider{} } -func (s *mapProvider) Retrieve(_ context.Context, uri string, _ config.WatcherFunc) (config.Retrieved, error) { +func (s *provider) Retrieve(_ context.Context, uri string, _ confmap.WatcherFunc) (confmap.Retrieved, error) { if !strings.HasPrefix(uri, schemeName+":") { - return config.Retrieved{}, fmt.Errorf("%v uri is not supported by %v provider", uri, schemeName) + return confmap.Retrieved{}, fmt.Errorf("%v uri is not supported by %v provider", uri, schemeName) } var data map[string]interface{} if err := yaml.Unmarshal([]byte(uri[len(schemeName)+1:]), &data); err != nil { - return config.Retrieved{}, fmt.Errorf("unable to parse yaml: %w", err) + return confmap.Retrieved{}, fmt.Errorf("unable to parse yaml: %w", err) } - return config.NewRetrievedFromMap(config.NewMapFromStringMap(data)), nil + return confmap.NewRetrievedFromMap(confmap.NewFromStringMap(data)), nil } -func (*mapProvider) Scheme() string { +func (*provider) Scheme() string { return schemeName } -func (s *mapProvider) Shutdown(context.Context) error { +func (s *provider) Shutdown(context.Context) error { return nil } diff --git a/config/mapprovider/yamlmapprovider/mapprovider_test.go b/confmap/provider/yamlprovider/mapprovider_test.go similarity index 99% rename from config/mapprovider/yamlmapprovider/mapprovider_test.go rename to confmap/provider/yamlprovider/mapprovider_test.go index e8bb648879c..70171da061b 100644 --- a/config/mapprovider/yamlmapprovider/mapprovider_test.go +++ b/confmap/provider/yamlprovider/mapprovider_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package yamlmapprovider +package yamlprovider import ( "context" diff --git a/config/mapprovider_test.go b/confmap/provider_test.go similarity index 80% rename from config/mapprovider_test.go rename to confmap/provider_test.go index ece23f2502f..06e39aef5ed 100644 --- a/config/mapprovider_test.go +++ b/confmap/provider_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package config +package confmap import ( "context" @@ -24,20 +24,20 @@ import ( ) func TestNewRetrievedFromMap(t *testing.T) { - cfgMap := NewMap() - ret := NewRetrievedFromMap(cfgMap) + conf := New() + ret := NewRetrievedFromMap(conf) retMap, err := ret.AsMap() require.NoError(t, err) - assert.Same(t, cfgMap, retMap) + assert.Same(t, conf, retMap) assert.NoError(t, ret.Close(context.Background())) } func TestNewRetrievedFromMapWithOptions(t *testing.T) { want := errors.New("my error") - cfgMap := NewMap() - ret := NewRetrievedFromMap(cfgMap, WithRetrievedClose(func(context.Context) error { return want })) + conf := New() + ret := NewRetrievedFromMap(conf, WithRetrievedClose(func(context.Context) error { return want })) retMap, err := ret.AsMap() require.NoError(t, err) - assert.Same(t, cfgMap, retMap) + assert.Same(t, conf, retMap) assert.Equal(t, want, ret.Close(context.Background())) } diff --git a/config/testdata/basic_types.yaml b/confmap/testdata/basic_types.yaml similarity index 100% rename from config/testdata/basic_types.yaml rename to confmap/testdata/basic_types.yaml diff --git a/config/testdata/config.yaml b/confmap/testdata/config.yaml similarity index 100% rename from config/testdata/config.yaml rename to confmap/testdata/config.yaml diff --git a/config/testdata/embedded_keys.yaml b/confmap/testdata/embedded_keys.yaml similarity index 100% rename from config/testdata/embedded_keys.yaml rename to confmap/testdata/embedded_keys.yaml diff --git a/receiver/otlpreceiver/config.go b/receiver/otlpreceiver/config.go index ed1727b23d2..6a4552db25a 100644 --- a/receiver/otlpreceiver/config.go +++ b/receiver/otlpreceiver/config.go @@ -20,6 +20,7 @@ import ( "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configgrpc" "go.opentelemetry.io/collector/config/confighttp" + "go.opentelemetry.io/collector/confmap" ) const ( @@ -54,8 +55,8 @@ func (cfg *Config) Validate() error { return nil } -// Unmarshal a config.Map into the config struct. -func (cfg *Config) Unmarshal(componentParser *config.Map) error { +// Unmarshal a confmap.Conf into the config struct. +func (cfg *Config) Unmarshal(componentParser *confmap.Conf) error { if componentParser == nil || len(componentParser.AllKeys()) == 0 { return errors.New("empty config for OTLP receiver") } @@ -65,7 +66,7 @@ func (cfg *Config) Unmarshal(componentParser *config.Map) error { return err } - // next manually search for protocols in the config.Map, if a protocol is not present it means it is disabled. + // next manually search for protocols in the confmap.Conf, if a protocol is not present it means it is disabled. protocols, err := componentParser.Sub(protocolsFieldName) if err != nil { return err diff --git a/service/collector_test.go b/service/collector_test.go index e79ccd80d5d..bf69e3aba4c 100644 --- a/service/collector_test.go +++ b/service/collector_test.go @@ -34,7 +34,7 @@ import ( "go.uber.org/zap/zapcore" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config" + "go.opentelemetry.io/collector/confmap" "go.opentelemetry.io/collector/internal/testcomponents" "go.opentelemetry.io/collector/internal/testutil" "go.opentelemetry.io/collector/internal/version" @@ -184,9 +184,9 @@ type mapConverter struct { extraMap map[string]*string } -func (m mapConverter) Convert(ctx context.Context, cfgMap *config.Map) error { +func (m mapConverter) Convert(ctx context.Context, conf *confmap.Conf) error { for k, v := range m.extraMap { - cfgMap.Set(k, v) + conf.Set(k, v) } return nil } @@ -309,7 +309,7 @@ func testCollectorStartHelper(t *testing.T, telemetry collectorTelemetryExporter extraCfgAsProps["service::telemetry::resource::"+k] = v } - cfgSet.MapConverters = append([]config.MapConverter{ + cfgSet.MapConverters = append([]confmap.Converter{ mapConverter{extraCfgAsProps}}, cfgSet.MapConverters..., ) diff --git a/service/collector_windows.go b/service/collector_windows.go index b9dc2274b65..c33f960e052 100644 --- a/service/collector_windows.go +++ b/service/collector_windows.go @@ -29,8 +29,8 @@ import ( "golang.org/x/sys/windows/svc" "golang.org/x/sys/windows/svc/eventlog" - "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/mapconverter/overwritepropertiesmapconverter" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/converter/overwritepropertiesconverter" "go.opentelemetry.io/collector/service/featuregate" ) @@ -144,7 +144,7 @@ func newWithWindowsEventLogCore(set CollectorSettings, elog *eventlog.Log) (*Col cfgSet := newDefaultConfigProviderSettings(getConfigFlag()) // Append the "overwrite properties converter" as the first converter. cfgSet.MapConverters = append( - []config.MapConverter{overwritepropertiesmapconverter.New(getSetFlag())}, + []confmap.Converter{overwritepropertiesconverter.New(getSetFlag())}, cfgSet.MapConverters...) set.ConfigProvider, err = NewConfigProvider(cfgSet) if err != nil { diff --git a/service/command.go b/service/command.go index 5b7e68aa1fc..556ab0d027d 100644 --- a/service/command.go +++ b/service/command.go @@ -17,8 +17,8 @@ package service // import "go.opentelemetry.io/collector/service" import ( "github.com/spf13/cobra" - "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/mapconverter/overwritepropertiesmapconverter" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/converter/overwritepropertiesconverter" "go.opentelemetry.io/collector/service/featuregate" ) @@ -35,7 +35,7 @@ func NewCommand(set CollectorSettings) *cobra.Command { cfgSet := newDefaultConfigProviderSettings(getConfigFlag()) // Append the "overwrite properties converter" as the first converter. cfgSet.MapConverters = append( - []config.MapConverter{overwritepropertiesmapconverter.New(getSetFlag())}, + []confmap.Converter{overwritepropertiesconverter.New(getSetFlag())}, cfgSet.MapConverters...) set.ConfigProvider, err = NewConfigProvider(cfgSet) if err != nil { diff --git a/service/config_provider.go b/service/config_provider.go index e6eef5c125a..aca1fb585e4 100644 --- a/service/config_provider.go +++ b/service/config_provider.go @@ -19,11 +19,11 @@ import ( "fmt" "go.opentelemetry.io/collector/component" - "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/mapconverter/expandmapconverter" - "go.opentelemetry.io/collector/config/mapprovider/envmapprovider" - "go.opentelemetry.io/collector/config/mapprovider/filemapprovider" - "go.opentelemetry.io/collector/config/mapprovider/yamlmapprovider" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/converter/expandconverter" + "go.opentelemetry.io/collector/confmap/provider/envprovider" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" + "go.opentelemetry.io/collector/confmap/provider/yamlprovider" "go.opentelemetry.io/collector/service/internal/configunmarshaler" ) @@ -67,31 +67,31 @@ type configProvider struct { // ConfigProviderSettings are the settings to configure the behavior of the ConfigProvider. type ConfigProviderSettings struct { - // Locations from where the config.Map is retrieved, and merged in the given order. + // Locations from where the confmap.Conf is retrieved, and merged in the given order. // It is required to have at least one location. Locations []string - // MapProviders is a map of pairs . - // It is required to have at least one config.MapProvider. - MapProviders map[string]config.MapProvider + // MapProviders is a map of pairs . + // It is required to have at least one confmap.Provider. + MapProviders map[string]confmap.Provider - // MapConverters is a slice of config.MapConverter. - MapConverters []config.MapConverter + // MapConverters is a slice of cconfmap.Converter. + MapConverters []confmap.Converter } func newDefaultConfigProviderSettings(locations []string) ConfigProviderSettings { return ConfigProviderSettings{ Locations: locations, - MapProviders: makeMapProvidersMap(filemapprovider.New(), envmapprovider.New(), yamlmapprovider.New()), - MapConverters: []config.MapConverter{expandmapconverter.New()}, + MapProviders: makeMapProvidersMap(fileprovider.New(), envprovider.New(), yamlprovider.New()), + MapConverters: []confmap.Converter{expandconverter.New()}, } } // NewConfigProvider returns a new ConfigProvider that provides the service configuration: // * Initially it resolves the "configuration map": -// * Retrieve the config.Map by merging all retrieved maps from the given `locations` in order. -// * Then applies all the config.MapConverter in the given order. -// * Then unmarshalls the config.Map into the service Config. +// * Retrieve the confmap.Conf by merging all retrieved maps from the given `locations` in order. +// * Then applies all the confmap.Converter in the given order. +// * Then unmarshalls the confmap.Conf into the service Config. func NewConfigProvider(set ConfigProviderSettings) (ConfigProvider, error) { mr, err := newMapResolver(set.Locations, set.MapProviders, set.MapConverters) if err != nil { diff --git a/service/internal/configunmarshaler/defaultunmarshaler.go b/service/internal/configunmarshaler/defaultunmarshaler.go index 4a3c5cce553..8d0e0844acf 100644 --- a/service/internal/configunmarshaler/defaultunmarshaler.go +++ b/service/internal/configunmarshaler/defaultunmarshaler.go @@ -23,6 +23,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configtelemetry" + "go.opentelemetry.io/collector/confmap" ) // These are errors that can be returned by Unmarshal(). Note that error codes are not part @@ -83,9 +84,9 @@ func New() ConfigUnmarshaler { return ConfigUnmarshaler{} } -// Unmarshal the config.Config from a config.Map. +// Unmarshal the config.Config from a confmap.Conf. // After the config is unmarshalled, `Validate()` must be called to validate. -func (ConfigUnmarshaler) Unmarshal(v *config.Map, factories component.Factories) (*config.Config, error) { +func (ConfigUnmarshaler) Unmarshal(v *confmap.Conf, factories component.Factories) (*config.Config, error) { var cfg config.Config // Unmarshal top level sections and validate. @@ -154,7 +155,7 @@ func unmarshalExtensions(exts map[config.ComponentID]map[string]interface{}, fac // Now that the default config struct is created we can Unmarshal into it, // and it will apply user-defined config on top of the default. - if err := config.UnmarshalExtension(config.NewMapFromStringMap(value), extensionCfg); err != nil { + if err := config.UnmarshalExtension(confmap.NewFromStringMap(value), extensionCfg); err != nil { return nil, errorUnmarshalError(extensionsKeyName, id, err) } @@ -183,7 +184,7 @@ func unmarshalService(srvRaw map[string]interface{}) (config.Service, error) { }, } - if err := config.NewMapFromStringMap(srvRaw).UnmarshalExact(&srv); err != nil { + if err := confmap.NewFromStringMap(srvRaw).UnmarshalExact(&srv); err != nil { return srv, fmt.Errorf("error reading service configuration: %w", err) } @@ -203,7 +204,7 @@ func defaultServiceTelemetryMetricsSettings() config.ServiceTelemetryMetrics { } // LoadReceiver loads a receiver config from componentConfig using the provided factories. -func LoadReceiver(componentConfig *config.Map, id config.ComponentID, factory component.ReceiverFactory) (config.Receiver, error) { +func LoadReceiver(componentConfig *confmap.Conf, id config.ComponentID, factory component.ReceiverFactory) (config.Receiver, error) { // Create the default config for this receiver. receiverCfg := factory.CreateDefaultConfig() receiverCfg.SetIDName(id.Name()) @@ -229,7 +230,7 @@ func unmarshalReceivers(recvs map[config.ComponentID]map[string]interface{}, fac return nil, errorUnknownType(receiversKeyName, id, reflect.ValueOf(factories).MapKeys()) } - receiverCfg, err := LoadReceiver(config.NewMapFromStringMap(value), id, factory) + receiverCfg, err := LoadReceiver(confmap.NewFromStringMap(value), id, factory) if err != nil { // LoadReceiver already wraps the error. return nil, err @@ -259,7 +260,7 @@ func unmarshalExporters(exps map[config.ComponentID]map[string]interface{}, fact // Now that the default config struct is created we can Unmarshal into it, // and it will apply user-defined config on top of the default. - if err := config.UnmarshalExporter(config.NewMapFromStringMap(value), exporterCfg); err != nil { + if err := config.UnmarshalExporter(confmap.NewFromStringMap(value), exporterCfg); err != nil { return nil, errorUnmarshalError(exportersKeyName, id, err) } @@ -287,7 +288,7 @@ func unmarshalProcessors(procs map[config.ComponentID]map[string]interface{}, fa // Now that the default config struct is created we can Unmarshal into it, // and it will apply user-defined config on top of the default. - if err := config.UnmarshalProcessor(config.NewMapFromStringMap(value), processorCfg); err != nil { + if err := config.UnmarshalProcessor(confmap.NewFromStringMap(value), processorCfg); err != nil { return nil, errorUnmarshalError(processorsKeyName, id, err) } diff --git a/service/internal/configunmarshaler/defaultunmarshaler_test.go b/service/internal/configunmarshaler/defaultunmarshaler_test.go index 1a8f9bcb518..3b5da6101d4 100644 --- a/service/internal/configunmarshaler/defaultunmarshaler_test.go +++ b/service/internal/configunmarshaler/defaultunmarshaler_test.go @@ -28,7 +28,7 @@ import ( "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/configtelemetry" - "go.opentelemetry.io/collector/config/configtest" + "go.opentelemetry.io/collector/confmap/confmaptest" ) func TestDecodeConfig(t *testing.T) { @@ -186,10 +186,10 @@ func TestLoadEmptyAllSections(t *testing.T) { } func loadConfigFile(t *testing.T, fileName string, factories component.Factories) (*config.Config, error) { - cm, err := configtest.LoadConfigMap(fileName) + cm, err := confmaptest.LoadConf(fileName) require.NoError(t, err) - // Unmarshal the config from the config.Map using the given factories. + // Unmarshal the config from the confmap.Conf using the given factories. return New().Unmarshal(cm, factories) } diff --git a/service/mapresolver.go b/service/mapresolver.go index 4a7a24d2b36..473691d33c2 100644 --- a/service/mapresolver.go +++ b/service/mapresolver.go @@ -24,22 +24,22 @@ import ( "go.uber.org/multierr" - "go.opentelemetry.io/collector/config" "go.opentelemetry.io/collector/config/experimental/configsource" + "go.opentelemetry.io/collector/confmap" ) // follows drive-letter specification: // https://tools.ietf.org/id/draft-kerwin-file-scheme-07.html#syntax var driverLetterRegexp = regexp.MustCompile("^[A-z]:") -// mapResolver resolves a configuration as a config.Map. +// mapResolver resolves a configuration as a confmap.Conf. type mapResolver struct { - uris []string - mapProviders map[string]config.MapProvider - mapConverters []config.MapConverter + uris []string + providers map[string]confmap.Provider + converters []confmap.Converter sync.Mutex - closers []config.CloseFunc + closers []confmap.CloseFunc watcher chan error } @@ -47,7 +47,7 @@ type mapResolver struct { // // To resolve a configuration the following steps will happen: // 1. Retrieves individual configurations from all given "URIs", and merge them in the retrieve order. -// 2. Once the config.Map is merged, apply the converters in the given order. +// 2. Once the confmap.Conf is merged, apply the converters in the given order. // // After the configuration was resolved the `mapResolver` can be used as a single point to watch for updates in // the configuration data retrieved via the config providers used to process the "initial" configuration and to generate @@ -62,44 +62,44 @@ type mapResolver struct { // // `uri` must follow the ":" format. This format is compatible with the URI definition // (see https://datatracker.ietf.org/doc/html/rfc3986). An empty "" defaults to "file" schema. -func newMapResolver(uris []string, mapProviders map[string]config.MapProvider, mapConverters []config.MapConverter) (*mapResolver, error) { +func newMapResolver(uris []string, providers map[string]confmap.Provider, converters []confmap.Converter) (*mapResolver, error) { if len(uris) == 0 { return nil, errors.New("invalid map resolver config: no URIs") } - if len(mapProviders) == 0 { + if len(providers) == 0 { return nil, errors.New("invalid map resolver config: no map providers") } // Safe copy, ensures the slices and maps cannot be changed from the caller. urisCopy := make([]string, len(uris)) copy(urisCopy, uris) - mapProvidersCopy := make(map[string]config.MapProvider, len(mapProviders)) - for k, v := range mapProviders { - mapProvidersCopy[k] = v + providersCopy := make(map[string]confmap.Provider, len(providers)) + for k, v := range providers { + providersCopy[k] = v } - mapConvertersCopy := make([]config.MapConverter, len(mapConverters)) - copy(mapConvertersCopy, mapConverters) + convertersCopy := make([]confmap.Converter, len(converters)) + copy(convertersCopy, converters) return &mapResolver{ - uris: urisCopy, - mapProviders: mapProvidersCopy, - mapConverters: mapConvertersCopy, - watcher: make(chan error, 1), + uris: urisCopy, + providers: providersCopy, + converters: convertersCopy, + watcher: make(chan error, 1), }, nil } -// Resolve returns the configuration as a config.Map, or error otherwise. +// Resolve returns the configuration as a confmap.Conf, or error otherwise. // // Should never be called concurrently with itself, Watch or Shutdown. -func (mr *mapResolver) Resolve(ctx context.Context) (*config.Map, error) { +func (mr *mapResolver) Resolve(ctx context.Context) (*confmap.Conf, error) { // First check if already an active watching, close that if any. if err := mr.closeIfNeeded(ctx); err != nil { return nil, fmt.Errorf("cannot close previous watch: %w", err) } // Retrieves individual configurations from all URIs in the given order, and merge them in retMap. - retMap := config.NewMap() + retMap := confmap.New() for _, uri := range mr.uris { // For backwards compatibility: // - empty url scheme means "file". @@ -110,7 +110,7 @@ func (mr *mapResolver) Resolve(ctx context.Context) (*config.Map, error) { } else { uri = scheme + ":" + uri } - p, ok := mr.mapProviders[scheme] + p, ok := mr.providers[scheme] if !ok { return nil, fmt.Errorf("scheme %q is not supported for uri %q", scheme, uri) } @@ -129,9 +129,9 @@ func (mr *mapResolver) Resolve(ctx context.Context) (*config.Map, error) { } // Apply the converters in the given order. - for _, cfgMapConv := range mr.mapConverters { - if err := cfgMapConv.Convert(ctx, retMap); err != nil { - return nil, fmt.Errorf("cannot convert the config.Map: %w", err) + for _, confConv := range mr.converters { + if err := confConv.Convert(ctx, retMap); err != nil { + return nil, fmt.Errorf("cannot convert the confmap.Conf: %w", err) } } @@ -158,14 +158,14 @@ func (mr *mapResolver) Shutdown(ctx context.Context) error { var errs error errs = multierr.Append(errs, mr.closeIfNeeded(ctx)) - for _, p := range mr.mapProviders { + for _, p := range mr.providers { errs = multierr.Append(errs, p.Shutdown(ctx)) } return errs } -func (mr *mapResolver) onChange(event *config.ChangeEvent) { +func (mr *mapResolver) onChange(event *confmap.ChangeEvent) { // TODO: Remove check for configsource.ErrSessionClosed when providers updated to not call onChange when closed. if !errors.Is(event.Error, configsource.ErrSessionClosed) { mr.watcher <- event.Error @@ -180,8 +180,8 @@ func (mr *mapResolver) closeIfNeeded(ctx context.Context) error { return err } -func makeMapProvidersMap(providers ...config.MapProvider) map[string]config.MapProvider { - ret := make(map[string]config.MapProvider, len(providers)) +func makeMapProvidersMap(providers ...confmap.Provider) map[string]confmap.Provider { + ret := make(map[string]confmap.Provider, len(providers)) for _, provider := range providers { ret[provider.Scheme()] = provider } diff --git a/service/mapresolver_test.go b/service/mapresolver_test.go index a750a922405..9b7f7aef8d5 100644 --- a/service/mapresolver_test.go +++ b/service/mapresolver_test.go @@ -24,34 +24,34 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/configtest" "go.opentelemetry.io/collector/config/experimental/configsource" - "go.opentelemetry.io/collector/config/mapprovider/filemapprovider" + "go.opentelemetry.io/collector/confmap" + "go.opentelemetry.io/collector/confmap/confmaptest" + "go.opentelemetry.io/collector/confmap/provider/fileprovider" ) type mockProvider struct { scheme string - retM *config.Map + retM *confmap.Conf errR error errS error errW error errC error } -func (m *mockProvider) Retrieve(_ context.Context, _ string, watcher config.WatcherFunc) (config.Retrieved, error) { +func (m *mockProvider) Retrieve(_ context.Context, _ string, watcher confmap.WatcherFunc) (confmap.Retrieved, error) { if m.errR != nil { - return config.Retrieved{}, m.errR + return confmap.Retrieved{}, m.errR } if m.retM == nil { - return config.NewRetrievedFromMap(config.NewMap()), nil + return confmap.NewRetrievedFromMap(confmap.New()), nil } if watcher != nil { - watcher(&config.ChangeEvent{Error: m.errW}) + watcher(&confmap.ChangeEvent{Error: m.errW}) } - return config.NewRetrievedFromMap( + return confmap.NewRetrievedFromMap( m.retM, - config.WithRetrievedClose(func(ctx context.Context) error { return m.errC })), nil + confmap.WithRetrievedClose(func(ctx context.Context) error { return m.errC })), nil } func (m *mockProvider) Scheme() string { @@ -69,7 +69,7 @@ type mockConverter struct { err error } -func (m *mockConverter) Convert(context.Context, *config.Map) error { +func (m *mockConverter) Convert(context.Context, *confmap.Conf) error { return errors.New("converter_err") } @@ -77,8 +77,8 @@ func TestMapResolver_Errors(t *testing.T) { tests := []struct { name string locations []string - mapProviders []config.MapProvider - mapConverters []config.MapConverter + providers []confmap.Provider + converters []confmap.Converter expectResolveErr bool expectWatchErr bool expectCloseErr bool @@ -87,13 +87,13 @@ func TestMapResolver_Errors(t *testing.T) { { name: "unsupported location scheme", locations: []string{"mock:", "not_supported:"}, - mapProviders: []config.MapProvider{&mockProvider{}}, + providers: []confmap.Provider{&mockProvider{}}, expectResolveErr: true, }, { name: "retrieve location config error", locations: []string{"mock:", "err:"}, - mapProviders: []config.MapProvider{ + providers: []confmap.Provider{ &mockProvider{}, &mockProvider{scheme: "err", errR: errors.New("retrieve_err")}, }, @@ -102,29 +102,29 @@ func TestMapResolver_Errors(t *testing.T) { { name: "converter error", locations: []string{"mock:", filepath.Join("testdata", "otelcol-nop.yaml")}, - mapProviders: []config.MapProvider{&mockProvider{}, filemapprovider.New()}, - mapConverters: []config.MapConverter{&mockConverter{err: errors.New("converter_err")}}, + providers: []confmap.Provider{&mockProvider{}, fileprovider.New()}, + converters: []confmap.Converter{&mockConverter{err: errors.New("converter_err")}}, expectResolveErr: true, }, { name: "watch error", locations: []string{"mock:", "err:"}, - mapProviders: func() []config.MapProvider { - cfgMap, err := configtest.LoadConfigMap(filepath.Join("testdata", "otelcol-nop.yaml")) + providers: func() []confmap.Provider { + conf, err := confmaptest.LoadConf(filepath.Join("testdata", "otelcol-nop.yaml")) require.NoError(t, err) - return []config.MapProvider{&mockProvider{}, &mockProvider{scheme: "err", retM: cfgMap, errW: errors.New("watch_err")}} + return []confmap.Provider{&mockProvider{}, &mockProvider{scheme: "err", retM: conf, errW: errors.New("watch_err")}} }(), expectWatchErr: true, }, { name: "close error", locations: []string{"mock:", "err:"}, - mapProviders: func() []config.MapProvider { - cfgMap, err := configtest.LoadConfigMap(filepath.Join("testdata", "otelcol-nop.yaml")) + providers: func() []confmap.Provider { + conf, err := confmaptest.LoadConf(filepath.Join("testdata", "otelcol-nop.yaml")) require.NoError(t, err) - return []config.MapProvider{ + return []confmap.Provider{ &mockProvider{}, - &mockProvider{scheme: "err", retM: cfgMap, errC: errors.New("close_err")}, + &mockProvider{scheme: "err", retM: conf, errC: errors.New("close_err")}, } }(), expectCloseErr: true, @@ -132,12 +132,12 @@ func TestMapResolver_Errors(t *testing.T) { { name: "shutdown error", locations: []string{"mock:", "err:"}, - mapProviders: func() []config.MapProvider { - cfgMap, err := configtest.LoadConfigMap(filepath.Join("testdata", "otelcol-nop.yaml")) + providers: func() []confmap.Provider { + conf, err := confmaptest.LoadConf(filepath.Join("testdata", "otelcol-nop.yaml")) require.NoError(t, err) - return []config.MapProvider{ + return []confmap.Provider{ &mockProvider{}, - &mockProvider{scheme: "err", retM: cfgMap, errS: errors.New("close_err")}, + &mockProvider{scheme: "err", retM: conf, errS: errors.New("close_err")}, } }(), expectShutdownErr: true, @@ -145,7 +145,7 @@ func TestMapResolver_Errors(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - resolver, err := newMapResolver(tt.locations, makeMapProvidersMap(tt.mapProviders...), tt.mapConverters) + resolver, err := newMapResolver(tt.locations, makeMapProvidersMap(tt.providers...), tt.converters) assert.NoError(t, err) _, errN := resolver.Resolve(context.Background()) @@ -217,7 +217,7 @@ func TestBackwardsCompatibilityForFilePath(t *testing.T) { }, } for _, tt := range tests { - resolver, err := newMapResolver([]string{tt.location}, makeMapProvidersMap(filemapprovider.New()), nil) + resolver, err := newMapResolver([]string{tt.location}, makeMapProvidersMap(fileprovider.New()), nil) assert.NoError(t, err) _, err = resolver.Resolve(context.Background()) assert.Contains(t, err.Error(), tt.errMessage, tt.name) @@ -225,13 +225,13 @@ func TestBackwardsCompatibilityForFilePath(t *testing.T) { } func TestMapResolver(t *testing.T) { - mapProvider := func() config.MapProvider { - cfgMap, err := configtest.LoadConfigMap(filepath.Join("testdata", "otelcol-nop.yaml")) + provider := func() confmap.Provider { + conf, err := confmaptest.LoadConf(filepath.Join("testdata", "otelcol-nop.yaml")) require.NoError(t, err) - return &mockProvider{retM: cfgMap} + return &mockProvider{retM: conf} }() - resolver, err := newMapResolver([]string{"mock:"}, makeMapProvidersMap(mapProvider), nil) + resolver, err := newMapResolver([]string{"mock:"}, makeMapProvidersMap(provider), nil) require.NoError(t, err) _, errN := resolver.Resolve(context.Background()) assert.NoError(t, errN) @@ -252,7 +252,7 @@ func TestMapResolver(t *testing.T) { } func TestMapResolverNoLocations(t *testing.T) { - _, err := newMapResolver([]string{}, makeMapProvidersMap(filemapprovider.New()), nil) + _, err := newMapResolver([]string{}, makeMapProvidersMap(fileprovider.New()), nil) assert.Error(t, err) } @@ -265,7 +265,7 @@ func TestMapResolverNoWatcher(t *testing.T) { watcherWG := sync.WaitGroup{} resolver, err := newMapResolver( []string{filepath.Join("testdata", "otelcol-nop.yaml")}, - makeMapProvidersMap(filemapprovider.New()), nil) + makeMapProvidersMap(fileprovider.New()), nil) require.NoError(t, err) _, errN := resolver.Resolve(context.Background()) assert.NoError(t, errN) @@ -284,14 +284,14 @@ func TestMapResolverNoWatcher(t *testing.T) { } func TestMapResolverShutdownClosesWatch(t *testing.T) { - mapProvider := func() config.MapProvider { + provider := func() confmap.Provider { // Use fakeRetrieved with nil errors to have Watchable interface implemented. - cfgMap, err := configtest.LoadConfigMap(filepath.Join("testdata", "otelcol-nop.yaml")) + conf, err := confmaptest.LoadConf(filepath.Join("testdata", "otelcol-nop.yaml")) require.NoError(t, err) - return &mockProvider{retM: cfgMap, errW: configsource.ErrSessionClosed} + return &mockProvider{retM: conf, errW: configsource.ErrSessionClosed} }() - resolver, err := newMapResolver([]string{"mock:"}, makeMapProvidersMap(mapProvider), nil) + resolver, err := newMapResolver([]string{"mock:"}, makeMapProvidersMap(provider), nil) _, errN := resolver.Resolve(context.Background()) require.NoError(t, err) diff --git a/service/service_test.go b/service/service_test.go index cdb20024d6f..d8f0b285546 100644 --- a/service/service_test.go +++ b/service/service_test.go @@ -25,7 +25,7 @@ import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/component/componenttest" "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/configtest" + "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/service/internal/configunmarshaler" ) @@ -93,9 +93,9 @@ func TestService_GetExporters(t *testing.T) { func createExampleService(t *testing.T, factories component.Factories) *service { // Read yaml config from file - cfgMap, err := configtest.LoadConfigMap(filepath.Join("testdata", "otelcol-nop.yaml")) + conf, err := confmaptest.LoadConf(filepath.Join("testdata", "otelcol-nop.yaml")) require.NoError(t, err) - cfg, err := configunmarshaler.New().Unmarshal(cfgMap, factories) + cfg, err := configunmarshaler.New().Unmarshal(conf, factories) require.NoError(t, err) srv, err := newService(&svcSettings{ diff --git a/service/servicetest/configprovider.go b/service/servicetest/configprovider.go index 1d7196bf59b..6f69ef785fe 100644 --- a/service/servicetest/configprovider.go +++ b/service/servicetest/configprovider.go @@ -17,18 +17,18 @@ package servicetest // import "go.opentelemetry.io/collector/service/servicetest import ( "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config" - "go.opentelemetry.io/collector/config/configtest" + "go.opentelemetry.io/collector/confmap/confmaptest" "go.opentelemetry.io/collector/service/internal/configunmarshaler" ) // LoadConfig loads a config.Config from file, and does NOT validate the configuration. func LoadConfig(fileName string, factories component.Factories) (*config.Config, error) { // Read yaml config from file - cfgMap, err := configtest.LoadConfigMap(fileName) + conf, err := confmaptest.LoadConf(fileName) if err != nil { return nil, err } - return configunmarshaler.New().Unmarshal(cfgMap, factories) + return configunmarshaler.New().Unmarshal(conf, factories) } // LoadConfigAndValidate loads a config from the file, and validates the configuration.