Skip to content

Rename configparser.Parser as config.Map #4075

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
## 🛑 Breaking changes 🛑

- Move configcheck.ValidateConfigFromFactories as internal function in service package (#3876).
- Rename `configparser.Parser` as `config.Map` (#4075)

## 💡 Enhancements 💡

- Add Gen dependabot into CI (#4083)

## v0.36.0 Beta
Expand Down
9 changes: 3 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import (
"fmt"

"go.uber.org/zap/zapcore"

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

var (
Expand Down Expand Up @@ -203,10 +201,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 un-marshals a Parser into the unmarshable struct in a custom way.
// componentSection *Parser
// The config for this specific component. May be nil or empty if no config available.
Unmarshal(componentSection *configparser.ConfigMap) error
// 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
}

// DataType is the data type that is supported for collection. We currently support
Expand Down
53 changes: 27 additions & 26 deletions config/configparser/parser.go → config/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package configparser
package config

import (
"fmt"
Expand All @@ -35,58 +35,59 @@ const (
KeyDelimiter = "::"
)

// NewConfigMap creates a new empty ConfigMap instance.
func NewConfigMap() *ConfigMap {
return &ConfigMap{k: koanf.New(KeyDelimiter)}
// NewMap creates a new empty config.Map instance.
func NewMap() *Map {
return &Map{k: koanf.New(KeyDelimiter)}
}

// NewConfigMapFromFile creates a new ConfigMap by reading the given file.
func NewConfigMapFromFile(fileName string) (*ConfigMap, error) {
// NewMapFromFile creates a new config.Map by reading the given file.
func NewMapFromFile(fileName string) (*Map, error) {
// Read yaml config from file.
p := NewConfigMap()
p := NewMap()
if err := p.k.Load(file.Provider(fileName), yaml.Parser()); err != nil {
return nil, fmt.Errorf("unable to read the file %v: %w", fileName, err)
}
return p, nil
}

// NewConfigMapFromBuffer creates a new ConfigMap by reading the given yaml buffer.
func NewConfigMapFromBuffer(buf io.Reader) (*ConfigMap, error) {
// NewMapFromBuffer creates a new config.Map by reading the given yaml buffer.
func NewMapFromBuffer(buf io.Reader) (*Map, error) {
content, err := ioutil.ReadAll(buf)
if err != nil {
return nil, err
}

p := NewConfigMap()
p := NewMap()
if err := p.k.Load(rawbytes.Provider(content), yaml.Parser()); err != nil {
return nil, err
}

return p, nil
}

// NewConfigMapFromStringMap creates a ConfigMap from a map[string]interface{}.
func NewConfigMapFromStringMap(data map[string]interface{}) *ConfigMap {
p := NewConfigMap()
// NewMapFromStringMap creates a config.Map from a map[string]interface{}.
func NewMapFromStringMap(data map[string]interface{}) *Map {
p := NewMap()
// Cannot return error because the koanf instance is empty.
_ = p.k.Load(confmap.Provider(data, KeyDelimiter), nil)
return p
}

// ConfigMap loads configuration.
type ConfigMap struct {
// 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 {
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 *ConfigMap) AllKeys() []string {
func (l *Map) 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 *ConfigMap) Unmarshal(rawVal interface{}) error {
func (l *Map) Unmarshal(rawVal interface{}) error {
decoder, err := mapstructure.NewDecoder(decoderConfig(rawVal))
if err != nil {
return err
Expand All @@ -95,7 +96,7 @@ func (l *ConfigMap) Unmarshal(rawVal interface{}) error {
}

// UnmarshalExact unmarshalls the config into a struct, erroring if a field is nonexistent.
func (l *ConfigMap) UnmarshalExact(intoCfg interface{}) error {
func (l *Map) UnmarshalExact(intoCfg interface{}) error {
dc := decoderConfig(intoCfg)
dc.ErrorUnused = true
decoder, err := mapstructure.NewDecoder(dc)
Expand All @@ -106,12 +107,12 @@ func (l *ConfigMap) UnmarshalExact(intoCfg interface{}) error {
}

// Get can retrieve any value given the key to use.
func (l *ConfigMap) Get(key string) interface{} {
func (l *Map) Get(key string) interface{} {
return l.k.Get(key)
}

// Set sets the value for the key.
func (l *ConfigMap) Set(key string, value interface{}) {
func (l *Map) 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)
Expand All @@ -120,34 +121,34 @@ func (l *ConfigMap) 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 *ConfigMap) IsSet(key string) bool {
func (l *Map) 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 *ConfigMap) Merge(in *ConfigMap) error {
func (l *Map) Merge(in *Map) error {
return l.k.Merge(in.k)
}

// Sub returns new Parser instance representing a sub-config of this instance.
// It returns an error is the sub-config is not a map (use Get()) and an empty Parser if
// none exists.
func (l *ConfigMap) Sub(key string) (*ConfigMap, error) {
func (l *Map) Sub(key string) (*Map, error) {
data := l.Get(key)
if data == nil {
return NewConfigMap(), nil
return NewMap(), nil
}

if reflect.TypeOf(data).Kind() == reflect.Map {
return NewConfigMapFromStringMap(cast.ToStringMap(data)), nil
return NewMapFromStringMap(cast.ToStringMap(data)), 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 *ConfigMap) ToStringMap() map[string]interface{} {
func (l *Map) ToStringMap() map[string]interface{} {
return maps.Unflatten(l.k.All(), KeyDelimiter)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package configparser
package config

import (
"testing"
Expand All @@ -22,7 +22,7 @@ import (
)

func TestToStringMap_WithSet(t *testing.T) {
parser := NewConfigMap()
parser := NewMap()
parser.Set("key::embedded", int64(123))
assert.Equal(t, map[string]interface{}{"key": map[string]interface{}{"embedded": int64(123)}}, parser.ToStringMap())
}
Expand Down Expand Up @@ -98,7 +98,7 @@ func TestToStringMap(t *testing.T) {
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
parser, err := NewConfigMapFromFile(test.fileName)
parser, err := NewMapFromFile(test.fileName)
require.NoError(t, err, "Unable to read configuration file '%s'", test.fileName)
assert.Equal(t, test.stringMap, parser.ToStringMap())
})
Expand Down
3 changes: 1 addition & 2 deletions config/configtest/configtest.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/configparser"
"go.opentelemetry.io/collector/config/configunmarshaler"
"go.opentelemetry.io/collector/consumer/consumererror"
)
Expand All @@ -33,7 +32,7 @@ var configFieldTagRegExp = regexp.MustCompile("^[a-z0-9][a-z0-9_]*$")
// LoadConfig loads a config from file, and does NOT validate the configuration.
func LoadConfig(fileName string, factories component.Factories) (*config.Config, error) {
// Read yaml config from file
cp, err := configparser.NewConfigMapFromFile(fileName)
cp, err := config.NewMapFromFile(fileName)
if err != nil {
return nil, err
}
Expand Down
21 changes: 10 additions & 11 deletions config/configunmarshaler/defaultunmarshaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/configparser"
)

// These are errors that can be returned by Unmarshal(). Note that error codes are not part
Expand Down Expand Up @@ -109,9 +108,9 @@ func NewDefault() ConfigUnmarshaler {
return &defaultUnmarshaler{}
}

// Unmarshal the Config from a Parser.
// Unmarshal the Config from a config.Map.
// After the config is unmarshaled, `Validate()` must be called to validate.
func (*defaultUnmarshaler) Unmarshal(v *configparser.ConfigMap, factories component.Factories) (*config.Config, error) {
func (*defaultUnmarshaler) Unmarshal(v *config.Map, factories component.Factories) (*config.Config, error) {
var cfg config.Config

// Unmarshal the config.
Expand Down Expand Up @@ -209,7 +208,7 @@ func unmarshalExtensions(exts map[string]map[string]interface{}, factories map[c

// Iterate over extensions and create a config for each.
for key, value := range exts {
componentConfig := configparser.NewConfigMapFromStringMap(value)
componentConfig := config.NewMapFromStringMap(value)
expandEnvConfig(componentConfig)

// Decode the key into type and fullName components.
Expand Down Expand Up @@ -280,7 +279,7 @@ func unmarshalService(rawService serviceSettings) (config.Service, error) {
}

// LoadReceiver loads a receiver config from componentConfig using the provided factories.
func LoadReceiver(componentConfig *configparser.ConfigMap, id config.ComponentID, factory component.ReceiverFactory) (config.Receiver, error) {
func LoadReceiver(componentConfig *config.Map, id config.ComponentID, factory component.ReceiverFactory) (config.Receiver, error) {
// Create the default config for this receiver.
receiverCfg := factory.CreateDefaultConfig()
receiverCfg.SetIDName(id.Name())
Expand All @@ -301,7 +300,7 @@ func unmarshalReceivers(recvs map[string]map[string]interface{}, factories map[c

// Iterate over input map and create a config for each.
for key, value := range recvs {
componentConfig := configparser.NewConfigMapFromStringMap(value)
componentConfig := config.NewMapFromStringMap(value)
expandEnvConfig(componentConfig)

// Decode the key into type and fullName components.
Expand Down Expand Up @@ -338,7 +337,7 @@ func unmarshalExporters(exps map[string]map[string]interface{}, factories map[co

// Iterate over Exporters and create a config for each.
for key, value := range exps {
componentConfig := configparser.NewConfigMapFromStringMap(value)
componentConfig := config.NewMapFromStringMap(value)
expandEnvConfig(componentConfig)

// Decode the key into type and fullName components.
Expand Down Expand Up @@ -380,7 +379,7 @@ func unmarshalProcessors(procs map[string]map[string]interface{}, factories map[

// Iterate over processors and create a config for each.
for key, value := range procs {
componentConfig := configparser.NewConfigMapFromStringMap(value)
componentConfig := config.NewMapFromStringMap(value)
expandEnvConfig(componentConfig)

// Decode the key into type and fullName components.
Expand Down Expand Up @@ -475,9 +474,9 @@ func parseIDNames(pipelineID config.ComponentID, componentType string, names []s
return ret, nil
}

// expandEnvConfig updates a configparser.ConfigMap with expanded values for all the values (simple, list or map value).
// expandEnvConfig updates a config.Map with expanded values for all the values (simple, list or map value).
// It does not expand the keys.
func expandEnvConfig(v *configparser.ConfigMap) {
func expandEnvConfig(v *config.Map) {
for _, k := range v.AllKeys() {
v.Set(k, expandStringValues(v.Get(k)))
}
Expand Down Expand Up @@ -568,7 +567,7 @@ func expandEnv(s string) string {
})
}

func unmarshal(componentSection *configparser.ConfigMap, intoCfg interface{}) error {
func unmarshal(componentSection *config.Map, intoCfg interface{}) error {
if cu, ok := intoCfg.(config.Unmarshallable); ok {
return cu.Unmarshal(componentSection)
}
Expand Down
5 changes: 2 additions & 3 deletions config/configunmarshaler/defaultunmarshaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/confignet"
"go.opentelemetry.io/collector/config/configparser"
"go.opentelemetry.io/collector/internal/testcomponents"
)

Expand Down Expand Up @@ -462,10 +461,10 @@ func TestLoadEmptyAllSections(t *testing.T) {
}

func loadConfigFile(t *testing.T, fileName string, factories component.Factories) (*config.Config, error) {
v, err := configparser.NewConfigMapFromFile(fileName)
v, err := config.NewMapFromFile(fileName)
require.NoError(t, err)

// Unmarshal the config from the configparser.ConfigMap using the given factories.
// Unmarshal the config from the config.Map using the given factories.
return NewDefault().Unmarshal(v, factories)
}

Expand Down
2 changes: 1 addition & 1 deletion config/configunmarshaler/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package configunmarshaler implements configuration unmarshalling from a config.Parser.
// Package configunmarshaler implements configuration unmarshalling from a config.Map.
// The implementation relies on registered factories that allow creating
// default configuration for each type of receiver/exporter/processor.
package configunmarshaler
5 changes: 2 additions & 3 deletions config/configunmarshaler/unmarshaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,10 @@ package configunmarshaler
import (
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config"
"go.opentelemetry.io/collector/config/configparser"
)

// ConfigUnmarshaler is the interface that unmarshalls the collector configuration from the configparser.ConfigMap.
// ConfigUnmarshaler is the interface that unmarshalls the collector configuration from the config.Map.
type ConfigUnmarshaler interface {
// Unmarshal the configuration from the given parser and factories.
Unmarshal(v *configparser.ConfigMap, factories component.Factories) (*config.Config, error)
Unmarshal(v *config.Map, factories component.Factories) (*config.Config, error)
}
2 changes: 1 addition & 1 deletion config/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
//
// To satisfy these requirements we declare interfaces Receiver, Exporter, Processor,
// which define the behavior. We also provide helper structs ReceiverSettings, ExporterSettings,
// ProcessorSettings, which define the common settings and un-marshaling from config files.
// ProcessorSettings, which define the common settings and unmarshaling from config files.
//
// Specific Receivers/Exporters/Processors are expected to at the minimum implement the
// corresponding interface and if they have additional settings they must also extend
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/configparser"
"go.opentelemetry.io/collector/config"
)

// 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 *configparser.ConfigMap) (Retrieved, error)
Retrieve(ctx context.Context, selector string, paramsConfigMap *config.Map) (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
Loading