Skip to content

Commit 7e48852

Browse files
Fix targeting filter parameter (#25)
* fix targeting filter parameter issue * fix json tag
1 parent 5d86d15 commit 7e48852

4 files changed

Lines changed: 54 additions & 56 deletions

File tree

featuremanagement/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module github.com/microsoft/Featuremanagement-Go/featuremanagement
22

33
go 1.23.0
4+
5+
require github.com/go-viper/mapstructure/v2 v2.4.0

featuremanagement/go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
2+
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=

featuremanagement/targeting.go

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,37 @@ package featuremanagement
66
import (
77
"crypto/sha256"
88
"encoding/binary"
9-
"encoding/json"
109
"fmt"
1110
"math"
11+
12+
"github.com/go-viper/mapstructure/v2"
1213
)
1314

1415
type TargetingFilter struct{}
1516

1617
// TargetingGroup defines a named group with a specific rollout percentage
1718
type TargetingGroup struct {
18-
Name string `json:"name"`
19-
RolloutPercentage float64 `json:"rollout_percentage"`
19+
Name string
20+
RolloutPercentage float64
2021
}
2122

2223
// TargetingExclusion defines users and groups explicitly excluded from targeting
2324
type TargetingExclusion struct {
24-
Users []string `json:"users,omitempty"`
25-
Groups []string `json:"groups,omitempty"`
25+
Users []string
26+
Groups []string
2627
}
2728

2829
// TargetingAudience defines the targeting configuration for feature rollout
2930
type TargetingAudience struct {
30-
DefaultRolloutPercentage float64 `json:"default_rollout_percentage"`
31-
Users []string `json:"users,omitempty"`
32-
Groups []TargetingGroup `json:"groups,omitempty"`
33-
Exclusion *TargetingExclusion `json:"exclusion,omitempty"`
31+
DefaultRolloutPercentage float64
32+
Users []string
33+
Groups []TargetingGroup
34+
Exclusion *TargetingExclusion
3435
}
3536

3637
// TargetingFilterParameters defines the parameters for the targeting filter
3738
type TargetingFilterParameters struct {
38-
Audience TargetingAudience `json:"audience"`
39+
Audience TargetingAudience
3940
}
4041

4142
func (t *TargetingFilter) Name() string {
@@ -102,15 +103,10 @@ func (t *TargetingFilter) Evaluate(evalCtx FeatureFilterEvaluationContext, appCt
102103
}
103104

104105
func getTargetingParams(evalCtx FeatureFilterEvaluationContext) (TargetingFilterParameters, error) {
105-
// First, unmarshal the parameters to our structured type
106-
paramsBytes, err := json.Marshal(evalCtx.Parameters)
107-
if err != nil {
108-
return TargetingFilterParameters{}, fmt.Errorf("failed to marshal targeting parameters: %w", err)
109-
}
110-
111106
var params TargetingFilterParameters
112-
if err := json.Unmarshal(paramsBytes, &params); err != nil {
113-
return TargetingFilterParameters{}, fmt.Errorf("invalid targeting parameters format: %w", err)
107+
err := mapstructure.Decode(evalCtx.Parameters, &params)
108+
if err != nil {
109+
return TargetingFilterParameters{}, fmt.Errorf("failed to decode feature flag parameters: %v", err)
114110
}
115111

116112
// Validate DefaultRolloutPercentage

featuremanagement/targeting_test.go

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,50 +4,48 @@
44
package featuremanagement
55

66
import (
7-
"encoding/json"
87
"testing"
8+
9+
"github.com/go-viper/mapstructure/v2"
910
)
1011

1112
func TestTargetingFilter(t *testing.T) {
12-
// Define the test feature flag with complex targeting rules
13-
jsonData := `{
14-
"id": "ComplexTargeting",
15-
"description": "A feature flag using a targeting filter, that will return true for Alice, Stage1, and 50% of Stage2. Dave and Stage3 are excluded. The default rollout percentage is 25%.",
16-
"enabled": true,
17-
"conditions": {
18-
"client_filters": [
19-
{
20-
"name": "Microsoft.Targeting",
21-
"parameters": {
22-
"audience": {
23-
"users": [
24-
"Alice"
25-
],
26-
"groups": [
27-
{
28-
"name": "Stage1",
29-
"rollout_percentage": 100
30-
},
31-
{
32-
"name": "Stage2",
33-
"rollout_percentage": 50
34-
}
35-
],
36-
"default_rollout_percentage": 25,
37-
"exclusion": {
38-
"users": ["Dave"],
39-
"groups": ["Stage3"]
40-
}
41-
}
42-
}
43-
}
44-
]
45-
}
46-
}`
13+
featureFlagData := map[string]any{
14+
"ID": "ComplexTargeting",
15+
"Description": "A feature flag using a targeting filter, that will return true for Alice, Stage1, and 50% of Stage2. Dave and Stage3 are excluded. The default rollout percentage is 25%.",
16+
"Enabled": true,
17+
"Conditions": map[string]any{
18+
"ClientFilters": []any{
19+
map[string]any{
20+
"Name": "Microsoft.Targeting",
21+
"Parameters": map[string]any{
22+
"Audience": map[string]any{
23+
"Users": []any{"Alice"},
24+
"Groups": []any{
25+
map[string]any{
26+
"Name": "Stage1",
27+
"RolloutPercentage": 100,
28+
},
29+
map[string]any{
30+
"Name": "Stage2",
31+
"RolloutPercentage": 50,
32+
},
33+
},
34+
"DefaultRolloutPercentage": 25,
35+
"Exclusion": map[string]any{
36+
"Users": []any{"Dave"},
37+
"Groups": []any{"Stage3"},
38+
},
39+
},
40+
},
41+
},
42+
},
43+
},
44+
}
4745

48-
// Parse the JSON
4946
var featureFlag FeatureFlag
50-
if err := json.Unmarshal([]byte(jsonData), &featureFlag); err != nil {
47+
err := mapstructure.Decode(featureFlagData, &featureFlag)
48+
if err != nil {
5149
t.Fatalf("Failed to parse feature flag JSON: %v", err)
5250
}
5351

0 commit comments

Comments
 (0)