Skip to content

Commit

Permalink
Add a new bytes provier, allows providing yaml bytes
Browse files Browse the repository at this point in the history
Open Question: Should the schema be "yaml:" or "bytes:"?

Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
  • Loading branch information
bogdandrutu committed Mar 14, 2022
1 parent 317c08e commit ca5cf04
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
58 changes: 58 additions & 0 deletions config/configmapprovider/bytes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// 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 configmapprovider // import "go.opentelemetry.io/collector/config/configmapprovider"

import (
"context"
"fmt"
"strings"

"gopkg.in/yaml.v2"

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

const bytesSchemeName = "bytes"

type bytesMapProvider struct{}

// NewBytes returns a new Provider that allows to provide yaml bytes.
//
// This Provider supports "bytes" scheme, and can be called with a "location" that follows:
// bytes-location = "bytes:" yaml-bytes
//
// Examples:
// `bytes:processors::batch::timeout: 2s`
// `bytes:processors::batch/foo::timeout: 3s`
func NewBytes() Provider {
return &bytesMapProvider{}
}

func (s *bytesMapProvider) Retrieve(_ context.Context, location string, _ WatcherFunc) (Retrieved, error) {
if !strings.HasPrefix(location, bytesSchemeName+":") {
return Retrieved{}, fmt.Errorf("%v location is not supported by %v provider", location, bytesSchemeName)
}

var data map[string]interface{}
if err := yaml.Unmarshal([]byte(location[len(bytesSchemeName)+1:]), &data); err != nil {
return Retrieved{}, fmt.Errorf("unable to parse yaml: %w", err)
}

return Retrieved{Map: config.NewMapFromStringMap(data)}, nil
}

func (s *bytesMapProvider) Shutdown(context.Context) error {
return nil
}
75 changes: 75 additions & 0 deletions config/configmapprovider/bytes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// 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 configmapprovider

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
)

func TestBytesProvider_Empty(t *testing.T) {
sp := NewBytes()
_, err := sp.Retrieve(context.Background(), "", nil)
assert.Error(t, err)
}

func TestBytesProvider_InvalidValue(t *testing.T) {
sp := NewBytes()
_, err := sp.Retrieve(context.Background(), "bytes::2s", nil)
assert.Error(t, err)
}

func TestBytesProvider(t *testing.T) {
sp := NewBytes()

ret, err := sp.Retrieve(context.Background(), "bytes:processors::batch::timeout: 2s", nil)
assert.NoError(t, err)
assert.Equal(t, map[string]interface{}{
"processors": map[string]interface{}{
"batch": map[string]interface{}{
"timeout": "2s",
},
},
}, ret.Map.ToStringMap())

ret, err = sp.Retrieve(context.Background(), "bytes:processors::batch/foo::timeout: 3s", nil)
assert.NoError(t, err)
assert.Equal(t, map[string]interface{}{
"processors": map[string]interface{}{
"batch/foo": map[string]interface{}{
"timeout": "3s",
},
},
}, ret.Map.ToStringMap())

ret, err = sp.Retrieve(context.Background(), "bytes:processors: {batch/foo::timeout: 3s, batch::timeout: 2s}", nil)
assert.NoError(t, err)
assert.Equal(t, map[string]interface{}{
"processors": map[string]interface{}{
"batch/foo": map[string]interface{}{
"timeout": "3s",
},
"batch": map[string]interface{}{
"timeout": "2s",
},
},
}, ret.Map.ToStringMap())

ret, err = sp.Retrieve(context.Background(), "bytes:processors.batch.timeout: 4s", nil)
assert.NoError(t, err)
assert.Equal(t, map[string]interface{}{"processors.batch.timeout": "4s"}, ret.Map.ToStringMap())
}

0 comments on commit ca5cf04

Please sign in to comment.