Skip to content

Commit b88e8d8

Browse files
authored
Extend predicate OTelBaggage to match with value (#3940)
## Context Currently the predicate OTelBaggage only matches based on key. This needs to be extended to match based on value if the value is not empty. ## Tasks - [x] Update `baggagePredicate` struct to include optional value field - [x] Modify `Create()` to accept 1 or 2 arguments (key only or key+value) - [x] Update `Match()` to check value when provided, key-only when not - [x] Add test cases for value matching scenarios - [x] Run tests to verify working implementation Signed-off-by: greeshma1196 <greeshma.mathew@gmail.com>
1 parent eebc937 commit b88e8d8

3 files changed

Lines changed: 49 additions & 9 deletions

File tree

docs/reference/predicates.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -776,10 +776,16 @@ predicates are able to match based on OTel data.
776776
### OTelBaggage
777777

778778
OpenTelemetry defined Baggage as [W3C spec](https://www.w3.org/TR/baggage/).
779-
OTelBaggage predicate is able to match the Baggage item by key.
779+
OTelBaggage predicate is able to match the Baggage item by key or by key and value.
780780

781-
The example matches the key of a baggage item key `foo` whatever the baggage item value or property is:
781+
The example matches the key of a baggage item key `foo` regardless of value or properties:
782782

783783
```
784784
OTelBaggage("foo")
785785
```
786+
787+
The example matches the key of baggage item key `foo` with its corresponding value `bar`:
788+
789+
```
790+
OTelBaggage("foo", "bar")
791+
```

predicates/otel/otel.go

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import (
1111
type baggageSpec struct{}
1212

1313
type baggagePredicate struct {
14-
key string
14+
key string
15+
value string
1516
}
1617

1718
// NewBaggage provides a predicate spec to create a Predicate instance that matches a baggage by key.
@@ -23,22 +24,38 @@ func (*baggageSpec) Name() string {
2324

2425
// Create a predicate instance that always evaluates to baggage
2526
func (*baggageSpec) Create(args []interface{}) (routing.Predicate, error) {
26-
if len(args) != 1 {
27+
if len(args) == 0 || len(args) > 2 {
2728
return nil, predicates.ErrInvalidPredicateParameters
2829
}
2930

3031
var key string
32+
var value string
33+
3134
if sarg, ok := args[0].(string); ok {
3235
key = sarg
3336
} else {
3437
return nil, predicates.ErrInvalidPredicateParameters
3538
}
39+
40+
if len(args) == 2 {
41+
if sarg, ok := args[1].(string); ok {
42+
value = sarg
43+
} else {
44+
return nil, predicates.ErrInvalidPredicateParameters
45+
}
46+
}
47+
3648
return &baggagePredicate{
37-
key: key,
49+
key: key,
50+
value: value,
3851
}, nil
3952
}
4053

4154
func (p *baggagePredicate) Match(r *http.Request) bool {
4255
bp := baggage.FromContext(r.Context())
43-
return bp.Member(p.key).Key() == p.key
56+
member := bp.Member(p.key)
57+
if p.value != "" {
58+
return member.Key() == p.key && member.Value() == p.value
59+
}
60+
return member.Key() == p.key
4461
}

predicates/otel/otel_test.go

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ func TestOTelBaggage(t *testing.T) {
2626
if err != nil {
2727
t.Fatalf("Failed to create property: %v", err)
2828
}
29+
keyValPropertyExistsEmptyVal, err := baggage.NewKeyValueProperty("exists", "")
30+
if err != nil {
31+
t.Fatalf("Failed to create property: %v", err)
32+
}
2933

3034
member, err := baggage.NewMember("exists", "val")
3135
if err != nil {
@@ -47,6 +51,10 @@ func TestOTelBaggage(t *testing.T) {
4751
if err != nil {
4852
t.Fatalf("Failed to create member: %v", err)
4953
}
54+
memberWithMatchingKeyEmptyVal, err := baggage.NewMember("exists", "", keyPropertyExists, keyValPropertyExistsEmptyVal)
55+
if err != nil {
56+
t.Fatalf("Failed to create member: %v", err)
57+
}
5058

5159
for _, tt := range []struct {
5260
name string
@@ -82,7 +90,7 @@ func TestOTelBaggage(t *testing.T) {
8290
},
8391
{
8492
name: "test no match member with key-val property",
85-
args: []interface{}{"no-match"},
93+
args: []interface{}{"no-match", "no-val"},
8694
member: []baggage.Member{
8795
memberWithKeyValProperty,
8896
},
@@ -122,12 +130,21 @@ func TestOTelBaggage(t *testing.T) {
122130
},
123131
{
124132
name: "test match member with key-val property",
125-
args: []interface{}{"exists"},
133+
args: []interface{}{"exists", "val"},
126134
member: []baggage.Member{
127135
memberWithKeyValProperty,
128136
},
129137
want: true,
130-
}} {
138+
},
139+
{
140+
name: "test match member with matching key and no val",
141+
args: []interface{}{"exists"},
142+
member: []baggage.Member{
143+
memberWithMatchingKeyEmptyVal,
144+
},
145+
want: true,
146+
},
147+
} {
131148
t.Run(tt.name, func(t *testing.T) {
132149
spec := NewBaggage()
133150
pred, err := spec.Create(tt.args)

0 commit comments

Comments
 (0)