package xstream import ( "encoding/json" "fmt" "github.com/emqx/kuiper/common" "io/ioutil" "os" "path/filepath" "strings" ) type Conf map[string]interface{} var confs = make(map[string]Conf) func GetConfAsString(file, key string) (string, error) { val, err := getConfValue(file, key) if err != nil { return "", err } if v, ok := val.(string); ok { return v, nil } else if val == nil { return "", nil } else { return "", fmt.Errorf("The value %s is not type of string for key %s", val, key) } } func GetConfAsInt(file, key string) (int, error) { val, err := getConfValue(file, key) if err != nil { return 0, err } if v, ok := val.(float64); ok { return int(v), nil } else { return 0, fmt.Errorf("The value {0} is not type of int for key {1}") } } func GetConfAsFloat(file, key string) (float64, error) { val, err := getConfValue(file, key) if err != nil { return 0, err } if v, ok := val.(float64); ok { return v, nil } else { return 0, fmt.Errorf("The value {0} is not type of float for key {1}") } } func GetConfAsBool(file, key string) (bool, error) { val, err := getConfValue(file, key) if err != nil { return false, err } if v, ok := val.(bool); ok { return v, nil } else { return false, fmt.Errorf("The value {0} is not type of bool for key {1}") } } func getConfValue(file, key string) (interface{}, error) { if conf, ok := confs[file]; !ok { if c, e := initConf(file); e != nil { return nil, e } else { confs[file] = c return getValue(c, key) } } else { return getValue(conf, key) } } func initConf(file string) (Conf, error) { conf := make(Conf) fp, _ := filepath.Abs(file) if f, err1 := os.Open(fp); err1 == nil { defer f.Close() byteValue, _ := ioutil.ReadAll(f) if err2 := json.Unmarshal([]byte(byteValue), &conf); err2 != nil { return nil, err2 } common.Log.Printf("Successfully to load the configuration file %s", fp) } else { //Try as absolute path if f, err1 := os.Open(file); err1 == nil { byteValue, _ := ioutil.ReadAll(f) if err2 := json.Unmarshal([]byte(byteValue), &conf); err2 != nil { return nil, err2 } common.Log.Printf("Successfully to load the configuration file %s", file) } else { return nil, fmt.Errorf("Cannot load configuration file %s", file) } } return conf, nil } func getValue(conf Conf, key string) (interface{}, error) { keys := strings.Split(key, ".") if len(keys) == 1 { return conf[key], nil } nkey := strings.Join(keys[1:], ".") ckey := strings.Join(keys[0:1], "") if c, ok := conf[ckey].(map[string]interface{}); ok { return getValue(c, nkey) } else { return nil, fmt.Errorf("%s does not exsit for key %s.", conf, key) } }