From 931c12012891834c112714e9151a0132c823e390 Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Tue, 17 Dec 2024 10:52:02 +0530 Subject: [PATCH 1/7] return flag metadata as well Signed-off-by: Aasif Khan --- core/pkg/evaluator/json.go | 10 ++++++++++ core/pkg/model/flag.go | 6 ++++++ core/pkg/store/flags.go | 17 +++++++++++++---- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/core/pkg/evaluator/json.go b/core/pkg/evaluator/json.go index 655eaf75c..0a8100c54 100644 --- a/core/pkg/evaluator/json.go +++ b/core/pkg/evaluator/json.go @@ -33,6 +33,8 @@ const ( // evaluation if the user did not supply the optional bucketing property. targetingKeyKey = "targetingKey" Disabled = "DISABLED" + ID = "id" + VERSION = "version" ) var regBrace *regexp.Regexp @@ -327,6 +329,14 @@ func (je *Resolver) evaluateVariant(ctx context.Context, reqID string, flagKey s metadata[SelectorMetadataKey] = selector } + flagMetadata := je.store.MetadataForFlag(ctx, flag) + if flagMetadata.ID != "" { + metadata[ID] = flagMetadata.ID + } + if flagMetadata.Version != "" { + metadata[VERSION] = flagMetadata.Version + } + if flag.State == Disabled { je.Logger.DebugWithID(reqID, fmt.Sprintf("requested flag is disabled: %s", flagKey)) return "", flag.Variants, model.ErrorReason, metadata, errors.New(model.FlagDisabledErrorCode) diff --git a/core/pkg/model/flag.go b/core/pkg/model/flag.go index 342b0488b..0b6e12802 100644 --- a/core/pkg/model/flag.go +++ b/core/pkg/model/flag.go @@ -9,6 +9,12 @@ type Flag struct { Targeting json.RawMessage `json:"targeting,omitempty"` Source string `json:"source"` Selector string `json:"selector"` + Metadata Metadata `json:"metadata"` +} + +type Metadata struct { + ID string `json:"id"` + Version string `json:"version"` } type Evaluators struct { diff --git a/core/pkg/store/flags.go b/core/pkg/store/flags.go index 626e2940f..1ab38605a 100644 --- a/core/pkg/store/flags.go +++ b/core/pkg/store/flags.go @@ -15,13 +15,15 @@ type IStore interface { GetAll(ctx context.Context) (map[string]model.Flag, error) Get(ctx context.Context, key string) (model.Flag, bool) SelectorForFlag(ctx context.Context, flag model.Flag) string + MetadataForFlag(ctx context.Context, flag model.Flag) model.Metadata } type Flags struct { - mx sync.RWMutex - Flags map[string]model.Flag `json:"flags"` - FlagSources []string - SourceMetadata map[string]SourceDetails + mx sync.RWMutex + Flags map[string]model.Flag `json:"flags"` + FlagSources []string + SourceMetadata map[string]SourceDetails + FlagSetMetadata model.Metadata } type SourceDetails struct { @@ -72,6 +74,13 @@ func (f *Flags) SelectorForFlag(_ context.Context, flag model.Flag) string { return f.SourceMetadata[flag.Source].Selector } +func (f *Flags) MetadataForFlag(_ context.Context, flag model.Flag) model.Metadata { + f.mx.RLock() + defer f.mx.RUnlock() + + return flag.Metadata +} + func (f *Flags) Delete(key string) { f.mx.Lock() defer f.mx.Unlock() From 5d8173e21570360c8c7f88d3697bdb2acb404e0a Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Tue, 17 Dec 2024 11:01:12 +0530 Subject: [PATCH 2/7] added a json name for flagsetmetadata Signed-off-by: Aasif Khan --- core/pkg/store/flags.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/pkg/store/flags.go b/core/pkg/store/flags.go index 1ab38605a..35b60d3a6 100644 --- a/core/pkg/store/flags.go +++ b/core/pkg/store/flags.go @@ -23,7 +23,7 @@ type Flags struct { Flags map[string]model.Flag `json:"flags"` FlagSources []string SourceMetadata map[string]SourceDetails - FlagSetMetadata model.Metadata + FlagSetMetadata model.Metadata `json:"metadata"` } type SourceDetails struct { From dd48ee3d4ffe7529013ae299678e0831536c6114 Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Wed, 18 Dec 2024 16:58:06 +0530 Subject: [PATCH 3/7] fix: start returning flagSetId, flagSetVersion as well in flag metadata Signed-off-by: Aasif Khan --- core/pkg/evaluator/json.go | 21 ++++++++++++++++++++- core/pkg/evaluator/json_model.go | 10 ++++++++++ core/pkg/model/flag.go | 6 ++++-- core/pkg/store/flags.go | 10 +++++----- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/core/pkg/evaluator/json.go b/core/pkg/evaluator/json.go index 0a8100c54..f2a3b1028 100644 --- a/core/pkg/evaluator/json.go +++ b/core/pkg/evaluator/json.go @@ -35,6 +35,8 @@ const ( Disabled = "DISABLED" ID = "id" VERSION = "version" + FLAGSETVERSION = "flagSetVersion" + FLAGSETID = "flagSetId" ) var regBrace *regexp.Regexp @@ -336,6 +338,12 @@ func (je *Resolver) evaluateVariant(ctx context.Context, reqID string, flagKey s if flagMetadata.Version != "" { metadata[VERSION] = flagMetadata.Version } + if flagMetadata.FlagSetID != "" { + metadata[FLAGSETID] = flagMetadata.FlagSetID + } + if flagMetadata.FlagSetVersion != "" { + metadata[FLAGSETVERSION] = flagMetadata.FlagSetVersion + } if flag.State == Disabled { je.Logger.DebugWithID(reqID, fmt.Sprintf("requested flag is disabled: %s", flagKey)) @@ -470,11 +478,22 @@ func configToFlags(log *logger.Logger, config string, newFlags *Flags) error { return fmt.Errorf("transposing evaluators: %w", err) } - err = json.Unmarshal([]byte(transposedConfig), &newFlags) + var configData ConfigWithMetadata + err = json.Unmarshal([]byte(transposedConfig), &configData) if err != nil { return fmt.Errorf("unmarshalling provided configurations: %w", err) } + // Assign the flags from the unmarshalled config to the newFlags struct + newFlags.Flags = configData.Flags + + // Assign version and id from metadata to the flags + for key, flag := range newFlags.Flags { + flag.Metadata.FlagSetID = configData.MetaData.ID + flag.Metadata.FlagSetVersion = configData.MetaData.Version + newFlags.Flags[key] = flag + } + return validateDefaultVariants(newFlags) } diff --git a/core/pkg/evaluator/json_model.go b/core/pkg/evaluator/json_model.go index 00a7105ef..3e06d9b23 100644 --- a/core/pkg/evaluator/json_model.go +++ b/core/pkg/evaluator/json_model.go @@ -10,6 +10,16 @@ type Evaluators struct { Evaluators map[string]json.RawMessage `json:"$evaluators"` } +type Metadata struct { + ID string `json:"id"` + Version string `json:"version"` +} + +type ConfigWithMetadata struct { + Flags map[string]model.Flag `json:"flags"` + MetaData Metadata `json:"metadata"` +} + type Flags struct { Flags map[string]model.Flag `json:"flags"` } diff --git a/core/pkg/model/flag.go b/core/pkg/model/flag.go index 0b6e12802..532935adb 100644 --- a/core/pkg/model/flag.go +++ b/core/pkg/model/flag.go @@ -13,8 +13,10 @@ type Flag struct { } type Metadata struct { - ID string `json:"id"` - Version string `json:"version"` + ID string `json:"id"` + Version string `json:"version"` + FlagSetID string `json:"flagSetId"` + FlagSetVersion string `json:"flagSetVersion"` } type Evaluators struct { diff --git a/core/pkg/store/flags.go b/core/pkg/store/flags.go index 35b60d3a6..8e95c1c40 100644 --- a/core/pkg/store/flags.go +++ b/core/pkg/store/flags.go @@ -19,11 +19,11 @@ type IStore interface { } type Flags struct { - mx sync.RWMutex - Flags map[string]model.Flag `json:"flags"` - FlagSources []string - SourceMetadata map[string]SourceDetails - FlagSetMetadata model.Metadata `json:"metadata"` + mx sync.RWMutex + Flags map[string]model.Flag `json:"flags"` + FlagSources []string + SourceMetadata map[string]SourceDetails + Metadata model.Metadata `json:"metadata"` } type SourceDetails struct { From 5cb824c69310579c9e4297674ee651fd8d606f00 Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Fri, 20 Dec 2024 13:27:51 +0530 Subject: [PATCH 4/7] fetching flag metadata with a single lock Signed-off-by: Aasif Khan --- core/pkg/evaluator/json.go | 17 ++++++++--------- core/pkg/store/flags.go | 8 -------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/core/pkg/evaluator/json.go b/core/pkg/evaluator/json.go index f2a3b1028..e5044c1a3 100644 --- a/core/pkg/evaluator/json.go +++ b/core/pkg/evaluator/json.go @@ -331,18 +331,17 @@ func (je *Resolver) evaluateVariant(ctx context.Context, reqID string, flagKey s metadata[SelectorMetadataKey] = selector } - flagMetadata := je.store.MetadataForFlag(ctx, flag) - if flagMetadata.ID != "" { - metadata[ID] = flagMetadata.ID + if flag.Metadata.ID != "" { + metadata[ID] = flag.Metadata.ID } - if flagMetadata.Version != "" { - metadata[VERSION] = flagMetadata.Version + if flag.Metadata.Version != "" { + metadata[VERSION] = flag.Metadata.Version } - if flagMetadata.FlagSetID != "" { - metadata[FLAGSETID] = flagMetadata.FlagSetID + if flag.Metadata.FlagSetID != "" { + metadata[FLAGSETID] = flag.Metadata.FlagSetID } - if flagMetadata.FlagSetVersion != "" { - metadata[FLAGSETVERSION] = flagMetadata.FlagSetVersion + if flag.Metadata.FlagSetVersion != "" { + metadata[FLAGSETVERSION] = flag.Metadata.FlagSetVersion } if flag.State == Disabled { diff --git a/core/pkg/store/flags.go b/core/pkg/store/flags.go index 8e95c1c40..fd51c6d7f 100644 --- a/core/pkg/store/flags.go +++ b/core/pkg/store/flags.go @@ -15,7 +15,6 @@ type IStore interface { GetAll(ctx context.Context) (map[string]model.Flag, error) Get(ctx context.Context, key string) (model.Flag, bool) SelectorForFlag(ctx context.Context, flag model.Flag) string - MetadataForFlag(ctx context.Context, flag model.Flag) model.Metadata } type Flags struct { @@ -74,13 +73,6 @@ func (f *Flags) SelectorForFlag(_ context.Context, flag model.Flag) string { return f.SourceMetadata[flag.Source].Selector } -func (f *Flags) MetadataForFlag(_ context.Context, flag model.Flag) model.Metadata { - f.mx.RLock() - defer f.mx.RUnlock() - - return flag.Metadata -} - func (f *Flags) Delete(key string) { f.mx.Lock() defer f.mx.Unlock() From bb2ca430dc95b0d728cc9e36d54af8fc48fa5d3c Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Tue, 7 Jan 2025 00:35:56 +0530 Subject: [PATCH 5/7] change id of flagSet -> id Signed-off-by: Aasif Khan --- core/pkg/evaluator/json.go | 4 ++-- core/pkg/evaluator/json_model.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/pkg/evaluator/json.go b/core/pkg/evaluator/json.go index e5044c1a3..55a1faa07 100644 --- a/core/pkg/evaluator/json.go +++ b/core/pkg/evaluator/json.go @@ -488,8 +488,8 @@ func configToFlags(log *logger.Logger, config string, newFlags *Flags) error { // Assign version and id from metadata to the flags for key, flag := range newFlags.Flags { - flag.Metadata.FlagSetID = configData.MetaData.ID - flag.Metadata.FlagSetVersion = configData.MetaData.Version + flag.Metadata.FlagSetID = configData.MetaData.FlagSetID + flag.Metadata.FlagSetVersion = configData.MetaData.FlagSetVersion newFlags.Flags[key] = flag } diff --git a/core/pkg/evaluator/json_model.go b/core/pkg/evaluator/json_model.go index 3e06d9b23..e31ebe03e 100644 --- a/core/pkg/evaluator/json_model.go +++ b/core/pkg/evaluator/json_model.go @@ -11,8 +11,8 @@ type Evaluators struct { } type Metadata struct { - ID string `json:"id"` - Version string `json:"version"` + FlagSetID string `json:"flagSetId"` + FlagSetVersion string `json:"flagSetVersion"` } type ConfigWithMetadata struct { From c1770b1285b788dff4b5a7e1f192df4de8e489b1 Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Tue, 7 Jan 2025 18:45:01 +0530 Subject: [PATCH 6/7] metadata can be any generic value Signed-off-by: Aasif Khan --- core/pkg/evaluator/json.go | 30 ++++++++++++------------------ core/pkg/evaluator/json_model.go | 9 ++------- core/pkg/model/flag.go | 21 +++++++-------------- core/pkg/store/flags.go | 2 +- 4 files changed, 22 insertions(+), 40 deletions(-) diff --git a/core/pkg/evaluator/json.go b/core/pkg/evaluator/json.go index 55a1faa07..08e51efde 100644 --- a/core/pkg/evaluator/json.go +++ b/core/pkg/evaluator/json.go @@ -33,10 +33,6 @@ const ( // evaluation if the user did not supply the optional bucketing property. targetingKeyKey = "targetingKey" Disabled = "DISABLED" - ID = "id" - VERSION = "version" - FLAGSETVERSION = "flagSetVersion" - FLAGSETID = "flagSetId" ) var regBrace *regexp.Regexp @@ -331,17 +327,11 @@ func (je *Resolver) evaluateVariant(ctx context.Context, reqID string, flagKey s metadata[SelectorMetadataKey] = selector } - if flag.Metadata.ID != "" { - metadata[ID] = flag.Metadata.ID - } - if flag.Metadata.Version != "" { - metadata[VERSION] = flag.Metadata.Version - } - if flag.Metadata.FlagSetID != "" { - metadata[FLAGSETID] = flag.Metadata.FlagSetID - } - if flag.Metadata.FlagSetVersion != "" { - metadata[FLAGSETVERSION] = flag.Metadata.FlagSetVersion + for key, value := range flag.MetaData { + // If value is not nil or empty, copy to metadata + if value != nil { + metadata[key] = value + } } if flag.State == Disabled { @@ -486,10 +476,14 @@ func configToFlags(log *logger.Logger, config string, newFlags *Flags) error { // Assign the flags from the unmarshalled config to the newFlags struct newFlags.Flags = configData.Flags - // Assign version and id from metadata to the flags + // Assign metadata as a map to each flag's metadata for key, flag := range newFlags.Flags { - flag.Metadata.FlagSetID = configData.MetaData.FlagSetID - flag.Metadata.FlagSetVersion = configData.MetaData.FlagSetVersion + if flag.MetaData == nil { + flag.MetaData = make(map[string]interface{}) + } + for metaKey, metaValue := range configData.MetaData { + flag.MetaData[metaKey] = metaValue + } newFlags.Flags[key] = flag } diff --git a/core/pkg/evaluator/json_model.go b/core/pkg/evaluator/json_model.go index e31ebe03e..04824ecd7 100644 --- a/core/pkg/evaluator/json_model.go +++ b/core/pkg/evaluator/json_model.go @@ -10,14 +10,9 @@ type Evaluators struct { Evaluators map[string]json.RawMessage `json:"$evaluators"` } -type Metadata struct { - FlagSetID string `json:"flagSetId"` - FlagSetVersion string `json:"flagSetVersion"` -} - type ConfigWithMetadata struct { - Flags map[string]model.Flag `json:"flags"` - MetaData Metadata `json:"metadata"` + Flags map[string]model.Flag `json:"flags"` + MetaData map[string]interface{} `json:"metadata"` } type Flags struct { diff --git a/core/pkg/model/flag.go b/core/pkg/model/flag.go index 532935adb..5b736635b 100644 --- a/core/pkg/model/flag.go +++ b/core/pkg/model/flag.go @@ -3,20 +3,13 @@ package model import "encoding/json" type Flag struct { - State string `json:"state"` - DefaultVariant string `json:"defaultVariant"` - Variants map[string]any `json:"variants"` - Targeting json.RawMessage `json:"targeting,omitempty"` - Source string `json:"source"` - Selector string `json:"selector"` - Metadata Metadata `json:"metadata"` -} - -type Metadata struct { - ID string `json:"id"` - Version string `json:"version"` - FlagSetID string `json:"flagSetId"` - FlagSetVersion string `json:"flagSetVersion"` + State string `json:"state"` + DefaultVariant string `json:"defaultVariant"` + Variants map[string]any `json:"variants"` + Targeting json.RawMessage `json:"targeting,omitempty"` + Source string `json:"source"` + Selector string `json:"selector"` + MetaData map[string]interface{} `json:"metadata"` } type Evaluators struct { diff --git a/core/pkg/store/flags.go b/core/pkg/store/flags.go index fd51c6d7f..01a1b8203 100644 --- a/core/pkg/store/flags.go +++ b/core/pkg/store/flags.go @@ -22,7 +22,7 @@ type Flags struct { Flags map[string]model.Flag `json:"flags"` FlagSources []string SourceMetadata map[string]SourceDetails - Metadata model.Metadata `json:"metadata"` + MetaData map[string]interface{} `json:"metadata"` } type SourceDetails struct { From 9907dd4ebe537130bf7c2f0281df05337ada3254 Mon Sep 17 00:00:00 2001 From: Aasif Khan Date: Wed, 8 Jan 2025 12:57:14 +0530 Subject: [PATCH 7/7] changed MetaData -> Metadata Signed-off-by: Aasif Khan --- core/pkg/evaluator/json.go | 10 +++++----- core/pkg/evaluator/json_model.go | 2 +- core/pkg/model/flag.go | 2 +- core/pkg/store/flags.go | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/core/pkg/evaluator/json.go b/core/pkg/evaluator/json.go index 08e51efde..bf9a23e9c 100644 --- a/core/pkg/evaluator/json.go +++ b/core/pkg/evaluator/json.go @@ -327,7 +327,7 @@ func (je *Resolver) evaluateVariant(ctx context.Context, reqID string, flagKey s metadata[SelectorMetadataKey] = selector } - for key, value := range flag.MetaData { + for key, value := range flag.Metadata { // If value is not nil or empty, copy to metadata if value != nil { metadata[key] = value @@ -478,11 +478,11 @@ func configToFlags(log *logger.Logger, config string, newFlags *Flags) error { // Assign metadata as a map to each flag's metadata for key, flag := range newFlags.Flags { - if flag.MetaData == nil { - flag.MetaData = make(map[string]interface{}) + if flag.Metadata == nil { + flag.Metadata = make(map[string]interface{}) } - for metaKey, metaValue := range configData.MetaData { - flag.MetaData[metaKey] = metaValue + for metaKey, metaValue := range configData.Metadata { + flag.Metadata[metaKey] = metaValue } newFlags.Flags[key] = flag } diff --git a/core/pkg/evaluator/json_model.go b/core/pkg/evaluator/json_model.go index 04824ecd7..8b9c17114 100644 --- a/core/pkg/evaluator/json_model.go +++ b/core/pkg/evaluator/json_model.go @@ -12,7 +12,7 @@ type Evaluators struct { type ConfigWithMetadata struct { Flags map[string]model.Flag `json:"flags"` - MetaData map[string]interface{} `json:"metadata"` + Metadata map[string]interface{} `json:"metadata"` } type Flags struct { diff --git a/core/pkg/model/flag.go b/core/pkg/model/flag.go index 5b736635b..6ea0988f0 100644 --- a/core/pkg/model/flag.go +++ b/core/pkg/model/flag.go @@ -9,7 +9,7 @@ type Flag struct { Targeting json.RawMessage `json:"targeting,omitempty"` Source string `json:"source"` Selector string `json:"selector"` - MetaData map[string]interface{} `json:"metadata"` + Metadata map[string]interface{} `json:"metadata"` } type Evaluators struct { diff --git a/core/pkg/store/flags.go b/core/pkg/store/flags.go index 01a1b8203..00d27c57c 100644 --- a/core/pkg/store/flags.go +++ b/core/pkg/store/flags.go @@ -22,7 +22,7 @@ type Flags struct { Flags map[string]model.Flag `json:"flags"` FlagSources []string SourceMetadata map[string]SourceDetails - MetaData map[string]interface{} `json:"metadata"` + Metadata map[string]interface{} `json:"metadata"` } type SourceDetails struct {