ifw-daq  1.0.0
IFW Data Acquisition modules
config.cpp
Go to the documentation of this file.
1 /**
2  * @file
3  * @ingroup server
4  * @copyright ESO - European Southern Observatory
5  * @author
6  *
7  * @brief Config class source file.
8  */
9 
10 #include "config.hpp"
11 #include "dbInterface.hpp"
12 #include "logger.hpp"
13 
14 #include <rad/assert.hpp>
15 #include <rad/exceptions.hpp>
16 #include <rad/helper.hpp>
17 
18 #include <fmt/format.h>
19 #include <boost/program_options.hpp>
20 
21 #include <iostream>
22 
23 namespace bpo = boost::program_options;
24 
25 namespace server {
26 
28 : m_proc_name(CONFIG_DEFAULT_PROCNAME),
29  m_log_level(CONFIG_DEFAULT_LOGLEVEL),
30  m_log_properties(CONFIG_DEFAULT_LOG_PROPERTIES),
31  m_config_filename(CONFIG_DEFAULT_FILENAME),
32  m_scxml_filename(CONFIG_DEFAULT_SCXML_FILENAME),
33  m_db_host_endpoint(CONFIG_DEFAULT_DB_ENDPOINT),
34  m_db_timeout_sec(CONFIG_DEFAULT_DB_TIMEOUT_SEC),
35  m_req_endpoint(CONFIG_DEFAULT_REQ_ENDPOINT),
36  m_pub_endpoint(CONFIG_DEFAULT_PUB_ENDPOINT),
37  m_out_path(rad::Helper::GetEnvVar(CONFIG_ENVVAR_OUT_PATH)) {
38  RAD_TRACE(GetLogger());
39 
40  /*
41  * @todo these msgs won't be displayed until the DEBUG logLevel is applied.
42  */
43  LOG4CPLUS_DEBUG(GetLogger(), "Default - Log level: <" << m_log_level << ">");
44  LOG4CPLUS_DEBUG(GetLogger(), "Default - Log properties: <" << m_log_properties << ">");
45  LOG4CPLUS_DEBUG(GetLogger(), "Default - Configuration filename: <"
46  << m_config_filename << ">");
47  LOG4CPLUS_DEBUG(GetLogger(), "Default - DB host: <" << m_db_host_endpoint
48  << "> (timeout " << m_db_timeout_sec << " sec)");
49  LOG4CPLUS_DEBUG(GetLogger(), "Default - Requests endpoint: <" << m_req_endpoint
50  << ">");
51  LOG4CPLUS_DEBUG(GetLogger(), "Default - Publish endpoint: <" << m_pub_endpoint
52  << ">");
53 
54  /*
55  * Read environment variables.
56  */
57  std::string db_addr = rad::Helper::GetEnvVar(CONFIG_ENVVAR_DBHOST);
58  if (db_addr.size() > 0) {
59  m_db_host_endpoint = db_addr;
60  LOG4CPLUS_DEBUG(GetLogger(), "EnvVar - DB host: <" << m_db_host_endpoint << ">");
61  }
62  if (!m_out_path.empty()) {
63  LOG4CPLUS_DEBUG(GetLogger(), "EnvVar - Out path: <" << m_out_path << ">");
64  }
65 }
66 
68  RAD_TRACE(GetLogger());
69 }
70 
71 bool Config::ParseOptions(int argc, char *argv[]) {
72  RAD_TRACE(GetLogger());
73 
74  /*
75  * Define command line options.
76  */
77  bpo::options_description options_desc("Options");
78  // clang-format off
79  options_desc.add_options()
80  ("help,h", "Print help messages")
81  ("proc-name,n",
82  bpo::value<std::string>(&m_proc_name)->default_value(m_proc_name),
83  "Process name")
84  ("log-level,l",
85  bpo::value<std::string>(&m_log_level)->default_value(m_log_level),
86  "Log level: ERROR, WARNING, STATE, EVENT, ACTION, INFO, DEBUG, TRACE")
87  ("config,c",
88  bpo::value<std::string>(&m_config_filename)->default_value(m_config_filename),
89  "Configuration filename")
90  ("db-host,d",
91  bpo::value<std::string>(&m_db_host_endpoint)->default_value(m_db_host_endpoint),
92  "In-memory DB host (ipaddr:port)");
93  // clang-format on
94 
95  // Parse the options.
96  try {
97  bpo::variables_map options_map;
98  bpo::store(bpo::parse_command_line(argc, argv, options_desc),
99  options_map);
100  if (options_map.count("help")) {
101  std::cout << options_desc << std::endl;
102  return false;
103  }
104 
105  /*
106  * Throws on error, so do after help in case
107  * there are any problems.
108  */
109  bpo::notify(options_map);
110 
111  if (options_map.count("log-level")) {
112  log4cplus::LogLevelManager& log_mgr = log4cplus::getLogLevelManager();
113  log4cplus::LogLevel ll = log_mgr.fromString(m_log_level);
114  if (ll != log4cplus::NOT_SET_LOG_LEVEL) {
115  GetLogger().setLogLevel(ll);
116  LOG4CPLUS_DEBUG(GetLogger(), "CmdOpt - Log level: <" << m_log_level
117  << ">");
118  } else {
119  std::cout << options_desc << std::endl;
120  throw rad::InvalidOptionException("Invalid log level.");
121  }
122  }
123 
124  if (options_map.count("proc-name") == 0) {
125  m_proc_name = std::string(argv[0]);
126  LOG4CPLUS_DEBUG(GetLogger(), "Default - Process name: <" << m_proc_name
127  << ">");
128  } else {
129  LOG4CPLUS_DEBUG(GetLogger(), "CmdOpt - Process name: <" << m_proc_name
130  << ">");
131  }
132 
133  if (options_map.count("db-host")) {
134  LOG4CPLUS_DEBUG(GetLogger(), "CmdOpt - DB host: <" << m_db_host_endpoint
135  << ">");
136  } else {
137  LOG4CPLUS_DEBUG(GetLogger(), "Default - DB host: <" << m_db_host_endpoint
138  << ">");
139  }
140 
141  if (options_map.count("config")) {
142  LOG4CPLUS_DEBUG(GetLogger(), "CmdOpt - Configuration filename: <"
143  << m_config_filename << ">");
144  } else {
145  LOG4CPLUS_DEBUG(GetLogger(), "Default - Configuration filename: <"
146  << m_config_filename << ">");
147  }
148  } catch (bpo::error& e) {
149  std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
150  std::cerr << options_desc << std::endl;
151  throw rad::InvalidOptionException(e.what());
152  }
153 
154  return true;
155 }
156 
157 void Config::LoadConfig(const std::string& filename) {
158  RAD_TRACE(GetLogger());
159 
160  std::string config_filename = filename;
161  if (config_filename == "") {
162  config_filename = m_config_filename;
163  }
164 
165  // resolve filename
166  std::string resolved_config_filename = rad::Helper::FindFile(
167  config_filename);
168  if (resolved_config_filename.size() == 0) {
169  LOG4CPLUS_ERROR(GetLogger(), "Cannot find <" << config_filename << ">");
170  throw rad::Exception(rad::errorMsg::CFG_LOAD, resolved_config_filename);
171  }
172 
173  try {
174  m_config_node = YAML::LoadFile(resolved_config_filename);
175 
178  LOG4CPLUS_DEBUG(GetLogger(), "CfgFile - " << KEY_CONFIG_LOG_PROPERTIES
179  << " = <" << m_log_properties << ">");
180  }
181 
184  .as<std::string>();
185  if (m_req_endpoint.empty()) {
186  throw rad::Exception(rad::errorMsg::CFG_LOAD,
187  fmt::format("invalid configuration for '{}': '{}' request "
188  "endpoint must be non-empty and have a trailing "
189  "path separator '/'.", KEY_CONFIG_REQ_ENDPOINT,
190  m_req_endpoint));
191  }
192  LOG4CPLUS_DEBUG(GetLogger(), "CfgFile - " << KEY_CONFIG_REQ_ENDPOINT
193  << " = <" << m_req_endpoint << ">");
194  }
197  .as<std::string>();
198  if (m_pub_endpoint.empty()) {
199  throw rad::Exception(rad::errorMsg::CFG_LOAD,
200  fmt::format("invalid configuration for '{}': '{}' publish "
201  "endpoint must be non-empty and have a trailing "
202  "path separator '/'.", KEY_CONFIG_PUB_ENDPOINT,
203  m_pub_endpoint));
204  }
205  LOG4CPLUS_DEBUG(GetLogger(), "CfgFile - " << KEY_CONFIG_PUB_ENDPOINT
206  << " = <" << m_pub_endpoint << ">");
207  }
208 
211  .as<std::string>();
212  LOG4CPLUS_DEBUG(GetLogger(), "CfgFile - " << KEY_CONFIG_DB_ENDPOINT
213  << " = <" << m_db_host_endpoint << ">");
214  }
215 
219  LOG4CPLUS_DEBUG(GetLogger(), "CfgFile - " << KEY_CONFIG_DB_TIMEOUT_SEC
220  << " = <" << m_db_timeout_sec << "> sec");
221  }
222 
225  .as<std::string>();
226  LOG4CPLUS_DEBUG(GetLogger(), "CfgFile - " << KEY_CONFIG_SM_SCXML << " = <"
227  << m_scxml_filename << ">");
228  }
229 
232  m_config_node[KEY_CONFIG_INSTRUMENT_ID].as<std::string>();
233  LOG4CPLUS_DEBUG(GetLogger(), "CfgFile - " << KEY_CONFIG_INSTRUMENT_ID
234  << " = <" << m_instrument_id << ">");
235  } else {
236  LOG4CPLUS_ERROR(GetLogger(), "Required configuration parameter <" <<
237  KEY_CONFIG_INSTRUMENT_ID << "> missing");
238  throw rad::Exception(rad::errorMsg::CFG_LOAD, resolved_config_filename);
239  }
241  m_out_path = m_config_node[KEY_CONFIG_DATAROOT].as<std::string>();
242  LOG4CPLUS_DEBUG(GetLogger(), "Out path - " << KEY_CONFIG_DATAROOT
243  << " = <" << m_out_path << ">");
244  }
245  } catch (YAML::Exception& e) {
246  throw rad::Exception(rad::errorMsg::CFG_LOAD, resolved_config_filename);
247  }
248  RAD_ASSERT(m_config_node.IsNull() == false);
249 
250  m_config_filename = resolved_config_filename;
251  LOG4CPLUS_DEBUG(GetLogger(), "Loaded configuration file <" << m_config_filename
252  << ">");
253 }
254 
255 const std::string& Config::GetMsgReplierEndpoint() const {
256  RAD_TRACE(GetLogger());
257  return m_req_endpoint;
258 }
259 
260 const std::string& Config::GetPubEndpoint() const {
261  RAD_TRACE(GetLogger());
262  return m_pub_endpoint;
263 }
264 
265 const std::string& Config::GetDbEndpoint() const {
266  RAD_TRACE(GetLogger());
267  return m_db_host_endpoint;
268 }
269 
270 const timeval Config::GetDbTimeout() const {
271  RAD_TRACE(GetLogger());
272  timeval timeout = { m_db_timeout_sec, 0 }; // default
273  return timeout;
274 }
275 
276 const std::string& Config::GetSmScxmlFilename() const {
277  RAD_TRACE(GetLogger());
278  return m_scxml_filename;
279 }
280 
281 const std::string& Config::GetConfigFilename() const {
282  RAD_TRACE(GetLogger());
283  return m_config_filename;
284 }
285 
286 const std::string& Config::GetProcName() const {
287  RAD_TRACE(GetLogger());
288  return m_proc_name;
289 }
290 
291 const std::string& Config::GetLogLevel() const {
292  RAD_TRACE(GetLogger());
293  return m_log_level;
294 }
295 
296 const std::string& Config::GetLogProperties() const {
297  RAD_TRACE(GetLogger());
298  return m_log_properties;
299 }
300 
301 } // namespace server
server::Config::m_req_endpoint
std::string m_req_endpoint
Definition: config.hpp:137
server::CONFIG_DEFAULT_LOG_PROPERTIES
const std::string CONFIG_DEFAULT_LOG_PROPERTIES
Definition: config.hpp:25
server::Config::Config
Config()
Default constructor.
Definition: config.cpp:27
server::KEY_CONFIG_REQ_ENDPOINT
const std::string KEY_CONFIG_REQ_ENDPOINT
Definition: dbInterface.hpp:20
server::KEY_CONFIG_DATAROOT
const std::string KEY_CONFIG_DATAROOT
Definition: dbInterface.hpp:29
server::Config::m_instrument_id
std::string m_instrument_id
Definition: config.hpp:130
server::CONFIG_DEFAULT_PUB_ENDPOINT
const std::string CONFIG_DEFAULT_PUB_ENDPOINT
Definition: config.hpp:29
server::CONFIG_DEFAULT_DB_TIMEOUT_SEC
const int CONFIG_DEFAULT_DB_TIMEOUT_SEC
Definition: config.hpp:27
server::Config::LoadConfig
void LoadConfig(const std::string &filename="")
This method load from a configuration file the application configuration overriding the initializatio...
Definition: config.cpp:157
server::CONFIG_DEFAULT_LOGLEVEL
const std::string CONFIG_DEFAULT_LOGLEVEL
Definition: config.hpp:24
server::Config::m_proc_name
std::string m_proc_name
Definition: config.hpp:129
server::KEY_CONFIG_PUB_ENDPOINT
const std::string KEY_CONFIG_PUB_ENDPOINT
Definition: dbInterface.hpp:21
server::CONFIG_DEFAULT_PROCNAME
const std::string CONFIG_DEFAULT_PROCNAME
Default application configuration values.
Definition: config.hpp:21
server::Config::~Config
virtual ~Config()
Default destructor.
Definition: config.cpp:67
server::Config::m_db_host_endpoint
std::string m_db_host_endpoint
Definition: config.hpp:135
server::KEY_CONFIG_INSTRUMENT_ID
const std::string KEY_CONFIG_INSTRUMENT_ID
Definition: dbInterface.hpp:28
server::CONFIG_ENVVAR_OUT_PATH
const std::string CONFIG_ENVVAR_OUT_PATH
Definition: config.hpp:35
server::KEY_CONFIG_DB_ENDPOINT
const std::string KEY_CONFIG_DB_ENDPOINT
Definition: dbInterface.hpp:22
server::Config::m_out_path
std::string m_out_path
Definition: config.hpp:139
server::Config::GetDbEndpoint
const std::string & GetDbEndpoint() const
Definition: config.cpp:265
server::CONFIG_DEFAULT_SCXML_FILENAME
const std::string CONFIG_DEFAULT_SCXML_FILENAME
Definition: config.hpp:23
server::Config::ParseOptions
bool ParseOptions(int argc, char *argv[])
This method parses the command line parameters overriding the initialization done in the constructor.
Definition: config.cpp:71
server::Config::m_config_filename
std::string m_config_filename
Definition: config.hpp:133
server::Config::m_db_timeout_sec
int m_db_timeout_sec
Definition: config.hpp:136
server::Config::GetPubEndpoint
const std::string & GetPubEndpoint() const
Definition: config.cpp:260
server::Config::m_config_node
YAML::Node m_config_node
Disable assignment operator.
Definition: config.hpp:128
rad
Definition: ioExecutor.hpp:6
server::CONFIG_DEFAULT_REQ_ENDPOINT
const std::string CONFIG_DEFAULT_REQ_ENDPOINT
Definition: config.hpp:28
config.hpp
Config class header file.
server::Config::GetLogProperties
const std::string & GetLogProperties() const
Definition: config.cpp:296
server::Config::GetDbTimeout
const timeval GetDbTimeout() const
Definition: config.cpp:270
server::Config::GetLogLevel
const std::string & GetLogLevel() const
Definition: config.cpp:291
server::Config::m_pub_endpoint
std::string m_pub_endpoint
Definition: config.hpp:138
server::Config::GetSmScxmlFilename
const std::string & GetSmScxmlFilename() const
Definition: config.cpp:276
dbInterface.hpp
DbInterface class header file.
server::CONFIG_DEFAULT_FILENAME
const std::string CONFIG_DEFAULT_FILENAME
Definition: config.hpp:22
server::KEY_CONFIG_DB_TIMEOUT_SEC
const std::string KEY_CONFIG_DB_TIMEOUT_SEC
Definition: dbInterface.hpp:23
server::Config::m_scxml_filename
std::string m_scxml_filename
Definition: config.hpp:134
server::Config::GetConfigFilename
const std::string & GetConfigFilename() const
Definition: config.cpp:281
server::CONFIG_DEFAULT_DB_ENDPOINT
const std::string CONFIG_DEFAULT_DB_ENDPOINT
Definition: config.hpp:26
server
Definition: actionMgr.cpp:21
server::GetLogger
log4cplus::Logger & GetLogger()
Definition: logger.cpp:14
logger.hpp
Default logger name.
server::Config::GetMsgReplierEndpoint
const std::string & GetMsgReplierEndpoint() const
Definition: config.cpp:255
server::Config::m_log_properties
std::string m_log_properties
Definition: config.hpp:132
server::KEY_CONFIG_LOG_PROPERTIES
const std::string KEY_CONFIG_LOG_PROPERTIES
Definition: dbInterface.hpp:27
server::Config::GetProcName
const std::string & GetProcName() const
Definition: config.cpp:286
server::Config::m_log_level
std::string m_log_level
Definition: config.hpp:131
server::KEY_CONFIG_SM_SCXML
const std::string KEY_CONFIG_SM_SCXML
Definition: dbInterface.hpp:24
server::CONFIG_ENVVAR_DBHOST
const std::string CONFIG_ENVVAR_DBHOST
Application configuration environment variables.
Definition: config.hpp:34