github.com/ashishbhate/mattermost-server@v5.11.1+incompatible/config/memory.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See License.txt for license information.
     3  
     4  package config
     5  
     6  import (
     7  	"bytes"
     8  	"fmt"
     9  	"io/ioutil"
    10  
    11  	"github.com/pkg/errors"
    12  
    13  	"github.com/mattermost/mattermost-server/model"
    14  )
    15  
    16  // memoryStore implements the Store interface. It is meant primarily for testing.
    17  type memoryStore struct {
    18  	commonStore
    19  
    20  	allowEnvironmentOverrides bool
    21  	validate                  bool
    22  	files                     map[string][]byte
    23  	savedConfig               *model.Config
    24  }
    25  
    26  // MemoryStoreOptions makes configuration of the memory store explicit.
    27  type MemoryStoreOptions struct {
    28  	IgnoreEnvironmentOverrides bool
    29  	SkipValidation             bool
    30  	InitialConfig              *model.Config
    31  	InitialFiles               map[string][]byte
    32  }
    33  
    34  // NewMemoryStore creates a new memoryStore instance with default options.
    35  func NewMemoryStore() (*memoryStore, error) {
    36  	return NewMemoryStoreWithOptions(&MemoryStoreOptions{})
    37  }
    38  
    39  // NewMemoryStoreWithOptions creates a new memoryStore instance.
    40  func NewMemoryStoreWithOptions(options *MemoryStoreOptions) (*memoryStore, error) {
    41  	savedConfig := options.InitialConfig
    42  	if savedConfig == nil {
    43  		savedConfig = &model.Config{}
    44  		savedConfig.SetDefaults()
    45  	}
    46  
    47  	initialFiles := options.InitialFiles
    48  	if initialFiles == nil {
    49  		initialFiles = make(map[string][]byte)
    50  	}
    51  
    52  	ms := &memoryStore{
    53  		allowEnvironmentOverrides: !options.IgnoreEnvironmentOverrides,
    54  		validate:                  !options.SkipValidation,
    55  		files:                     initialFiles,
    56  		savedConfig:               savedConfig,
    57  	}
    58  
    59  	ms.commonStore.config = &model.Config{}
    60  	ms.commonStore.config.SetDefaults()
    61  
    62  	if err := ms.Load(); err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	return ms, nil
    67  }
    68  
    69  // Set replaces the current configuration in its entirety.
    70  func (ms *memoryStore) Set(newCfg *model.Config) (*model.Config, error) {
    71  	validate := ms.commonStore.validate
    72  	if !ms.validate {
    73  		validate = nil
    74  	}
    75  
    76  	return ms.commonStore.set(newCfg, validate, ms.persist)
    77  }
    78  
    79  // persist copies the active config to the saved config.
    80  func (ms *memoryStore) persist(cfg *model.Config) error {
    81  	ms.savedConfig = cfg.Clone()
    82  
    83  	return nil
    84  }
    85  
    86  // Load applies environment overrides to the default config as if a re-load had occurred.
    87  func (ms *memoryStore) Load() (err error) {
    88  	var cfgBytes []byte
    89  	cfgBytes, err = marshalConfig(ms.savedConfig)
    90  	if err != nil {
    91  		return errors.Wrap(err, "failed to serialize config")
    92  	}
    93  
    94  	f := ioutil.NopCloser(bytes.NewReader(cfgBytes))
    95  
    96  	validate := ms.commonStore.validate
    97  	if !ms.validate {
    98  		validate = nil
    99  	}
   100  
   101  	return ms.commonStore.load(f, false, validate, ms.persist)
   102  }
   103  
   104  // GetFile fetches the contents of a previously persisted configuration file.
   105  func (ms *memoryStore) GetFile(name string) ([]byte, error) {
   106  	ms.configLock.RLock()
   107  	defer ms.configLock.RUnlock()
   108  
   109  	data, ok := ms.files[name]
   110  	if !ok {
   111  		return nil, fmt.Errorf("file %s not stored", name)
   112  	}
   113  
   114  	return data, nil
   115  }
   116  
   117  // SetFile sets or replaces the contents of a configuration file.
   118  func (ms *memoryStore) SetFile(name string, data []byte) error {
   119  	ms.configLock.Lock()
   120  	defer ms.configLock.Unlock()
   121  
   122  	ms.files[name] = data
   123  
   124  	return nil
   125  }
   126  
   127  // HasFile returns true if the given file was previously persisted.
   128  func (ms *memoryStore) HasFile(name string) (bool, error) {
   129  	ms.configLock.RLock()
   130  	defer ms.configLock.RUnlock()
   131  
   132  	_, ok := ms.files[name]
   133  	return ok, nil
   134  }
   135  
   136  // RemoveFile removes a previously persisted configuration file.
   137  func (ms *memoryStore) RemoveFile(name string) error {
   138  	ms.configLock.Lock()
   139  	defer ms.configLock.Unlock()
   140  
   141  	delete(ms.files, name)
   142  
   143  	return nil
   144  }
   145  
   146  // String returns a hard-coded description, as there is no backing store.
   147  func (ms *memoryStore) String() string {
   148  	return "memory://"
   149  }
   150  
   151  // Close does nothing for a memory store.
   152  func (ms *memoryStore) Close() error {
   153  	return nil
   154  }