DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dalMethods.cpp
Go to the documentation of this file.
1
22#include "confmodel/Segment.hpp"
23#include "confmodel/Session.hpp"
24#include "confmodel/Service.hpp"
26
28
29#include "nlohmann/json.hpp"
32#include "conffwk/Schema.hpp"
37
38#include <list>
39#include <set>
40#include <iostream>
41
42// Stolen from ATLAS dal package
43using namespace dunedaq::conffwk;
44
45namespace dunedaq::confmodel {
52static void
54 const ConfigObjectImpl * child,
55 const dunedaq::confmodel::ResourceSet * resource_set,
56 std::vector<const dunedaq::confmodel::Component *> & p_list,
57 std::list< std::vector<const dunedaq::confmodel::Component *> >& 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->get_contains()) {
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
79static void
81 const ConfigObjectImpl * child,
82 const dunedaq::confmodel::Segment * segment,
83 std::vector<const dunedaq::confmodel::Component *> & p_list,
84 std::list<std::vector<const dunedaq::confmodel::Component *> >& 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
115static void
117 std::list< std::vector<const dunedaq::confmodel::Component *> >& out,
118 const dunedaq::confmodel::Segment * segment,
119 const ConfigObjectImpl * child,
120 bool is_segment,
122{
123 dunedaq::confmodel::AddTestOnCircularDependency add_fuse_test(cd_fuse, segment);
124
125 std::vector<const dunedaq::confmodel::Component *> 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
133void
136 std::list<std::vector<const dunedaq::confmodel::Component *>>& parents) const
137{
138 const ConfigObjectImpl * obj_impl = config_object().implementation();
139
140 const bool is_segment = castable(dunedaq::confmodel::Segment::s_class_name);
141
142 try {
143 dunedaq::confmodel::TestCircularDependency cd_fuse("component parents", &session);
144
145 // check session's segment
146 check_segment(parents, session.get_segment(), obj_impl, is_segment,
147 cd_fuse);
148
149
150 if (parents.empty()) {
151 TLOG_DEBUG(1) << "cannot find segment/resource path(s) between Component " << this << " and session " << &session << " objects (check this object is linked with the session as a segment or a resource)" ;
152 }
153 }
154 catch (ers::Issue & ex) {
155 ers::error(CannotGetParents(ERS_HERE, full_name(), ex));
156 }
157}
158
159// ========================================================================
160
161 static std::vector<const Application*> getSegmentApps(const Segment* segment,
162 const Session* session,
163 bool enabled_only) {
164 std::vector<const Application*> apps;
165 auto segapps = segment->get_applications();
166 if (enabled_only) {
167 for (auto app : segapps) {
168 auto comp = app->cast<Component>();
169 if (comp == nullptr || !comp->disabled(*session)) {
170 apps.insert(apps.end(), app);
171 }
172 }
173 }
174 else {
175 apps.swap(segapps);
176 }
177 for (auto seg : segment->get_segments()) {
178 if (!enabled_only || !seg->disabled(*session)) {
179 auto segapps = getSegmentApps(seg, session, enabled_only);
180 apps.insert(apps.end(), segapps.begin(),segapps.end());
181 }
182 }
183 return apps;
184}
185
186std::vector<const Application*>
188 std::vector<const Application*> apps;
189 auto segapps = getSegmentApps(m_segment, this, false);
190 apps.insert(apps.end(), segapps.begin(),segapps.end());
191 return apps;
192}
193
194std::vector<const Application*>
196 std::vector<const Application*> apps;
197 auto segapps = getSegmentApps(m_segment, this, true);
198 apps.insert(apps.end(), segapps.begin(),segapps.end());
199 return apps;
200}
201
202// ========================================================================
203
204std::set<const HostComponent*>
206 std::set<const HostComponent*> res;
207 for (auto module : get_modules()) {
208 for (auto hostresource : module->get_used_resources()) {
209 res.insert(hostresource);
210 }
211 }
212 return res;
213}
214
215namespace {
216nlohmann::json get_json_config(conffwk::Configuration& confdb,
217 const std::string& class_name,
218 const std::string& uid,
219 bool direct_only,
220 bool skip_object_name) {
221 using nlohmann::json;
222 using namespace conffwk;
223 TLOG_DBG(9) << "Getting attributes for " << uid << " of class " << class_name;
224 json attributes;
225 auto class_info = confdb.get_class_info(class_name);
226 ConfigObject obj;
227 confdb.get(class_name, uid, obj);
228 for (auto attr : class_info.p_attributes) {
229 if (attr.p_type == type_t::u8_type) {
230 add_json_value<uint8_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
231 }
232 else if (attr.p_type == type_t::u16_type) {
233 add_json_value<uint16_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
234 }
235 else if (attr.p_type == type_t::u32_type) {
236 add_json_value<uint32_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
237 }
238 else if (attr.p_type == type_t::u64_type) {
239 add_json_value<uint64_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
240 }
241 else if (attr.p_type == type_t::s8_type) {
242 add_json_value<int8_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
243 }
244 else if (attr.p_type == type_t::s16_type) {
245 add_json_value<int16_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
246 }
247 else if (attr.p_type == type_t::s32_type ||
248 attr.p_type == type_t::s16_type) {
249 add_json_value<int32_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
250 }
251 else if (attr.p_type == type_t::s64_type) {
252 add_json_value<int64_t>(obj, attr.p_name, attr.p_is_multi_value, attributes);
253 }
254 else if (attr.p_type == type_t::float_type) {
255 add_json_value<float>(obj, attr.p_name, attr.p_is_multi_value, attributes);
256 }
257 else if (attr.p_type == type_t::double_type) {
258 add_json_value<double>(obj, attr.p_name, attr.p_is_multi_value, attributes);
259 }
260 else if (attr.p_type == type_t::bool_type) {
261 add_json_value<bool>(obj, attr.p_name, attr.p_is_multi_value, attributes);
262 }
263 else if ((attr.p_type == type_t::string_type) ||
264 (attr.p_type == type_t::enum_type) ||
265 (attr.p_type == type_t::date_type) ||
266 (attr.p_type == type_t::time_type)) {
267 add_json_value<std::string>(obj, attr.p_name, attr.p_is_multi_value, attributes);
268 }
269 }
270 if (!direct_only) {
271 TLOG_DBG(9) << "Processing relationships";
272 for (auto iter: class_info.p_relationships) {
273 std::string rel_name = iter.p_name;
274 if (iter.p_cardinality == cardinality_t::zero_or_one ||
275 iter.p_cardinality == cardinality_t::only_one) {
276 ConfigObject rel_obj;
277 obj.get(rel_name, rel_obj);
278 if (!rel_obj.is_null()) {
279 TLOG_DBG(9) << "Getting attibute of relationship " << rel_name;
280 attributes[rel_name] = get_json_config(confdb, rel_obj.class_name(),
281 rel_obj.UID(),
282 direct_only,
283 skip_object_name);
284 }
285 else {
286 TLOG_DBG(9) << "Relationship " << rel_name << " not set";
287 }
288 }
289 else {
290 TLOG_DBG(9) << "Relationship " << rel_name << " is multi value. "
291 << "Getting attibutes for relationship.";
292 std::vector<ConfigObject> rel_vec;
293 obj.get(rel_name, rel_vec);
294 std::vector<json> configs;
295 for (auto rel_obj : rel_vec) {
296 TLOG_DBG(9) << "Getting attibute of relationship " << rel_obj.UID();
297 auto rel_conf = get_json_config(confdb, rel_obj.class_name(), rel_obj.UID(),
298 direct_only, skip_object_name);
299 configs.push_back(rel_conf);
300 }
301 attributes[rel_name] = configs;
302 }
303 }
304 }
305
306 if (skip_object_name) {
307 return attributes;
308 }
309 json json_config;
310 json_config[uid] = attributes;
311 return json_config;
312}
313} // namespace
314
315nlohmann::json Jsonable::to_json(bool direct_only,
316 bool skip_object_name) const {
317 return get_json_config(p_registry.configuration(), class_name(), UID(), direct_only,
318 skip_object_name);
319}
320
327
329 const conffwk::Configuration& confdb,
331
332 const std::string configuration_uri = confdb.get_impl_spec();
333 const dunedaq::confmodel::Service* control_service = nullptr;
334
335 const std::string controller_log_level = session->get_controller_log_level();
336
337 for (auto const *as : get_exposes_service()) {
338 if (as->UID().ends_with("_control")) {
339 if (control_service)
340 throw DuplicatedControlService(ERS_HERE, as->UID());
341 control_service = as;
342 }
343 }
344
345 if (control_service == nullptr)
346 throw NoControlServiceDefined(ERS_HERE, UID());
347
348 const std::string control_uri =
349 control_service->get_protocol()
350 + "://"
351 + get_runs_on()->get_runs_on()->UID()
352 + ":"
353 + std::to_string(control_service->get_port());
354
355 std::vector<std::string> ret = { "-l", controller_log_level };
356 ret.push_back(configuration_uri);
357 ret.push_back(control_uri);
358 ret.push_back(UID());
359 ret.push_back(session->UID());
360 return ret;
361}
362
363
364std::vector<const confmodel::DetDataSender*> DetectorToDaqConnection::get_senders() const {
365 std::vector<const confmodel::DetDataSender*> senders;
366
367 for ( auto d2d_res : this->get_contains() ) {
368 // Maybe senders not in a resource set so check for direct containment
369 auto sender = d2d_res->cast<confmodel::DetDataSender>();
370 if ( sender != nullptr ) {
371 senders.push_back(sender);
372 }
373 else {
374 // Look for a resource set containing senders
375 auto rs = d2d_res->cast<confmodel::ResourceSet>();
376 if (rs != nullptr) {
377 // Look for senders in resource set
378 for (auto res : rs->get_contains()) {
379 auto sender = res->cast<confmodel::DetDataSender>();
380 if ( sender != nullptr ) {
381 senders.push_back(sender);
382 }
383 }
384 }
385 }
386 }
387
388 return senders;
389}
390
391
393
394 std::vector<const confmodel::DetDataReceiver*> receivers;
395
396 for ( auto d2d_res : this->get_contains() ) {
397 auto r = d2d_res->cast<confmodel::DetDataReceiver>();
398 if ( r == nullptr )
399 continue;
400
401 receivers.push_back(r);
402 }
403
404 if (receivers.size() != 1) {
405 throw(ConfigurationError(ERS_HERE, "DetectorToDaqConnection : expected 1 receiver in D2d conection {name of connection}, found {number found}"));
406 }
407
408 // Receiver identified
409 return receivers.at(0);
410
411}
412
413
414std::vector<const confmodel::DetectorStream*> DetectorToDaqConnection::get_streams() const {
415
416 std::vector<const confmodel::DetectorStream*> streams;
417 // Loop over senders
418 for (auto sender : this->get_senders()) {
419 // loop over streams
420 for (auto stream_res : sender->get_contains()) {
421 auto stream = stream_res->cast<confmodel::DetectorStream>();
422 if ( !stream ) {
423 throw(ConfigurationError(ERS_HERE, "DetectorToDaqConnection : Non-stream object '"+stream_res->UID()+"' found in DetDataSender '"+stream_res->UID()+"'"));
424 }
425
426 streams.push_back(stream->cast<confmodel::DetectorStream>());
427 }
428 }
429
430 return streams;
431}
432
433std::string OpMonURI::get_URI( const std::string & app ) const {
434
435 auto type = get_type();
436 if ( type == "file" ) {
437 return type + "://" + get_path();
438 }
439
440 if ( type == "stream" ) {
441 return type + "://" + get_path();
442 }
443
444 return "stdout://";
445}
446
447}
448
#define ERS_HERE
Implements database objects.
Represents database objects.
const std::string & UID() const noexcept
Return object identity.
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.
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.
void get_parents(const dunedaq::confmodel::Session &session, std::list< std::vector< const dunedaq::confmodel::Component * > > &parents) const
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
std::vector< const confmodel::DetDataSender * > get_senders() const
const confmodel::DetDataReceiver * get_receiver() const
std::vector< const confmodel::DetectorStream * > get_streams() 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
const std::vector< const dunedaq::confmodel::ResourceBase * > & get_contains() const
Get "contains" relationship value. A resource set is a container of resources to easily implement gro...
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
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 * > get_all_applications() const
std::vector< const dunedaq::confmodel::Application * > get_enabled_applications() const
const dunedaq::confmodel::Segment * m_segment
Definition Session.hpp:100
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
#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:100
static void check_segment(std::list< std::vector< const dunedaq::confmodel::Component * > > &out, const dunedaq::confmodel::Segment *segment, const ConfigObjectImpl *child, bool is_segment, dunedaq::confmodel::TestCircularDependency &cd_fuse)
void add_json_value(conffwk::ConfigObject &obj, std::string &name, bool multi_value, nlohmann::json &attributes)
Definition util.hpp:86
static void make_parents_list(const ConfigObjectImpl *child, const dunedaq::confmodel::ResourceSet *resource_set, std::vector< const dunedaq::confmodel::Component * > &p_list, std::list< std::vector< const dunedaq::confmodel::Component * > > &out, dunedaq::confmodel::TestCircularDependency &cd_fuse)
static std::vector< const Application * > getSegmentApps(const Segment *segment, const Session *session, bool enabled_only)
FELIX Initialization std::string initerror FELIX queue timed out
The opmon infrastructure has not been set up in the DuplicatedControlService
Definition util.hpp:38
ConfigurationError
Definition util.hpp:27
void error(const Issue &issue)
Definition ers.hpp:81