blob: 6481dc6b893d336ae4b28d8a5181a02baec4d9d4 [file] [log] [blame] [edit]
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package config
import (
"github.com/30x/apid-core"
"github.com/spf13/viper"
"log"
"os"
"strings"
"sync"
"time"
)
const (
localStoragePathKey = "local_storage_path"
localStoragePathDefault = "/var/tmp/apid"
configFileEnvVar = "APID_CONFIG_FILE"
configFileType = "yaml"
configFileNameKey = "apid_config_filename"
configPathKey = "apid_config_path"
defaultConfigFilename = "apid_config.yaml"
defaultConfigPath = "."
)
var configlock sync.Mutex
type ConfigMgr struct {
sync.Mutex
vcfg *viper.Viper
}
// Wrapper function to make the viper calls thread safe
var cfg *ConfigMgr
func (c *ConfigMgr) SetDefault(key string, value interface{}) {
c.Lock()
c.vcfg.SetDefault(key, value)
c.Unlock()
}
func (c *ConfigMgr) Set(key string, value interface{}) {
c.Lock()
c.vcfg.Set(key, value)
c.Unlock()
}
func (c *ConfigMgr) Get(key string) interface{} {
c.Lock()
defer c.Unlock()
return c.vcfg.Get(key)
}
func (c *ConfigMgr) GetBool(key string) bool {
c.Lock()
defer c.Unlock()
return c.vcfg.GetBool(key)
}
func (c *ConfigMgr) GetFloat64(key string) float64 {
c.Lock()
defer c.Unlock()
return c.vcfg.GetFloat64(key)
}
func (c *ConfigMgr) GetInt(key string) int {
c.Lock()
defer c.Unlock()
return c.vcfg.GetInt(key)
}
func (c *ConfigMgr) GetString(key string) string {
cfg.Lock()
defer cfg.Unlock()
return c.vcfg.GetString(key)
}
func (c *ConfigMgr) GetDuration(key string) time.Duration {
cfg.Lock()
defer cfg.Unlock()
return c.vcfg.GetDuration(key)
}
func (c *ConfigMgr) IsSet(key string) bool {
c.Lock()
defer c.Unlock()
return c.vcfg.IsSet(key)
}
func GetConfig() apid.ConfigService {
configlock.Lock()
defer configlock.Unlock()
if cfg == nil {
vcfg := viper.New()
// for config file search path
vcfg.SetConfigType(configFileType)
vcfg.SetDefault(configPathKey, defaultConfigPath)
configFilePath := vcfg.GetString(configPathKey)
vcfg.AddConfigPath(configFilePath)
vcfg.SetDefault(configFileNameKey, defaultConfigFilename)
configFileName := vcfg.GetString(configFileNameKey)
configFileName = strings.TrimSuffix(configFileName, ".yaml")
vcfg.SetConfigName(configFileName)
// for user-specified absolute config file
configFile, ok := os.LookupEnv(configFileEnvVar)
if ok {
vcfg.SetConfigFile(configFile)
}
vcfg.SetDefault(localStoragePathKey, localStoragePathDefault)
err := vcfg.ReadInConfig()
if err != nil {
log.Printf("Error in config file '%s': %s", configFileNameKey, err)
}
vcfg.SetEnvPrefix("apid") // eg. env var "APID_SOMETHING" will bind to config var "something"
vcfg.AutomaticEnv()
cfg = &ConfigMgr{vcfg: vcfg}
}
return cfg
}