...

Source file src/discovery/config/configuration.go

Documentation: discovery/config

     1  /*
     2   * P2PFaaS - A framework for FaaS Load Balancing
     3   * Copyright (c) 2019. Gabriele Proietti Mattia <pm.gabriele@outlook.com>
     4   *
     5   * This program is free software: you can redistribute it and/or modify
     6   * it under the terms of the GNU General Public License as published by
     7   * the Free Software Foundation, either version 3 of the License, or
     8   * (at your option) any later version.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
    17   */
    18  
    19  package config
    20  
    21  import (
    22  	"discovery/log"
    23  	"discovery/utils"
    24  	"encoding/json"
    25  	"fmt"
    26  	"io/ioutil"
    27  	"os"
    28  	"strconv"
    29  )
    30  
    31  type ConfigurationStatic struct {
    32  	PollTime                          uint   `json:"poll_time" bson:"poll_time"`
    33  	DataPath                          string `json:"data_path" bson:"data_path"`
    34  	ListeningHost                     string `json:"listening_host" bson:"listening_host"`
    35  	ListeningPort                     uint   `json:"listening_port" bson:"listening_port"`
    36  	PollTimeout                       uint   `json:"poll_timeout" bson:"poll_timeout"`
    37  	MachineDeadPollsRemovingThreshold uint   `json:"machine_dead_polls_removing_threshold" bson:"machine_dead_polls_removing_threshold"`
    38  	RunningEnvironment                string `json:"running_environment" bson:"running_environment"`
    39  	DefaultIface                      string `json:"default_iface" bson:"default_iface"`
    40  }
    41  
    42  type ConfigurationDynamic struct {
    43  	MachineIp        string   `json:"machine_ip" bson:"machine_ip"`
    44  	MachineId        string   `json:"machine_id" bson:"machine_id"`
    45  	MachineGroupName string   `json:"machine_group_name" bson:"machine_group_name"`
    46  	InitServers      []string `json:"init_servers" bson:"init_servers"`
    47  }
    48  
    49  /*
    50   * Sample configuration file
    51   *
    52   * {
    53   *   "machine_ip": "192.168.99.102",
    54   *   "machine_id": "p2pfogc2n0",
    55   *   "init_servers": ["192.168.99.100"]
    56   * }
    57   *
    58   */
    59  
    60  type ConfigError struct{}
    61  
    62  func (ConfigError) Error() string {
    63  	return "Configuration Error"
    64  }
    65  
    66  /*
    67   * Inits
    68   */
    69  
    70  func InitConfigurationStatic() {
    71  	configurationStatic = GetDefaultConfigurationStatic()
    72  
    73  	if envVar := os.Getenv(EnvRunningEnvironment); envVar != "" {
    74  		if envVar == RunningEnvironmentProduction || envVar == RunningEnvironmentDevelopment {
    75  			configurationStatic.RunningEnvironment = envVar
    76  		}
    77  	}
    78  
    79  	if envVar := os.Getenv(EnvDataPath); envVar != "" {
    80  		configurationStatic.DataPath = envVar
    81  	}
    82  
    83  	if envVar := os.Getenv(EnvListeningHost); envVar != "" {
    84  		configurationStatic.ListeningHost = envVar
    85  	}
    86  
    87  	if envVar := os.Getenv(EnvListeningPort); envVar != "" {
    88  		listPort, err := strconv.Atoi(envVar)
    89  		if err == nil && listPort > 0 {
    90  			configurationStatic.ListeningPort = uint(listPort)
    91  		}
    92  	}
    93  
    94  	if envVar := os.Getenv(EnvPollTime); envVar != "" {
    95  		listPort, err := strconv.Atoi(envVar)
    96  		if err == nil && listPort > 0 {
    97  			configurationStatic.PollTime = uint(listPort)
    98  		}
    99  	}
   100  
   101  	if envVar := os.Getenv(EnvPollTimeout); envVar != "" {
   102  		listPort, err := strconv.Atoi(envVar)
   103  		if err == nil && listPort > 0 {
   104  			configurationStatic.PollTime = uint(listPort)
   105  		}
   106  	}
   107  
   108  	// if envVar := os.Getenv(EnvInitServers); envVar != "" {
   109  	//	configurationStatic.InitServers = strings.Split(envVar, ",")
   110  	//}
   111  
   112  	if envVar := os.Getenv(EnvDefaultIface); envVar != "" {
   113  		configurationStatic.DefaultIface = envVar
   114  	}
   115  
   116  	if envVar := os.Getenv(EnvMachineDeadPollsRemovingThreshold); envVar != "" {
   117  		listPort, err := strconv.Atoi(envVar)
   118  		if err == nil && listPort > 0 {
   119  			configurationStatic.MachineDeadPollsRemovingThreshold = uint(listPort)
   120  		}
   121  	}
   122  }
   123  
   124  // InitConfigurationDynamic prepare the configuration object, returns if config is read from file
   125  func InitConfigurationDynamic() {
   126  	configurationDynamic = GetDefaultConfigurationDynamic()
   127  
   128  	// try to read the dynamic from file
   129  	newConf, err := ReadConfigurationDynamicFromFile()
   130  	if err == nil {
   131  		configurationDynamic = newConf
   132  		configurationDynamicReadFromFile = true
   133  	}
   134  
   135  	if !configurationDynamicReadFromFile {
   136  		err = SaveConfigurationDynamicToConfigFile()
   137  		if err != nil {
   138  			log.Log.Errorf("Cannot save configuration dynamic to file %s", GetConfigurationDynamicFilePath())
   139  		}
   140  	}
   141  }
   142  
   143  /*
   144   * Getters
   145   */
   146  
   147  func GetMachineIp() string {
   148  	return configurationDynamic.MachineIp
   149  }
   150  func GetMachineId() string {
   151  	return configurationDynamic.MachineIp
   152  }
   153  func GetMachineGroupName() string {
   154  	return configurationDynamic.MachineGroupName
   155  }
   156  func GetDataPath() string {
   157  	return configurationStatic.DataPath
   158  }
   159  func GetInitServers() []string {
   160  	return configurationDynamic.InitServers
   161  }
   162  func GetPollTime() uint {
   163  	return configurationStatic.PollTime
   164  }
   165  func GetListeningPort() uint {
   166  	return configurationStatic.ListeningPort
   167  }
   168  func GetListeningHost() string {
   169  	return configurationStatic.ListeningHost
   170  }
   171  func GetPollTimeout() uint {
   172  	return configurationStatic.PollTimeout
   173  }
   174  func GetMachineDeadPollsRemovingThreshold() uint {
   175  	return configurationStatic.MachineDeadPollsRemovingThreshold
   176  }
   177  func GetRunningEnvironment() string {
   178  	return configurationStatic.RunningEnvironment
   179  }
   180  func GetDefaultIface() string {
   181  	return configurationStatic.DefaultIface
   182  }
   183  
   184  func GetConfigurationDynamicCopy() *ConfigurationDynamic {
   185  	copiedConf := *configurationDynamic
   186  
   187  	return &copiedConf
   188  }
   189  
   190  func GetConfigurationStaticString() string {
   191  	confBytes, err := json.Marshal(configurationStatic)
   192  	if err != nil {
   193  		return ""
   194  	}
   195  
   196  	return string(confBytes)
   197  }
   198  
   199  /*
   200   * Setters
   201   */
   202  
   203  func SetMachineIp(ip string) {
   204  	configurationDynamic.MachineIp = ip
   205  }
   206  func SetMachineId(id string) {
   207  	configurationDynamic.MachineId = id
   208  }
   209  func SetMachineFogNetId(id string) {
   210  	configurationDynamic.MachineGroupName = id
   211  }
   212  func SetInitServers(servers []string) {
   213  	configurationDynamic.InitServers = servers
   214  }
   215  
   216  /*
   217   * Utils
   218   */
   219  
   220  func ReadConfigurationDynamicFromFile() (*ConfigurationDynamic, error) {
   221  	conf := GetDefaultConfigurationDynamic()
   222  
   223  	file, err := ioutil.ReadFile(GetConfigurationDynamicFilePath())
   224  	if err != nil {
   225  		log.Log.Info("Cannot read configuration file at %s", GetConfigurationDynamicFilePath())
   226  		return nil, err
   227  	} else {
   228  		err = json.Unmarshal(file, conf)
   229  		if err != nil {
   230  			log.Log.Errorf("Cannot decode configuration file, maybe not valid json: %s", err.Error())
   231  			return nil, err
   232  		}
   233  	}
   234  
   235  	// check fields
   236  	if conf.MachineId == "" || conf.MachineIp == "" {
   237  		log.Log.Warningf("Configuration file does not contain MachineId or MachineIp. Will try to get ip from \"%s\"", GetDefaultIface())
   238  		// get ip from machine
   239  		ip, err := utils.GetInternalIP(GetDefaultIface())
   240  		if err != nil {
   241  			return conf, nil
   242  		}
   243  		conf.MachineIp = ip
   244  		// generate machine id
   245  		conf.MachineId = fmt.Sprintf("p2pfaas-%s", conf.MachineIp)
   246  		log.Log.Infof("Got from machine ip: %s and id: %s", conf.MachineIp, conf.MachineId)
   247  	}
   248  
   249  	return conf, nil
   250  }
   251  
   252  func GetDefaultConfigurationStatic() *ConfigurationStatic {
   253  	conf := &ConfigurationStatic{
   254  		PollTime:                          DefaultPollTime,
   255  		DataPath:                          DefaultDataPath,
   256  		ListeningHost:                     DefaultListeningHost,
   257  		ListeningPort:                     DefaultListeningPort,
   258  		PollTimeout:                       DefaultPollTimeoutTime,
   259  		MachineDeadPollsRemovingThreshold: DefaultMachineDeadPollsRemovingThreshold,
   260  		DefaultIface:                      DefaultIfaceName,
   261  		RunningEnvironment:                os.Getenv(EnvRunningEnvironment),
   262  	}
   263  	return conf
   264  }
   265  
   266  func GetDefaultConfigurationDynamic() *ConfigurationDynamic {
   267  	conf := &ConfigurationDynamic{
   268  		InitServers:      []string{},
   269  		MachineIp:        "",
   270  		MachineId:        "",
   271  		MachineGroupName: "",
   272  	}
   273  	return conf
   274  }
   275  

View as plain text