DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
OksConfiguration.cpp
Go to the documentation of this file.
1//
2// DUNE DAQ modification notice:
3// This file has been modified from the original ATLAS oksconfig source for the DUNE DAQ project.
4// Fork baseline commit: oksconfig-03-02-00 (2021-04-20).
5// Renamed since fork: no.
6//
7
8#include <errno.h>
9#include <stdlib.h>
10#include <sys/stat.h>
11#include <unistd.h>
12
13#include <algorithm>
14#include <memory>
15
16#include "ers/ers.hpp"
17
18#include "oks/file.hpp"
19#include "oks/kernel.hpp"
20#include "oks/object.hpp"
21#include "oks/query.hpp"
22#include "oks/relationship.hpp"
24
25#include "conffwk/Change.hpp"
28#include "conffwk/Schema.hpp"
29
32
33namespace dunedaq {
34ERS_DECLARE_ISSUE(oksconflibs, Exception, , )
35}
36using namespace dunedaq;
37using namespace dunedaq::oks;
38using namespace dunedaq::oksconflibs;
39// to be used as plug-in
40
42_oksconflibs_creator_(const std::string& spec)
43{
44 try {
45 std::unique_ptr<OksConfiguration> impl(new OksConfiguration());
46 if (!spec.empty()) {
47 impl->open_db(spec);
48 }
49 return impl.release();
50 } catch (dunedaq::conffwk::Exception& ex) {
51 throw dunedaq::conffwk::Generic(ERS_HERE, "oksconflibs initialization error", ex);
52 } catch (...) {
53 throw dunedaq::conffwk::Generic(ERS_HERE,
54 "oksconflibs initialization error:\n***** caught unknown exception *****");
55 }
56}
57
59{
60
62 bool m_run;
63
65 : m_db(db)
66 , m_run(true)
67 {
68 ;
69 }
70
72 {
73 TLOG_DEBUG(3) << "Call destructor of OksConfigurationCheckDB object";
74 m_db = nullptr;
75 }
76
78 {
79 TLOG_DEBUG(2) << "Call user notification";
80
81 while (m_run) {
82 sleep(1);
83 try {
84 m_db->check_db();
85 } catch (dunedaq::conffwk::Generic& ex) {
86 m_db->m_check_db_thread = nullptr;
87 m_db->m_check_db_obj = nullptr;
88
89 if (getenv("OKSCONFLIBS_NO_RELOAD_ABORT") != nullptr) {
90 ers::fatal(dunedaq::conffwk::Generic(ERS_HERE, "database reload has failed, unsubscribing...", ex));
91 return;
92 } else {
93 ers::fatal(dunedaq::conffwk::Generic(ERS_HERE, "database reload has failed, aborting...", ex));
94 abort();
95 }
96 }
97 }
98
99 TLOG_DEBUG(4) << "Destroy OksConfigurationCheckDB object = " << (void*)this;
100
101 delete this;
102
103 TLOG_DEBUG(2) << "Exit user notification";
104 }
105};
106
107bool
108is_repo_name(const std::string& name)
109{
110 if (!OksKernel::get_repository_root().empty()) {
111 std::string s(name);
112
114
115 bool is_absolute_path = (s[0] == '/');
116
117 if (!is_absolute_path)
118 s = std::string(OksKernel::get_cwd()) + '/' + s;
119
120 // if file system path exists
121 if (Oks::real_path(s, true)) {
123 return true;
124
125 static std::string user_repo_dir;
126 static std::once_flag flag;
127
128 std::call_once(flag, []() {
129 if (const char* s = getenv("TDAQ_DB_USER_REPOSITORY")) {
130 user_repo_dir = s;
131
132 try {
133 Oks::real_path(user_repo_dir, false);
134 } catch (oks::exception& ex) {
135 TLOG_DEBUG(0) << "Failed to read TDAQ_DB_USER_REPOSITORY = \'" << s << "\':\n\tcaused by: " << ex.what();
136 }
137 }
138 });
139
140 if (!user_repo_dir.empty() && s.find(user_repo_dir) == 0)
141 return true;
142
143 return false;
144 } else
145 return true;
146 }
147
148 return false;
149}
150
151void
152OksConfiguration::open_db(const std::string& spec_params)
153{
154 // separate parameters first
155
156 std::string::size_type idx = spec_params.find_first_of('&');
157
158 std::string data, params;
159
160 if (idx == std::string::npos) {
161 data = spec_params;
162 } else {
163 data = spec_params.substr(0, idx);
164 params = spec_params.substr(idx + 1);
165 }
166
167 std::string token;
168
169 // guess about oks kernel mode based on the file names
170
171 {
172 Oks::Tokenizer t(data, ":");
173
174 while (!(token = t.next()).empty()) {
175 if (is_repo_name(token) == false)
177 }
178 }
179
180 // create OKS kernel if it was not created
181
182 if (m_kernel == nullptr) {
183 if (!params.empty()) {
184 Oks::Tokenizer t(params, ";");
185
186 while (!(token = t.next()).empty()) {
187 if (token == "norepo")
189 }
190 }
191
193 }
194
195 Oks::Tokenizer t(data, ":");
196
197 while (!(token = t.next()).empty()) {
198 try {
199 m_kernel->load_file(token);
200 } catch (oks::exception& e) {
201 std::ostringstream text;
202 text << "cannot load file \'" << token << "\':\n" << e.what();
203 close_db();
204 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
205 } catch (...) {
206 std::ostringstream text;
207 text << "cannot load file \'" << token << '\'';
208 close_db();
209 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
210 }
211 }
212}
213
214void
216{
217 clean(); // clean implementation cache
218
219 if (m_kernel)
220 try {
221 if (m_check_db_obj) {
222 if (call_unsubscribe)
223 unsubscribe();
224 else
225 m_check_db_obj->m_run = false;
226 }
227
231
234
235 delete m_kernel;
236 m_kernel = 0;
237 } catch (oksconflibs::Exception& ex) {
238 throw(dunedaq::conffwk::Generic(ERS_HERE, "failed to close database", ex));
239 } catch (std::exception& ex) {
240 throw(dunedaq::conffwk::Generic(ERS_HERE, "failed to close database", ex));
241 }
242}
243
244void
245OksConfiguration::create(const std::string& db_name, const std::list<std::string>& includes)
246{
247 // create OKS kernel if it was not created
248
249 if (m_kernel == nullptr) {
250 if (is_repo_name(db_name) == false)
252
254 }
255
256 // create new data file
257
258 try {
259 OksFile* h = m_kernel->new_data(db_name);
260 m_created_files.insert(h);
261
262 // add includes
263
264 for (std::list<std::string>::const_iterator i = includes.begin(); i != includes.end(); ++i) {
265 try {
266 h->add_include_file(*i);
267 } catch (oks::exception& e) {
268 std::ostringstream text;
269 text << "cannot add and load include file \'" << *i << "\' to \'" << db_name << "\':\n" << e.what();
270 close_db();
271 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
272 } catch (...) {
273 std::ostringstream text;
274 text << "cannot add and load include file \'" << *i << "\' to \'" << db_name << '\'';
275 close_db();
276 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
277 }
278 }
279
281 } catch (oks::exception& ex) {
282 close_db();
283 std::ostringstream text;
284 text << "cannot create new data file \'" << db_name << "\': " << ex.what();
285 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
286 } catch (dunedaq::conffwk::Generic& ex) {
287 close_db();
288 std::ostringstream text;
289 text << "cannot create new data file \'" << db_name << "\'";
290 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str(), ex));
291 } catch (...) {
292 close_db();
293 std::ostringstream text;
294 text << "cannot create new data file \'" << db_name << '\'';
295 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
296 }
297}
298
299static std::string
300mk_no_file_error_text(const std::string& db)
301{
302 std::ostringstream text;
303 text << "cannot find file \'" << db << '\'';
304 return text.str();
305}
306
307static std::string
308mk_add_include_error_text(const std::string& db, const std::string& include, const char* error = nullptr)
309{
310 std::ostringstream text;
311 text << "cannot add and load include file \'" << include << "\' to \'" << db << '\'';
312 if (error)
313 text << ":\n" << error;
314 return text.str();
315}
316
317void
318OksConfiguration::get_updated_dbs(std::list<std::string>& dbs) const
319{
320 for (const auto& i : m_kernel->data_files()) {
321 if (i.second->is_updated())
322 dbs.push_back(i.second->get_full_file_name());
323 }
324}
325
326void
327OksConfiguration::set_commit_credentials(const std::string& user, const std::string& password)
328{
329 m_user = user;
330 m_password = password;
331}
332
333static void
334throw_update_exception(const OksFile* file_h, const char* action, const char* reason)
335{
336 std::ostringstream text;
337 text << "cannot " << action << " file \'" << file_h->get_full_file_name() << "\' since " << reason;
338 throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());
339}
340
341void
342OksConfiguration::commit(const std::string& log_message)
343{
344 try {
345 m_kernel->set_active_data(nullptr);
346 } catch (oks::exception& ex) {
347 throw(dunedaq::conffwk::Generic(ERS_HERE, ex.what()));
348 }
349
350 const bool commit2repo(!m_kernel->get_user_repository_root().empty() && m_kernel->is_user_repository_created());
351 unsigned int count(0);
352
353 for (const auto& i : m_kernel->data_files()) {
354 OksFile* file_h = i.second;
355
356 if (file_h->is_updated()) {
357 const OksFile::FileStatus file_status = file_h->get_status_of_file();
358
359 if (file_status == OksFile::FileModified)
360 throw_update_exception(file_h, "save", "it was externally modified");
361 else if (file_status == OksFile::FileRemoved)
362 throw_update_exception(file_h, "save", "it was externally removed");
363
364 try {
365 if (!commit2repo && !log_message.empty())
366 file_h->add_comment(log_message, m_kernel->get_user_name());
367
368 m_kernel->save_data(file_h);
369
370 count++;
371 } catch (oks::exception& ex) {
372 std::ostringstream text;
373 text << "cannot save updated data file \'" << *(i.first) << "\':\n" << ex.what();
374 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
375 }
376 }
377 }
378
379 if (commit2repo && count) {
380 try {
381 m_kernel->commit_repository(log_message);
382 } catch (oks::exception& ex) {
383 throw(dunedaq::conffwk::Generic(ERS_HERE, ex.what()));
384 }
385 }
386
387 m_created_files.clear();
388}
389
390namespace dunedaq {
391namespace oksconflibs {
393{
394
395public:
397 : m_db(db)
398 {
399 if (m_db.m_check_db_obj) {
400 m_db.unsubscribe();
401 m_restart = true;
402 } else {
403 m_restart = false;
404 }
405
406 m_db.m_created.clear();
407 m_db.m_modified.clear();
408 m_db.m_removed.clear();
409 }
410
412 {
413 if (m_restart) {
414 m_db.subscribe();
415 }
416 }
417
418private:
421};
422
423void
425{
426 // unsubscribe changes; if there are any, re-subscribe on return from this method
427
428 ResubscribeGuard __rg__(*this);
429
430 // destroy any newly created files
431 for (const auto& i : m_created_files) {
432 const std::string file_name(i->get_full_file_name());
433
434 TLOG_DEBUG(1) << "destroy created file \'" << file_name << "\')";
436
437 if (int result = unlink(file_name.c_str())) {
438 std::ostringstream text;
439 text << "abort changes failed since cannot erase created file \'" << file_name << "\'; unlink failed with code "
440 << result << ": " << dunedaq::oks::strerror(errno);
441 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
442 }
443 }
444
445 m_created_files.clear();
446
447 // add to "updated" any modified file
448 std::set<OksFile*> updated;
449
450 for (const auto& i : m_kernel->data_files()) {
451 if (i.second->is_updated()) {
452 updated.insert(i.second);
453 TLOG_DEBUG(2) << "file \'" << i.second->get_full_file_name() << "\' was updated, to be reloaded...";
454 }
455 }
456
457 if (!m_kernel->get_user_repository_root().empty()) {
458 std::set<OksFile*> mfs, rfs;
459 try {
460 m_kernel->get_modified_files(mfs, rfs, "origin/master");
461 } catch (const oks::exception& ex) {
462 std::ostringstream text;
463 text << "failed to get differences between revisions " << m_kernel->get_repository_version()
464 << " and origin/master: " << ex.what() << '\n';
465 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str(), ex));
466 }
467 }
468
469 if (!updated.empty()) {
470 try {
471 if (!m_kernel->get_user_repository_root().empty())
473
474 m_kernel->reload_data(updated);
475 } catch (oks::exception& ex) {
476 throw(dunedaq::conffwk::Generic(ERS_HERE, "cannot reload updated data files", ex));
477 } catch (...) {
478 throw(dunedaq::conffwk::Generic(ERS_HERE, "cannot reload updated data files"));
479 }
480 }
481}
482
483static std::vector<dunedaq::conffwk::Version>
484oks2config(const std::vector<OksRepositoryVersion>& in)
485{
486 std::vector<dunedaq::conffwk::Version> out;
487 out.reserve(in.size());
488
489 for (auto& x : in)
490 out.emplace_back(x.m_commit_hash, x.m_user, x.m_date, x.m_comment, x.m_files);
491
492 return out;
493}
494
495std::vector<dunedaq::conffwk::Version>
497{
498 if (!m_kernel->get_repository_root().empty()) {
499 try {
501 } catch (const oks::exception& ex) {
502 throw(dunedaq::conffwk::Generic(ERS_HERE, "cannot get new versions", ex));
503 }
504 } else {
505 std::vector<dunedaq::conffwk::Version> out;
506
507 std::set<OksFile*> oks_files;
508 m_kernel->get_modified_files(oks_files, oks_files, "");
509
510 if (!oks_files.empty()) {
511 std::vector<std::string> files;
512
513 for (const auto& x : oks_files)
514 files.push_back(x->get_well_formed_name());
515
516 out.emplace_back("", "", 0, "", files);
517 }
518
519 return out;
520 }
521}
522
523std::vector<dunedaq::conffwk::Version>
524OksConfiguration::get_versions(const std::string& since,
525 const std::string& until,
527 bool skip_irrelevant)
528{
529 if (!m_kernel->get_repository_root().empty()) {
530 try {
532 ? m_kernel->get_repository_versions_by_date(skip_irrelevant, since, until)
533 : m_kernel->get_repository_versions_by_hash(skip_irrelevant, since, until));
534 } catch (const oks::exception& ex) {
535 throw(dunedaq::conffwk::Generic(ERS_HERE, "cannot get repository versions", ex));
536 }
537 } else {
538 throw(dunedaq::conffwk::Generic(ERS_HERE, "cannot get versions, repository is not set"));
539 }
540}
541
542}
543}
544
550
551bool
552OksConfiguration::test_object(const std::string& class_name,
553 const std::string& name,
554 unsigned long /*rlevel*/,
555 const std::vector<std::string>* /*rclasses*/)
556{
557 // Looking for the class. If it does not exist, we return false.
558 OksClass* cl = m_kernel->find_class(class_name);
559 if (!cl)
560 return false;
561
562 // The object exist for this class?
563 if (cl->get_object(name))
564 return true;
565
566 // Trying all subclasses
567 if (const OksClass::FList* subclasses = cl->all_sub_classes()) {
568 for (OksClass::FList::const_iterator it = subclasses->begin(); it != subclasses->end(); ++it) {
569 if ((*it)->get_object(name))
570 return true;
571 }
572 }
573 // If we get here, we found the class, but not the object.
574 return false;
575}
576
577void
579 const std::string& name,
581 unsigned long /*rlevel*/,
582 const std::vector<std::string>* /* rclasses */)
583{
584 if (OksClass* cl = m_kernel->find_class(class_name)) {
585 OksObject* obj = cl->get_object(name);
586 if (obj == nullptr) {
587 // try all subclasses
588 if (const OksClass::FList* subclasses = cl->all_sub_classes()) {
589 for (const auto& it : *subclasses) {
590 obj = it->get_object(name);
591 if (obj != nullptr)
592 break;
593 }
594 }
595 if (obj == nullptr) {
596 const std::string id(name + '@' + class_name);
597 throw dunedaq::conffwk::NotFound(ERS_HERE, "object", id.c_str());
598 }
599 }
600
601 object = new_object(obj);
602 } else {
603 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", class_name.c_str());
604 }
605}
606
607void
608OksConfiguration::get(const std::string& class_name,
609 std::vector<conffwk::ConfigObject>& objects,
610 const std::string& query,
611 unsigned long /*rlevel*/,
612 const std::vector<std::string>* /* rclasses */)
613{
614 if (OksClass* cl = m_kernel->find_class(class_name)) {
615 objects.clear();
616
617 OksObject::List* objs = 0;
618
619 if (query.empty()) {
620 objs = cl->create_list_of_all_objects();
621 } else {
622 try {
623 std::unique_ptr<OksQuery> qe(new OksQuery(cl, query.c_str()));
624 if (qe->good() == false) {
625 std::ostringstream text;
626 text << "bad query syntax \"" << query << "\" in scope of class \"" << class_name << '\"';
627 throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());
628 }
629 objs = cl->execute_query(qe.get()); // FIXME: check .get()
630 } catch (oks::exception& ex) {
631 std::ostringstream text;
632 text << "failed to execute query:\n" << ex.what();
633 throw dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str());
634 }
635 }
636
637 if (objs) {
638 for (OksObject::List::iterator i = objs->begin(); i != objs->end(); ++i) {
639 objects.push_back(new_object(*i));
640 }
641 delete objs;
642 }
643 } else {
644 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", class_name.c_str());
645 }
646}
647
648void
650 const std::string& query,
651 std::vector<conffwk::ConfigObject>& objects,
652 unsigned long /*rlevel*/,
653 const std::vector<std::string>* /* rclasses */)
654{
655 if (obj_from.is_null()) {
656 throw(dunedaq::conffwk::Generic(ERS_HERE, "parameter \'obj_from\' is (null)"));
657 }
658
659 OksObject* o = (static_cast<const OksConfigObject*>(obj_from.implementation()))->m_obj;
660
661 try {
662 oks::QueryPath q(query, *m_kernel);
663 if (OksObject::List* objs = o->find_path(q)) {
664 for (OksObject::List::iterator i = objs->begin(); i != objs->end(); ++i) {
665 objects.push_back(new_object(*i));
666 }
667 delete objs;
668 }
669 } catch (oks::bad_query_syntax& e) {
670 std::ostringstream text;
671 text << "bad path-query \"" << query << "\" to object " << o;
672 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
673 }
674}
675
677OksConfiguration::get(const std::string& class_name, bool direct_only)
678{
679 OksClass* c = m_kernel->find_class(class_name);
680
681 if (c == 0) {
682 throw dunedaq::conffwk::NotFound(ERS_HERE, "class", class_name.c_str());
683 }
684
686 c->get_name(), c->get_description(), c->get_file()->get_full_file_name(), c->get_is_abstract());
687
688 if (direct_only) {
689 if (const std::list<std::string*>* classes = c->direct_super_classes()) {
690 for (const auto& i : *classes) {
691 const_cast<std::vector<std::string>&>(d->p_superclasses).push_back(*i);
692 }
693 }
694 } else {
695 if (const OksClass::FList* classes = c->all_super_classes()) {
696 for (const auto& i : *classes) {
697 const_cast<std::vector<std::string>&>(d->p_superclasses).push_back(i->get_name());
698 }
699 }
700 }
701
702 if (const OksClass::FList* subclasses = c->all_sub_classes()) {
703 for (const auto& i : *subclasses) {
704 if (direct_only == false || i->has_direct_super_class(c->get_name()) == true) {
705 const_cast<std::vector<std::string>&>(d->p_subclasses).push_back(i->get_name());
706 }
707 }
708 }
709
710 if (const std::list<OksAttribute*>* attrs = (direct_only ? c->direct_attributes() : c->all_attributes())) {
711 for (const auto& i : *attrs) {
712 OksAttribute::Format format = i->get_format();
713 OksData::Type type = i->get_data_type();
714
715 const_cast<std::vector<dunedaq::conffwk::attribute_t>&>(d->p_attributes)
717 i->get_name(),
734 i->get_range(),
735 (i->is_integer() == false ? dunedaq::conffwk::na_int_format
739 i->get_is_no_null(),
740 i->get_is_multi_values(),
741 i->get_init_value(),
742 i->get_description()));
743 }
744 }
745
746 if (const std::list<OksRelationship*>* rels = (direct_only ? c->direct_relationships() : c->all_relationships())) {
747 for (const auto& i : *rels) {
748 const_cast<std::vector<dunedaq::conffwk::relationship_t>&>(d->p_relationships)
749 .push_back(dunedaq::conffwk::relationship_t(i->get_name(),
750 i->get_type(),
751 (i->get_low_cardinality_constraint() == OksRelationship::Zero),
752 (i->get_high_cardinality_constraint() == OksRelationship::Many),
753 i->get_is_composite(),
754 i->get_description()));
755 }
756 }
757
758 return d;
759}
760
761void
763{
764 schema.clear();
765
766 if (!m_kernel) {
767 return; // throw ( dunedaq::conffwk::Generic( ERS_HERE, "database is not loaded" ) );
768 }
769
770 schema.reserve(m_kernel->classes().size() * 3);
771
772 for (OksClass::Map::const_iterator i = m_kernel->classes().begin(); i != m_kernel->classes().end(); ++i) {
773 if (const OksClass::FList* scl = i->second->all_super_classes()) {
774 const std::string* name = &conffwk::DalFactory::instance().get_known_class_name_ref(i->second->get_name());
775
776 auto& subclasses = schema[name];
777
778 if (!scl->empty()) {
779 subclasses.reserve(scl->size() * 3);
780 for (OksClass::FList::const_iterator j = scl->begin(); j != scl->end(); ++j) {
781 subclasses.insert(&conffwk::DalFactory::instance().get_known_class_name_ref((*j)->get_name()));
782 }
783 }
784 }
785 }
786}
787
788void
790 const std::string& class_name,
791 const std::string& id,
792 conffwk::ConfigObject& object)
793{
794 try {
796 } catch (oks::exception& ex) {
797 throw(dunedaq::conffwk::Generic(ERS_HERE, ex.what()));
798 }
799
800 OksClass* c = m_kernel->find_class(class_name);
801
802 if (c == nullptr) {
803 std::ostringstream text;
804 text << "cannot find class \"" << class_name << '\"';
805 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
806 } else if (id.empty() == false) {
807 if (OksObject* obj = c->get_object(id)) {
808 std::ostringstream text;
809 text << "object \"" << id << '@' << class_name << "\" already exists in file \""
810 << obj->get_file()->get_full_file_name() << '\"';
811 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
812 }
813 }
814
818 }
819
820 try {
821 object = new_object(new OksObject(c, id.c_str()));
822 } catch (oks::exception& ex) {
823 throw(dunedaq::conffwk::Generic(ERS_HERE, "cannot create configuration object", ex));
824 }
825}
826
827void
828OksConfiguration::create(const std::string& at,
829 const std::string& class_name,
830 const std::string& id,
831 conffwk::ConfigObject& object)
832{
833 if (at.empty() == true) {
834 throw(dunedaq::conffwk::Generic(ERS_HERE, "parameter \'at\' (i.e. filename) cannot be empty"));
835 }
836
837 if (OksFile* h = m_kernel->find_data_file(at)) {
838 return create(h, class_name, id, object);
839 } else {
840 std::ostringstream text;
841 text << "file \"" << at << "\" is not loaded";
842 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
843 }
844}
845
846void
848 const std::string& class_name,
849 const std::string& id,
850 conffwk::ConfigObject& object)
851{
852 create((static_cast<const OksConfigObject*>(at.implementation()))->m_obj->get_file(), class_name, id, object);
853}
854
855void
857{
858 reinterpret_cast<OksConfiguration*>(p)->m_created.push_back(o);
859}
860
861void
863{
864 reinterpret_cast<OksConfiguration*>(p)->m_modified.insert(o);
865}
866
867void
869{
870 reinterpret_cast<OksConfiguration*>(p)->m_removed[o->GetClass()->get_name()].insert(o->GetId());
871}
872
874{
875
877
878 const OksConfiguration::SMap& data() const { return m_data; }
879
881};
882
884{
885 for (OksClass::Map::const_iterator i = kernel.classes().begin(); i != kernel.classes().end(); ++i)
886 if (const OksClass::FList* slist = i->second->all_super_classes()) {
887 std::set<std::string>& data(m_data[i->second->get_name()]);
888 for (const auto& j : *slist)
889 data.insert(j->get_name());
890 }
891}
892
901
902static void
903check(std::vector<conffwk::ConfigurationChange*>& changes,
904 const InheritanceData& inheritance,
905 const std::set<std::string>& class_names,
906 const OksConfiguration::SMap& objects,
907 const std::string& obj_class,
908 const std::string& obj_id,
909 const char action)
910{
911
912 bool any = (class_names.empty() && objects.empty());
913
914 // check subscription on objects
915 //
916 // omi iterator in non-null, if on an object of class 'obj_class'
917 // there is explicit subscription
918
919 OksConfiguration::SMap::const_iterator omi = objects.end();
920
921 if (action != '+') {
922 omi = objects.find(obj_class);
923 if (omi != objects.end()) {
924 std::set<std::string>::const_iterator i = omi->second.find(obj_id);
925
926 if (i != omi->second.end()) {
927 conffwk::ConfigurationChange::add(changes, obj_class, obj_id, action);
928 }
929 }
930 }
931
932 // process the class
933
934 if (action == '+' || omi == objects.end()) {
935 if (any || class_names.find(obj_class) != class_names.end()) {
936 conffwk::ConfigurationChange::add(changes, obj_class, obj_id, action);
937 }
938 }
939
940 // process subclasses
941
942 OksConfiguration::SMap::const_iterator it = inheritance.data().find(obj_class);
943 if (it != inheritance.data().end()) {
944 for (std::set<std::string>::const_iterator j = it->second.begin(); j != it->second.end(); ++j) {
945 omi = (action != '+' ? objects.find(*j) : objects.end());
946
947 // 1. add objects if criteria is 'any'
948 // 2. add object of class which has subscription and has no explicit object subscription
949 // 3. add explicitly subscribed object
950
951 if (any || (omi == objects.end() && class_names.find(*j) != class_names.end()) ||
952 (omi != objects.end() && omi->second.find(obj_id) != omi->second.end())) {
953 conffwk::ConfigurationChange::add(changes, *j, obj_id, action);
954 }
955 }
956 }
957}
958
960{
961
962public:
964 : m_kernel(kernel)
965 {
966 ;
967 }
968
969 ~DestroyGuard1() { m_kernel.subscribe_delete_object(0, 0); }
970
971private:
973};
974
976{
977
978public:
980 : m_removed(removed)
981 {
982 ;
983 }
984
986
987private:
989};
990
991void
993{
994 OksObject* o((static_cast<const OksConfigObject*>(obj.implementation()))->m_obj);
995
996 DestroyGuard2 dg2(m_removed); // => on exit from method, call m_removed.clear();
997
998 InheritanceData inheritance(*m_kernel);
999
1000 try {
1001 m_kernel->subscribe_delete_object(delete_notify, reinterpret_cast<void*>(this));
1002 DestroyGuard1 dg1(*m_kernel); // => on exit from try block, call m_kernel->subscribe_delete_object(0, 0);
1004 } catch (oks::exception& ex) {
1005 throw(dunedaq::conffwk::Generic(ERS_HERE, ex.what()));
1006 }
1007
1008 if (m_conf) {
1009 std::vector<conffwk::ConfigurationChange*> changes;
1010
1011 for (SMap::iterator i = m_removed.begin(); i != m_removed.end(); ++i) {
1012 for (std::set<std::string>::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
1013 check(changes, inheritance, m_class_names, m_objects, i->first, *j, '-');
1014 }
1015 }
1016
1017 if (!changes.empty()) {
1018 m_conf->update_cache(changes);
1020 }
1021 }
1022}
1023
1024bool
1025OksConfiguration::is_writable(const std::string& db_name)
1026{
1027 if (OksFile* h = m_kernel->find_data_file(db_name)) {
1028 try {
1029 if (!m_kernel->get_user_repository_root().empty()) {
1031 } else {
1032 return !OksKernel::check_read_only(h);
1033 }
1034 } catch (const std::exception& ex) {
1035 std::ostringstream text;
1036 text << "cannot check access status of file \'" << db_name << "\': " << ex.what();
1037 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
1038 }
1039 } else {
1040 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_no_file_error_text(db_name).c_str()));
1041 }
1042}
1043
1044static std::string
1045mk_rm_include_error_text(const std::string& db, const std::string& include, const char* error = 0)
1046{
1047 std::ostringstream text;
1048 text << "cannot remove include file \'" << include << "\' from \'" << db << '\'';
1049 if (error)
1050 text << ":\n" << error;
1051 return text.str();
1052}
1053
1054void
1055OksConfiguration::add_include(const std::string& db_name, const std::string& include)
1056{
1057 if (OksFile* h = m_kernel->find_data_file(db_name)) {
1058 try {
1059 h->add_include_file(include);
1060 } catch (dunedaq::conffwk::Generic& ex) {
1061 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_add_include_error_text(db_name, include).c_str()), ex);
1062 } catch (oks::exception& ex) {
1063 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_add_include_error_text(db_name, include, ex.what()).c_str()));
1064 } catch (...) {
1065 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_add_include_error_text(db_name, include).c_str()));
1066 }
1067 } else {
1068 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_no_file_error_text(db_name).c_str()));
1069 }
1070}
1071
1072void
1073OksConfiguration::remove_include(const std::string& db_name, const std::string& include)
1074{
1075 InheritanceData inheritance(*m_kernel);
1076
1077 DestroyGuard2 dg2(m_removed); // => on exit from method, call m_removed.clear();
1078
1079 if (OksFile* h = m_kernel->find_data_file(db_name)) {
1080 try {
1081 m_kernel->subscribe_delete_object(delete_notify, reinterpret_cast<void*>(this));
1082 DestroyGuard1 dg1(*m_kernel); // => on exit from try block, call m_kernel->subscribe_delete_object(0, 0);
1083 h->remove_include_file(include);
1084 } catch (dunedaq::conffwk::Generic& ex) {
1085 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_rm_include_error_text(db_name, include).c_str()), ex);
1086 } catch (oks::exception& ex) {
1087 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_rm_include_error_text(db_name, include, ex.what()).c_str()));
1088 } catch (...) {
1089 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_rm_include_error_text(db_name, include).c_str()));
1090 }
1091 } else {
1092 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_no_file_error_text(db_name).c_str()));
1093 }
1094
1095 std::vector<conffwk::ConfigurationChange*> changes;
1096
1097 for (SMap::iterator i = m_removed.begin(); i != m_removed.end(); ++i) {
1098 for (std::set<std::string>::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
1099 check(changes, inheritance, m_class_names, m_objects, i->first, *j, '-');
1100 }
1101 }
1102
1103 if (!changes.empty()) {
1104 m_conf->update_cache(changes);
1106 }
1107}
1108
1109void
1110OksConfiguration::get_includes(const std::string& db_name, std::list<std::string>& includes) const
1111{
1112 if (db_name.empty()) {
1113 for (auto& i : m_kernel->data_files()) {
1114 if (i.second->get_parent() == nullptr)
1115 includes.push_back(*i.first);
1116 }
1117 } else {
1118 if (OksFile* h = m_kernel->find_data_file(db_name)) {
1119 for (auto& i : h->get_include_files()) {
1120 includes.push_back(i);
1121 }
1122 } else {
1123 throw(dunedaq::conffwk::Generic(ERS_HERE, mk_no_file_error_text(db_name).c_str()));
1124 }
1125 }
1126}
1127
1128void
1130{
1131 static const std::string version("origin/master");
1132
1133 if (m_fn) {
1134 std::set<OksFile*> ufs, rfs;
1135
1136 try {
1139 } catch (const oks::RepositoryOperationFailed& ex) {
1140 std::ostringstream text;
1141 text << "cannot get modified repository files (attempt " << ++m_repo_error_count << "): " << ex.what();
1142 ers::error(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
1143 } catch (const oks::exception& ex) {
1144 std::ostringstream text;
1145 text << "cannot get modified files: " << ex.what();
1146 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
1147 }
1148
1149 for (const auto& x : ufs) {
1150 if (x->get_oks_format() == "schema") {
1151 std::ostringstream text;
1152 text << "reload of schema files is not supported (\'" << x->get_well_formed_name() << "\')";
1153 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
1154 }
1155 }
1156
1157 if (ufs.empty() == false) {
1158 InheritanceData inheritance(*m_kernel);
1159
1160 m_kernel->subscribe_create_object(create_notify, reinterpret_cast<void*>(this));
1161 m_kernel->subscribe_change_object(change_notify, reinterpret_cast<void*>(this));
1162 m_kernel->subscribe_delete_object(delete_notify, reinterpret_cast<void*>(this));
1163
1164 (*m_pre_fn)(m_conf);
1165
1166 try {
1167 if (!m_kernel->get_user_repository_root().empty())
1169
1170 m_kernel->reload_data(ufs, false);
1171 } catch (oks::exception& ex) {
1172 close_database(false);
1173 m_fn = 0;
1174 std::ostringstream text;
1175 text << "failed to reload updated files:\n" << ex.what();
1176 throw(dunedaq::conffwk::Generic(ERS_HERE, text.str().c_str()));
1177 } catch (...) {
1178 close_database(false);
1179 m_fn = 0;
1180 throw(dunedaq::conffwk::Generic(ERS_HERE, "failed to reload updated files"));
1181 }
1182
1186
1187 std::vector<conffwk::ConfigurationChange*> changes;
1188
1189 {
1190 for (auto& i : m_created) {
1191 check(changes, inheritance, m_class_names, m_objects, i->GetClass()->get_name(), i->GetId(), '+');
1192
1193 std::set<OksObject*>::iterator j = m_modified.find(i);
1194 if (j != m_modified.end()) {
1195 TLOG_DEBUG(1) << "created object " << i << " appears in \'modified\' set, removing...";
1196 m_modified.erase(j);
1197 }
1198 }
1199 }
1200
1201 {
1202 for (auto& i : m_modified) {
1203 if (m_kernel->is_dangling(i)) {
1204 TLOG_DEBUG(1) << "object " << (void*)(i) << " is dangling, ignore...";
1205 } else {
1206 check(changes, inheritance, m_class_names, m_objects, i->GetClass()->get_name(), i->GetId(), '~');
1207 }
1208 }
1209 }
1210
1211 {
1212 for (auto& i : m_removed) {
1213 for (auto& j : i.second) {
1214 check(changes, inheritance, m_class_names, m_objects, i.first, j, '-');
1215 }
1216 }
1217 }
1218
1219 if (!changes.empty()) {
1220 (*m_fn)(changes, m_conf);
1222 }
1223
1224 m_created.clear();
1225 m_modified.clear();
1226 m_removed.clear();
1227 }
1228 } else {
1229 throw(dunedaq::conffwk::Generic(ERS_HERE, "no subscription has been done"));
1230 }
1231}
1232
1233//
1234// Subscribe on changes by class name
1235//
1236
1237void
1238OksConfiguration::subscribe(const std::set<std::string>& class_names,
1239 const SMap& objs,
1240 ConfigurationImpl::notify cb,
1241 ConfigurationImpl::pre_notify pre_cb)
1242{
1243 m_fn = cb;
1244 m_pre_fn = pre_cb;
1245 m_class_names = class_names;
1246 m_objects = objs;
1247
1248 subscribe();
1249}
1250
1251// Start subscription thread
1252
1253void
1255{
1256 if (m_check_db_obj == 0) {
1257 TLOG_DEBUG(2) << "starting CheckDB thread ...";
1259 m_check_db_thread = new std::thread(std::ref(*m_check_db_obj));
1260 }
1261}
1262
1263//
1264// Unsubscribe
1265//
1266
1267void
1269{
1270 if (m_check_db_obj) {
1271 TLOG_DEBUG(2) << "stopping CheckDB thread ...";
1272 m_check_db_obj->m_run = false;
1273 m_check_db_thread->join(); // wait thread termination
1274 delete m_check_db_thread;
1276 m_check_db_obj = 0;
1277 TLOG_DEBUG(2) << "the CheckDB thread has been terminated";
1278 }
1279}
1280
1281void
1283{
1284 std::cout << "OksConfiguration profiler report:\n"
1285 " number of loaded schema files: "
1286 << (m_kernel ? m_kernel->schema_files().size() : 0)
1287 << "\n"
1288 " number of loaded data files: "
1289 << (m_kernel ? m_kernel->data_files().size() : 0)
1290 << "\n"
1291 " number of loaded classes: "
1292 << (m_kernel ? m_kernel->classes().size() : 0)
1293 << "\n"
1294 " number of loaded objects: "
1295 << (m_kernel ? m_kernel->objects().size() : 0) << std::endl;
1296}
1297
1298// read OksKernel parameters from environment (silence mode)
1299
1300void
1302{
1303 m_oks_kernel_silence = (getenv("OKSCONFLIBS_NO_KERNEL_SILENCE") == nullptr);
1304}
#define ERS_HERE
static void throw_update_exception(const OksFile *file_h, const char *action, const char *reason)
conffwk::ConfigurationImpl * _oksconflibs_creator_(const std::string &spec)
static std::string mk_no_file_error_text(const std::string &db)
static void check(std::vector< conffwk::ConfigurationChange * > &changes, const InheritanceData &inheritance, const std::set< std::string > &class_names, const OksConfiguration::SMap &objects, const std::string &obj_class, const std::string &obj_id, const char action)
bool is_repo_name(const std::string &name)
static std::string mk_add_include_error_text(const std::string &db, const std::string &include, const char *error=nullptr)
static std::string mk_rm_include_error_text(const std::string &db, const std::string &include, const char *error=0)
#define sleep(x)
Definition WIB_FEMB.cpp:12
DestroyGuard1(OksKernel &kernel)
DestroyGuard2(OksConfiguration::SMap &removed)
OksConfiguration::SMap & m_removed
Represents database objects.
bool is_null() const noexcept
Check if object's implementation points to null.
const ConfigObjectImpl * implementation() const noexcept
Returns pointer on implementation.
static void clear(std::vector< ConfigurationChange * > &changes)
Helper method to clear vector of changes (pointers).
static void add(std::vector< ConfigurationChange * > &changes, const std::string &class_name, const std::string &obj_id, const char action)
Helper method to add object to the vector of existing changes.
Provides pure virtual interface used by the Configuration class.
void clean() noexcept
clean cache (e.g. to be used by destructor)
Configuration * m_conf
Configuration pointer is needed for notification on changes, e.g. in case of subscription or an objec...
T * insert_object(OBJ &obj, const std::string &id, const std::string &class_name) noexcept
insert new object (update cache or create-and-insert)
void update_cache(std::vector< ConfigurationChange * > &changes) noexcept
System function invoked in case of modifications.
The OKS class.
Definition class.hpp:223
const FList * all_sub_classes() const noexcept
Definition class.hpp:463
std::list< OksClass *, boost::fast_pool_allocator< OksClass * > > FList
Definition class.hpp:254
OksObject * get_object(const std::string &id) const noexcept
Get object by ID.
Definition class.cpp:1479
Provides interface to the OKS XML schema and data files.
Definition file.hpp:355
void add_include_file(const std::string &name)
Add include file.
Definition file.cpp:1157
void add_comment(const std::string &text, const std::string &author)
Add new comment to file.
Definition file.cpp:687
bool is_updated() const
Return update status of OKS file.
Definition file.hpp:619
const std::string & get_full_file_name() const
Definition file.hpp:528
FileStatus get_status_of_file() const
Return update status of file.
Definition file.cpp:1394
Provides interface to the OKS kernel.
Definition kernel.hpp:615
static const std::string & get_repository_mapping_dir()
Get OKS repository name.
Definition kernel.cpp:318
void subscribe_change_object(OksObject::notify_obj, void *)
Subscribe on object changing.
Definition kernel.hpp:2117
const std::string & get_user_repository_root() const
Get user OKS repository root.
Definition kernel.cpp:335
void subscribe_delete_object(OksObject::notify_obj, void *)
Subscribe on object deleting.
Definition kernel.hpp:2124
OksFile * load_file(const std::string &name, bool bind=true)
Load OKS database file.
Definition kernel.cpp:1625
static std::string & get_user_name()
Get username of given process.
Definition kernel.cpp:427
bool is_dangling(OksClass *class_ptr) const
Check pointer on oks class.
Definition kernel.cpp:4415
static bool check_read_only(OksFile *f)
Check if the OKS file is read-only.
Definition kernel.cpp:1394
void update_repository(const std::string &hash_val, RepositoryUpdateType update_type)
Update user repository files from origin by hash.
Definition kernel.hpp:1573
void get_modified_files(std::set< OksFile * > &mfs, std::set< OksFile * > &rfs, const std::string &version)
Get modified data files.
Definition kernel.cpp:2817
const OksFile::Map & data_files() const
Get all data files.
Definition kernel.hpp:1472
OksFile * new_data(const std::string &name, const std::string &logical_name="", const std::string &type="")
Create OKS data file.
Definition kernel.cpp:3500
OksFile * find_data_file(const std::string &s) const
Finds OKS data file.
Definition kernel.cpp:2119
bool is_user_repository_created() const
Definition kernel.hpp:952
void registrate_all_classes(bool skip_registered=false)
The method rebuilds all classes taking into account inheritance.
Definition kernel.cpp:4271
const OksObject::Set & objects() const
Get objects.
Definition kernel.hpp:1732
bool get_test_duplicated_objects_via_inheritance_mode() const
Get status of test inherited duplicated objects mode. The method returns true, if the mode is switche...
Definition kernel.hpp:791
OksKernel(bool silence_mode=false, bool verbose_mode=false, bool profiling_mode=false, bool allow_repository=true, const char *version=nullptr, std::string branch_name="")
Constructor to build OksKernel object.
Definition kernel.cpp:675
void reload_data(std::set< OksFile * > &files, bool allow_schema_extension=true)
Reload OKS data files.
Definition kernel.cpp:3000
const OksClass::Map & classes() const
Get classes.
Definition kernel.hpp:1711
std::vector< OksRepositoryVersion > get_repository_versions_by_date(bool skip_irrelevant=true, const std::string &since="", const std::string &until="")
Return repository versions between timestamps.
Definition kernel.cpp:5238
void subscribe_create_object(OksObject::notify_obj cb_f, void *parameter)
Subscribe on object creation.
Definition kernel.hpp:2110
void close_all_data()
Close all OKS data files.
Definition kernel.cpp:4027
void save_data(OksFile *file_h, bool ignore_bad_objects=false, OksFile *true_file_h=nullptr, bool force_defaults=false)
Save OKS data file.
Definition kernel.cpp:3572
void set_test_duplicated_objects_via_inheritance_mode(const bool b)
Set status of test inherited duplicated objects mode. To switch 'On'/'Off' use the method's parameter...
Definition kernel.hpp:782
void bind_objects()
Bind oks objects.
Definition kernel.cpp:4138
static const std::string & get_repository_root()
Get OKS repository root.
Definition kernel.cpp:280
void commit_repository(const std::string &comments, const std::string &credentials="")
Commit user modifications into repository.
Definition kernel.cpp:4828
const std::string & get_repository_version()
Definition kernel.hpp:950
void close_data(OksFile *file_h, bool unbind_objects=true)
Close OKS data file.
Definition kernel.cpp:3966
static const char * get_cwd()
Definition kernel.cpp:636
std::vector< OksRepositoryVersion > get_repository_versions_by_hash(bool skip_irrelevant=true, const std::string &sha1="", const std::string &sha2="")
Return repository versions between hash keys.
Definition kernel.cpp:5208
OksClass * find_class(const std::string &class_name) const
Find class by name (C++ string).
Definition kernel.hpp:1754
void close_all_schema()
Close all OKS schema files.
Definition kernel.cpp:2679
void set_active_data(OksFile *file_h)
Set active OKS data file.
Definition kernel.cpp:4062
const OksFile::Map & schema_files() const
Get all schema files.
Definition kernel.hpp:1211
OksObject describes instance of OksClass.
Definition object.hpp:1144
static void destroy(OksObject *obj, bool fast=false)
Destroy OKS object.
Definition object.cpp:1284
std::list< OksObject * > List
Definition object.hpp:1179
OksObject(const OksClass *oks_class, const char *object_id=0, bool skip_init=false)
OKS object constructor.
Definition object.cpp:1151
OksObject::List * find_path(const oks::QueryPath &query) const
Definition query.cpp:923
OksQuery(bool b, OksQueryExpression *q=0)
Definition query.hpp:42
String tokenizer.
Definition defs.hpp:59
const std::string next()
Definition time.cpp:190
static void substitute_variables(std::string &)
Definition kernel.cpp:525
static bool real_path(std::string &, bool ignore_errors)
Definition kernel.cpp:546
Cannot commit, checkout or release files.
Definition kernel.hpp:116
virtual const char * what() const noexcept
virtual bool test_object(const std::string &class_name, const std::string &name, unsigned long rlevel, const std::vector< std::string > *rclasses)
Test object existence (used by Python binding).
conffwk::ConfigurationImpl::pre_notify m_pre_fn
static void change_notify(oks::OksObject *, void *) noexcept
virtual void open_db(const std::string &db_name)
Open database implementation in accordance with given name.
static void delete_notify(oks::OksObject *, void *) noexcept
virtual void subscribe(const std::set< std::string > &class_names, const SMap &objs, ConfigurationImpl::notify cb, ConfigurationImpl::pre_notify pre_cb)
std::list< oks::OksObject * > m_created
virtual void print_profiling_info() noexcept
Print implementation specific profiling information.
std::set< oks::OksObject * > m_modified
virtual void get_includes(const std::string &db_name, std::list< std::string > &includes) const
Get included files.
virtual void destroy(conffwk::ConfigObject &object)
Destroy object of class by id.
static void create_notify(oks::OksObject *, void *) noexcept
virtual void remove_include(const std::string &db_name, const std::string &include)
Remove include file.
OksConfigObject * new_object(oks::OksObject *obj) noexcept
virtual void get_updated_dbs(std::list< std::string > &dbs) const
Get uncommitted files.
virtual void close_db()
Close database implementation.
std::map< std::string, std::set< std::string > > SMap
std::map< std::string, std::set< std::string > > m_removed
virtual void set_commit_credentials(const std::string &user, const std::string &password)
Set commit credentials.
virtual std::vector< dunedaq::conffwk::Version > get_versions(const std::string &since, const std::string &until, dunedaq::conffwk::Version::QueryType type, bool skip_irrelevant)
Get archived versions.
virtual void unsubscribe()
Remove subscription on database changes.
std::set< oks::OksFile * > m_created_files
virtual void add_include(const std::string &db_name, const std::string &include)
Add include file.
virtual std::vector< dunedaq::conffwk::Version > get_changes()
Get newly available versions.
virtual void create(const std::string &at, const std::string &class_name, const std::string &id, conffwk::ConfigObject &object)
Create object of class by id at given file.
virtual void abort()
Abort database changes.
virtual void get_superclasses(conffwk::fmap< conffwk::fset > &schema)
Get inheritance hierarchy.
virtual bool is_writable(const std::string &db_name)
Return write access status.
virtual void get(const std::string &class_name, const std::string &name, conffwk::ConfigObject &object, unsigned long rlevel, const std::vector< std::string > *rclasses)
Get object of class by id.
virtual void commit(const std::string &why)
Commit database changes.
conffwk::ConfigurationImpl::notify m_fn
conffwk entry point
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:116
const std::string strerror(int error)
Convert C error number to string.
Definition kernel.cpp:111
static std::vector< dunedaq::conffwk::Version > oks2config(const std::vector< OksRepositoryVersion > &in)
bool is_writable(const oks::OksFile &file, const std::string &user=oks::OksKernel::get_user_name())
The DUNE-DAQ namespace.
FELIX Initialization std::string initerror FELIX queue timed out
msgpack::object obj
ERS_DECLARE_ISSUE(cibmodules, CIBCommunicationError, " CIB Hardware Communication Error: "<< descriptor,((std::string) descriptor)) ERS_DECLARE_ISSUE(cibmodules
FELIX Initialization std::string initerror FELIX queue timed std::string queuename Unexpected chunk size
CIB Buffer std::string descriptor Message from std::string descriptor CIB process error
void fatal(const Issue &issue)
Definition ers.hpp:111
void error(const Issue &issue)
Definition ers.hpp:101
InheritanceData(const OksKernel &)
const OksConfiguration::SMap & data() const
OksConfiguration::SMap m_data