Skip to content

Commit c68cc6a

Browse files
committed
[pkg/ottl] Fix OTTL functions by using setters
1 parent 0796f50 commit c68cc6a

23 files changed

+380
-163
lines changed

.chloggen/fix-ottl-functions.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: bug_fix
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: pkg/ottl
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Fix OTTL functions by using setters.
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [39100]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user]

pkg/ottl/expression.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,24 @@ func (g StandardFunctionGetter[K]) Get(args Arguments) (Expr[K], error) {
406406
return Expr[K]{exprFunc: fn}, nil
407407
}
408408

409+
type PMapGetSetter[K any] interface {
410+
Get(ctx context.Context, tCtx K) (pcommon.Map, error)
411+
Set(ctx context.Context, tCtx K, val pcommon.Map) error
412+
}
413+
414+
type StandardPMapGetSetter[K any] struct {
415+
Getter func(ctx context.Context, tCtx K) (pcommon.Map, error)
416+
Setter func(ctx context.Context, tCtx K, val any) error
417+
}
418+
419+
func (path StandardPMapGetSetter[K]) Get(ctx context.Context, tCtx K) (pcommon.Map, error) {
420+
return path.Getter(ctx, tCtx)
421+
}
422+
423+
func (path StandardPMapGetSetter[K]) Set(ctx context.Context, tCtx K, val pcommon.Map) error {
424+
return path.Setter(ctx, tCtx, val)
425+
}
426+
409427
// PMapGetter is a Getter that must return a pcommon.Map.
410428
type PMapGetter[K any] interface {
411429
// Get retrieves a pcommon.Map value.

pkg/ottl/functions.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,16 @@ func (p *Parser[K]) buildArg(argVal value, argType reflect.Type) (any, error) {
590590
return nil, err
591591
}
592592
return StandardIntLikeGetter[K]{Getter: arg.Get}, nil
593+
case strings.HasPrefix(name, "PMapGetSetter"):
594+
if argVal.Literal == nil || argVal.Literal.Path == nil {
595+
return nil, errors.New("must be a path")
596+
}
597+
pathGetSetter, err := p.buildGetSetterFromPath(argVal.Literal.Path)
598+
if err != nil {
599+
return nil, err
600+
}
601+
stdMapGetter := StandardPMapGetter[K]{Getter: pathGetSetter.Get}
602+
return StandardPMapGetSetter[K]{Getter: stdMapGetter.Get, Setter: pathGetSetter.Set}, nil
593603
case strings.HasPrefix(name, "PMapGetter"):
594604
arg, err := p.newGetter(argVal)
595605
if err != nil {

pkg/ottl/ottlfuncs/func_delete_key.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
)
1212

1313
type DeleteKeyArguments[K any] struct {
14-
Target ottl.PMapGetter[K]
14+
Target ottl.PMapGetSetter[K]
1515
Key string
1616
}
1717

@@ -29,13 +29,13 @@ func createDeleteKeyFunction[K any](_ ottl.FunctionContext, oArgs ottl.Arguments
2929
return deleteKey(args.Target, args.Key), nil
3030
}
3131

32-
func deleteKey[K any](target ottl.PMapGetter[K], key string) ottl.ExprFunc[K] {
32+
func deleteKey[K any](target ottl.PMapGetSetter[K], key string) ottl.ExprFunc[K] {
3333
return func(ctx context.Context, tCtx K) (any, error) {
3434
val, err := target.Get(ctx, tCtx)
3535
if err != nil {
3636
return nil, err
3737
}
3838
val.Remove(key)
39-
return nil, nil
39+
return nil, target.Set(ctx, tCtx, val)
4040
}
4141
}

pkg/ottl/ottlfuncs/func_delete_key_test.go

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package ottlfuncs
55

66
import (
77
"context"
8+
"errors"
89
"testing"
910

1011
"github.com/stretchr/testify/assert"
@@ -19,15 +20,22 @@ func Test_deleteKey(t *testing.T) {
1920
input.PutInt("test2", 3)
2021
input.PutBool("test3", true)
2122

22-
target := &ottl.StandardPMapGetter[pcommon.Map]{
23-
Getter: func(_ context.Context, tCtx pcommon.Map) (any, error) {
23+
target := &ottl.StandardPMapGetSetter[pcommon.Map]{
24+
Getter: func(_ context.Context, tCtx pcommon.Map) (pcommon.Map, error) {
2425
return tCtx, nil
2526
},
27+
Setter: func(_ context.Context, tCtx pcommon.Map, val any) error {
28+
if v, ok := val.(pcommon.Map); ok {
29+
v.CopyTo(tCtx)
30+
return nil
31+
}
32+
return errors.New("expected pcommon.Map")
33+
},
2634
}
2735

2836
tests := []struct {
2937
name string
30-
target ottl.PMapGetter[pcommon.Map]
38+
target ottl.PMapGetSetter[pcommon.Map]
3139
key string
3240
want func(pcommon.Map)
3341
}{
@@ -80,9 +88,12 @@ func Test_deleteKey(t *testing.T) {
8088

8189
func Test_deleteKey_bad_input(t *testing.T) {
8290
input := pcommon.NewValueStr("not a map")
83-
target := &ottl.StandardPMapGetter[any]{
84-
Getter: func(_ context.Context, tCtx any) (any, error) {
85-
return tCtx, nil
91+
target := &ottl.StandardPMapGetSetter[any]{
92+
Getter: func(_ context.Context, tCtx any) (pcommon.Map, error) {
93+
if v, ok := tCtx.(pcommon.Map); ok {
94+
return v, nil
95+
}
96+
return pcommon.Map{}, errors.New("expected pcommon.Map")
8697
},
8798
}
8899

@@ -94,9 +105,12 @@ func Test_deleteKey_bad_input(t *testing.T) {
94105
}
95106

96107
func Test_deleteKey_get_nil(t *testing.T) {
97-
target := &ottl.StandardPMapGetter[any]{
98-
Getter: func(_ context.Context, tCtx any) (any, error) {
99-
return tCtx, nil
108+
target := &ottl.StandardPMapGetSetter[any]{
109+
Getter: func(_ context.Context, tCtx any) (pcommon.Map, error) {
110+
if v, ok := tCtx.(pcommon.Map); ok {
111+
return v, nil
112+
}
113+
return pcommon.Map{}, errors.New("expected pcommon.Map")
100114
},
101115
}
102116

pkg/ottl/ottlfuncs/func_delete_matching_keys.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
)
1616

1717
type DeleteMatchingKeysArguments[K any] struct {
18-
Target ottl.PMapGetter[K]
18+
Target ottl.PMapGetSetter[K]
1919
Pattern string
2020
}
2121

@@ -33,7 +33,7 @@ func createDeleteMatchingKeysFunction[K any](_ ottl.FunctionContext, oArgs ottl.
3333
return deleteMatchingKeys(args.Target, args.Pattern)
3434
}
3535

36-
func deleteMatchingKeys[K any](target ottl.PMapGetter[K], pattern string) (ottl.ExprFunc[K], error) {
36+
func deleteMatchingKeys[K any](target ottl.PMapGetSetter[K], pattern string) (ottl.ExprFunc[K], error) {
3737
compiledPattern, err := regexp.Compile(pattern)
3838
if err != nil {
3939
return nil, fmt.Errorf("the regex pattern supplied to delete_matching_keys is not a valid pattern: %w", err)
@@ -46,6 +46,6 @@ func deleteMatchingKeys[K any](target ottl.PMapGetter[K], pattern string) (ottl.
4646
val.RemoveIf(func(key string, _ pcommon.Value) bool {
4747
return compiledPattern.MatchString(key)
4848
})
49-
return nil, nil
49+
return nil, target.Set(ctx, tCtx, val)
5050
}, nil
5151
}

pkg/ottl/ottlfuncs/func_delete_matching_keys_test.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package ottlfuncs
55

66
import (
77
"context"
8+
"errors"
89
"testing"
910

1011
"github.com/stretchr/testify/assert"
@@ -20,15 +21,22 @@ func Test_deleteMatchingKeys(t *testing.T) {
2021
input.PutInt("test2", 3)
2122
input.PutBool("test3", true)
2223

23-
target := &ottl.StandardPMapGetter[pcommon.Map]{
24-
Getter: func(_ context.Context, tCtx pcommon.Map) (any, error) {
24+
target := &ottl.StandardPMapGetSetter[pcommon.Map]{
25+
Getter: func(_ context.Context, tCtx pcommon.Map) (pcommon.Map, error) {
2526
return tCtx, nil
2627
},
28+
Setter: func(_ context.Context, tCtx pcommon.Map, m any) error {
29+
if v, ok := m.(pcommon.Map); ok {
30+
v.CopyTo(tCtx)
31+
return nil
32+
}
33+
return errors.New("expected pcommon.Map")
34+
},
2735
}
2836

2937
tests := []struct {
3038
name string
31-
target ottl.PMapGetter[pcommon.Map]
39+
target ottl.PMapGetSetter[pcommon.Map]
3240
pattern string
3341
want func(pcommon.Map)
3442
}{
@@ -80,9 +88,12 @@ func Test_deleteMatchingKeys(t *testing.T) {
8088

8189
func Test_deleteMatchingKeys_bad_input(t *testing.T) {
8290
input := pcommon.NewValueInt(1)
83-
target := &ottl.StandardPMapGetter[any]{
84-
Getter: func(_ context.Context, tCtx any) (any, error) {
85-
return tCtx, nil
91+
target := &ottl.StandardPMapGetSetter[any]{
92+
Getter: func(_ context.Context, tCtx any) (pcommon.Map, error) {
93+
if v, ok := tCtx.(pcommon.Map); ok {
94+
return v, nil
95+
}
96+
return pcommon.Map{}, errors.New("expected pcommon.Map")
8697
},
8798
}
8899

@@ -94,9 +105,12 @@ func Test_deleteMatchingKeys_bad_input(t *testing.T) {
94105
}
95106

96107
func Test_deleteMatchingKeys_get_nil(t *testing.T) {
97-
target := &ottl.StandardPMapGetter[any]{
98-
Getter: func(_ context.Context, tCtx any) (any, error) {
99-
return tCtx, nil
108+
target := &ottl.StandardPMapGetSetter[any]{
109+
Getter: func(_ context.Context, tCtx any) (pcommon.Map, error) {
110+
if v, ok := tCtx.(pcommon.Map); ok {
111+
return v, nil
112+
}
113+
return pcommon.Map{}, errors.New("expected pcommon.Map")
100114
},
101115
}
102116

@@ -107,10 +121,10 @@ func Test_deleteMatchingKeys_get_nil(t *testing.T) {
107121
}
108122

109123
func Test_deleteMatchingKeys_invalid_pattern(t *testing.T) {
110-
target := &ottl.StandardPMapGetter[any]{
111-
Getter: func(_ context.Context, _ any) (any, error) {
124+
target := &ottl.StandardPMapGetSetter[any]{
125+
Getter: func(_ context.Context, _ any) (pcommon.Map, error) {
112126
t.Errorf("nothing should be received in this scenario")
113-
return nil, nil
127+
return pcommon.Map{}, nil
114128
},
115129
}
116130

pkg/ottl/ottlfuncs/func_flatten.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import (
1616
)
1717

1818
type FlattenArguments[K any] struct {
19-
Target ottl.PMapGetter[K]
19+
Target ottl.PMapGetSetter[K]
2020
Prefix ottl.Optional[string]
2121
Depth ottl.Optional[int64]
2222
ResolveConflicts ottl.Optional[bool]
@@ -43,7 +43,7 @@ func createFlattenFunction[K any](_ ottl.FunctionContext, oArgs ottl.Arguments)
4343
return flatten(args.Target, args.Prefix, args.Depth, args.ResolveConflicts)
4444
}
4545

46-
func flatten[K any](target ottl.PMapGetter[K], p ottl.Optional[string], d ottl.Optional[int64], c ottl.Optional[bool]) (ottl.ExprFunc[K], error) {
46+
func flatten[K any](target ottl.PMapGetSetter[K], p ottl.Optional[string], d ottl.Optional[int64], c ottl.Optional[bool]) (ottl.ExprFunc[K], error) {
4747
depth := int64(math.MaxInt64)
4848
if !d.IsEmpty() {
4949
depth = d.Get()
@@ -72,7 +72,7 @@ func flatten[K any](target ottl.PMapGetter[K], p ottl.Optional[string], d ottl.O
7272
flattenData.flattenMap(m, prefix, 0)
7373
flattenData.result.MoveTo(m)
7474

75-
return nil, nil
75+
return nil, target.Set(ctx, tCtx, m)
7676
}, nil
7777
}
7878

pkg/ottl/ottlfuncs/func_flatten_test.go

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package ottlfuncs
55

66
import (
77
"context"
8+
"errors"
89
"reflect"
910
"testing"
1011

@@ -340,10 +341,19 @@ func Test_flatten(t *testing.T) {
340341
m := pcommon.NewMap()
341342
err := m.FromRaw(tt.target)
342343
assert.NoError(t, err)
343-
target := ottl.StandardPMapGetter[any]{
344-
Getter: func(_ context.Context, _ any) (any, error) {
344+
target := ottl.StandardPMapGetSetter[any]{
345+
Getter: func(_ context.Context, _ any) (pcommon.Map, error) {
345346
return m, nil
346347
},
348+
Setter: func(_ context.Context, _ any, m any) error {
349+
if v, ok := m.(pcommon.Map); ok {
350+
if dst, ok2 := m.(pcommon.Map); ok2 {
351+
v.CopyTo(dst)
352+
return nil
353+
}
354+
}
355+
return errors.New("expected pcommon.Map")
356+
},
347357
}
348358

349359
exprFunc, err := flatten[any](target, tt.prefix, tt.depth, ottl.NewTestingOptional[bool](tt.conflict))
@@ -490,10 +500,19 @@ func Test_flatten_undeterministic(t *testing.T) {
490500
m := pcommon.NewMap()
491501
err := m.FromRaw(tt.target)
492502
assert.NoError(t, err)
493-
target := ottl.StandardPMapGetter[any]{
494-
Getter: func(_ context.Context, _ any) (any, error) {
503+
target := ottl.StandardPMapGetSetter[any]{
504+
Getter: func(_ context.Context, _ any) (pcommon.Map, error) {
495505
return m, nil
496506
},
507+
Setter: func(_ context.Context, tCtx any, m any) error {
508+
if v, ok := m.(pcommon.Map); ok {
509+
if dst, ok2 := tCtx.(pcommon.Map); ok2 {
510+
v.CopyTo(dst)
511+
}
512+
return nil
513+
}
514+
return errors.New("expected pcommon.Map")
515+
},
497516
}
498517

499518
exprFunc, err := flatten[any](target, tt.prefix, tt.depth, ottl.NewTestingOptional[bool](tt.conflict))
@@ -509,18 +528,6 @@ func Test_flatten_undeterministic(t *testing.T) {
509528
}
510529
}
511530

512-
func Test_flatten_bad_target(t *testing.T) {
513-
target := &ottl.StandardPMapGetter[any]{
514-
Getter: func(_ context.Context, _ any) (any, error) {
515-
return 1, nil
516-
},
517-
}
518-
exprFunc, err := flatten[any](target, ottl.Optional[string]{}, ottl.Optional[int64]{}, ottl.NewTestingOptional[bool](false))
519-
assert.NoError(t, err)
520-
_, err = exprFunc(nil, nil)
521-
assert.Error(t, err)
522-
}
523-
524531
func Test_flatten_bad_depth(t *testing.T) {
525532
tests := []struct {
526533
name string
@@ -538,8 +545,8 @@ func Test_flatten_bad_depth(t *testing.T) {
538545

539546
for _, tt := range tests {
540547
t.Run(tt.name, func(t *testing.T) {
541-
target := &ottl.StandardPMapGetter[any]{
542-
Getter: func(_ context.Context, _ any) (any, error) {
548+
target := &ottl.StandardPMapGetSetter[any]{
549+
Getter: func(_ context.Context, _ any) (pcommon.Map, error) {
543550
return pcommon.NewMap(), nil
544551
},
545552
}

0 commit comments

Comments
 (0)