Skip to content

Commit a1a8b7b

Browse files
[pkg/ottl] Add isInt function (#31307)
**Description:** <Describe what has changed.> Adds a new `IsInt` function to facilitate type checking. **Link to tracking Issue:** #27894 **Testing:** Added unit test **Documentation:** Updated the func readme. Co-authored-by: Tyler Helmuth <[email protected]>
1 parent 58f5fb7 commit a1a8b7b

File tree

5 files changed

+179
-0
lines changed

5 files changed

+179
-0
lines changed
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: enhancement
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: Add new IsInt function to facilitate type checking.
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: [27894]
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/ottlfuncs/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ Available Converters:
388388
- [Int](#int)
389389
- [IsBool](#isbool)
390390
- [IsDouble](#isdouble)
391+
- [IsInt](#isint)
391392
- [IsMap](#ismap)
392393
- [IsMatch](#ismatch)
393394
- [IsString](#isstring)
@@ -629,6 +630,22 @@ Examples:
629630

630631
- `IsDouble(attributes["maybe a double"])`
631632

633+
### IsInt
634+
635+
`IsInt(value)`
636+
637+
The `IsInt` Converter returns true if the given value is a int.
638+
639+
The `value` is either a path expression to a telemetry field to retrieve, or a literal.
640+
641+
If `value` is a `int64` or a `pcommon.ValueTypeInt` then returns `true`, otherwise returns `false`.
642+
643+
Examples:
644+
645+
- `IsInt(body)`
646+
647+
- `IsInt(attributes["maybe a int"])`
648+
632649
### IsMap
633650

634651
`IsMap(value)`

pkg/ottl/ottlfuncs/func_is_int.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package ottlfuncs // import "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl/ottlfuncs"
5+
6+
import (
7+
"context"
8+
"fmt"
9+
10+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
11+
)
12+
13+
type IsIntArguments[K any] struct {
14+
Target ottl.IntGetter[K]
15+
}
16+
17+
func NewIsIntFactory[K any]() ottl.Factory[K] {
18+
return ottl.NewFactory("IsInt", &IsIntArguments[K]{}, createIsIntFunction[K])
19+
}
20+
21+
func createIsIntFunction[K any](_ ottl.FunctionContext, oArgs ottl.Arguments) (ottl.ExprFunc[K], error) {
22+
args, ok := oArgs.(*IsIntArguments[K])
23+
24+
if !ok {
25+
return nil, fmt.Errorf("IsIntFactory args must be of type *IsIntArguments[K]")
26+
}
27+
28+
return isInt(args.Target), nil
29+
}
30+
31+
// nolint:errorlint
32+
func isInt[K any](target ottl.IntGetter[K]) ottl.ExprFunc[K] {
33+
return func(ctx context.Context, tCtx K) (any, error) {
34+
_, err := target.Get(ctx, tCtx)
35+
// Use type assertion because we don't want to check wrapped errors
36+
switch err.(type) {
37+
case ottl.TypeError:
38+
return false, nil
39+
case nil:
40+
return true, nil
41+
default:
42+
return false, err
43+
}
44+
}
45+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package ottlfuncs
5+
6+
import (
7+
"context"
8+
"testing"
9+
10+
"github.com/stretchr/testify/assert"
11+
"go.opentelemetry.io/collector/pdata/pcommon"
12+
13+
"github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl"
14+
)
15+
16+
func Test_IsInt(t *testing.T) {
17+
tests := []struct {
18+
name string
19+
value any
20+
expected bool
21+
}{
22+
{
23+
name: "int",
24+
value: int64(0),
25+
expected: true,
26+
},
27+
{
28+
name: "ValueTypeInt",
29+
value: pcommon.NewValueInt(0),
30+
expected: true,
31+
},
32+
{
33+
name: "float64",
34+
value: float64(2.7),
35+
expected: false,
36+
},
37+
{
38+
name: "ValueTypeString",
39+
value: pcommon.NewValueStr("a string"),
40+
expected: false,
41+
},
42+
{
43+
name: "not Int",
44+
value: "string",
45+
expected: false,
46+
},
47+
{
48+
name: "string number",
49+
value: "0",
50+
expected: false,
51+
},
52+
{
53+
name: "ValueTypeSlice",
54+
value: pcommon.NewValueSlice(),
55+
expected: false,
56+
},
57+
{
58+
name: "nil",
59+
value: nil,
60+
expected: false,
61+
},
62+
}
63+
for _, tt := range tests {
64+
t.Run(tt.name, func(t *testing.T) {
65+
exprFunc := isInt[any](&ottl.StandardIntGetter[any]{
66+
Getter: func(context.Context, any) (any, error) {
67+
return tt.value, nil
68+
},
69+
})
70+
result, err := exprFunc(context.Background(), nil)
71+
assert.NoError(t, err)
72+
assert.Equal(t, tt.expected, result)
73+
})
74+
}
75+
}
76+
77+
// nolint:errorlint
78+
func Test_IsInt_Error(t *testing.T) {
79+
exprFunc := isInt[any](&ottl.StandardIntGetter[any]{
80+
Getter: func(context.Context, any) (any, error) {
81+
return nil, ottl.TypeError("")
82+
},
83+
})
84+
result, err := exprFunc(context.Background(), nil)
85+
assert.Equal(t, false, result)
86+
assert.Error(t, err)
87+
_, ok := err.(ottl.TypeError)
88+
assert.False(t, ok)
89+
}

pkg/ottl/ottlfuncs/functions.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ func converters[K any]() []ottl.Factory[K] {
4646
NewIntFactory[K](),
4747
NewIsBoolFactory[K](),
4848
NewIsDoubleFactory[K](),
49+
NewIsIntFactory[K](),
4950
NewIsMapFactory[K](),
5051
NewIsMatchFactory[K](),
5152
NewIsStringFactory[K](),

0 commit comments

Comments
 (0)