Skip to content

Commit b3949fe

Browse files
feat: flagd add scope to flag metadata (#420)
Signed-off-by: Kavindu Dodanduwa <[email protected]>
1 parent c061cf4 commit b3949fe

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

providers/flagd/pkg/service/in_process/service.go

+21
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type InProcess struct {
2222
events chan of.Event
2323
listenerShutdown chan interface{}
2424
logger *logger.Logger
25+
serviceMetadata map[string]interface{}
2526
sync sync.ISync
2627
syncEnd context.CancelFunc
2728
}
@@ -50,6 +51,13 @@ func NewInProcessService(cfg Configuration) *InProcess {
5051
Selector: cfg.Selector,
5152
}, log)
5253

54+
// service specific metadata
55+
var svcMetadata map[string]interface{}
56+
if cfg.Selector != "" {
57+
svcMetadata = make(map[string]interface{}, 1)
58+
svcMetadata["scope"] = cfg.Selector
59+
}
60+
5361
flagStore := store.NewFlags()
5462
flagStore.FlagSources = append(flagStore.FlagSources, uri)
5563

@@ -77,6 +85,7 @@ func NewInProcessService(cfg Configuration) *InProcess {
7785
events: make(chan of.Event, 5),
7886
logger: log,
7987
listenerShutdown: make(chan interface{}),
88+
serviceMetadata: svcMetadata,
8089
sync: grpcSync,
8190
}
8291
}
@@ -147,6 +156,7 @@ func (i *InProcess) Shutdown() {
147156
func (i *InProcess) ResolveBoolean(ctx context.Context, key string, defaultValue bool,
148157
evalCtx map[string]interface{}) of.BoolResolutionDetail {
149158
value, variant, reason, metadata, err := i.evaluator.ResolveBooleanValue(ctx, "", key, evalCtx)
159+
i.appendMetadata(metadata)
150160
if err != nil {
151161
return of.BoolResolutionDetail{
152162
Value: defaultValue,
@@ -172,6 +182,7 @@ func (i *InProcess) ResolveBoolean(ctx context.Context, key string, defaultValue
172182
func (i *InProcess) ResolveString(ctx context.Context, key string, defaultValue string,
173183
evalCtx map[string]interface{}) of.StringResolutionDetail {
174184
value, variant, reason, metadata, err := i.evaluator.ResolveStringValue(ctx, "", key, evalCtx)
185+
i.appendMetadata(metadata)
175186
if err != nil {
176187
return of.StringResolutionDetail{
177188
Value: defaultValue,
@@ -197,6 +208,7 @@ func (i *InProcess) ResolveString(ctx context.Context, key string, defaultValue
197208
func (i *InProcess) ResolveFloat(ctx context.Context, key string, defaultValue float64,
198209
evalCtx map[string]interface{}) of.FloatResolutionDetail {
199210
value, variant, reason, metadata, err := i.evaluator.ResolveFloatValue(ctx, "", key, evalCtx)
211+
i.appendMetadata(metadata)
200212
if err != nil {
201213
return of.FloatResolutionDetail{
202214
Value: defaultValue,
@@ -222,6 +234,7 @@ func (i *InProcess) ResolveFloat(ctx context.Context, key string, defaultValue f
222234
func (i *InProcess) ResolveInt(ctx context.Context, key string, defaultValue int64,
223235
evalCtx map[string]interface{}) of.IntResolutionDetail {
224236
value, variant, reason, metadata, err := i.evaluator.ResolveIntValue(ctx, "", key, evalCtx)
237+
i.appendMetadata(metadata)
225238
if err != nil {
226239
return of.IntResolutionDetail{
227240
Value: defaultValue,
@@ -247,6 +260,7 @@ func (i *InProcess) ResolveInt(ctx context.Context, key string, defaultValue int
247260
func (i *InProcess) ResolveObject(ctx context.Context, key string, defaultValue interface{},
248261
evalCtx map[string]interface{}) of.InterfaceResolutionDetail {
249262
value, variant, reason, metadata, err := i.evaluator.ResolveObjectValue(ctx, "", key, evalCtx)
263+
i.appendMetadata(metadata)
250264
if err != nil {
251265
return of.InterfaceResolutionDetail{
252266
Value: defaultValue,
@@ -273,6 +287,13 @@ func (i *InProcess) EventChannel() <-chan of.Event {
273287
return i.events
274288
}
275289

290+
func (i *InProcess) appendMetadata(evalMetadata map[string]interface{}) {
291+
// For a nil slice, the number of iterations is 0
292+
for k, v := range i.serviceMetadata {
293+
evalMetadata[k] = v
294+
}
295+
}
296+
276297
// mapError is a helper to map evaluation errors to OF errors
277298
func mapError(err error) of.ResolutionError {
278299
switch err.Error() {

providers/flagd/pkg/service/in_process/service_grpc_test.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ func TestInProcessProviderEvaluation(t *testing.T) {
1717
// given
1818
host := "localhost"
1919
port := 8090
20+
scope := "app=myapp"
2021

2122
listen, err := net.Listen("tcp", fmt.Sprintf("%s:%d", host, port))
2223
if err != nil {
@@ -51,7 +52,7 @@ func TestInProcessProviderEvaluation(t *testing.T) {
5152
inProcessService := NewInProcessService(Configuration{
5253
Host: host,
5354
Port: port,
54-
Selector: "",
55+
Selector: scope,
5556
TLSEnabled: false,
5657
})
5758

@@ -102,6 +103,15 @@ func TestInProcessProviderEvaluation(t *testing.T) {
102103
if !detail.Value {
103104
t.Fatal("Expected true, but got false")
104105
}
106+
107+
// check for metadata - scope from grpc sync
108+
if len(detail.FlagMetadata) == 0 && detail.FlagMetadata["scope"] == "" {
109+
t.Fatal("Expected scope to be present, but got none")
110+
}
111+
112+
if scope != detail.FlagMetadata["scope"] {
113+
t.Fatalf("Wrong scope value. Expected %s, but got %s", scope, detail.FlagMetadata["scope"])
114+
}
105115
}
106116

107117
// bufferedServer - a mock grpc service backed by buffered connection

0 commit comments

Comments
 (0)