PhoenixSwarm  3.5.0
Library to ease communication between daemons
Loading...
Searching...
No Matches
daemon_load_config.cpp
Go to the documentation of this file.
1/***************************************
2 Auteur : Pierre Aubert
3 Mail : pierre.aubert@lapp.in2p3.fr
4 Licence : CeCILL-C
5****************************************/
6
7#include "parser_json.h"
8#include "parser_toml.h"
9#include "parser_yml.h"
10#include "daemon_load_config.h"
12#include <sstream>
13
15
21void daemon_load_config(PLog & log, ConfigNode & dico, const PString & inputConfig, ConfigFormat::ConfigFormat format){
22 if(format == ConfigFormat::JSON){
23 if(!parser_jsonString(dico, inputConfig)){
24 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load config from input string");
25 }
26 }else if(format == ConfigFormat::TOML){
27 if(!parser_tomlString(dico, inputConfig)){
28 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load config from input string");
29 }
30 }else if(format == ConfigFormat::YAML){
31 if(!parser_ymlString(dico, inputConfig)){
32 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load config from input string");
33 }
34 }else{
35 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "unknown format '"+std::to_string(static_cast<int>(format))+"' of config");
36 }
37}
38
40
45void daemon_load_config(PLog & log, ConfigNode & dico, const PPath & configFile){
46 PString extension = configFile.getExtension();
47 if(extension == "toml"){
48 if(!parser_toml(dico, configFile)){
49 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load toml file '"+configFile+"'");
50 }
51 }else if(extension == "yml"){
52 if(!parser_yml(dico, configFile)){
53 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load yml file '"+configFile+"'");
54 }
55 }else if(extension == "json"){
56 if(!parser_json(dico, configFile)){
57 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "cannot load json file '"+configFile+"'");
58 }
59 }else{
60 log.criticalAndThrow<Phoenix::ParserException>("daemon_load_config", "unknown extension '"+extension+"' of config file '"+configFile+"'");
61 }
62}
63
65
69PString daemon_loadString(const ConfigNode & dico, const PString & attributeName){
70 return phoenix_get_string(dico, attributeName, "unnamed_daemon").eraseFirstLastChar("\"'\t\n ");
71// return phoenix_load_value_from_config<PString>(dico, attributeName, "unnamed_daemon").eraseFirstLastChar("\"'\t\n ");
72}
73
74
81void set_daemon_config_from_node(DaemonConfig & config, PLog & log, MapTimeout & mapTimeout, const ConfigNode & nodeDict, bool throwOnError)
82{
83 config.setName(daemon_loadString(nodeDict, "name"));
84 config.setDescription(daemon_loadString(nodeDict, "description"));
85 config.setHostName(PString(phoenix_get_string(nodeDict, "hostname", "localhost")).eraseFirstLastChar("\"'\t\n "));
86 config.setReceivingPort(phoenix_get_value<size_t>(nodeDict, "receiving_port", -1lu));
87 config.setStatNbBin(phoenix_get_value<size_t>(nodeDict, "stat_nb_bin", 100lu));
88 config.setStatHistLowerBound(phoenix_get_value<float>(nodeDict, "stat_hist_lower_bound", 0.f));
89 config.setStatHistUpperBound(phoenix_get_value<float>(nodeDict, "stat_hist_upper_bound", 100.f));
90 config.setStatTimerPeriodMs(phoenix_get_value<time_t>(nodeDict, "stat_timer_period", 1000lu));
91 //Add the timeout of current config to global daemon config
92 mapTimeout[config.getName()] = phoenix_get_value<size_t>(nodeDict, "daemon_required_response_timeout", 1000lu);
93 if(config.getReceivingPort() >= 65536lu){
94 std::string errorString("BaseDaemon::set_daemon_config_from_node : 'receiving_port' of Daemon '"+config.getName()+"' has invalid value '"+std::to_string(config.getReceivingPort())+"'");
95 if(throwOnError){
96 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::set_daemon_config_from_node", errorString);
97 }else{
98 log.getLogError() << errorString << std::endl;
99 }
100 }
101}
102
103
105
114void daemon_read_configNode(DaemonConfig & daemonConfig, MapDaemonConfig & mapDaemon,
115 PLog & log, MapTimeout & mapTimeout, const ConfigNode *& extraConfigParam, const ConfigNode & dico, const PString & daemonName)
116{
117 const ConfigNode * mapBaseDaemon = dico.getChild("daemon");
118 if(mapBaseDaemon == nullptr){
119 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::daemon_read_configNode" , "Config doesn't contain a 'daemon' section'");
120 }
121
122 bool foundDaemonName(false);
123 const VecConfigNode & vecBaseDaemon = mapBaseDaemon->getVecChild();
124 //Make a first pass to load the current daemon to set the logger as soon as possible
125 for(VecConfigNode::const_iterator it(vecBaseDaemon.begin()); it != vecBaseDaemon.end() && !foundDaemonName; ++it){
126 if(daemon_loadString(**it, "name") == daemonName){
127 log.getLogInfo() << "BaseDaemon::daemon_read_configNode : configuration of current Daemon '"<<daemonName<<"' found" << std::endl;
128 //Set logger
129 log.setFileName(daemon_loadString(**it, "log_file"));
130 log.setLogLevel(phoenix_strToLogLevel(phoenix_get_string(**it, "log_level", "WARNING").eraseFirstLastChar("\"'\t\n ")));
131 if(!log.open()){
132 if(log.getMode() == PLog::FILE_ONLY || log.getMode() == PLog::FILE_CAPTURE_STDOUT_STDERR){
133 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::daemon_read_configNode", "cannot open log file'"+log.getFileName()+"' of current daemon '"+daemonName+"' but log mode requires it.");
134 }else{
135 std::cerr << "BaseDaemon::daemon_read_configNode : cannot open log file '"<<log.getFileName()<<"' of current daemon '"<<daemonName<<"'"<<std::endl;
136 }
137 }
138 set_daemon_config_from_node(daemonConfig, log, mapTimeout, **it, true);
139 //Extra-parameters of current daemon
140 extraConfigParam = (*it)->getChild("extra_parameter");
141 log.getLogInfo() << "BaseDaemon::daemon_read_configNode : Daemon '"<<daemonName<<"' on host '"<<daemonConfig.getHostName()<<"' and port "<<std::to_string(daemonConfig.getReceivingPort())<<" is configured !"<<std::endl;
142 foundDaemonName = true;
143 }
144 }
145 if(!foundDaemonName){
146 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::daemon_read_configNode", "current daemon '"+daemonName+"' not found!");
147 }
148 //Make second pass to load the other daemons, checking for duplicates definitions
149 std::map<PString, PLocation> daemon_config_location;
150 for(VecConfigNode::const_iterator it(vecBaseDaemon.begin()); it != vecBaseDaemon.end(); ++it){
151 DaemonConfig config;
152 config.setName(daemon_loadString(**it, "name"));
153 //Check for duplicates
154 std::map<PString, PLocation>::iterator daemon_config_location_iter = daemon_config_location.find(config.getName());
155 if(daemon_config_location_iter != daemon_config_location.end()){
156 std::stringstream errorStringStream;
157 errorStringStream << "BaseDaemon::daemon_read_configNode : Current daemon '" << daemonName << "' defined twice,"
158 << " first at " << daemon_config_location_iter->second
159 << " then at " << (*it)->getLocation();
160 if(config.getName() == daemonName){
161 log.criticalAndThrow<Phoenix::ConfigException>("BaseDaemon::daemon_read_configNode", errorStringStream.str());
162 }else{
163 log.getLogWarning() << errorStringStream.str() << std::endl;
164 }
165 }else{
166 daemon_config_location[config.getName()] = (*it)->getLocation();
167 }
168 if(config.getName() != daemonName){
169 set_daemon_config_from_node(config, log, mapTimeout, **it, false);
170 mapDaemon[config.getName()] = config;
171 log.getLogInfo() << "BaseDaemon::daemon_read_configNode : contact daemon '"<<config.getName()<<"' on host '"<<config.getHostName()<<"' and port "<<std::to_string(config.getReceivingPort())<<" loaded!"<<std::endl;
172 }
173 }
174}
175
Describe a Daemon of the Swarm.
const PString & getName() const
Gets the name of the DaemonConfig.
void setDescription(const PString &description)
Sets the description of the DaemonConfig.
void setStatHistLowerBound(float statHistLowerBound)
Sets the statHistLowerBound of the DaemonConfig.
void setStatHistUpperBound(float statHistUpperBound)
Sets the statHistUpperBound of the DaemonConfig.
void setReceivingPort(size_t receivingPort)
Sets the receivingPort of the DaemonConfig.
void setName(const PString &name)
Sets the name of the DaemonConfig.
const PString & getHostName() const
Gets the hostName of the DaemonConfig.
size_t getReceivingPort() const
Gets the receivingPort of the DaemonConfig.
void setHostName(const PString &hostName)
Sets the hostName of the DaemonConfig.
void setStatTimerPeriodMs(const time_t &statTimerPeriodMs)
Sets the statTimerPeriodMs of the DaemonConfig.
void setStatNbBin(size_t statNbBin)
Sets the statNbBin of the DaemonConfig.
Exception for daemon configuration errors.
Exception for configuration errors.
PString daemon_loadString(const ConfigNode &dico, const PString &attributeName)
Load a string value.
void set_daemon_config_from_node(DaemonConfig &config, PLog &log, MapTimeout &mapTimeout, const ConfigNode &nodeDict, bool throwOnError)
void daemon_load_config(PLog &log, ConfigNode &dico, const PString &inputConfig, ConfigFormat::ConfigFormat format)
Load the daemon config into a ConfigNode from a json string.
void daemon_read_configNode(DaemonConfig &daemonConfig, MapDaemonConfig &mapDaemon, PLog &log, MapTimeout &mapTimeout, const ConfigNode *&extraConfigParam, const ConfigNode &dico, const PString &daemonName)
Read the ConfigNode to initialise current Daemon.
ConfigFormat
Type of the Message which can be exchanged by Daemon.
std::map< PString, time_t > MapTimeout
std::map< PString, DaemonConfig > MapDaemonConfig