ifw-ccf  2.0.0
setup.hpp
Go to the documentation of this file.
1 
5 #ifndef CCF_COMMON_SETUP_HPP_H_
6 #define CCF_COMMON_SETUP_HPP_H_
7 
8 #include <yaml-cpp/yaml.h>
9 
10 #include <config-ng/ciiConfigApi.hpp>
11 
12 #include <ccf/common/base.hpp>
13 
14 // TODO: Check correct usage of const in all methods.
15 
16 namespace ccf::common {
17 
21  class Setup: public Base {
22  public:
23 
25  static Setup* s_instance;
26 
28  static Setup& Instance();
29 
30 
31  Setup();
32 
33  ~Setup();
34 
36  elt::configng::CiiConfigInstanceNode& GetNode(const std::vector<std::string>& names);
37 
39  elt::configng::CiiConfigInstanceNode& GetStagingNode(const std::vector<std::string>& names);
40 
42  elt::configng::CiiConfigInstanceNode& GetNode(const elt::configng::CiiConfigDocument* doc,
43  const std::vector<std::string>& names);
44 
46  const std::string& GetRootNodeName() const;
47 
50  template <class TYPE>
51  bool HasPar(const std::vector<std::string>& names, TYPE& value) {
52  LOG4CPLUS_TRACE_METHOD(Logger(), __PRETTY_FUNCTION__);
53  auto tmp_names = _CheckNodeNames(names);
54  if (HasStagingPar(tmp_names, value)) {
55  return true;
56  } else {
57  try {
58  auto tmp_node = GetNode(tmp_names);
59  value = tmp_node.As<TYPE>();
60  return true;
61  } catch (...) {
62  return false;
63  }
64  }
65  }
66 
69  template <class TYPE>
70  bool HasStagingPar(const std::vector<std::string>& names, TYPE& value) {
71  LOG4CPLUS_TRACE_METHOD(Logger(), __PRETTY_FUNCTION__);
72  auto tmp_names = _CheckNodeNames(names);
73 
74  // Try first in the Staging Par map:
75  auto tmp_name = BuildKey(tmp_names);
76  auto it = s_staging_setup_map.find(tmp_name);
77  if (it != s_staging_setup_map.end()) {
78  core::utils::conversion::Convert(it->second, value);
79  return true;
80  }
81  // - then in the CII Cfg Service doc:
82  try {
83  auto tmp_node = GetStagingNode(tmp_names);
84  value = tmp_node.As<TYPE>();
85  return true;
86  } catch (...) {
87  return false;
88  }
89  }
90 
92  bool HasStagingNodeKey(const std::string& name);
93 
96  template <class TYPE>
97  bool HasStagingParKey(const std::string& name, TYPE& value) {
98  LOG4CPLUS_TRACE_METHOD(Logger(), __PRETTY_FUNCTION__);
99  auto tmp_name = _CheckNodeName(name);
100  auto it = s_staging_setup_map.find(tmp_name);
101  if (it != s_staging_setup_map.end()) {
102  core::utils::conversion::Convert(it->second, value);
103  return true;
104  } else {
105  try {
106  auto tmp_node = GetStagingNode(SplitKey(tmp_name));
107  value = tmp_node.As<TYPE>();
108  return true;
109  } catch (...) {
110  return false;
111  }
112  return false;
113  }
114  }
115 
117  void ResetStagingSetup();
118 
121  template <class TYPE>
122  void AddStagingPar(const std::string& name, const TYPE value) {
123  LOG4CPLUS_TRACE_METHOD(Logger(), __PRETTY_FUNCTION__);
124  std::string tmp_name = _CheckNodeName(name);
125  CCFINFO(Logger(), fmt::format("Handling Staging Setup Parameter: |{}|=|{}|...",
126  tmp_name, value));
127  // Check if parameter is defined in the 'reference setup document'.
128  if (m_ref_setup_doc.get() == nullptr) {
129  CCFTHROW("Must load an Init Setup as reference before submitting setup parameters");
130  }
131  // 1: Check if keyword is defined in the reference setup.
132  try {
133  GetNode(m_ref_setup_doc.get(), SplitKey(name));
134  } catch (...) {
135  CCFTHROW(fmt::format("Parameter: |{}| not defined for this instance", name));
136  }
137  // 2: Check if keyword value is valid according to the schema.
138  // TODO: This is a workaround. the ngconfig document class does not provide a
139  // "CheckKeyword()", which could be used for this; see also
140  std::stringstream tmp_val;
141  tmp_val << value;
142  auto node = GetNode(m_ref_setup_doc.get(), SplitKey(name));
143  node = tmp_val.str();
144  m_ref_setup_doc.get()->Check();
145  auto issues = m_ref_setup_doc.get()->Check();
146  if (issues) {
147  // Reload the Reference Staging Setup to be ready for the next check to be performed.
148  m_ref_setup_doc = std::make_unique<elt::configng::CiiConfigDocument>
149  (elt::configng::CiiConfigClient::Load(m_staging_setup_file));
150  for (auto issue : issues) {
151  auto err = fmt::format("Value: {} provided with parameter: {} not valid: {}", name,
152  tmp_val.str(), issue.GetMessageWithOrigin());
153  CCFWARNING(Logger(), err);
154  CCFTHROW(err);
155  }
156  }
157 
158  s_staging_setup_map[tmp_name] = tmp_val.str();
159  CCFINFO(Logger(), fmt::format("Added Staging Setup Parameter: |{}|=|{}|", tmp_name,
160  tmp_val.str()));
161  }
162 
164  const std::map<std::string, std::string>& GetStagingPars();
165 
167  template <class TYPE>
168  TYPE GetValue(const std::vector<std::string>& names) {
169  LOG4CPLUS_TRACE_METHOD(Logger(), __PRETTY_FUNCTION__);
170  auto tmp_names = _CheckNodeNames(names);
171  TYPE tmp_value;
172  if (HasPar(tmp_names, tmp_value)) {
173  return tmp_value;
174  } else {
175  CCFTHROW("Setup parameter requested not defined: " + BuildKey(tmp_names));
176  }
177  }
178 
180  template <class TYPE>
181  TYPE GetValueKey(const std::string& name) {
182  LOG4CPLUS_TRACE_METHOD(Logger(), __PRETTY_FUNCTION__);
183  auto tmp_name = _CheckNodeName(name);
184  TYPE tmp_value;
185  if (HasPar(SplitKey(tmp_name), tmp_value)) {
186  return tmp_value;
187  } else {
188  CCFTHROW("Setup parameter requested not defined: " + tmp_name);
189  }
190  }
191 
193  void LoadStagingSetup(const std::string& filename);
194 
196  void AcceptStagingSetup();
197 
199  std::string SetupFileToString() const;
200 
201  protected:
202 
203  private:
204  std::string m_root_node_name;
205  std::string m_staging_setup_file;
206 
207  std::vector<std::string> _CheckNodeNames(const std::vector<std::string>& names) const;
208  std::string _CheckNodeName(const std::string& name) const;
209 
210  // The Staging Setup contains the parameters received for a new Setup Command,
211  // while it is being handled.
212  std::unique_ptr<elt::configng::CiiConfigDocument> m_staging_setup_doc;
213 
214  // Reference setup document, used as a 'dictionary' to check parameters submitted
215  // in SPF format.
216  std::unique_ptr<elt::configng::CiiConfigDocument> m_ref_setup_doc;
217 
218  // Keys are represented as SPF ("<key el1>.<key el2>....") in the map.
219  // Used for setup keywords provided on a string format via the Setup command.
220  // TODO: In principle it should not be necessary to declare this map as static, but if it is
221  // a normal member it doesn't work...
222  static std::map<std::string, std::string> s_staging_setup_map;
223 
224  // The Setup object contains the current setup, accepted and installed (in use).
225  std::unique_ptr<elt::configng::CiiConfigDocument> m_setup_doc;
226  };
227 
228  inline Setup& GetSetup() {
229  return Setup::Instance();
230  }
231 
232 }
233 
234 #endif // CCF_COMMON_SETUP_HPP_H_
ccf::Base
Class to be used as parent all CCF classes.
Definition: base.hpp:152
ccf::common::Setup::AcceptStagingSetup
void AcceptStagingSetup()
Merge the parameters in the Staging Setup into the Installed Setup set of parameters.
Definition: setup.cpp:111
CCFTHROW
#define CCFTHROW(msg)
Definition: base.hpp:568
ccf::common::GetSetup
Setup & GetSetup()
Definition: setup.hpp:228
CCFINFO
#define CCFINFO(logger, msg)
INFO log macro. Includes the location ("CCFLOC") in the log message.
Definition: base.hpp:552
ccf::common::Setup
Global setup class for CCF applications. An Initialisation Setup, containing all the parameters shall...
Definition: setup.hpp:21
ccf::common::Setup::HasStagingPar
bool HasStagingPar(const std::vector< std::string > &names, TYPE &value)
Definition: setup.hpp:70
CCFWARNING
#define CCFWARNING(logger, msg)
WARNING log macro. Includes the location ("CCFLOC") in the log message.
Definition: base.hpp:549
ccf::common::Setup::ResetStagingSetup
void ResetStagingSetup()
Reset the internal Staging Setup.
Definition: setup.cpp:62
ccf::common::Setup::GetValueKey
TYPE GetValueKey(const std::string &name)
Get value from either the 1) Staging Setup, or 2) Installed Setup from the SPF key.
Definition: setup.hpp:181
ccf::common::Setup::AddStagingPar
void AddStagingPar(const std::string &name, const TYPE value)
Definition: setup.hpp:122
ccf::common::Setup::HasPar
bool HasPar(const std::vector< std::string > &names, TYPE &value)
Definition: setup.hpp:51
ccf::common::Setup::Setup
Setup()
Definition: setup.cpp:22
ccf::common::Setup::GetNode
elt::configng::CiiConfigInstanceNode & GetNode(const std::vector< std::string > &names)
Get the reference to a specific node in the Installed Setup.
Definition: setup.cpp:33
ccf::common::Setup::GetStagingNode
elt::configng::CiiConfigInstanceNode & GetStagingNode(const std::vector< std::string > &names)
Get the reference to a specific node in the Staging Setup.
Definition: setup.cpp:38
ccf::common::Setup::SetupFileToString
std::string SetupFileToString() const
Return string representation of the setup file loaded.
Definition: setup.cpp:161
ccf::common::Setup::HasStagingNodeKey
bool HasStagingNodeKey(const std::string &name)
Probe if a given parameter is defined among the Setup Staging Parameters.
Definition: setup.cpp:151
ccf::common::Setup::GetValue
TYPE GetValue(const std::vector< std::string > &names)
Get value from either the 1) Staging Setup, or 2) Installed Setup.
Definition: setup.hpp:168
ccf::common::Setup::Instance
static Setup & Instance()
Return reference to unique instance of the application class.
Definition: setup.cpp:13
ccf::common::Setup::s_instance
static Setup * s_instance
Singleton instance.
Definition: setup.hpp:25
ccf::common::Setup::HasStagingParKey
bool HasStagingParKey(const std::string &name, TYPE &value)
Definition: setup.hpp:97
base.hpp
ccf::common::Setup::LoadStagingSetup
void LoadStagingSetup(const std::string &filename)
Load a Setup File into the Staging Setup object.
Definition: setup.cpp:68
ccf::common
Definition: appBase.cpp:8
ccf::common::Setup::GetStagingPars
const std::map< std::string, std::string > & GetStagingPars()
Return list of staging pars.
Definition: setup.cpp:106
ccf::common::Setup::~Setup
~Setup()
Definition: setup.cpp:29
ccf::common::Setup::GetRootNodeName
const std::string & GetRootNodeName() const
Return the name of the setup document root node name.
Definition: setup.cpp:170
ccf::BuildKey
std::string BuildKey(const std::vector< std::string > &elements)
Build a concatenated key from a number of elements (<el1>.<el2.>...).
Definition: base.cpp:218
ccf::SplitKey
std::vector< std::string > SplitKey(const std::string &key)
Split up a concatenated key.
Definition: base.cpp:222
ccf::Logger
log4cplus::Logger & Logger()
Definition: base.cpp:9