ifw-ccf  3.0.0-pre2
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  LOG4CPLUS_INFO(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  LOG4CPLUS_WARN(Logger(), err);
154  CCFTHROW(err);
155  }
156  }
157 
158  s_staging_setup_map[tmp_name] = tmp_val.str();
159  LOG4CPLUS_INFO(Logger(), fmt::format("Added Staging Setup Parameter: |{}|=|{}|", tmp_name,
160  tmp_val.str()));
161  }
162 
164  const std::map<std::string, std::string>& GetCmdStagingPars();
165 
167  void GetPars(std::map<std::string, std::string>& pars,
168  const std::string& pattern = "*");
169 
171  template <class TYPE>
172  TYPE GetValue(const std::vector<std::string>& names) {
173  LOG4CPLUS_TRACE_METHOD(Logger(), __PRETTY_FUNCTION__);
174  auto tmp_names = _CheckNodeNames(names);
175  TYPE tmp_value;
176  if (HasPar(tmp_names, tmp_value)) {
177  return tmp_value;
178  } else {
179  CCFTHROW("Setup parameter requested not defined: " + BuildKey(tmp_names));
180  }
181  }
182 
184  template <class TYPE>
185  TYPE GetValueKey(const std::string& name) {
186  LOG4CPLUS_TRACE_METHOD(Logger(), __PRETTY_FUNCTION__);
187  auto tmp_name = _CheckNodeName(name);
188  TYPE tmp_value;
189  if (HasPar(SplitKey(tmp_name), tmp_value)) {
190  return tmp_value;
191  } else {
192  CCFTHROW("Setup parameter requested not defined: " + tmp_name);
193  }
194  }
195 
197  void LoadStagingSetup(const std::string& filename);
198 
200  void AcceptStagingSetup();
201 
203  std::string SetupFileToString() const;
204 
205  protected:
206 
207  private:
208  std::string m_root_node_name;
209  std::string m_staging_setup_file;
210 
211  std::vector<std::string> _CheckNodeNames(const std::vector<std::string>& names) const;
212  std::string _CheckNodeName(const std::string& name) const;
213 
214  // The Staging Setup contains the parameters received for a new Setup Command,
215  // while it is being handled.
216  // => Used when the Staging Setup is loaded from a file. <=
217  std::unique_ptr<elt::configng::CiiConfigDocument> m_staging_setup_doc;
218 
219  // Reference setup document, used as a 'dictionary' to check parameters submitted
220  // in SPF format.
221  std::unique_ptr<elt::configng::CiiConfigDocument> m_ref_setup_doc;
222 
223  // Keys are represented as SPF ("<key el1>.<key el2>....") in the map.
224  // => Used when Staging Setup Parameters provided in SPF via the Setup command. <=
225  // TODO: In principle it should not be necessary to declare this map as static, but if it is
226  // a normal member it doesn't work...
227  static std::map<std::string, std::string> s_staging_setup_map;
228 
229  // The Setup object contains the current setup, accepted and installed (in use).
230  std::unique_ptr<elt::configng::CiiConfigDocument> m_setup_doc;
231  };
232 
233  inline Setup& GetSetup() {
234  return Setup::Instance();
235  }
236 
237 }
238 
239 #endif // CCF_COMMON_SETUP_HPP_H_
#define CCFTHROW(msg)
Guard for TRACE logs. Ensures log text is only generated when the given log level is enabled.
Definition: base.hpp:489
Class to be used as parent all CCF classes.
Definition: base.hpp:151
Global setup class for CCF applications. An Initialisation Setup, containing all the parameters shall...
Definition: setup.hpp:21
bool HasStagingParKey(const std::string &name, TYPE &value)
Definition: setup.hpp:97
bool HasStagingNodeKey(const std::string &name)
Probe if a given parameter is defined among the Setup Staging Parameters.
Definition: setup.cpp:180
bool HasPar(const std::vector< std::string > &names, TYPE &value)
Definition: setup.hpp:51
static Setup * s_instance
Singleton instance.
Definition: setup.hpp:25
static Setup & Instance()
Return reference to unique instance of the application class.
Definition: setup.cpp:13
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:185
void AcceptStagingSetup()
Merge the parameters in the Staging Setup into the Installed Setup set of parameters.
Definition: setup.cpp:137
void AddStagingPar(const std::string &name, const TYPE value)
Definition: setup.hpp:122
const std::map< std::string, std::string > & GetCmdStagingPars()
Return list of staging pars, provided via the Setup command.
Definition: setup.cpp:132
void ResetStagingSetup()
Reset the internal Staging Setup.
Definition: setup.cpp:62
TYPE GetValue(const std::vector< std::string > &names)
Get value from either the 1) Staging Setup, or 2) Installed Setup.
Definition: setup.hpp:172
std::string SetupFileToString() const
Return string representation of the setup file loaded.
Definition: setup.cpp:190
Setup()
Definition: setup.cpp:22
bool HasStagingPar(const std::vector< std::string > &names, TYPE &value)
Definition: setup.hpp:70
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
const std::string & GetRootNodeName() const
Return the name of the setup document root node name.
Definition: setup.cpp:199
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
void GetPars(std::map< std::string, std::string > &pars, const std::string &pattern="*")
Return map with all parameters in the object. Staging pars take precedence.
Definition: setup.cpp:106
~Setup()
Definition: setup.cpp:29
void LoadStagingSetup(const std::string &filename)
Load a Setup File into the Staging Setup object.
Definition: setup.cpp:68
Definition: appBase.cpp:8
Setup & GetSetup()
Definition: setup.hpp:233
std::string BuildKey(const std::vector< std::string > &elements)
Build a concatenated key from a number of elements (<el1>.<el2.>...).
Definition: base.cpp:218
log4cplus::Logger & Logger()
Definition: base.cpp:9
std::vector< std::string > SplitKey(const std::string &key)
Split up a concatenated key.
Definition: base.cpp:222