5#include <unordered_map>
39 type << " \"" << data << "\" is not found",
49 "
object \'" << object_id << '@' << class_name << "\' was deleted",
51 ((const
char*)class_name)
52 ((const
char*)object_id)
58template <
typename T>
static T*
get_new(ConfigObject& co,
59 const std::string& attrname) {
61 co.get(attrname, *retval);
68 std::lock_guard<std::mutex> scoped_lock(m_actn_mutex);
69 m_actions.push_back(ac);
75 std::lock_guard<std::mutex> scoped_lock(m_actn_mutex);
80Configuration::action_on_update(
const ConfigObject& obj,
const std::string& name)
82 std::lock_guard<std::mutex> scoped_lock(m_actn_mutex);
83 for (
auto &i : m_actions)
92 return (getenv(
"TDAQ_DB_PREFETCH_ALL_DATA") !=
nullptr);
97Configuration::Configuration() :
98 p_number_of_cache_hits(0), p_number_of_template_object_created(0), p_number_of_template_object_read(0), m_impl(nullptr), m_shlib_h(nullptr), m_registry(*this){
103 p_number_of_cache_hits(0), p_number_of_template_object_created(0), p_number_of_template_object_read(0), m_impl(nullptr), m_shlib_h(nullptr), m_registry(*this)
109 if (const char *env = getenv(
"TDAQ_DB"))
120 std::string::size_type idx =
m_impl_spec.find_first_of(
':');
122 if (idx == std::string::npos)
132 std::string plugin_name = std::string(
"lib") +
m_impl_name +
".so";
133 std::string impl_creator = std::string(
"_") +
m_impl_name +
"_creator_";
136 m_shlib_h = dlopen(plugin_name.c_str(), RTLD_LAZY | RTLD_GLOBAL);
140 std::ostringstream text;
141 text <<
"failed to load implementation plug-in \'" << plugin_name <<
"\': \"" << dlerror() <<
'\"';
148 (*f)(
const std::string& spec);
151 (*)(
const std::string&))dlsym(
m_shlib_h, impl_creator.c_str());
155 if ((
error = dlerror()) != 0)
157 std::ostringstream text;
158 text <<
"failed to find implementation creator function \'" << impl_creator <<
"\' in plug-in \'" << plugin_name <<
"\': \"" <<
error <<
'\"';
178 TLOG_DEBUG(2) <<
"\n*** DUMP CONFIGURATION ***\n" << *
this;
185 std::lock_guard < std::mutex > scoped_lock(
m_impl_mutex);
187 std::cout <<
"Configuration profiler report:\n"
216 if (::getenv(
"TDAQ_DUMP_CONFFWK_PROFILER_INFO"))
243 _get(class_name,
id,
object, rlevel, rclasses);
247Configuration::_get(
const std::string& class_name,
const std::string& name,
ConfigObject&
object,
unsigned long rlevel,
const std::vector<std::string> * rclasses)
251 m_impl->
get(class_name, name,
object, rlevel, rclasses);
255 std::ostringstream text;
256 text <<
"failed to get object \'" << name <<
'@' << class_name <<
'\'';
262Configuration::get(
const std::string& class_name, std::vector<ConfigObject>& objects,
const std::string& query,
unsigned long rlevel,
const std::vector<std::string> * rclasses)
267 m_impl->
get(class_name, objects, query, rlevel, rclasses);
271 std::ostringstream text;
272 text <<
"failed to get objects of class \'" << class_name <<
'\'';
275 text <<
" with query \'" << query <<
'\'';
282Configuration::get(
const ConfigObject& obj_from,
const std::string& query, std::vector<ConfigObject>& objects,
unsigned long rlevel,
const std::vector<std::string> * rclasses)
287 m_impl->
get(obj_from, query, objects, rlevel, rclasses);
291 std::ostringstream text;
292 text <<
"failed to get path \'" << query <<
"\' from object \'" << obj_from <<
'\'';
316 const char * s = ::getenv(
"TDAQ_DB_NAME");
317 if (s == 0 || *s == 0)
318 s = ::getenv(
"TDAQ_DB_DATA");
359 TLOG_DEBUG(2) <<
"\n*** DUMP CONFIGURATION ***\n" << *
this;
407 for (
auto& a : *l.second)
445 std::ostringstream text;
446 text <<
"failed to create database \'" << db_name <<
'\'';
466 std::ostringstream text;
467 text <<
"failed to get write access status for database \'" << db_name<<
'\'';
490 std::ostringstream text;
491 text <<
"failed to add include \'" << include <<
"\' to database \'" << db_name<<
'\'';
514 std::ostringstream text;
515 text <<
"failed to remove include \'" << include <<
"\' from database \'" << db_name<<
'\'';
534 std::ostringstream text;
535 text <<
"failed to get includes of database \'" << db_name<<
'\'';
646 if (unread_implementation_objs)
649 unread_template_objects();
663 for (
auto &i : m_impl->m_impl_objects)
664 for (
auto &j : *i.second)
666 std::lock_guard<std::mutex> scoped_lock(j.second->m_mutex);
668 j.second->m_state = state;
671 for (
auto& x : m_impl->m_tangled_objects)
673 std::lock_guard<std::mutex> scoped_lock(x->m_mutex);
686 for (
const auto &j : i.second)
701std::deque<std::set<std::string>>
704 std::deque<std::set<std::string>> domains;
706 std::deque<dunedaq::conffwk::class_t> seeds;
709 if (ci.p_superclasses.empty())
713 for (
const auto& ci : seeds) {
715 std::set<std::string> class_domain;
716 class_domain.insert(ci.p_name);
717 class_domain.insert(ci.p_subclasses.begin(), ci.p_subclasses.end());
720 std::deque<std::set<std::string>> overlapping;
721 for (
auto& d : domains) {
722 std::set<std::string> intersection;
723 std::set_intersection(d.begin(), d.end(), class_domain.begin(), class_domain.end(), std::inserter(intersection, intersection.begin()));
725 if (intersection.size() > 0) {
726 overlapping.push_back(d);
732 if ( !overlapping.empty() ) {
733 for(
auto& d : overlapping ) {
735 class_domain.insert(d.begin(), d.end());
737 auto it = std::find(domains.begin(), domains.end(), d);
738 if (it!= domains.end()) {
744 domains.push_back(class_domain);
757 for(
size_t i(0); i<domains.size(); ++i ) {
758 const auto& dom = domains[i];
759 for(
const auto& class_name : dom ) {
760 p_class_domain_map[&conffwk::DalFactory::instance().get_known_class_name_ref(class_name)] = i;
775Configuration::test_object(
const std::string& class_name,
const std::string&
id,
unsigned long rlevel,
const std::vector<std::string> * rclasses)
784 std::ostringstream text;
785 text <<
"failed to test existence of object \'" <<
id <<
'@' << class_name <<
'\'';
800 std::ostringstream text;
801 text <<
"failed to create object \'" <<
id <<
'@' << class_name <<
'\'';
816 std::ostringstream text;
817 text <<
"failed to create object \'" <<
id <<
'@' << class_name <<
'\'';
834 std::ostringstream text;
835 text <<
"failed to destroy object \'" <<
object <<
'\'';
844 std::lock_guard<std::mutex> scoped_impl_lock(
m_tmpl_mutex);
845 std::lock_guard<std::mutex> scoped_tmpl_lock(
m_impl_mutex);
847 std::lock_guard<std::mutex> scoped_obj_lock(obj.m_impl->m_mutex);
849 const std::string old_id(obj.m_impl->m_id);
851 obj.m_impl->throw_if_deleted();
852 obj.m_impl->rename(new_id);
853 obj.m_impl->m_id = new_id;
856 TLOG_DEBUG(3) <<
" * call rename \'" << old_id <<
"\' to \'" << new_id <<
"\' in class \'" << obj.class_name() <<
"\')";
901 if (i != d_cache.end())
907 d_cache[class_name] = d;
913 std::ostringstream text;
914 text <<
"failed to get description of class \'" << class_name <<
'\'';
922init_regex(std::unique_ptr<std::regex>& ptr,
const std::string& str,
const char * what)
927 ptr = std::make_unique<std::regex>(str);
929 catch (
const std::regex_error &ex)
931 std::ostringstream text;
932 text <<
"failed to create " << what <<
" regex \"" << str <<
"\": " << ex.what();
942 boost::property_tree::ptree child;
944 pt.push_back(std::make_pair(
"", child));
950 std::unique_ptr<std::regex> classes_regex;
952 init_regex(classes_regex, classes_str,
"classes");
954 auto cmp_str_ptr = [](
const std::string * s1,
const std::string * s2) {
return *s1 < *s2; };
955 std::set<
const std::string *,
decltype(cmp_str_ptr)> sorted_classes(cmp_str_ptr);
958 if (classes_str.empty() || std::regex_match(*c.first, *classes_regex.get()))
959 sorted_classes.insert(c.first);
961 for (
const auto &c : sorted_classes)
962 if (classes_str.empty() || std::regex_match(*c, *classes_regex.get()))
966 boost::property_tree::ptree class_pt;
968 class_pt.put(
"abstract", info.p_abstract);
969 if (!info.p_description.empty())
970 class_pt.put(
"description", info.p_description);
972 if (!info.p_superclasses.empty())
976 for (
const auto &x : info.p_superclasses)
982 if (!info.p_attributes.empty())
984 boost::property_tree::ptree attributes;
986 for (
const auto &x : info.p_attributes)
988 boost::property_tree::ptree attribute;
991 if (!x.p_range.empty())
992 attribute.put(
"range", x.p_range);
996 attribute.put(
"is-not-null", x.p_is_not_null);
997 if (x.p_is_multi_value)
998 attribute.put(
"is-multi-value", x.p_is_multi_value);
999 if (!x.p_default_value.empty())
1000 attribute.put(
"default-value", x.p_default_value);
1001 if (!x.p_description.empty())
1002 attribute.put(
"description", x.p_description);
1004 attributes.push_back(boost::property_tree::ptree::value_type(x.p_name, attribute));
1007 class_pt.add_child(
"attributes", attributes);
1010 if (!info.p_relationships.empty())
1012 boost::property_tree::ptree relationships;
1014 for (
const auto &x : info.p_relationships)
1016 boost::property_tree::ptree relationship;
1018 relationship.put(
"type", x.p_type);
1020 if (!x.p_is_aggregation)
1021 relationship.put(
"is-aggregation", x.p_is_aggregation);
1022 if (!x.p_description.empty())
1023 relationship.put(
"description", x.p_description);
1025 relationships.push_back(boost::property_tree::ptree::value_type(x.p_name, relationship));
1028 class_pt.add_child(
"relationships", relationships);
1031 pt.put_child(boost::property_tree::ptree::path_type(*c), class_pt);
1039 auto &o =
const_cast<ConfigObject&
>(obj);
1040 if (!attribute.p_is_multi_value)
1043 const_cast<ConfigObject&
>(obj).get(attribute.p_name, val);
1044 pt.put(attribute.p_name, val);
1048 std::vector<T> values;
1049 o.get(attribute.p_name, values);
1051 boost::property_tree::ptree children;
1053 if (!values.empty())
1054 for (
const auto &v : values)
1057 else if (!empty_array_item.empty())
1060 pt.add_child(attribute.p_name, children);
1069 std::vector<ConfigObject> values;
1070 const_cast<ConfigObject&
>(obj).get(relationship.
p_name, values);
1072 boost::property_tree::ptree children;
1074 if (!values.empty())
1075 for (
const auto &v : values)
1078 else if (!empty_array_item.empty())
1081 pt.add_child(relationship.
p_name, children);
1086 const_cast<ConfigObject&
>(obj).get(relationship.
p_name, val);
1087 pt.put(relationship.
p_name, !val.is_null() ? val.full_name() :
"");
1092Configuration::export_data(boost::property_tree::ptree& pt,
const std::string& classes_str,
const std::string& objects_str,
const std::string& files_str,
const std::string& empty_array_item)
1094 std::unique_ptr<std::regex> classes_regex, objects_regex, files_regex;
1096 init_regex(classes_regex, classes_str,
"classes");
1097 init_regex(objects_regex, objects_str,
"objects");
1100 auto cmp_str_ptr = [](
const std::string * s1,
const std::string * s2) {
return *s1 < *s2; };
1101 std::set<
const std::string *,
decltype(cmp_str_ptr)> sorted_classes(cmp_str_ptr);
1104 if (classes_str.empty() || std::regex_match(*c.first, *classes_regex.get()))
1105 sorted_classes.insert(c.first);
1107 for (
const auto &c : sorted_classes)
1108 if (classes_str.empty() || std::regex_match(*c, *classes_regex.get()))
1112 boost::property_tree::ptree pt_objects;
1114 std::vector<ConfigObject> objects;
1118 std::set<
const ConfigObject *,
decltype(comp_obj_ptr)> sorted_objects(comp_obj_ptr);
1120 for (
const auto& x : objects)
1121 if (objects_str.empty() || std::regex_match(x.UID(), *objects_regex.get()))
1122 if (x.class_name() == *c)
1123 if(files_str.empty() || std::regex_match(x.contained_in(), *files_regex.get()))
1124 sorted_objects.insert(&x);
1126 if (!sorted_objects.empty())
1128 boost::property_tree::ptree pt_objects;
1130 for (
const auto& x : sorted_objects)
1132 boost::property_tree::ptree data;
1134 for (
const auto &a : info.p_attributes)
1178 throw std::runtime_error(
"Invalid type of attribute " + a.p_name);
1182 for (
const auto &r : info.p_relationships)
1183 add_data(data, *x, r, empty_array_item);
1185 pt_objects.push_back(boost::property_tree::ptree::value_type(x->UID(), data));
1188 pt.put_child(boost::property_tree::ptree::path_type(*c), pt_objects);
1202std::vector<dunedaq::conffwk::Version>
1217std::vector<dunedaq::conffwk::Version>
1261 Configuration::CallbackSubscription * cs =
new CallbackSubscription();
1263 cs->m_criteria = criteria;
1265 cs->m_param = parameter;
1295 CallbackPreSubscription * cs =
new CallbackPreSubscription();
1298 cs->m_param = parameter;
1305 return reinterpret_cast<CallbackSubscription *
>(cs);
1312 std::lock_guard < std::mutex > scoped_lock(
m_else_mutex);
1331 std::ostringstream text;
1332 text <<
"unsubscription failed for CallbackId = " << (
void *)
id <<
" (no such callback id found)";
1373 std::set<std::string> class_subscriptions;
1377 bool found_subscribe_all =
false;
1380 if (i->m_criteria.get_classes_subscription().empty() && i->m_criteria.get_objects_subscription().empty())
1382 found_subscribe_all =
true;
1386 if (found_subscribe_all ==
false)
1390 for (
const auto &j : i->m_criteria.get_classes_subscription())
1391 class_subscriptions.insert(j);
1395 for (
const auto &j : i->m_criteria.get_objects_subscription())
1397 const std::string &obj_class_name = j.first;
1398 if (class_subscriptions.find(obj_class_name) == class_subscriptions.end())
1399 for (
const auto &k : j.second)
1400 obj_subscriptions[obj_class_name].insert(k);
1415 if (i != cache.end())
1420 if (j != i->second->end())
1422 TLOG_DEBUG( 2 ) <<
"set implementation object " << x <<
'@' << *class_name <<
" [" << (
void *)j->second <<
"] deleted";
1424 std::lock_guard<std::mutex> scoped_lock(j->second->m_mutex);
1436 if (i != cache.end())
1441 if (j != i->second->end())
1443 TLOG_DEBUG( 2 ) <<
"re-set created implementation object " << x <<
'@' << *class_name <<
" [" << (
void *)j->second <<
']';
1445 std::lock_guard<std::mutex> scoped_lock(j->second->m_mutex);
1456 if (i != cache.end())
1461 if (j != i->second->end())
1463 TLOG_DEBUG(2) <<
"clear implementation object " << x <<
'@' << *class_name <<
" [" << (
void *)j->second <<
']';
1465 std::lock_guard<std::mutex> scoped_lock(j->second->m_mutex);
1483 TLOG_DEBUG(3) <<
"*** Enter Configuration::update_cache() with changes:\n" << changes;
1486 for (
const auto& i : changes)
1488 const std::string * class_name = &DalFactory::instance().get_known_class_name_ref(i->get_class_name());
1490 update_impl_objects(m_impl->m_impl_objects, *i, class_name);
1495 if (sc != p_superclasses.end())
1496 for (
const auto &c : sc->second)
1497 update_impl_objects(m_impl->m_impl_objects, *i, c);
1500 sc = p_subclasses.find(class_name);
1502 if (sc != p_subclasses.end())
1503 for (
const auto &c : sc->second)
1504 update_impl_objects(m_impl->m_impl_objects, *i, c);
1507 for (
const auto& i : changes)
1510 m_registry.update(i->get_class_name(), i->get_modified_objs(), i->get_removed_objs(), i->get_created_objs());
1578 "*** Enter Configuration::system_cb()\n"
1579 "*** Number of user subscriptions: " << conf->m_callbacks.size()
1584 std::lock_guard<std::mutex> scoped_lock(conf->m_impl_mutex);
1585 std::lock_guard<std::mutex> scoped_lock2(conf->m_actn_mutex);
1586 for (
auto & i : conf->m_actions)
1593 std::lock_guard<std::mutex> scoped_lock(conf->m_tmpl_mutex);
1594 std::lock_guard<std::mutex> scoped_lock2(conf->m_impl_mutex);
1595 conf->update_cache(changes);
1600 if(conf->m_callbacks.empty())
return;
1605 std::lock_guard<std::mutex> scoped_lock(conf->m_else_mutex);
1608 if (conf->m_callbacks.size() == 1)
1610 auto j = *conf->m_callbacks.begin();
1611 (*(j->m_cb))(changes, j->m_param);
1616 for (
const auto &j : conf->m_callbacks)
1621 std::ostringstream text;
1624 "*** Process subscription " << (
void*) j <<
"\n"
1625 " class subscription done for " << j->m_criteria.get_classes_subscription().size() <<
" classes:\n";
1627 for (
const auto &i1 : j->m_criteria.get_classes_subscription())
1628 text <<
" * class \"" << i1 <<
"\"\n";
1630 text <<
" object subscription done in " << j->m_criteria.get_objects_subscription().size() <<
" classes:\n";
1632 for (
const auto &i2 : j->m_criteria.get_objects_subscription())
1634 text <<
" * class \"" << (i2.first) <<
"\":\n";
1635 for (
const auto &i3 : i2.second)
1636 text <<
" - \"" << i3 <<
"\"\n";
1642 if (j->m_criteria.get_classes_subscription().empty() && j->m_criteria.get_objects_subscription().empty())
1646 TLOG_DEBUG(3) <<
"*** Invoke callback " << (
void *)j <<
" with\n" << changes;
1647 (*(j->m_cb))(changes, j->m_param);
1653 catch (
const std::exception &ex)
1664 std::vector<ConfigurationChange*> changes1;
1666 for (
const auto &i : changes)
1668 const std::string &cname = i->get_class_name();
1671 ConfigurationSubscriptionCriteria::ObjectMap::const_iterator p = j->m_criteria.get_objects_subscription().find(cname);
1672 const bool found_obj_subscription(p != j->m_criteria.get_objects_subscription().end());
1673 const bool found_class_subscription(j->m_criteria.get_classes_subscription().find(cname) != j->m_criteria.get_classes_subscription().end());
1675 if (found_class_subscription || found_obj_subscription)
1678 if (found_class_subscription)
1680 for (
const auto &k : i->m_modified)
1683 for (
const auto &k : i->m_created)
1686 for (
const auto &k : i->m_removed)
1690 if (found_obj_subscription)
1692 for (
const auto &obj_id : i->m_modified)
1693 if (p->second.find(obj_id) != p->second.end())
1696 for (
const auto &obj_id : i->m_removed)
1697 if (p->second.find(obj_id) != p->second.end())
1698 class_changes->
m_removed.push_back(obj_id);
1705 delete class_changes;
1707 changes1.push_back(class_changes);
1711 if (!changes1.empty())
1713 TLOG_DEBUG(3) <<
"*** Invoke callback " << (
void *)j <<
" with\n" << changes1;
1717 (*(j->m_cb))(changes1, j->m_param);
1723 catch (
const std::exception &ex)
1732 for (
const auto &i : changes1)
1739 TLOG_DEBUG(3) <<
"*** Leave Configuration::system_cb()";
1746 TLOG_DEBUG(3) <<
"*** Enter Configuration::system_pre_cb()";
1748 std::lock_guard<std::mutex> scoped_lock(conf->m_else_mutex);
1750 for(
auto& j : conf->m_pre_callbacks)
1752 TLOG_DEBUG(3) <<
"*** Invoke callback " << (
void *)(j);
1753 (*(j->m_cb))(j->m_param);
1756 TLOG_DEBUG(3) <<
"*** Leave Configuration::system_pre_cb()";
1761ConfigurationChange::add(std::vector<ConfigurationChange*> &changes,
const std::string &class_name,
const std::string &obj_name,
const char action)
1765 for (
const auto &c : changes)
1766 if (class_name == c->get_class_name())
1775 changes.push_back(class_changes);
1778 std::vector<std::string>& clist = (
1779 action ==
'+' ? class_changes->
m_created :
1780 action ==
'-' ? class_changes->
m_removed :
1784 clist.push_back(obj_name);
1791 for (
const auto &i : changes)
1799print_svect(std::ostream& s,
const std::vector<std::string>& v,
const char * name)
1801 s <<
" * " << v.size() << name;
1803 for (
auto i = v.begin(); i != v.end(); ++i)
1805 s << ((i == v.begin()) ?
": " :
", ");
1806 s <<
'\"' << *i <<
'\"';
1814operator<<(std::ostream &s,
const ConfigurationChange &c)
1816 s <<
" changes for class \'" << c.get_class_name() <<
"\' include:\n";
1818 print_svect(s, c.get_modified_objs(),
" modified object(s)");
1819 print_svect(s, c.get_created_objs(),
" created object(s)");
1820 print_svect(s, c.get_removed_objs(),
" removed object(s)");
1827operator<<(std::ostream &s,
const std::vector<ConfigurationChange*> &v)
1829 s <<
"There are configuration changes in " << v.size() <<
" classes:\n";
1831 for (
const auto &i : v)
1840 s <<
"Configuration object:\n Inheritance Hierarchy (class - all it's superclasses):\n";
1842 for (
const auto &i : p_superclasses)
1844 s <<
" * \'" << *i.first <<
"\' - ";
1845 if (i.second.empty())
1848 for (
auto j = i.second.begin(); j != i.second.end(); ++j)
1850 if (j != i.second.begin())
1852 s <<
'\'' << **j <<
'\'';
1862 return is_superclass_of(target, source);
1868 return is_superclass_of(target, source);
1874 return is_superclass_of(&DalFactory::instance().get_known_class_name_ref(base_class), &DalFactory::instance().get_known_class_name_ref(child_class));
1880 if (base_class == child_class)
1882 TLOG_DEBUG(50) <<
"cast \'" << *child_class <<
"\' => \'" << *base_class <<
"\' is allowed (equal classes)";
1886 conffwk::fmap<conffwk::fset>::iterator i = p_superclasses.find(child_class);
1888 if (i == p_superclasses.end())
1890 TLOG_DEBUG(50) <<
"cast \'" << *child_class <<
"\' => \'" << *base_class <<
"\' is not possible (base class is not loaded)";
1894 if (i->second.find(base_class) != i->second.end())
1896 TLOG_DEBUG(50) <<
"cast \'" << *child_class <<
"\' => \'" << *base_class <<
"\' is allowed (use inheritance)";
1900 TLOG_DEBUG(50) <<
"cast \'" << *child_class <<
"\' => \'" << *base_class <<
"\' is not allowed (class \'" << *child_class <<
"\' has no \'" << *base_class <<
"\' as a superclass)";
1907operator<<(std::ostream &s,
const Configuration &c)
1942 std::ostringstream text;
1943 text <<
"failed to get " << what <<
" of class \'" << cname <<
"\' via relationship \'" << rname <<
"\' of object \'" << obj <<
'\'';
1951 std::ostringstream text;
1952 text <<
"failed to get objects of class \'" << cname <<
"\' referencing object \'" << obj <<
"\' via relationship \'" << rname <<
'\'';
1977std::vector<const DalObject*>
1979 bool check_composite_only,
bool upcast_unregistered,
1980 bool ,
unsigned long rlevel,
1981 const std::vector<std::string> * rclasses)
1985 std::vector<ConfigObject> objs;
1988 obj.p_obj.referenced_by(objs, relationship_name, check_composite_only, rlevel, rclasses);
1998std::unordered_map<std::string, std::unordered_map<std::string, std::string>>
2001 std::unordered_map<std::string, std::unordered_map<std::string, std::string>> all_attributes_properties;
2005 for (
const auto& ap : c.p_attributes) {
2006 std::unordered_map<std::string, std::string> attribute_properties;
2009 attribute_properties[
"range"] = ap.p_range.empty() ?
"None" : ap.p_range;
2011 attribute_properties[
"description"] = ap.p_description;
2013 attribute_properties[
"multivalue"] = ap.p_is_multi_value ?
"True" :
"False";
2015 attribute_properties[
"not-null"] = ap.p_is_not_null ?
"True" :
"False";
2017 attribute_properties[
"init-value"] = ap.p_default_value.empty() ?
"None" : ap.p_default_value;
2019 all_attributes_properties[ap.p_name] = attribute_properties;
2022 return all_attributes_properties;
2025std::vector<std::string>
2027 std::vector<std::string> classes;
2029 classes.push_back(*it.first);
2038 this->
create(at, class_name,
id, *co);
2046 this->create(at, class_name,
id, *co);
2054 this->
get(class_name,
id, *co);
2055 if (co->is_null()) {
2062std::vector<ConfigObject>*
2064 auto objs =
new std::vector<ConfigObject>;
2065 this->
get(class_name, *objs, query);
2070std::unordered_map<std::string, std::unordered_map<std::string, std::string>>
2073 std::unordered_map<std::string, std::unordered_map<std::string, std::string>> all_relationships_properties;
2077 for (
const auto& rp : c.p_relationships) {
2078 std::unordered_map<std::string, std::string> relationship_properties;
2080 relationship_properties[
"type"] = rp.p_type;
2081 relationship_properties[
"description"] = rp.p_description;
2083 relationship_properties[
"aggregation"] = rp.p_is_aggregation ?
"True" :
"False";
2086 all_relationships_properties[rp.p_name] = relationship_properties;
2089 return all_relationships_properties;
2092std::list<std::string>*
2094 auto l =
new std::list<std::string>;
2099std::vector<std::string>
2103 return c.p_subclasses;
2106std::vector<std::string>
2110 return c.p_superclasses;
#define ERS_DEFINE_ISSUE_CXX(namespace_name, class_name, message, attributes)
#define ERS_DEFINE_ISSUE_BASE_CXX(namespace_name, class_name, base_class_name, message, base_attributes, attributes)
Represents database objects.
const std::string & UID() const noexcept
Return object identity.
Describes changes inside a class returned by the notification mechanism.
const std::vector< std::string > & get_created_objs() const
Return vector of identies of created objects.
std::vector< std::string > m_removed
static void clear(std::vector< ConfigurationChange * > &changes)
Helper method to clear vector of changes (pointers).
ConfigurationChange(const ConfigurationChange &)
std::vector< std::string > m_created
std::vector< std::string > m_modified
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.
const std::vector< std::string > & get_modified_objs() const
Return vector of identies of modified objects.
const std::vector< std::string > & get_removed_objs() const
Return vector of identies of removed objects.
Provides pure virtual interface used by the Configuration class.
virtual bool test_object(const std::string &class_name, const std::string &id, unsigned long rlevel, const std::vector< std::string > *rclasses)=0
Test object existence (used by Python binding)
virtual void subscribe(const std::set< std::string > &class_names, const std::map< std::string, std::set< std::string > > &objs, notify cb, pre_notify pre_cb)=0
Subscribe on database changes.
virtual void set_commit_credentials(const std::string &user, const std::string &password)=0
Set commit credentials.
virtual void close_db()=0
Close database implementation.
virtual void get_superclasses(conffwk::fmap< conffwk::fset > &schema)=0
Get inheritance hierarchy.
virtual void abort()=0
Abort database changes.
virtual void get(const std::string &class_name, const std::string &id, ConfigObject &object, unsigned long rlevel, const std::vector< std::string > *rclasses)=0
Get object of class by id.
virtual void get_includes(const std::string &db_name, std::list< std::string > &includes) const =0
Get included files.
virtual void print_profiling_info() noexcept=0
Print implementation specific profiling information.
virtual void prefetch_all_data()=0
Prefetch all data into client cache.
virtual void get_updated_dbs(std::list< std::string > &dbs) const =0
Get uncommitted files.
virtual bool is_writable(const std::string &db_name)=0
Return write access status.
virtual std::vector< dunedaq::conffwk::Version > get_changes()=0
Get newly available versions.
virtual bool loaded() const noexcept=0
Check if a database is loaded.
void rename_impl_object(const std::string *class_name, const std::string &old_id, const std::string &new_id) noexcept
rename object in cache
virtual void destroy(ConfigObject &object)=0
Destroy object of class by id.
virtual void add_include(const std::string &db_name, const std::string &include)=0
Add include file.
virtual void commit(const std::string &log_message)=0
Commit database changes.
void print_cache_info() noexcept
Print profiling information about objects in cache.
virtual std::vector< dunedaq::conffwk::Version > get_versions(const std::string &since, const std::string &until, dunedaq::conffwk::Version::QueryType type, bool skip_irrelevant)=0
Get archived versions.
virtual void remove_include(const std::string &db_name, const std::string &include)=0
Remove include file.
void set(Configuration *db) noexcept
set configuration object
virtual void create(const std::string &db_name, const std::list< std::string > &includes)=0
Create database.
virtual void open_db(const std::string &db_name)=0
Open database implementation in accordance with given name.
virtual void unsubscribe()=0
Remove subscription on database changes.
Describes a subscription criteria.
std::map< std::string, std::set< std::string > > ObjectMap
The map stores full subsription information.
Defines base class for cache of template objects.
void update_cache(std::vector< ConfigurationChange * > &changes) noexcept
System function invoked in case of modifications.
std::vector< ConfigObject > * get_objs_pybind(const std::string &class_name, const std::string &query="")
void _get(const std::string &class_name, const std::string &id, ConfigObject &object, unsigned long rlevel, const std::vector< std::string > *rclasses)
const conffwk::fmap< conffwk::fset > & superclasses() const noexcept
static void update_impl_objects(conffwk::pmap< conffwk::map< ConfigObjectImpl * > * > &cache, ConfigurationChange &change, const std::string *class_name)
void set_subclasses() noexcept
conffwk::map< std::list< AttributeConverterBase * > * > m_convert_map
void get(const std::string &class_name, const std::string &id, ConfigObject &object, unsigned long rlevel=0, const std::vector< std::string > *rclasses=0)
Get object by class name and object id (multi-thread safe).
void _unread_implementation_objects(dunedaq::conffwk::ObjectState state) noexcept
ConfigurationImpl * m_impl
friend class ConfigObject
static void system_cb(std::vector< ConfigurationChange * > &, Configuration *) noexcept
System callback function invoked in case of modifications.
std::unordered_map< std::string, std::unordered_map< std::string, std::string > > attributes_pybind(const std::string &class_name, bool all)
void destroy_obj(ConfigObject &object)
Destroy object.
std::unordered_map< std::string, std::unordered_map< std::string, std::string > > relations_pybind(const std::string &class_name, bool all)
void reset_subscription()
void remove_include(const std::string &db_name, const std::string &include)
Remove include file.
void get_updated_dbs(std::list< std::string > &dbs) const
Get list of updated files to be committed.
PreCallbackSet m_pre_callbacks
void prefetch_all_data()
Prefetch all data into client cache.
void load(const std::string &db_name)
Load database according to the name. If name is empty, take it from TDAQ_DB_NAME and TDAQ_DB_DATA env...
bool is_writable(const std::string &db_name) const
Get write access status.
std::list< ConfigAction * > m_actions
void set_commit_credentials(const std::string &user, const std::string &password)
Set commit credentials.
void print(std::ostream &) const noexcept
Prints out details of configuration object.
~Configuration() noexcept
Destructor to destroy a configuration object.
std::atomic< uint_least64_t > p_number_of_template_object_created
void update_classes() noexcept
static void system_pre_cb(Configuration *) noexcept
System callback function invoked in case of pre-modifications.
conffwk::fmap< conffwk::fset > p_subclasses
void referenced_by(const T &obj, std::vector< const V * > &objects, const std::string &relationship_name="*", bool check_composite_only=true, bool init=false, unsigned long rlevel=0, const std::vector< std::string > *rclasses=nullptr)
Get template DAL objects holding references on this object via given relationship (multi-thread safe)...
std::vector< std::string > superclasses_pybind(const std::string &class_name, bool all)
CallbackSubscription * find_callback(CallbackId cb_handler) const
void create(const std::string &at, const std::string &class_name, const std::string &id, ConfigObject &object)
Create new object by class name and object id.
static std::string mk_ref_ex_text(const char *what, const std::string &cname, const std::string &rname, const ConfigObject &obj) noexcept
const dunedaq::conffwk::class_t & _get_class_info(const std::string &class_name, bool direct_only=false)
std::vector< std::string > subclasses_pybind(const std::string &class_name, bool all)
std::list< std::string > * return_includes_pybind(const std::string &db_name)
bool loaded() const noexcept
Check if database is correctly loaded.
std::vector< std::string > get_class_list() const
conffwk::map< dunedaq::conffwk::class_t * > p_all_classes_desc_cache
void set_class_domain_map()
void unread_all_objects(bool unread_implementation_objs=false) noexcept
Mark object of given template class as unread (multi-thread unsafe).
std::deque< std::set< std::string > > find_class_domains()
CallbackSubscription * CallbackId
Callback identifier.
const dunedaq::conffwk::class_t & get_class_info(const std::string &class_name, bool direct_only=false)
The method provides access to description of class.
void get_includes(const std::string &db_name, std::list< std::string > &includes) const
Get include files.
conffwk::fmap< conffwk::fset > p_superclasses
std::vector< dunedaq::conffwk::Version > get_changes()
Get new conffwk versions.
conffwk::map< dunedaq::conffwk::class_t * > p_direct_classes_desc_cache
void commit(const std::string &log_message="")
Commit database changes.
conffwk::fmap< uint > p_class_domain_map
bool is_superclass_of(const std::string &target, const std::string &source) noexcept
void _unread_template_objects() noexcept
void export_data(boost::property_tree::ptree &tree, const std::string &classes="", const std::string &objects="", const std::string &files="", const std::string &empty_array_item="")
Export configuration data into ptree.
static std::string mk_ref_by_ex_text(const std::string &cname, const std::string &rname, const ConfigObject &obj) noexcept
ConfigObject * get_obj_pybind(const std::string &class_name, const std::string &id)
void export_schema(boost::property_tree::ptree &tree, const std::string &classes="", bool direct_only=false)
Export configuration schema into ptree.
void unsubscribe(CallbackId cb_handler=0)
Remove callback function.
void print_profiling_info() noexcept
Print out profiling information.
std::vector< dunedaq::conffwk::Version > get_versions(const std::string &since, const std::string &until, dunedaq::conffwk::Version::QueryType type=dunedaq::conffwk::Version::query_by_date, bool skip_irrelevant=true)
Get repository versions in interval.
std::atomic< uint_least64_t > p_number_of_template_object_read
void abort()
Abort database changes.
void unload()
Unload database.
bool test_object(const std::string &class_name, const std::string &id, unsigned long rlevel=0, const std::vector< std::string > *rclasses=0)
Test the object existence.
void add_include(const std::string &db_name, const std::string &include)
Add include file to existing database.
std::atomic< uint_least64_t > p_number_of_cache_hits
ConfigObject * create_and_return_obj_pybind(const std::string &at, const std::string &class_name, const std::string &id)
CallbackId subscribe(const ConfigurationSubscriptionCriteria &criteria, notify user_cb, void *user_param=nullptr)
Subscribe on configuration changes.
bool try_cast(const std::string &target, const std::string &source) noexcept
Checks if cast from source class to target class is allowed.
void rename_object(ConfigObject &obj, const std::string &new_id)
Cache of template object of given type.
The base class for any generated DAL object.
DalObject * get(ConfigObject &obj, bool upcast_unregistered=false)
void _rename_object(std::string class_name, std::string old_id, std::string new_id)
Rename object of given template class (multi-thread unsafe).
void clear()
Clear the content of the registy.
void unread_all()
Set the status of all objects in cache to unread.
void update_class_maps()
Update the internal class domains map.
Try to access deleted DAL object.
Generic configuration exception.
Try to access non-existent object or class.
Base class for any user define issue.
#define TLOG_DEBUG(lvl,...)
std::ostream & operator<<(std::ostream &, const ConfigurationChange &)
static type<< " \""<< data<< "\" is not found",,((const char *) type)((const char *) data)) ERS_DEFINE_ISSUE_BASE_CXX(conffwk, DeletedObject, conffwk::Exception, "object \'"<< object_id<< '@'<< class_name<< "\' was deleted",,((const char *) class_name)((const char *) object_id)) namespace conffwk {template< typename T > T * get_new(ConfigObject &co, const std::string &attrname)
static void init_regex(std::unique_ptr< std::regex > &ptr, const std::string &str, const char *what)
static bool check_prefetch_needs()
static void add_data(boost::property_tree::ptree &pt, const ConfigObject &obj, const dunedaq::conffwk::attribute_t &attribute, const std::string &empty_array_item)
static void add_array_item(boost::property_tree::ptree &pt, const T &val)
static void print_svect(std::ostream &s, const std::vector< std::string > &v, const char *name)
void error(const Issue &issue)
static const char * type(type_t type)
static const char * format2str(int_format_t format)
cardinality_t p_cardinality
static const char * card2str(cardinality_t cardinality)
Factory couldn t std::string alg_name Invalid configuration error