Skip to content

Commit

Permalink
Move config.Map to its own package which does not depend on any compo…
Browse files Browse the repository at this point in the history
…nent concept (#5237)

Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
  • Loading branch information
bogdandrutu authored May 31, 2022
1 parent 8dfdc1c commit 3356863
Show file tree
Hide file tree
Showing 57 changed files with 613 additions and 338 deletions.
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 🧰
Expand Down
11 changes: 7 additions & 4 deletions config/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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)
}
Expand Down
16 changes: 4 additions & 12 deletions config/configtest/configtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,22 @@
package configtest // import "go.opentelemetry.io/collector/config/configtest"

import (
"context"
"fmt"
"reflect"
"regexp"
"strings"

"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
Expand Down
4 changes: 2 additions & 2 deletions config/experimental/configsource/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 5 additions & 2 deletions config/exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
7 changes: 5 additions & 2 deletions config/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
26 changes: 13 additions & 13 deletions config/internal/configsource/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down Expand Up @@ -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{
Expand All @@ -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
}

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand All @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
38 changes: 19 additions & 19 deletions config/internal/configsource/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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)
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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()

Expand All @@ -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)
Expand Down Expand Up @@ -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()
Expand All @@ -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)
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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()}
}
Expand All @@ -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)
Expand Down Expand Up @@ -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 {
Expand All @@ -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
Expand Down
Loading

0 comments on commit 3356863

Please sign in to comment.