rad 8.2.0
Loading...
Searching...
No Matches
config.hpp
Go to the documentation of this file.
1
9#ifndef RAD_CONFIG_HPP
10#define RAD_CONFIG_HPP
11
12#include <rad/logger.hpp>
13#include <rad/assert.hpp>
14#include <rad/exceptions.hpp>
15
16#include <config-ng/ciiConfigApi.hpp>
17
18#include <boost/program_options.hpp>
19#include <boost/algorithm/string.hpp>
20
21#include <string>
22#include <memory>
23#include <optional>
24#include <vector>
25
26namespace bpo = boost::program_options;
27
28namespace rad {
29
31//const char CONFIG_KEY_SEPARATOR_CFG = '.';
32//const std::string CONFIG_DEFAULT_ROOT_NODE = "cfg";
33
37const std::string KEY_CONFIG = "cfg/";
38const std::string KEY_CONFIG_VERSION = KEY_CONFIG + "version";
39const std::string KEY_CONFIG_MODNAME = KEY_CONFIG + "modname";
40const std::string KEY_CONFIG_PROCNAME = KEY_CONFIG + "procname";
41const std::string KEY_CONFIG_FILENAME = KEY_CONFIG + "filename";
42const std::string KEY_CONFIG_LOG_LEVEL = KEY_CONFIG + "log_level";
43const std::string KEY_CONFIG_LOG_PROPERTIES = KEY_CONFIG + "log_properties";
44const std::string KEY_CONFIG_SM_SCXML = KEY_CONFIG + "sm_scxml";
45const std::string KEY_CONFIG_SM_APPEND = KEY_CONFIG + "sm_scxml_append";
46const std::string KEY_CONFIG_REQ_ENDPOINT = KEY_CONFIG + "req_endpoint";
47const std::string KEY_CONFIG_OLDB_URI_PREFIX = KEY_CONFIG + "oldb_uri_prefix";
48const std::string KEY_CONFIG_OLDB_CONN_TIMEOUT = KEY_CONFIG + "oldb_conn_timeout";
49const std::string KEY_CONFIG_OLDB_ASYNC_PERIOD = KEY_CONFIG + "oldb_async_period";
50const std::string KEY_CONFIG_TRS_HEALTH_ENABLED = KEY_CONFIG + "trs_health_enabled";
51const std::string KEY_CONFIG_TRS_PROTOCOL = KEY_CONFIG + "trs_protocol";
52const std::string KEY_CONFIG_TRS_SOCKET_PATH = KEY_CONFIG + "trs_socket_path";
53const std::string KEY_CONFIG_DDS_QOS_PROFILE = KEY_CONFIG + "dds_qos_profile";
54const std::string KEY_CONFIG_DDS_QOS_PARTICIPANT = KEY_CONFIG + "dds_qos_participant";
55const std::string KEY_CONFIG_DDS_QOS_INTERFACES = KEY_CONFIG + "dds_qos_interfaces";
56
77
78
83class Config {
84 public:
95 explicit Config(const std::string& name = LOGGER_NAME,
96 const std::string& log_level = "ERROR");
97
106 Config(const Config& cfg);
107
111 virtual ~Config();
112
122 Config& operator=(const Config& cfg);
123
128 inline const elt::configng::CiiConfigDocument& GetConfigDoc() const { return *m_config_doc; }
129
133 inline bpo::options_description& GetOptionsDesc() { return m_options_desc; }
134
138 inline bpo::variables_map& GetOptionsMap() { return m_options_map; }
139
143 inline const std::string& GetOldbPrefixAppenderKey() { return m_oldb_prefix_appender_key; }
144
152 inline void SetOldbPrefixAppenderKey(const std::string& key) {
153 m_oldb_prefix_appender_key = key;
154 }
155
161 std::string BuildOldbPrefix();
162
171 virtual bool ParseOptions(int argc, char* argv[]);
172
181 virtual void LoadConfig(const std::string& filename = "");
182
192 virtual void ConfigureLogging(const std::string& filename = "");
193
198 virtual void ApplyCmdLineOptions();
199
209 void CheckConfig() const;
210
223 virtual void ValidateConfig(const std::vector<std::string>& keys,
224 const Config& cfg) const;
225
233 void MergeConfig(const elt::configng::CiiConfigDocument& cfg_doc);
234
241 void CreateDefaultConfig(const std::string& default_cfg);
242
250 template<typename T>
251 void AddParam(const std::string& key, const T& value);
252
259 bool HasParam(const std::string& key) const;
260
267 template<typename T>
268 T GetParam(const std::string& key) const;
269
276 template<typename T>
277 void SetParam(const std::string& key, const T& value);
278
284 const std::string GetConfigAsString() const;
285
297 std::vector<std::string> SetConfigAsString(const std::string& config);
298
303 std::string PrintNode(const elt::configng::CiiConfigInstanceNode& node,
304 const std::string& indentation) const;
305
313 std::string Print(const elt::configng::CiiConfigInstanceNamespace& instances) const;
314
320 std::string Print() const;
321
322 private:
332 bool SplitKeyValue(const std::string& keyval, std::string& key, std::string& value) const;
333
343 void SplitVectorStr(const std::string& vector_str, std::string& vector_name,
344 int& vector_index) const;
345
346 bpo::options_description m_options_desc;
347 bpo::variables_map m_options_map;
348 std::string m_name;
349
350 /*
351 * Key to be used to build the OLDB prefix:
352 * - If m_oldb_prefix_appender_key is an empty string, the OLDB prefix will
353 * be only the value associated with the KEY_CONFIG_OLDB_URI_PREFIX key.
354 * - Otherwise m_oldb_prefix_appender_key can be set to be the key of a
355 * configuration parameter used to OLDB prefix (see BuildOldbPrefix() method).
356 * For example, m_oldb_prefix_appender_key could be KEY_CONFIG_MODNAME or
357 * KEY_CONFIG_PROCNAME. The latter case is useful when several instances of the
358 * same application is started (e.g. two instances of the m2m3WhCtr can be started:
359 * one to control the WH of M2 and one of M3).
360 * To preserve backward compatibility, this attribute should be initialized to
361 * KEY_CONFIG_MODNAME.
362 */
363 std::string m_oldb_prefix_appender_key;
364
365 /*
366 * We need to declare CiiConfigDocument as pointer since it logs info
367 * in the constructor and therefore uses [CII] logging before it has
368 * been properly configured.
369 */
370 std::optional<elt::configng::CiiConfigDocument> m_config_doc;
371};
372
373
374template<typename T>
375void Config::AddParam(const std::string& key, const T& value) {
377
378 std::vector<std::string> nodes;
379 std::string delim(1, CONFIG_KEY_SEPARATOR_OLDB);
380 boost::split(nodes, key, boost::is_any_of(delim));
381 if (nodes.size() < 2) {
382 RAD_LOG_THROW(rad::Exception, GetLogger(), "Key " + key +
383 " has no root/leaf node(s).");
384 }
385
386 /*
387 builder["three"] = elt::configng::CiiConfigInstanceNode::From(3);
388 builder["vector"] = elt::configng::CiiConfigInstanceNode::From(std::vector<int>{1,2,3,4,5,6},
389 "!cfg.type:vector_int32");
390 builder["map"]["d"] = elt::configng::CiiConfigInstanceNode::From(4);
391 builder["map"]["e"] = elt::configng::CiiConfigInstanceNode::From("text");
392 builder["map"]["f"] = elt::configng::CiiConfigInstanceNode::From(false, "!cfg.type:boolean");
393 */
394 elt::configng::CiiConfigMapBuilder builder;
395
396 auto curr_node = builder[nodes[0]];
397 size_t index = 1;
398 while (index < nodes.size()) {
399 //std::string child_node_name = nodes[index];
400 curr_node = curr_node[nodes[index]];
401 if (index + 1 == nodes.size()) {
402 //child_node.As<T>();
403 curr_node = elt::configng::CiiConfigInstanceNode::From(value);
404 }
405 index++;
406 }
407
408 if (!m_config_doc) {
409 m_config_doc = elt::configng::CiiConfigDocument();
410 m_config_doc->SetInstancesFromMap(builder);
411 } else {
412 auto document = elt::configng::CiiConfigDocument();
413 document.SetInstancesFromMap(builder);
414 MergeConfig(document);
415 }
416
417 auto issues = m_config_doc->Check();
418 if (issues.HasErrors() || issues.HasWarnings()) {
419 for (auto& issue : issues) {
420 LOG4CPLUS_ERROR(GetLogger(), "Config. issue: " << issue.GetMessage());
421 //std::cout << issue << std::endl;
422 }
423 RAD_LOG_THROW(rad::Exception, GetLogger(), "Error/warning while adding key " + key);
424 }
425}
426
427template<typename T>
428T Config::GetParam(const std::string& key) const {
430
431 if (!m_config_doc) {
432 RAD_LOG_THROW(rad::Exception, GetLogger(), "No configuration available.");
433 }
434
435 try {
436 std::vector<std::string> nodes;
437 std::string delim(1, CONFIG_KEY_SEPARATOR_OLDB);
438 boost::split(nodes, key, boost::is_any_of(delim));
439 if (nodes.size() < 2) {
440 RAD_LOG_THROW(rad::Exception, GetLogger(), "Key " + key +
441 " has no root/leaf node(s).");
442 }
443
444 auto instance = m_config_doc->Instances();
445 auto parent_node = instance[nodes[0]];
446 auto child_node = parent_node;
447 size_t index = 1;
448 while (index < nodes.size()) {
449 std::string child_node_name = nodes[index];
450
451 // check for arrays
452 int vector_index = -1;
453 SplitVectorStr(nodes[index], child_node_name, vector_index);
454 //std::cout << "Child node name: " << child_node_name << std::endl;
455
456 // check for sub-node or leaf-node.
457 if (parent_node.Has(child_node_name)) {
458 if (vector_index == -1) {
459 child_node = parent_node[child_node_name];
460 } else {
461 child_node = parent_node[child_node_name][vector_index];
462 }
463 if (index + 1 == nodes.size()) {
464 T val = child_node.As<T>();
465 return val;
466 }
467 parent_node = child_node;
468 } else {
469 RAD_LOG_THROW(rad::Exception, GetLogger(), "Configuration parameter " +
470 key + " does not exists.");
471 }
472 index++;
473 }
474 RAD_LOG_THROW(rad::Exception, GetLogger(), "Configuration parameter " +
475 key + " does not exists.");
476 } catch (std::exception& e) {
477 RAD_LOG_THROW(rad::Exception, GetLogger(), "Reading configuration parameter <" +
478 key + ">: " + std::string(e.what()));
479 }
480}
481
482template<typename T>
483void Config::SetParam(const std::string& key, const T& value) {
485
486 if (!m_config_doc) {
487 RAD_LOG_THROW(rad::Exception, GetLogger(), "No configuration available.");
488 }
489
490 try {
491 std::vector<std::string> nodes;
492 std::string delim(1, CONFIG_KEY_SEPARATOR_OLDB);
493 boost::split(nodes, key, boost::is_any_of(delim));
494 if (nodes.size() < 2) {
495 RAD_LOG_THROW(rad::Exception, GetLogger(), "Key " + key +
496 " has no root/leaf node(s).");
497 }
498
499 auto instance = m_config_doc->Instances();
500 auto parent_node = instance[nodes[0]];
501 auto child_node = parent_node;
502 size_t index = 1;
503 while (index < nodes.size()) {
504 std::string child_node_name = nodes[index];
505
506 // check for arrays
507 int vector_index = -1;
508 SplitVectorStr(nodes[index], child_node_name, vector_index);
509
510 // check for sub-node or leaf-node.
511 if (parent_node.Has(child_node_name)) {
512 if (vector_index == -1) {
513 child_node = parent_node[child_node_name];
514 } else {
515 child_node = parent_node[child_node_name][vector_index];
516 }
517 if (index + 1 == nodes.size()) {
518 child_node = value;
519 return;
520 }
521 parent_node = child_node;
522 } else {
523 RAD_LOG_THROW(rad::Exception, GetLogger(), "Configuration parameter " +
524 key + " does not exists.");
525 }
526 index++;
527 }
528 RAD_LOG_THROW(rad::Exception, GetLogger(), "Configuration parameter " +
529 key + " does not exists.");
530 } catch (std::exception& e) {
531 LOG4CPLUS_ERROR(GetLogger(), "Writing configuration parameter <"
532 << key << ">: " << e.what());
533 }
534}
535
543void GetListOfKeysFromConfig(const elt::configng::CiiConfigInstanceNode& node,
544 const std::string& prefix,
545 std::vector<std::string>& keys);
546
553std::vector<std::string> GetListOfKeysFromConfig(const elt::configng::CiiConfigDocument& cfg_doc);
554
555} // namespace rad
556
557#endif // RAD_CONFIG_HPP
Assert header file.
Definition config.hpp:83
void AddParam(const std::string &key, const T &value)
Definition config.hpp:375
bpo::variables_map & GetOptionsMap()
Definition config.hpp:138
void SetParam(const std::string &key, const T &value)
Definition config.hpp:483
void CheckConfig() const
Definition config.cpp:304
Config(const std::string &name=LOGGER_NAME, const std::string &log_level="ERROR")
Definition config.cpp:23
const std::string & GetOldbPrefixAppenderKey()
Definition config.hpp:143
std::vector< std::string > SetConfigAsString(const std::string &config)
Definition config.cpp:471
std::string BuildOldbPrefix()
Definition config.cpp:640
bpo::options_description & GetOptionsDesc()
Definition config.hpp:133
Config & operator=(const Config &cfg)
Definition config.cpp:91
const std::string GetConfigAsString() const
Definition config.cpp:448
void CreateDefaultConfig(const std::string &default_cfg)
Definition config.cpp:389
T GetParam(const std::string &key) const
Definition config.hpp:428
virtual void ConfigureLogging(const std::string &filename="")
Definition config.cpp:240
virtual ~Config()
Definition config.cpp:86
void SetOldbPrefixAppenderKey(const std::string &key)
Definition config.hpp:152
virtual void LoadConfig(const std::string &filename="")
Definition config.cpp:195
std::string PrintNode(const elt::configng::CiiConfigInstanceNode &node, const std::string &indentation) const
Definition config.cpp:542
virtual bool ParseOptions(int argc, char *argv[])
Definition config.cpp:114
void MergeConfig(const elt::configng::CiiConfigDocument &cfg_doc)
Definition config.cpp:371
virtual void ApplyCmdLineOptions()
Definition config.cpp:272
bool HasParam(const std::string &key) const
Definition config.cpp:397
const elt::configng::CiiConfigDocument & GetConfigDoc() const
Definition config.hpp:128
std::string Print() const
Definition config.cpp:590
virtual void ValidateConfig(const std::vector< std::string > &keys, const Config &cfg) const
Definition config.cpp:324
Base class for the exceptions thrown by RAD and its users.
Definition exceptions.hpp:53
Logger class.
#define RAD_TRACE(logger)
Definition logger.hpp:21
Exception classes header file.
#define RAD_LOG_THROW(exceptionType_t, logger, msg)
Throw exception with information about the throw location.
Definition exceptions.hpp:356
Definition actionsApp.cpp:67
const std::string KEY_CONFIG_PROCNAME
Definition config.hpp:40
const std::string KEY_CONFIG_VERSION
Definition config.hpp:38
const std::string LOGGER_NAME
Definition logger.hpp:76
const std::string KEY_CONFIG_TRS_PROTOCOL
Definition config.hpp:51
void GetListOfKeysFromConfig(const elt::configng::CiiConfigInstanceNode &node, const std::string &prefix, std::vector< std::string > &keys)
Definition config.cpp:650
const std::string KEY_CONFIG_SM_APPEND
Definition config.hpp:45
const std::string KEY_CONFIG_FILENAME
Definition config.hpp:41
log4cplus::Logger & GetLogger()
Definition logger.cpp:72
const char CONFIG_KEY_SEPARATOR_OLDB
Definition config.hpp:30
const std::string KEY_CONFIG_SM_SCXML
Definition config.hpp:44
const std::string KEY_CONFIG_DDS_QOS_PARTICIPANT
Definition config.hpp:54
const std::string KEY_CONFIG_OLDB_ASYNC_PERIOD
Definition config.hpp:49
const std::string KEY_CONFIG_TRS_HEALTH_ENABLED
Definition config.hpp:50
const std::string KEY_CONFIG_LOG_LEVEL
Definition config.hpp:42
const std::vector< std::string > KEYS_CONFIG
Definition config.hpp:57
const std::string KEY_CONFIG_OLDB_CONN_TIMEOUT
Definition config.hpp:48
const std::string KEY_CONFIG
Definition config.hpp:37
const std::string KEY_CONFIG_MODNAME
Definition config.hpp:39
const std::string KEY_CONFIG_LOG_PROPERTIES
Definition config.hpp:43
const std::string KEY_CONFIG_OLDB_URI_PREFIX
Definition config.hpp:47
const std::string KEY_CONFIG_REQ_ENDPOINT
Definition config.hpp:46
const std::string KEY_CONFIG_TRS_SOCKET_PATH
Definition config.hpp:52
const std::string KEY_CONFIG_DDS_QOS_PROFILE
Definition config.hpp:53
const std::string KEY_CONFIG_DDS_QOS_INTERFACES
Definition config.hpp:55