Skip to content

Commit

Permalink
add basic event tracking for confidence
Browse files Browse the repository at this point in the history
  • Loading branch information
vahidlazio committed May 17, 2024
1 parent 4579c32 commit 5ec5f0b
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 14 deletions.
30 changes: 29 additions & 1 deletion confidence/confidence.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package confidence
import (
"context"
"fmt"
"time"
"net/http"
"reflect"
"strings"
Expand All @@ -24,6 +25,7 @@ var (

type Confidence struct {
parent ContextProvider
uploader EventUploader
contextMap map[string]interface{}
Config APIConfig
ResolveClient ResolveClient
Expand Down Expand Up @@ -69,10 +71,36 @@ func NewConfidenceBuilder() ConfidenceBuilder {
}
}

func (e Confidence) putContext(key string, value interface{}) {
func (e Confidence) PutContext(key string, value interface{}) {
e.contextMap[key] = value
}

func (e Confidence) Track(ctx context.Context, eventName string, message map[string]interface{}) {
go func() {
currentTime := time.Now()
iso8601Time := currentTime.Format(time.RFC3339)

newMap := e.GetContext()

for key, value := range message {
newMap[key] = value
}

event := Event {
EventDefinition: fmt.Sprintf("eventDefinitions/%s", eventName),
EventTime: iso8601Time,
Payload: newMap,
}
batch := EventBatchRequest{
CclientSecret: e.Config.APIKey,
Sdk: sdk{SDK_ID, SDK_VERSION},
SendTime: iso8601Time,
Events: []Event{event},
}
e.uploader.upload(ctx, batch)
}()
}

func (e Confidence) WithContext(context map[string]interface{}) Confidence {
return Confidence{
parent: &e,
Expand Down
24 changes: 12 additions & 12 deletions confidence/confidence_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (r MockResolveClient) SendResolveRequest(_ context.Context,

func TestResolveBoolValue(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")
evalDetails := client.GetBoolFlag(context.Background(), "test-flag.boolean-key", false)

assert.Equal(t, true, evalDetails.Value)
Expand All @@ -34,7 +34,7 @@ func TestResolveBoolValue(t *testing.T) {

func TestResolveIntValue(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetIntFlag(context.Background(), "test-flag.integer-key", 99)

Expand All @@ -43,7 +43,7 @@ func TestResolveIntValue(t *testing.T) {

func TestResolveDoubleValue(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetDoubleFlag(context.Background(), "test-flag.double-key", 99.99)

Expand All @@ -52,7 +52,7 @@ func TestResolveDoubleValue(t *testing.T) {

func TestResolveStringValue(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetStringFlag(context.Background(), "test-flag.string-key", "default")

Expand All @@ -61,7 +61,7 @@ func TestResolveStringValue(t *testing.T) {

func TestResolveObjectValue(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetObjectFlag(context.Background(), "test-flag.struct-key", "default")
_, ok := evalDetails.Value.(map[string]interface{})
Expand All @@ -70,23 +70,23 @@ func TestResolveObjectValue(t *testing.T) {

func TestResolveNestedValue(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetBoolFlag(context.Background(), "test-flag.struct-key.boolean-key", true)
assert.Equal(t, false, evalDetails.Value)
}

func TestResolveDoubleNestedValue(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetBoolFlag(context.Background(), "test-flag.struct-key.nested-struct-key.nested-boolean-key", true)
assert.Equal(t, false, evalDetails.Value)
}

func TestResolveWholeFlagAsObject(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetObjectFlag(context.Background(), "test-flag", "default")
_, ok := evalDetails.Value.(map[string]interface{})
Expand All @@ -95,7 +95,7 @@ func TestResolveWholeFlagAsObject(t *testing.T) {

func TestResolveWholeFlagAsObjectWithInts(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetObjectFlag(context.Background(), "test-flag", "default")

Expand All @@ -113,7 +113,7 @@ func TestResolveWholeFlagAsObjectWithInts(t *testing.T) {

func TestResolveWithWrongType(t *testing.T) {
client := client(t, templateResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetBoolFlag(context.Background(), "test-flag.integer-key", false)

Expand All @@ -124,7 +124,7 @@ func TestResolveWithWrongType(t *testing.T) {

func TestResolveWithUnexpectedFlag(t *testing.T) {
client := client(t, templateResponseWithFlagName("wrong-flag"), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetBoolFlag(context.Background(), "test-flag.boolean-key", true)

Expand All @@ -136,7 +136,7 @@ func TestResolveWithUnexpectedFlag(t *testing.T) {

func TestResolveWithNonExistingFlag(t *testing.T) {
client := client(t, emptyResponse(), nil)
client.putContext("targeting_key", "user1")
client.PutContext("targeting_key", "user1")

evalDetails := client.GetBoolFlag(context.Background(), "test-flag.boolean-key", true)

Expand Down
13 changes: 13 additions & 0 deletions confidence/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@ type ResolveClient interface {

var errFlagNotFound = errors.New("flag not found")

type EventBatchRequest struct {
CclientSecret string `json:"clientSecret"`
Sdk sdk `json:"sdk"`
SendTime string `json:"sendTime"`
Events []Event `json:"events"`
}

type Event struct {
EventDefinition string `json:"eventDefinition"`
EventTime string `json:"eventTime"`
Payload map[string]interface{} `json:"payload"`
}

type ResolveRequest struct {
ClientSecret string `json:"client_secret"`
Apply bool `json:"apply"`
Expand Down
4 changes: 3 additions & 1 deletion demo/GoDemoApp.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import (
)

func main() {
clientSecret := "CLIENT_SECRET"
clientSecret := "xa0fQ4WKSvuxdjPtesupleiSbZeik6Gf"
fmt.Println("Fetching the flags...")

confidence := c.NewConfidenceBuilder().SetAPIConfig(c.APIConfig{APIKey: clientSecret}).Build()

confidence.PutContext("hello", "world")
confidence.Track(context.Background(), "navigate", map[string]interface{}{"test": "value"})
provider := p.NewFlagProvider(confidence)

openfeature.SetProvider(provider)
Expand Down
11 changes: 11 additions & 0 deletions demo/go.sum
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0=
github.com/cucumber/godog v0.14.0/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces=
github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/open-feature/go-sdk v1.10.0 h1:druQtYOrN+gyz3rMsXp0F2jW1oBXJb0V26PVQnUGLbM=
github.com/open-feature/go-sdk v1.10.0/go.mod h1:+rkJhLBtYsJ5PZNddAgFILhRAAxwrJ32aU7UEUm4zQI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a h1:HinSgX1tJRX3KsL//Gxynpw5CTOAIPhgL4W8PNiIpVE=
golang.org/x/exp v0.0.0-20240213143201-ec583247a57a/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2 changes: 2 additions & 0 deletions provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ func (e FlagProvider) StringEvaluation(ctx context.Context, flag string, default
}
}



func (e FlagProvider) FloatEvaluation(ctx context.Context, flag string, defaultValue float64,
evalCtx openfeature.FlattenedContext) openfeature.FloatResolutionDetail {
confidence := e.confidence.WithContext(processTargetingKey(evalCtx))
Expand Down

0 comments on commit 5ec5f0b

Please sign in to comment.