MM-28859 Add feature flag managment system using split.io and remove viper. (#15954)

* Add feature flag managment system using split.io and remove viper.

* Fixing tests.

* Attempt to fix postgres tests.

* Fix watch filepath for advanced logging.

* Review fixes.

* Some error wrapping.

* Remove unessisary store interface.

* Desanitize SplitKey

* Simplify.

* Review feedback.

* Rename split mlog adatper to split logger.

* fsInner

* Style.

* Restore oldcfg test.

* Downgrading non-actionable feature flag errors to warnings.

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Christopher Speller
2020-10-29 15:54:39 -07:00
коммит произвёл GitHub
родитель 8bb772638c
Коммит 1aadd36644
423 изменённых файлов: 37646 добавлений и 20257 удалений

Просмотреть файл

@@ -6,7 +6,7 @@ package config
import (
"bytes"
"database/sql"
"io/ioutil"
"encoding/json"
"strings"
"github.com/jmoiron/sqlx"
@@ -28,9 +28,8 @@ import (
const MaxWriteLength = 4 * 1024 * 1024
// DatabaseStore is a config store backed by a database.
// Not to be used directly. Only to be used as a backing store for config.Store
type DatabaseStore struct {
commonStore
originalDsn string
driverName string
dataSourceName string
@@ -59,10 +58,6 @@ func NewDatabaseStore(dsn string) (ds *DatabaseStore, err error) {
return nil, errors.Wrap(err, "failed to initialize")
}
if err = ds.Load(); err != nil {
return nil, errors.Wrap(err, "failed to load")
}
return ds, nil
}
@@ -159,8 +154,8 @@ func parseDSN(dsn string) (string, string, error) {
}
// Set replaces the current configuration in its entirety and updates the backing store.
func (ds *DatabaseStore) Set(newCfg *model.Config) (*model.Config, error) {
return ds.commonStore.set(newCfg, true, ds.commonStore.validate, ds.persist)
func (ds *DatabaseStore) Set(newCfg *model.Config) error {
return ds.persist(newCfg)
}
// maxLength identifies the maximum length of a configuration or configuration file
@@ -232,35 +227,23 @@ func (ds *DatabaseStore) persist(cfg *model.Config) error {
}
// Load updates the current configuration from the backing store.
func (ds *DatabaseStore) Load() (err error) {
var needsSave bool
func (ds *DatabaseStore) Load() ([]byte, error) {
var configurationData []byte
row := ds.db.QueryRow("SELECT Value FROM Configurations WHERE Active")
if err = row.Scan(&configurationData); err != nil && err != sql.ErrNoRows {
return errors.Wrap(err, "failed to query active configuration")
if err := row.Scan(&configurationData); err != nil && err != sql.ErrNoRows {
return nil, errors.Wrap(err, "failed to query active configuration")
}
// Initialize from the default config if no active configuration could be found.
if len(configurationData) == 0 {
needsSave = true
defaultCfg := &model.Config{}
defaultCfg.SetDefaults()
// Assume the database storing the config is also to be used for the application.
// This can be overridden using environment variables on first start if necessary,
// or changed from the system console afterwards.
*defaultCfg.SqlSettings.DriverName = ds.driverName
*defaultCfg.SqlSettings.DataSource = ds.dataSourceName
configurationData, err = marshalConfig(defaultCfg)
if err != nil {
return errors.Wrap(err, "failed to serialize default config")
}
configWithDB := model.Config{}
configWithDB.SqlSettings.DriverName = model.NewString(ds.driverName)
configWithDB.SqlSettings.DataSource = model.NewString(ds.dataSourceName)
return json.Marshal(configWithDB)
}
return ds.commonStore.load(ioutil.NopCloser(bytes.NewReader(configurationData)), needsSave, ds.commonStore.validate, ds.persist)
return configurationData, nil
}
// GetFile fetches the contents of a previously persisted configuration file.
@@ -287,7 +270,6 @@ func (ds *DatabaseStore) SetFile(name string, data []byte) error {
if err != nil {
return errors.Wrap(err, "file data failed length check")
}
params := map[string]interface{}{
"name": name,
"data": data,
@@ -352,8 +334,10 @@ func (ds *DatabaseStore) String() string {
// Close cleans up resources associated with the store.
func (ds *DatabaseStore) Close() error {
ds.configLock.Lock()
defer ds.configLock.Unlock()
return ds.db.Close()
}
// Watch nothing on memory store
func (ds *DatabaseStore) Watch(_ func()) error {
return nil
}