OpenFeature: Make OpenFeature initialization reusable with config struct (#112456)
* make existing pieces more reusable * inline func * tidy comment
This commit is contained in:
@@ -17,6 +17,48 @@ const (
|
||||
featuresProviderAudience = "features.grafana.app"
|
||||
)
|
||||
|
||||
// OpenFeatureConfig holds configuration for initializing OpenFeature
|
||||
type OpenFeatureConfig struct {
|
||||
// ProviderType is either "static" or "goff"
|
||||
ProviderType string
|
||||
// URL is the GOFF service URL (required for GOFF provider)
|
||||
URL *url.URL
|
||||
// HTTPClient is a pre-configured HTTP client (optional, used for GOFF provider)
|
||||
HTTPClient *http.Client
|
||||
// StaticFlags are the feature flags to use with static provider
|
||||
StaticFlags map[string]bool
|
||||
// TargetingKey is used for evaluation context
|
||||
TargetingKey string
|
||||
// ContextAttrs are additional attributes for evaluation context
|
||||
ContextAttrs map[string]any
|
||||
}
|
||||
|
||||
// InitOpenFeature initializes OpenFeature with the provided configuration
|
||||
func InitOpenFeature(config OpenFeatureConfig) error {
|
||||
// For GOFF provider, ensure we have a URL
|
||||
if config.ProviderType == setting.GOFFProviderType && (config.URL == nil || config.URL.String() == "") {
|
||||
return fmt.Errorf("URL is required for GOFF provider")
|
||||
}
|
||||
|
||||
p, err := createProvider(config.ProviderType, config.URL, config.StaticFlags, config.HTTPClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = openfeature.SetProviderAndWait(p); err != nil {
|
||||
return fmt.Errorf("failed to set global feature provider: %s, %w", config.ProviderType, err)
|
||||
}
|
||||
|
||||
contextAttrs := make(map[string]any)
|
||||
for k, v := range config.ContextAttrs {
|
||||
contextAttrs[k] = v
|
||||
}
|
||||
openfeature.SetEvaluationContext(openfeature.NewEvaluationContext(config.TargetingKey, contextAttrs))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitOpenFeatureWithCfg initializes OpenFeature from setting.Cfg
|
||||
func InitOpenFeatureWithCfg(cfg *setting.Cfg) error {
|
||||
confFlags, err := setting.ReadFeatureTogglesFromInitFile(cfg.Raw.Section("feature_toggles"))
|
||||
if err != nil {
|
||||
@@ -36,35 +78,19 @@ func InitOpenFeatureWithCfg(cfg *setting.Cfg) error {
|
||||
}
|
||||
}
|
||||
|
||||
err = initOpenFeature(cfg.OpenFeature.ProviderType, cfg.OpenFeature.URL, confFlags, httpcli)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize OpenFeature: %w", err)
|
||||
}
|
||||
contextAttrs := make(map[string]any)
|
||||
for k, v := range cfg.OpenFeature.ContextAttrs {
|
||||
contextAttrs[k] = v
|
||||
}
|
||||
openfeature.SetEvaluationContext(openfeature.NewEvaluationContext(cfg.OpenFeature.TargetingKey, contextAttrs))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func initOpenFeature(
|
||||
providerType string,
|
||||
u *url.URL,
|
||||
staticFlags map[string]bool,
|
||||
httpClient *http.Client,
|
||||
) error {
|
||||
p, err := createProvider(providerType, u, staticFlags, httpClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := openfeature.SetProviderAndWait(p); err != nil {
|
||||
return fmt.Errorf("failed to set global feature provider: %s, %w", providerType, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
return InitOpenFeature(OpenFeatureConfig{
|
||||
ProviderType: cfg.OpenFeature.ProviderType,
|
||||
URL: cfg.OpenFeature.URL,
|
||||
HTTPClient: httpcli,
|
||||
StaticFlags: confFlags,
|
||||
TargetingKey: cfg.OpenFeature.TargetingKey,
|
||||
ContextAttrs: contextAttrs,
|
||||
})
|
||||
}
|
||||
|
||||
func createProvider(
|
||||
|
||||
Reference in New Issue
Block a user