diff --git a/pkg/local_workflows/config_utils/feature_flag.go b/pkg/local_workflows/config_utils/feature_flag.go index 8248d46dd..728867f5b 100644 --- a/pkg/local_workflows/config_utils/feature_flag.go +++ b/pkg/local_workflows/config_utils/feature_flag.go @@ -4,23 +4,17 @@ import ( "github.com/snyk/go-application-framework/internal/api" "github.com/snyk/go-application-framework/pkg/configuration" "github.com/snyk/go-application-framework/pkg/workflow" + "sync" ) +//go:generate $GOPATH/bin/mockgen -source=feature_flag.go -destination ../../mocks/feature_flag.go -package mocks -self_package github.com/snyk/go-application-framework/pkg/local_workflows/config_utils + func AddFeatureFlagToConfig(engine workflow.Engine, configKey string, featureFlagName string) { config := engine.GetConfiguration() callback := func(existingValue interface{}) (interface{}, error) { if existingValue == nil { - httpClient := engine.GetNetworkAccess().GetHttpClient() - logger := engine.GetLogger() - url := config.GetString(configuration.API_URL) - org := config.GetString(configuration.ORGANIZATION) - apiClient := api.NewApi(url, httpClient) - result, err := apiClient.GetFeatureFlag(featureFlagName, org) - if err != nil { - logger.Printf("Failed to determine feature flag \"%s\" for org \"%s\": %s", featureFlagName, org, err) - } - return result, nil + return CurrentFeatureFlagChecker().GetFeatureFlag(engine, featureFlagName) } else { return existingValue, nil } @@ -28,3 +22,44 @@ func AddFeatureFlagToConfig(engine workflow.Engine, configKey string, featureFla config.AddDefaultValue(configKey, callback) } + +type FeatureFlagChecker interface { + GetFeatureFlag(engine workflow.Engine, featureFlagName string) (bool, error) +} + +type featureFlagCheckerImpl struct { +} + +var ( + currentFFC FeatureFlagChecker + mutex = &sync.RWMutex{} +) + +func CurrentFeatureFlagChecker() FeatureFlagChecker { + mutex.RLock() + defer mutex.RUnlock() + if currentFFC == nil { + currentFFC = &featureFlagCheckerImpl{} + } + return currentFFC +} + +func SetCurrentFeatureFlagChecker(ffc FeatureFlagChecker) { + mutex.Lock() + defer mutex.Unlock() + currentFFC = ffc +} + +func (ffc *featureFlagCheckerImpl) GetFeatureFlag(engine workflow.Engine, featureFlagName string) (bool, error) { + config := engine.GetConfiguration() + httpClient := engine.GetNetworkAccess().GetHttpClient() + logger := engine.GetLogger() + url := config.GetString(configuration.API_URL) + org := config.GetString(configuration.ORGANIZATION) + apiClient := api.NewApi(url, httpClient) + result, err := apiClient.GetFeatureFlag(featureFlagName, org) + if err != nil { + logger.Printf("Failed to determine feature flag \"%s\" for org \"%s\": %s", featureFlagName, org, err) + } + return result, nil +} diff --git a/pkg/mocks/feature_flag.go b/pkg/mocks/feature_flag.go new file mode 100644 index 000000000..c56598c2c --- /dev/null +++ b/pkg/mocks/feature_flag.go @@ -0,0 +1,50 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: feature_flag.go + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + + gomock "github.com/golang/mock/gomock" + workflow "github.com/snyk/go-application-framework/pkg/workflow" +) + +// MockFeatureFlagChecker is a mock of FeatureFlagChecker interface. +type MockFeatureFlagChecker struct { + ctrl *gomock.Controller + recorder *MockFeatureFlagCheckerMockRecorder +} + +// MockFeatureFlagCheckerMockRecorder is the mock recorder for MockFeatureFlagChecker. +type MockFeatureFlagCheckerMockRecorder struct { + mock *MockFeatureFlagChecker +} + +// NewMockFeatureFlagChecker creates a new mock instance. +func NewMockFeatureFlagChecker(ctrl *gomock.Controller) *MockFeatureFlagChecker { + mock := &MockFeatureFlagChecker{ctrl: ctrl} + mock.recorder = &MockFeatureFlagCheckerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockFeatureFlagChecker) EXPECT() *MockFeatureFlagCheckerMockRecorder { + return m.recorder +} + +// GetFeatureFlag mocks base method. +func (m *MockFeatureFlagChecker) GetFeatureFlag(engine workflow.Engine, featureFlagName string) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFeatureFlag", engine, featureFlagName) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFeatureFlag indicates an expected call of GetFeatureFlag. +func (mr *MockFeatureFlagCheckerMockRecorder) GetFeatureFlag(engine, featureFlagName interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeatureFlag", reflect.TypeOf((*MockFeatureFlagChecker)(nil).GetFeatureFlag), engine, featureFlagName) +}