Skip to content

Commit 565d4b9

Browse files
authored
High level encode/decode APIs (#3244)
* High level encode/decode APIs This provides the high level wrappers around encoding pdata to bytes and decoding bytes to pdata. Just adds pdata.Traces for now. Would like to find a way to do code generation since they're virtually identical for each telemetry type. * review updates
1 parent 41734c5 commit 565d4b9

File tree

5 files changed

+322
-0
lines changed

5 files changed

+322
-0
lines changed

internal/model/decoder.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package model
16+
17+
import (
18+
"fmt"
19+
20+
"go.opentelemetry.io/collector/consumer/pdata"
21+
"go.opentelemetry.io/collector/internal/model/serializer"
22+
"go.opentelemetry.io/collector/internal/model/translator"
23+
)
24+
25+
// TracesDecoder decodes bytes into pdata.Traces.
26+
type TracesDecoder struct {
27+
translate translator.TracesDecoder
28+
serialize serializer.TracesUnmarshaler
29+
}
30+
31+
// Decode bytes into pdata.Traces. On error pdata.Traces is invalid.
32+
func (t *TracesDecoder) Decode(buf []byte) (pdata.Traces, error) {
33+
model, err := t.serialize.UnmarshalTraces(buf)
34+
if err != nil {
35+
return pdata.Traces{}, fmt.Errorf("unmarshal failed: %w", err)
36+
}
37+
td, err := t.translate.DecodeTraces(model)
38+
if err != nil {
39+
return pdata.Traces{}, fmt.Errorf("converting model to pdata failed: %w", err)
40+
}
41+
return td, nil
42+
}

internal/model/decoder_test.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package model
16+
17+
import (
18+
"errors"
19+
"testing"
20+
21+
"github.com/stretchr/testify/assert"
22+
23+
"go.opentelemetry.io/collector/consumer/pdata"
24+
)
25+
26+
func TestTracesDecoder_SerializeError(t *testing.T) {
27+
translate := &mockTranslator{}
28+
serialize := &mockSerializer{}
29+
30+
d := &TracesDecoder{
31+
translate: translate,
32+
serialize: serialize,
33+
}
34+
35+
expectedBytes := []byte{1, 2, 3}
36+
expectedModel := struct{}{}
37+
38+
serialize.On("UnmarshalTraces", expectedBytes).Return(expectedModel, errors.New("decode failed"))
39+
40+
_, err := d.Decode(expectedBytes)
41+
42+
assert.Error(t, err)
43+
assert.EqualError(t, err, "unmarshal failed: decode failed")
44+
}
45+
46+
func TestTracesDecoder_TranslationError(t *testing.T) {
47+
translate := &mockTranslator{}
48+
serialize := &mockSerializer{}
49+
50+
d := &TracesDecoder{
51+
translate: translate,
52+
serialize: serialize,
53+
}
54+
55+
expectedBytes := []byte{1, 2, 3}
56+
expectedModel := struct{}{}
57+
58+
serialize.On("UnmarshalTraces", expectedBytes).Return(expectedModel, nil)
59+
translate.On("DecodeTraces", expectedModel).Return(pdata.NewTraces(), errors.New("translation failed"))
60+
61+
_, err := d.Decode(expectedBytes)
62+
63+
assert.Error(t, err)
64+
assert.EqualError(t, err, "converting model to pdata failed: translation failed")
65+
}
66+
67+
func TestTracesDecoder_Decode(t *testing.T) {
68+
translate := &mockTranslator{}
69+
serialize := &mockSerializer{}
70+
71+
d := &TracesDecoder{
72+
translate: translate,
73+
serialize: serialize,
74+
}
75+
76+
expectedTraces := pdata.NewTraces()
77+
expectedBytes := []byte{1, 2, 3}
78+
expectedModel := struct{}{}
79+
80+
serialize.On("UnmarshalTraces", expectedBytes).Return(expectedModel, nil)
81+
translate.On("DecodeTraces", expectedModel).Return(expectedTraces, nil)
82+
83+
actualTraces, err := d.Decode(expectedBytes)
84+
85+
assert.NoError(t, err)
86+
assert.Equal(t, expectedTraces, actualTraces)
87+
}

internal/model/encoder.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package model
16+
17+
import (
18+
"fmt"
19+
20+
"go.opentelemetry.io/collector/consumer/pdata"
21+
"go.opentelemetry.io/collector/internal/model/serializer"
22+
"go.opentelemetry.io/collector/internal/model/translator"
23+
)
24+
25+
// TracesEncoder encodes pdata.Traces into bytes.
26+
type TracesEncoder struct {
27+
translate translator.TracesEncoder
28+
serialize serializer.TracesMarshaler
29+
}
30+
31+
// Encode pdata.Traces into bytes. On error []byte is nil.
32+
func (t *TracesEncoder) Encode(td pdata.Traces) ([]byte, error) {
33+
model, err := t.translate.EncodeTraces(td)
34+
if err != nil {
35+
return nil, fmt.Errorf("converting pdata to model failed: %w", err)
36+
}
37+
buf, err := t.serialize.MarshalTraces(model)
38+
if err != nil {
39+
return nil, fmt.Errorf("marshal failed: %w", err)
40+
}
41+
return buf, nil
42+
}

internal/model/encoder_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package model
16+
17+
import (
18+
"errors"
19+
"testing"
20+
21+
"github.com/stretchr/testify/assert"
22+
23+
"go.opentelemetry.io/collector/consumer/pdata"
24+
)
25+
26+
func TestTracesEncoder_TranslationError(t *testing.T) {
27+
translate := &mockTranslator{}
28+
serialize := &mockSerializer{}
29+
30+
d := &TracesEncoder{
31+
translate: translate,
32+
serialize: serialize,
33+
}
34+
35+
td := pdata.NewTraces()
36+
37+
translate.On("EncodeTraces", td).Return(nil, errors.New("translation failed"))
38+
39+
_, err := d.Encode(td)
40+
41+
assert.Error(t, err)
42+
assert.EqualError(t, err, "converting pdata to model failed: translation failed")
43+
}
44+
45+
func TestTracesEncoder_SerializeError(t *testing.T) {
46+
translate := &mockTranslator{}
47+
serialize := &mockSerializer{}
48+
49+
d := &TracesEncoder{
50+
translate: translate,
51+
serialize: serialize,
52+
}
53+
54+
td := pdata.NewTraces()
55+
expectedModel := struct{}{}
56+
57+
translate.On("EncodeTraces", td).Return(expectedModel, nil)
58+
serialize.On("MarshalTraces", expectedModel).Return(nil, errors.New("serialization failed"))
59+
60+
_, err := d.Encode(td)
61+
62+
assert.Error(t, err)
63+
assert.EqualError(t, err, "marshal failed: serialization failed")
64+
}
65+
66+
func TestTracesEncoder_Encode(t *testing.T) {
67+
translate := &mockTranslator{}
68+
serialize := &mockSerializer{}
69+
70+
d := &TracesEncoder{
71+
translate: translate,
72+
serialize: serialize,
73+
}
74+
75+
expectedTraces := pdata.NewTraces()
76+
expectedBytes := []byte{1, 2, 3}
77+
expectedModel := struct{}{}
78+
79+
translate.On("EncodeTraces", expectedTraces).Return(expectedModel, nil)
80+
serialize.On("MarshalTraces", expectedModel).Return(expectedBytes, nil)
81+
82+
actualBytes, err := d.Encode(expectedTraces)
83+
84+
assert.NoError(t, err)
85+
assert.Equal(t, expectedBytes, actualBytes)
86+
}

internal/model/mocks_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright The OpenTelemetry Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package model
16+
17+
import (
18+
"github.com/stretchr/testify/mock"
19+
20+
"go.opentelemetry.io/collector/consumer/pdata"
21+
"go.opentelemetry.io/collector/internal/model/serializer"
22+
"go.opentelemetry.io/collector/internal/model/translator"
23+
)
24+
25+
var (
26+
_ serializer.TracesMarshaler = (*mockSerializer)(nil)
27+
_ serializer.TracesUnmarshaler = (*mockSerializer)(nil)
28+
)
29+
30+
type mockSerializer struct {
31+
mock.Mock
32+
}
33+
34+
func (m *mockSerializer) MarshalTraces(model interface{}) ([]byte, error) {
35+
args := m.Called(model)
36+
err := args.Error(1)
37+
if err != nil {
38+
return nil, err
39+
}
40+
return args.Get(0).([]byte), err
41+
}
42+
43+
func (m *mockSerializer) UnmarshalTraces(bytes []byte) (interface{}, error) {
44+
args := m.Called(bytes)
45+
return args.Get(0), args.Error(1)
46+
}
47+
48+
var (
49+
_ translator.TracesEncoder = (*mockTranslator)(nil)
50+
_ translator.TracesDecoder = (*mockTranslator)(nil)
51+
)
52+
53+
type mockTranslator struct {
54+
mock.Mock
55+
}
56+
57+
func (m *mockTranslator) DecodeTraces(src interface{}) (pdata.Traces, error) {
58+
args := m.Called(src)
59+
return args.Get(0).(pdata.Traces), args.Error(1)
60+
}
61+
62+
func (m *mockTranslator) EncodeTraces(md pdata.Traces) (interface{}, error) {
63+
args := m.Called(md)
64+
return args.Get(0), args.Error(1)
65+
}

0 commit comments

Comments
 (0)