diff --git a/.chloggen/fromrawerror.yaml b/.chloggen/fromrawerror.yaml new file mode 100755 index 00000000000..4d9c76f5d7f --- /dev/null +++ b/.chloggen/fromrawerror.yaml @@ -0,0 +1,11 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: pdata + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Return error from `pcommon.[Value|Map|Slice].FromRaw` when unsupported type. + +# One or more tracking issues or pull requests related to the change +issues: [6579] diff --git a/consumer/go.mod b/consumer/go.mod index 87723808eab..6221184caaa 100644 --- a/consumer/go.mod +++ b/consumer/go.mod @@ -16,6 +16,8 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + go.uber.org/atomic v1.10.0 // indirect + go.uber.org/multierr v1.8.0 // indirect golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect golang.org/x/sys v0.2.0 // indirect golang.org/x/text v0.3.7 // indirect diff --git a/consumer/go.sum b/consumer/go.sum index 401de03dd16..d597a15eed7 100644 --- a/consumer/go.sum +++ b/consumer/go.sum @@ -66,6 +66,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= @@ -73,6 +74,11 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -168,6 +174,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pdata/go.mod b/pdata/go.mod index 36075593456..f14b61c76a5 100644 --- a/pdata/go.mod +++ b/pdata/go.mod @@ -6,6 +6,7 @@ require ( github.com/gogo/protobuf v1.3.2 github.com/json-iterator/go v1.1.12 github.com/stretchr/testify v1.8.1 + go.uber.org/multierr v1.8.0 google.golang.org/grpc v1.50.1 google.golang.org/protobuf v1.28.1 ) @@ -16,6 +17,7 @@ require ( github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + go.uber.org/atomic v1.7.0 // indirect golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect golang.org/x/sys v0.2.0 // indirect golang.org/x/text v0.3.3 // indirect diff --git a/pdata/go.sum b/pdata/go.sum index 73b2fa5070a..c5f85cd090d 100644 --- a/pdata/go.sum +++ b/pdata/go.sum @@ -44,12 +44,17 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -125,6 +130,7 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pdata/pcommon/common.go b/pdata/pcommon/common.go index 3661e7401db..1d8a54d0714 100644 --- a/pdata/pcommon/common.go +++ b/pdata/pcommon/common.go @@ -26,6 +26,8 @@ import ( "sort" "strconv" + "go.uber.org/multierr" + "go.opentelemetry.io/collector/pdata/internal" otlpcommon "go.opentelemetry.io/collector/pdata/internal/data/protogen/common/v1" ) @@ -133,7 +135,7 @@ func (v Value) getOrig() *otlpcommon.AnyValue { return internal.GetOrigValue(internal.Value(v)) } -func (v Value) FromRaw(iv interface{}) { +func (v Value) FromRaw(iv any) error { switch tv := iv.(type) { case nil: v.getOrig().Value = nil @@ -167,13 +169,14 @@ func (v Value) FromRaw(iv interface{}) { v.SetBool(tv) case []byte: v.SetEmptyBytes().FromRaw(tv) - case map[string]interface{}: - v.SetEmptyMap().FromRaw(tv) - case []interface{}: - v.SetEmptySlice().FromRaw(tv) + case map[string]any: + return v.SetEmptyMap().FromRaw(tv) + case []any: + return v.SetEmptySlice().FromRaw(tv) default: - v.SetStr(fmt.Sprintf("", tv)) + return fmt.Errorf("", tv) } + return nil } // Type returns the type of the value for this Value. @@ -492,7 +495,7 @@ func float64AsString(f float64) string { return string(b) } -func (v Value) AsRaw() interface{} { +func (v Value) AsRaw() any { switch v.Type() { case ValueTypeEmpty: return nil @@ -779,8 +782,8 @@ func (m Map) CopyTo(dest Map) { } // AsRaw converts an OTLP Map to a standard go map -func (m Map) AsRaw() map[string]interface{} { - rawMap := make(map[string]interface{}) +func (m Map) AsRaw() map[string]any { + rawMap := make(map[string]any) m.Range(func(k string, v Value) bool { rawMap[k] = v.AsRaw() return true @@ -788,40 +791,44 @@ func (m Map) AsRaw() map[string]interface{} { return rawMap } -func (m Map) FromRaw(rawMap map[string]interface{}) { +func (m Map) FromRaw(rawMap map[string]any) error { if len(rawMap) == 0 { *m.getOrig() = nil - return + return nil } + var errs error origs := make([]otlpcommon.KeyValue, len(rawMap)) ix := 0 for k, iv := range rawMap { origs[ix].Key = k - newValue(&origs[ix].Value).FromRaw(iv) + errs = multierr.Append(errs, newValue(&origs[ix].Value).FromRaw(iv)) ix++ } *m.getOrig() = origs + return errs } -// AsRaw return []interface{} copy of the Slice. -func (es Slice) AsRaw() []interface{} { - rawSlice := make([]interface{}, 0, es.Len()) +// AsRaw return []any copy of the Slice. +func (es Slice) AsRaw() []any { + rawSlice := make([]any, 0, es.Len()) for i := 0; i < es.Len(); i++ { rawSlice = append(rawSlice, es.At(i).AsRaw()) } return rawSlice } -// FromRaw copies []interface{} into the Slice. -func (es Slice) FromRaw(rawSlice []interface{}) { +// FromRaw copies []any into the Slice. +func (es Slice) FromRaw(rawSlice []any) error { if len(rawSlice) == 0 { *es.getOrig() = nil - return + return nil } + var errs error origs := make([]otlpcommon.AnyValue, len(rawSlice)) for ix, iv := range rawSlice { - newValue(&origs[ix]).FromRaw(iv) + errs = multierr.Append(errs, newValue(&origs[ix]).FromRaw(iv)) } *es.getOrig() = origs + return errs } diff --git a/pdata/pcommon/common_test.go b/pdata/pcommon/common_test.go index e31a1679c23..1557d33545b 100644 --- a/pdata/pcommon/common_test.go +++ b/pdata/pcommon/common_test.go @@ -166,11 +166,11 @@ func TestNilOrigSetValue(t *testing.T) { assert.Equal(t, []byte{1, 2, 3}, av.Bytes().AsRaw()) av = NewValueEmpty() - av.SetEmptyMap().FromRaw(map[string]interface{}{"k": "v"}) + assert.NoError(t, av.SetEmptyMap().FromRaw(map[string]interface{}{"k": "v"})) assert.Equal(t, map[string]interface{}{"k": "v"}, av.Map().AsRaw()) av = NewValueEmpty() - av.SetEmptySlice().FromRaw([]interface{}{int64(1), "val"}) + assert.NoError(t, av.SetEmptySlice().FromRaw([]interface{}{int64(1), "val"})) assert.Equal(t, []interface{}{int64(1), "val"}, av.Slice().AsRaw()) } @@ -275,27 +275,27 @@ func TestMap(t *testing.T) { putInt := NewMap() putInt.PutInt("k", 123) - assert.EqualValues(t, generateTestIntMap(), putInt) + assert.EqualValues(t, generateTestIntMap(t), putInt) putDouble := NewMap() putDouble.PutDouble("k", 12.3) - assert.EqualValues(t, generateTestDoubleMap(), putDouble) + assert.EqualValues(t, generateTestDoubleMap(t), putDouble) putBool := NewMap() putBool.PutBool("k", true) - assert.EqualValues(t, generateTestBoolMap(), putBool) + assert.EqualValues(t, generateTestBoolMap(t), putBool) putBytes := NewMap() putBytes.PutEmptyBytes("k").FromRaw([]byte{1, 2, 3, 4, 5}) - assert.EqualValues(t, generateTestBytesMap(), putBytes) + assert.EqualValues(t, generateTestBytesMap(t), putBytes) putMap := NewMap() putMap.PutEmptyMap("k") - assert.EqualValues(t, generateTestEmptyMap(), putMap) + assert.EqualValues(t, generateTestEmptyMap(t), putMap) putSlice := NewMap() putSlice.PutEmptySlice("k") - assert.EqualValues(t, generateTestEmptySlice(), putSlice) + assert.EqualValues(t, generateTestEmptySlice(t), putSlice) removeMap := NewMap() assert.False(t, removeMap.Remove("k")) @@ -521,7 +521,7 @@ func TestMap_Range(t *testing.T) { "k_empty": nil, } am := NewMap() - am.FromRaw(rawMap) + assert.NoError(t, am.FromRaw(rawMap)) assert.Equal(t, 5, am.Len()) calls := 0 @@ -541,17 +541,17 @@ func TestMap_Range(t *testing.T) { func TestMap_FromRaw(t *testing.T) { am := NewMap() - am.FromRaw(map[string]interface{}{}) + assert.NoError(t, am.FromRaw(map[string]interface{}{})) assert.Equal(t, 0, am.Len()) am.PutEmpty("k") assert.Equal(t, 1, am.Len()) - am.FromRaw(nil) + assert.NoError(t, am.FromRaw(nil)) assert.Equal(t, 0, am.Len()) am.PutEmpty("k") assert.Equal(t, 1, am.Len()) - am.FromRaw(map[string]interface{}{ + assert.NoError(t, am.FromRaw(map[string]interface{}{ "k_string": "123", "k_int": 123, "k_double": 1.23, @@ -563,7 +563,7 @@ func TestMap_FromRaw(t *testing.T) { "k_int": 1, "k_string": "val", }, - }) + })) assert.Equal(t, 8, am.Len()) v, ok := am.Get("k_string") assert.True(t, ok) @@ -692,51 +692,39 @@ func TestMap_RemoveIf(t *testing.T) { assert.True(t, exists) } -func generateTestEmptyMap() Map { +func generateTestEmptyMap(t *testing.T) Map { m := NewMap() - m.FromRaw(map[string]interface{}{ - "k": map[string]interface{}(nil), - }) + assert.NoError(t, m.FromRaw(map[string]interface{}{"k": map[string]interface{}(nil)})) return m } -func generateTestEmptySlice() Map { +func generateTestEmptySlice(t *testing.T) Map { m := NewMap() - m.FromRaw(map[string]interface{}{ - "k": []interface{}(nil), - }) + assert.NoError(t, m.FromRaw(map[string]interface{}{"k": []interface{}(nil)})) return m } -func generateTestIntMap() Map { +func generateTestIntMap(t *testing.T) Map { m := NewMap() - m.FromRaw(map[string]interface{}{ - "k": 123, - }) + assert.NoError(t, m.FromRaw(map[string]interface{}{"k": 123})) return m } -func generateTestDoubleMap() Map { +func generateTestDoubleMap(t *testing.T) Map { m := NewMap() - m.FromRaw(map[string]interface{}{ - "k": 12.3, - }) + assert.NoError(t, m.FromRaw(map[string]interface{}{"k": 12.3})) return m } -func generateTestBoolMap() Map { +func generateTestBoolMap(t *testing.T) Map { m := NewMap() - m.FromRaw(map[string]interface{}{ - "k": true, - }) + assert.NoError(t, m.FromRaw(map[string]interface{}{"k": true})) return m } -func generateTestBytesMap() Map { +func generateTestBytesMap(t *testing.T) Map { m := NewMap() - m.FromRaw(map[string]interface{}{ - "k": []byte{1, 2, 3, 4, 5}, - }) + assert.NoError(t, m.FromRaw(map[string]interface{}{"k": []byte{1, 2, 3, 4, 5}})) return m } @@ -943,7 +931,7 @@ func TestMapAsRaw(t *testing.T) { "string": "string value", } m := NewMap() - m.FromRaw(raw) + assert.NoError(t, m.FromRaw(raw)) assert.Equal(t, raw, m.AsRaw()) } @@ -1044,7 +1032,7 @@ func TestNewValueFromRaw(t *testing.T) { }, expected: func() Value { m := NewValueMap() - m.Map().FromRaw(map[string]interface{}{"k": "v"}) + assert.NoError(t, m.Map().FromRaw(map[string]interface{}{"k": "v"})) return m }(), }, @@ -1053,7 +1041,7 @@ func TestNewValueFromRaw(t *testing.T) { input: map[string]interface{}{}, expected: func() Value { m := NewValueMap() - m.Map().FromRaw(map[string]interface{}{}) + assert.NoError(t, m.Map().FromRaw(map[string]interface{}{})) return m }(), }, @@ -1062,7 +1050,7 @@ func TestNewValueFromRaw(t *testing.T) { input: []interface{}{"v1", "v2"}, expected: (func() Value { s := NewValueSlice() - s.Slice().FromRaw([]interface{}{"v1", "v2"}) + assert.NoError(t, s.Slice().FromRaw([]interface{}{"v1", "v2"})) return s })(), }, @@ -1071,27 +1059,25 @@ func TestNewValueFromRaw(t *testing.T) { input: []interface{}{}, expected: (func() Value { s := NewValueSlice() - s.Slice().FromRaw([]interface{}{}) + assert.NoError(t, s.Slice().FromRaw([]interface{}{})) return s })(), }, - { - name: "invalid value", - input: ValueTypeDouble, - expected: (func() Value { - return NewValueStr("") - })(), - }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { actual := NewValueEmpty() - actual.FromRaw(tt.input) + assert.NoError(t, actual.FromRaw(tt.input)) assert.Equal(t, tt.expected, actual) }) } } +func TestNewValueFromRawInvalid(t *testing.T) { + actual := NewValueEmpty() + assert.EqualError(t, actual.FromRaw(ValueTypeDouble), "") +} + func generateTestValueMap() Value { ret := NewValueMap() attrMap := ret.Map()