rad 6.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_DDS_QOS_PROFILE = KEY_CONFIG + "dds_qos_profile";
52const std::string KEY_CONFIG_DDS_QOS_PARTICIPANT = KEY_CONFIG + "dds_qos_participant";
53
71
72
77class Config {
78 public:
89 explicit Config(const std::string& name = LOGGER_NAME,
90 const std::string& log_level = "ERROR");
91
100 Config(const Config& cfg);
101
105 virtual ~Config();
106
116 Config& operator=(const Config& cfg);
117
122 inline const elt::configng::CiiConfigDocument& GetConfigDoc() const { return *m_config_doc; }
123
127 inline bpo::options_description& GetOptionsDesc() { return m_options_desc; }
128
132 inline bpo::variables_map& GetOptionsMap() { return m_options_map; }
133
137 inline const std::string& GetOldbPrefixAppenderKey() { return m_oldb_prefix_appender_key; }
138
146 inline void SetOldbPrefixAppenderKey(const std::string& key) {
147 m_oldb_prefix_appender_key = key;
148 }
149
155 std::string BuildOldbPrefix();
156
165 virtual bool ParseOptions(int argc, char* argv[]);
166
175 virtual void LoadConfig(const std::string& filename = "");
176
186 virtual void ConfigureLogging(const std::string& filename = "");
187
192 virtual void ApplyCmdLineOptions();
193
203 void CheckConfig() const;
204
217 virtual void ValidateConfig(const std::vector<std::string>& keys,
218 const Config& cfg) const;
219
227 void MergeConfig(const elt::configng::CiiConfigDocument& cfg_doc);
228
235 void CreateDefaultConfig(const std::string& default_cfg);
236
244 template<typename T>
245 void AddParam(const std::string& key, const T& value);
246
253 bool HasParam(const std::string& key) const;
254
261 template<typename T>
262 T GetParam(const std::string& key) const;
263
270 template<typename T>
271 void SetParam(const std::string& key, const T& value);
272
278 const std::string GetConfigAsString() const;
279
291 std::vector<std::string> SetConfigAsString(const std::string& config);
292
297 std::string PrintNode(const elt::configng::CiiConfigInstanceNode& node,
298 const std::string& indentation) const;
299
307 std::string Print(const elt::configng::CiiConfigInstanceNamespace& instances) const;
308
314 std::string Print() const;
315
316 private:
326 bool SplitKeyValue(const std::string& keyval, std::string& key, std::string& value) const;
327
337 void SplitVectorStr(const std::string& vector_str, std::string& vector_name,
338 int& vector_index) const;
339
340 bpo::options_description m_options_desc;
341 bpo::variables_map m_options_map;
342 std::string m_name;
343
344 /*
345 * Key to be used to build the OLDB prefix:
346 * - If m_oldb_prefix_appender_key is an empty string, the OLDB prefix will
347 * be only the value associated with the KEY_CONFIG_OLDB_URI_PREFIX key.
348 * - Otherwise m_oldb_prefix_appender_key can be set to be the key of a
349 * configuration parameter used to OLDB prefix (see BuildOldbPrefix() method).
350 * For example, m_oldb_prefix_appender_key could be KEY_CONFIG_MODNAME or
351 * KEY_CONFIG_PROCNAME. The latter case is useful when several instances of the
352 * same application is started (e.g. two instances of the m2m3WhCtr can be started:
353 * one to control the WH of M2 and one of M3).
354 * To preserve backward compatibility, this attribute should be initialized to
355 * KEY_CONFIG_MODNAME.
356 */
357 std::string m_oldb_prefix_appender_key;
358
359 /*
360 * We need to declare CiiConfigDocument as pointer since it logs info
361 * in the constructor and therefore uses [CII] logging before it has
362 * been properly configured.
363 */
364 std::optional<elt::configng::CiiConfigDocument> m_config_doc;
365};
366
367
368template<typename T>
369void Config::AddParam(const std::string& key, const T& value) {
371
372 std::vector<std::string> nodes;
373 std::string delim(1, CONFIG_KEY_SEPARATOR_OLDB);
374 boost::split(nodes, key, boost::is_any_of(delim));
375 if (nodes.size() < 2) {
376 RAD_LOG_THROW(rad::Exception, GetLogger(), "Key " + key +
377 " has no root/leaf node(s).");
378 }
379
380 /*
381 builder["three"] = elt::configng::CiiConfigInstanceNode::From(3);
382 builder["vector"] = elt::configng::CiiConfigInstanceNode::From(std::vector<int>{1,2,3,4,5,6},
383 "!cfg.type:vector_int32");
384 builder["map"]["d"] = elt::configng::CiiConfigInstanceNode::From(4);
385 builder["map"]["e"] = elt::configng::CiiConfigInstanceNode::From("text");
386 builder["map"]["f"] = elt::configng::CiiConfigInstanceNode::From(false, "!cfg.type:boolean");
387 */
388 elt::configng::CiiConfigMapBuilder builder;
389
390 auto curr_node = builder[nodes[0]];
391 size_t index = 1;
392 while (index < nodes.size()) {
393 //std::string child_node_name = nodes[index];
394 curr_node = curr_node[nodes[index]];
395 if (index + 1 == nodes.size()) {
396 //child_node.As<T>();
397 curr_node = elt::configng::CiiConfigInstanceNode::From(value);
398 }
399 index++;
400 }
401
402 if (!m_config_doc) {
403 m_config_doc = elt::configng::CiiConfigDocument();
404 m_config_doc->SetInstancesFromMap(builder);
405 } else {
406 auto document = elt::configng::CiiConfigDocument();
407 document.SetInstancesFromMap(builder);
408 MergeConfig(document);
409 }
410
411 auto issues = m_config_doc->Check();
412 if (issues.HasErrors() || issues.HasWarnings()) {
413 for (auto& issue : issues) {
414 LOG4CPLUS_ERROR(GetLogger(), "Config. issue: " << issue.GetMessage());
415 //std::cout << issue << std::endl;
416 }
417 RAD_LOG_THROW(rad::Exception, GetLogger(), "Error/warning while adding key " + key);
418 }
419}
420
421template<typename T>
422T Config::GetParam(const std::string& key) const {
424
425 if (!m_config_doc) {
426 RAD_LOG_THROW(rad::Exception, GetLogger(), "No configuration available.");
427 }
428
429 try {
430 std::vector<std::string> nodes;
431 std::string delim(1, CONFIG_KEY_SEPARATOR_OLDB);
432 boost::split(nodes, key, boost::is_any_of(delim));
433 if (nodes.size() < 2) {
434 RAD_LOG_THROW(rad::Exception, GetLogger(), "Key " + key +
435 " has no root/leaf node(s).");
436 }
437
438 auto instance = m_config_doc->Instances();
439 auto parent_node = instance[nodes[0]];
440 auto child_node = parent_node;
441 size_t index = 1;
442 while (index < nodes.size()) {
443 std::string child_node_name = nodes[index];
444
445 // check for arrays
446 int vector_index = -1;
447 SplitVectorStr(nodes[index], child_node_name, vector_index);
448 //std::cout << "Child node name: " << child_node_name << std::endl;
449
450 // check for sub-node or leaf-node.
451 if (parent_node.Has(child_node_name)) {
452 if (vector_index == -1) {
453 child_node = parent_node[child_node_name];
454 } else {
455 child_node = parent_node[child_node_name][vector_index];
456 }
457 if (index + 1 == nodes.size()) {
458 T val = child_node.As<T>();
459 return val;
460 }
461 parent_node = child_node;
462 } else {
463 RAD_LOG_THROW(rad::Exception, GetLogger(), "Configuration parameter " +
464 key + " does not exists.");
465 }
466 index++;
467 }
468 RAD_LOG_THROW(rad::Exception, GetLogger(), "Configuration parameter " +
469 key + " does not exists.");
470 } catch (std::exception& e) {
471 RAD_LOG_THROW(rad::Exception, GetLogger(), "Reading configuration parameter <" +
472 key + ">: " + std::string(e.what()));
473 }
474}
475
476template<typename T>
477void Config::SetParam(const std::string& key, const T& value) {
479
480 if (!m_config_doc) {
481 RAD_LOG_THROW(rad::Exception, GetLogger(), "No configuration available.");
482 }
483
484 try {
485 std::vector<std::string> nodes;
486 std::string delim(1, CONFIG_KEY_SEPARATOR_OLDB);
487 boost::split(nodes, key, boost::is_any_of(delim));
488 if (nodes.size() < 2) {
489 RAD_LOG_THROW(rad::Exception, GetLogger(), "Key " + key +
490 " has no root/leaf node(s).");
491 }
492
493 auto instance = m_config_doc->Instances();
494 auto parent_node = instance[nodes[0]];
495 auto child_node = parent_node;
496 size_t index = 1;
497 while (index < nodes.size()) {
498 std::string child_node_name = nodes[index];
499
500 // check for arrays
501 int vector_index = -1;
502 SplitVectorStr(nodes[index], child_node_name, vector_index);
503
504 // check for sub-node or leaf-node.
505 if (parent_node.Has(child_node_name)) {
506 if (vector_index == -1) {
507 child_node = parent_node[child_node_name];
508 } else {
509 child_node = parent_node[child_node_name][vector_index];
510 }
511 if (index + 1 == nodes.size()) {
512 child_node = value;
513 return;
514 }
515 parent_node = child_node;
516 } else {
517 RAD_LOG_THROW(rad::Exception, GetLogger(), "Configuration parameter " +
518 key + " does not exists.");
519 }
520 index++;
521 }
522 RAD_LOG_THROW(rad::Exception, GetLogger(), "Configuration parameter " +
523 key + " does not exists.");
524 } catch (std::exception& e) {
525 LOG4CPLUS_ERROR(GetLogger(), "Writing configuration parameter <"
526 << key << ">: " << e.what());
527 }
528}
529
537void GetListOfKeysFromConfig(const elt::configng::CiiConfigInstanceNode& node,
538 const std::string& prefix,
539 std::vector<std::string>& keys);
540
547std::vector<std::string> GetListOfKeysFromConfig(const elt::configng::CiiConfigDocument& cfg_doc);
548
549} // namespace rad
550
551#endif // RAD_CONFIG_HPP
Assert header file.
Definition config.hpp:77
void AddParam(const std::string &key, const T &value)
Definition config.hpp:369
bpo::variables_map & GetOptionsMap()
Definition config.hpp:132
void SetParam(const std::string &key, const T &value)
Definition config.hpp:477
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:137
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:127
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:422
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:146
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:122
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:23
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
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:52
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:54
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_DDS_QOS_PROFILE
Definition config.hpp:51