DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dalMethods.cpp
Go to the documentation of this file.
1
25#include "confmodel/Segment.hpp"
26#include "confmodel/Session.hpp"
27#include "confmodel/Service.hpp"
29
31
32#include "nlohmann/json.hpp"
35#include "conffwk/Schema.hpp"
36
37#include <list>
38#include <set>
39#include <iostream>
40
41using namespace dunedaq::conffwk;
42
43
44// Stolen from ATLAS dal package
45namespace {
52void
53make_parents_list(
54 const ConfigObjectImpl * child,
55 const dunedaq::confmodel::ResourceSet * resource_set,
56 std::vector<const dunedaq::confmodel::Resource *> & p_list,
57 std::list< std::vector<const dunedaq::confmodel::Resource *> >& out,
59{
60 dunedaq::confmodel::AddTestOnCircularDependency add_fuse_test(cd_fuse, resource_set);
61
62 // add the resource set to the path
63 p_list.push_back(resource_set);
64
65 // check if the application is in the resource relationship, i.e. is a resource or belongs to resource set(s)
66 for (const auto& i : resource_set->contained_resources()) {
67 if (i->config_object().implementation() == child) {
68 out.push_back(p_list);
69 }
71 make_parents_list(child, rs, p_list, out, cd_fuse);
72 }
73 }
74
75 // remove the resource set from the path
76 p_list.pop_back();
77}
78
79void
80make_parents_list(
82 const dunedaq::confmodel::Segment * segment,
83 std::vector<const dunedaq::confmodel::Resource *> & p_list,
84 std::list<std::vector<const dunedaq::confmodel::Resource *> >& out,
85 bool is_segment,
87{
88 dunedaq::confmodel::AddTestOnCircularDependency add_fuse_test(cd_fuse, segment);
89
90 // add the segment to the path
91 p_list.push_back(segment);
92
93 // check if the application is in the nested segment
94 for (const auto& seg : segment->get_segments()) {
95 if (seg->config_object().implementation() == child)
96 out.push_back(p_list);
97 else
98 make_parents_list(child, seg, p_list, out, is_segment, cd_fuse);
99 }
100 if (!is_segment) {
101 for (const auto& app : segment->get_applications()) {
102 if (app->config_object().implementation() == child)
103 out.push_back(p_list);
104 else if (const auto resource_set = app->cast<dunedaq::confmodel::ResourceSet>())
105 make_parents_list(child, resource_set, p_list, out, cd_fuse);
106 }
107 }
108
109 // remove the segment from the path
110
111 p_list.pop_back();
112}
113
114
115void
116check_segment(
117 std::list< std::vector<const dunedaq::confmodel::Resource *> >& out,
118 const dunedaq::confmodel::Segment * segment,
120 bool is_segment,
122{
123 dunedaq::confmodel::AddTestOnCircularDependency add_fuse_test(cd_fuse, segment);
124
125 std::vector<const dunedaq::confmodel::Resource *> compList;
126
127 if (segment->config_object().implementation() == child) {
128 out.push_back(compList);
129 }
130 make_parents_list(child, segment, compList, out, is_segment, cd_fuse);
131}
132} // namespace
133
134
135namespace dunedaq::confmodel {
136
137void
139 const Session& session,
140 std::list<std::vector<const Resource *>>& parents) const
141{
142 const ConfigObjectImpl * obj_impl = config_object().implementation();
143
144 const bool is_segment = castable(Segment::s_class_name);
145
146 try {
147 TestCircularDependency cd_fuse("component parents", &session);
148
149 // check session's segment
150 check_segment(parents, session.get_segment(), obj_impl, is_segment,
151 cd_fuse);
152
153
154 if (parents.empty()) {
155 TLOG_DEBUG(1) << "cannot find segment/resource path(s) between Resource " << this << " and session " << &session << " objects (check this object is linked with the session as a segment or a resource)" ;
156 }
157 }
158 catch (ers::Issue & ex) {
159 ers::error(CannotGetParents(ERS_HERE, full_name(), ex));
160 }
161}
162
163// ========================================================================
164
165std::vector<const Application*>
167 bool enabled_only) const {
168 std::vector<const Application*> apps;
169 auto segapps = segment->get_applications();
170 if (enabled_only) {
171 for (auto app : segapps) {
172 auto comp = app->cast<Resource>();
173 if (comp == nullptr || !comp->is_disabled(*this)) {
174 apps.insert(apps.end(), app);
175 }
176 }
177 }
178 else {
179 apps.swap(segapps);
180 }
181 for (auto seg : segment->get_segments()) {
182 if (!enabled_only || !seg->is_disabled(*this)) {
183 auto segapps = getSegmentApps(seg, enabled_only);
184 apps.insert(apps.end(), segapps.begin(),segapps.end());
185 }
186 }
187 return apps;
188}
189
190std::vector<const Application*>
192 std::vector<const Application*> apps;
193 auto segapps = getSegmentApps(get_segment(), false);
194 apps.insert(apps.end(), segapps.begin(),segapps.end());
195 return apps;
196}
197
198std::vector<const Application*>
200 std::vector<const Application*> apps;
201 auto segapps = getSegmentApps(get_segment(), true);
202 apps.insert(apps.end(), segapps.begin(),segapps.end());
203 return apps;
204}
205
206
207// ========================================================================
208
209std::set<const HostComponent*>
211 std::set<const HostComponent*> res;
212 for (auto module : get_modules()) {
213 for (auto hostresource : module->get_used_resources()) {
214 res.insert(hostresource);
215 }
216 }
217 return res;
218}
219
220namespace {
221nlohmann::json get_json_config(conffwk::Configuration& confdb,
222 const std::string& class_name,
223 const std::string& uid,
224 bool direct_only,
225 bool skip_object_name) {
226 using nlohmann::json;
227 using namespace conffwk;
228 TLOG_DBG(9) << "Getting attributes for " << uid << " of class " << class_name;
229 json attributes;
230 auto class_info = confdb.get_class_info(class_name);
232 confdb.get(class_name, uid, obj);
233 for (auto attr : class_info.p_attributes) {
234 if (attr.p_type == type_t::u8_type) {
235 add_json_value<uint8_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
236 }
237 else if (attr.p_type == type_t::u16_type) {
238 add_json_value<uint16_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
239 }
240 else if (attr.p_type == type_t::u32_type) {
241 add_json_value<uint32_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
242 }
243 else if (attr.p_type == type_t::u64_type) {
244 add_json_value<uint64_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
245 }
246 else if (attr.p_type == type_t::s8_type) {
247 add_json_value<int8_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
248 }
249 else if (attr.p_type == type_t::s16_type) {
250 add_json_value<int16_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
251 }
252 else if (attr.p_type == type_t::s32_type ||
253 attr.p_type == type_t::s16_type) {
254 add_json_value<int32_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
255 }
256 else if (attr.p_type == type_t::s64_type) {
257 add_json_value<int64_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
258 }
259 else if (attr.p_type == type_t::float_type) {
260 add_json_value<float>(obj, attr.p_name, attr.p_is_multi_value, attributes);
261 }
262 else if (attr.p_type == type_t::double_type) {
263 add_json_value<double>(obj, attr.p_name, attr.p_is_multi_value, attributes);
264 }
265 else if (attr.p_type == type_t::bool_type) {
266 add_json_value<bool>(obj, attr.p_name, attr.p_is_multi_value, attributes);
267 }
268 else if ((attr.p_type == type_t::string_type) ||
269 (attr.p_type == type_t::enum_type) ||
270 (attr.p_type == type_t::date_type) ||
271 (attr.p_type == type_t::time_type)) {
272 add_json_value<std::string>(obj, attr.p_name, attr.p_is_multi_value, attributes);
273 }
274 }
275 if (!direct_only) {
276 TLOG_DBG(9) << "Processing relationships";
277 for (auto iter: class_info.p_relationships) {
278 std::string rel_name = iter.p_name;
279 if (iter.p_cardinality == cardinality_t::zero_or_one ||
280 iter.p_cardinality == cardinality_t::only_one) {
281 ConfigObject rel_obj;
282 obj.get(rel_name, rel_obj);
283 if (!rel_obj.is_null()) {
284 TLOG_DBG(9) << "Getting attibute of relationship " << rel_name;
285 attributes[rel_name] = get_json_config(confdb, rel_obj.class_name(),
286 rel_obj.UID(),
287 direct_only,
288 skip_object_name);
289 }
290 else {
291 TLOG_DBG(9) << "Relationship " << rel_name << " not set";
292 }
293 }
294 else {
295 TLOG_DBG(9) << "Relationship " << rel_name << " is multi value. "
296 << "Getting attibutes for relationship.";
297 std::vector<ConfigObject> rel_vec;
298 obj.get(rel_name, rel_vec);
299 std::vector<json> configs;
300 for (auto rel_obj : rel_vec) {
301 TLOG_DBG(9) << "Getting attibute of relationship " << rel_obj.UID();
302 auto rel_conf = get_json_config(confdb, rel_obj.class_name(), rel_obj.UID(),
303 direct_only, skip_object_name);
304 configs.push_back(rel_conf);
305 }
306 attributes[rel_name] = configs;
307 }
308 }
309 }
310
311 if (skip_object_name) {
312 return attributes;
313 }
314 json json_config;
315 json_config[uid] = attributes;
316 return json_config;
317}
318} // namespace
319
320nlohmann::json Jsonable::to_json(bool direct_only,
321 bool skip_object_name) const {
322 return get_json_config(p_registry.configuration(), class_name(), UID(), direct_only,
323 skip_object_name);
324}
325
332
334 const conffwk::Configuration& confdb,
336
337 const std::string configuration_uri = confdb.get_impl_spec();
338 const dunedaq::confmodel::Service* control_service = nullptr;
339
340 const std::string controller_log_level = session->get_controller_log_level();
341
342 for (auto const *as : get_exposes_service()) {
343 if (as->UID().ends_with("_control")) {
344 if (control_service)
345 throw DuplicatedControlService(ERS_HERE, as->UID());
346 control_service = as;
347 }
348 }
349
350 if (control_service == nullptr)
351 throw NoControlServiceDefined(ERS_HERE, UID());
352
353 const std::string control_uri =
354 control_service->get_protocol()
355 + "://"
356 + get_runs_on()->get_runs_on()->UID()
357 + ":"
358 + std::to_string(control_service->get_port());
359
360 std::vector<std::string> ret = { "-l", controller_log_level };
361 ret.push_back(configuration_uri);
362 ret.push_back(control_uri);
363 ret.push_back(UID());
364 ret.push_back(session->UID());
365 return ret;
366}
367
368
369
370std::vector<const confmodel::DetectorStream*>
372 std::vector<const confmodel::DetectorStream*> all_streams;
373 // Loop over senders
374 for (auto sender : this->senders()) {
375 auto sender_streams = sender->get_streams();
376 all_streams.insert(all_streams.end(), sender_streams.begin(), sender_streams.end());
377 }
378 return all_streams;
379}
380
381std::string OpMonURI::get_URI( const std::string & /* app */) const {
382
383 auto type = get_type();
384 if ( type == "file" ) {
385 return type + "://" + get_path();
386 }
387
388 if ( type == "stream" ) {
389 return type + "://" + get_path();
390 }
391
392 return "stdout://";
393}
394
396 return (!holder.disabled_components().is_enabled(this));
397}
398bool Resource::compute_disabled_state(const std::set<std::string>& disabled_resources) const {
399 TLOG_DEBUG(6) << "No compute_disabled_state method defined for Resource " << class_name();
400 if (disabled_resources.contains(UID())) {
401 return true;
402 }
403 return false;
404}
405
406std::vector<const Resource*> DetDataSender::contained_resources() const {
407 return to_resources(get_streams());
408}
409
410std::vector<const Resource*> DetectorToDaqConnection::contained_resources() const {
411 auto res = to_resources(senders());
412 res.push_back(receiver());
413 return res;
414}
415
416
417bool
418DetectorToDaqConnection::compute_disabled_state(const std::set<std::string>& disabled_resources) const {
419 if (disabled_resources.contains(UID())) {
420 return true;
421 }
422 bool send_disabled = true;
423 for (auto sender: senders()) {
424 if (!sender->compute_disabled_state(disabled_resources)) {
425 send_disabled = false;
426 break;
427 }
428 }
429 TLOG_DBG(6) << "receiver disabled=" << receiver()->compute_disabled_state(disabled_resources)
430 << " senders disabled=" << send_disabled;
431 if (receiver()->compute_disabled_state(disabled_resources) || send_disabled) {
432 return true;
433 }
434 return false;
435}
436
437std::vector<const Resource*>
439 // All our contained segments are resources
440 std::vector<const Resource*> resources = to_resources(get_segments());
441
442 // Only a subset of our applications might be resources so check individually
443 for (auto app: get_applications()) {
444 TLOG_DBG(6) << "Checking " << app->UID();
445 auto res=app->cast<const Resource>();
446 if (res != nullptr) {
447 TLOG_DBG(6) << "Adding " << app->UID();
448 resources.push_back(res);
449 }
450 }
451 TLOG_DBG(6) << "Returning vector of " << resources.size() << " resources";
452 return resources;
453}
454
455bool
456Segment::compute_disabled_state(const std::set<std::string>& disabled) const {
457 if (disabled.contains(UID())) {
458 return true;
459 }
460 for (auto app: get_applications()) {
461 auto res=app->cast<const Resource>();
462 if (res == nullptr) {
463 return false;
464 }
465 }
466 for (auto res: contained_resources()) {
467 if (!res->compute_disabled_state(disabled)) {
468 return false;
469 }
470 }
471 return true;
472}
473
474} // namespace dunedaq::confmodel
#define ERS_HERE
Implements database objects.
Represents database objects.
const std::string & UID() const noexcept
Return object identity.
void get(const std::string &name, T &value)
Get value of object's attribute or relationship.
bool is_null() const noexcept
Check if object's implementation points to null.
const ConfigObjectImpl * implementation() const noexcept
Returns pointer on implementation.
const std::string & class_name() const noexcept
Return object's class name.
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).
const std::string & get_impl_spec() const noexcept
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.
std::string full_name() const noexcept
bool castable(const std::string &target) const noexcept
const TARGET * cast() const noexcept
Casts object to different class.
const std::string & class_name() const noexcept
const ConfigObject & config_object() const
const std::string & UID() const noexcept
DalRegistry & p_registry
Configuration object.
Configuration & configuration()
const std::vector< const dunedaq::confmodel::Service * > & get_exposes_service() const
Get "exposes_service" relationship value. Services exposed i.e. provided by this application.
const dunedaq::confmodel::VirtualHost * get_runs_on() const
Get "runs_on" relationship value. VirtualHost to run this application on.
const std::vector< const dunedaq::confmodel::DaqModule * > & get_modules() const
Get "modules" relationship value.
const std::vector< std::string > construct_commandline_parameters(const conffwk::Configuration &confdb, const dunedaq::confmodel::Session *session) const
std::set< const dunedaq::confmodel::HostComponent * > get_used_hostresources() const
virtual std::vector< const Resource * > contained_resources() const override
const std::vector< const dunedaq::confmodel::DetectorStream * > & get_streams() const
Get "streams" relationship value.
bool compute_disabled_state(const std::set< std::string > &disabled) const final
virtual const DetDataReceiver * receiver() const =0
virtual std::vector< const Resource * > contained_resources() const override
std::vector< const confmodel::DetectorStream * > streams() const
virtual std::vector< const DetDataSender * > senders() const =0
bool is_enabled(const Resource *component) const
nlohmann::json to_json(bool direct=false, bool skip_name=false) const
std::string get_URI(const std::string &app) const
const std::string & get_type() const
Get "type" attribute value. type of the OpMonFacility.
Definition OpMonURI.hpp:137
const std::string & get_path() const
Get "path" attribute value. property used to generate the final URI.
Definition OpMonURI.hpp:94
const std::vector< std::string > construct_commandline_parameters(const conffwk::Configuration &confdb, const dunedaq::confmodel::Session *session) const
virtual std::vector< const Resource * > contained_resources() const =0
const dunedaq::confmodel::DisabledResources & disabled_components() const
virtual bool compute_disabled_state(const std::set< std::string > &) const
void parents(const dunedaq::confmodel::Session &session, std::list< std::vector< const dunedaq::confmodel::Resource * > > &parents) const
bool is_disabled(const dunedaq::confmodel::ResourceTree &session) const
bool compute_disabled_state(const std::set< std::string > &disabled) const final
const std::vector< const dunedaq::confmodel::Segment * > & get_segments() const
Get "segments" relationship value. Nested list of Segments that form part of this Segment.
Definition Segment.hpp:114
const std::vector< const dunedaq::confmodel::Application * > & get_applications() const
Get "applications" relationship value. List of Applications that run in this Segment.
Definition Segment.hpp:141
static const std::string & s_class_name
Definition Segment.hpp:54
virtual std::vector< const Resource * > contained_resources() const
const std::string & get_protocol() const
Get "protocol" attribute value.
Definition Service.hpp:99
uint16_t get_port() const
Get "port" attribute value.
Definition Service.hpp:130
std::vector< const dunedaq::confmodel::Application * > enabled_applications() const
const dunedaq::confmodel::Segment * get_segment() const
Get "segment" relationship value. List of configuration Segments that form this Session.
Definition Session.hpp:419
std::vector< const dunedaq::confmodel::Application * > all_applications() const
std::vector< const Application * > getSegmentApps(const Segment *, bool) const
const dunedaq::confmodel::PhysicalHost * get_runs_on() const
Get "runs_on" relationship value. The physical host that this virtual host runs on.
Base class for any user define issue.
Definition Issue.hpp:69
conffwk entry point
std::vector< const dunedaq::confmodel::Resource * > to_resources(const std::vector< T * > &vector_of_children)
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
std::vector< T > attributes(tref const &item)
const std::vector< std::string > construct_commandline_parameters_appfwk(const T *app, const conffwk::Configuration &confdb, const dunedaq::confmodel::Session *session)
Definition util.hpp:74
void add_json_value(conffwk::ConfigObject &obj, std::string &name, bool multi_value, nlohmann::json &attributes)
Definition util.hpp:60
FELIX Initialization std::string initerror FELIX queue timed out
msgpack::object obj
void error(const Issue &issue)
Definition ers.hpp:81