Line data Source code
1 : /**
2 : * @file FakeHSIApplication.cpp
3 : *
4 : * Implementation of FakeHSIApplication's generate_modules dal method
5 : *
6 : * This is part of the DUNE DAQ Software Suite, copyright 2023.
7 : * Licensing/copyright details are in the COPYING file that you should have
8 : * received with this code.
9 : */
10 :
11 :
12 : #include "ConfigObjectFactory.hpp"
13 : #include "appmodel/FakeHSIApplication.hpp"
14 : #include "appmodel/FakeHSIEventGeneratorModule.hpp"
15 : #include "appmodel/FakeHSIEventGeneratorConf.hpp"
16 : #include "appmodel/NetworkConnectionDescriptor.hpp"
17 : #include "appmodel/NetworkConnectionRule.hpp"
18 : #include "appmodel/QueueConnectionRule.hpp"
19 : #include "appmodel/QueueDescriptor.hpp"
20 : #include "appmodel/DFApplication.hpp"
21 : #include "appmodel/DataHandlerModule.hpp"
22 : #include "appmodel/DataHandlerConf.hpp"
23 : #include "appmodel/SourceIDConf.hpp"
24 : #include "appmodel/appmodelIssues.hpp"
25 : #include "confmodel/Connection.hpp"
26 : #include "confmodel/NetworkConnection.hpp"
27 : #include "confmodel/Service.hpp"
28 : #include "logging/Logging.hpp"
29 : #include "oks/kernel.hpp"
30 : #include "conffwk/Configuration.hpp"
31 :
32 : #include <iostream>
33 : #include <string>
34 : #include <vector>
35 :
36 : using namespace dunedaq;
37 : using namespace dunedaq::appmodel;
38 :
39 : namespace dunedaq {
40 : namespace appmodel {
41 :
42 : void
43 0 : FakeHSIApplication::generate_modules(const confmodel::Session* session) const
44 : {
45 0 : std::vector<const confmodel::DaqModule*> modules;
46 :
47 0 : ConfigObjectFactory obj_fac(this);
48 :
49 :
50 0 : auto dlhConf = get_link_handler();
51 0 : auto dlhClass = dlhConf->get_template_for();
52 :
53 : // 23-Sep-2025, KAB et al: prevent a mis-configuration of the system in which the
54 : // FakeHSI DLH is told to generate TimeSync messages. (TimeSync messages should only
55 : // be sent from Readout DLH modules so that we don't get confusing system behavior.)
56 0 : if (dlhConf->get_generate_timesync()) {
57 0 : throw(BadConf(ERS_HERE, "TimeSync generation is enabled for a FakeHSIApplication and this is not allowed"));
58 : }
59 :
60 0 : const QueueDescriptor* dlhInputQDesc = nullptr;
61 :
62 0 : for (auto rule : get_queue_rules()) {
63 0 : auto destination_class = rule->get_destination_class();
64 0 : auto data_type = rule->get_descriptor()->get_data_type();
65 0 : if (destination_class == "DataHandlerModule" || destination_class == dlhClass) {
66 0 : dlhInputQDesc = rule->get_descriptor();
67 : }
68 0 : }
69 :
70 0 : const NetworkConnectionDescriptor* dlhReqInputNetDesc = nullptr;
71 0 : const NetworkConnectionDescriptor* tsNetDesc = nullptr;
72 0 : const NetworkConnectionDescriptor* hsiNetDesc = nullptr;
73 :
74 0 : for (auto rule : get_network_rules()) {
75 0 : auto endpoint_class = rule->get_endpoint_class();
76 0 : auto data_type = rule->get_descriptor()->get_data_type();
77 :
78 0 : if (endpoint_class == "DataHandlerModule" || endpoint_class == dlhClass) {
79 0 : if (data_type == "TimeSync") {
80 0 : tsNetDesc = rule->get_descriptor();
81 : }
82 0 : if (data_type == "DataRequest") {
83 0 : dlhReqInputNetDesc = rule->get_descriptor();
84 : }
85 : }
86 0 : if (data_type == "HSIEvent") {
87 0 : hsiNetDesc = rule->get_descriptor();
88 : }
89 0 : }
90 :
91 0 : auto rdrConf = get_generator();
92 0 : if (rdrConf == 0) {
93 0 : throw(BadConf(ERS_HERE, "No FakeHSIEventGeneratorModule configuration given"));
94 : }
95 0 : if (dlhInputQDesc == nullptr) {
96 0 : throw(BadConf(ERS_HERE, "No DLH data input queue descriptor given"));
97 : }
98 0 : if (dlhReqInputNetDesc == nullptr) {
99 0 : throw(BadConf(ERS_HERE, "No DLH request input network descriptor given"));
100 : }
101 0 : if (hsiNetDesc == nullptr) {
102 0 : throw(BadConf(ERS_HERE, "No HSIEvent output network descriptor given"));
103 : }
104 :
105 0 : auto idconf = get_source_id();
106 0 : if (idconf == nullptr) {
107 0 : throw(BadConf(ERS_HERE, "No SourceIDConf given"));
108 : }
109 0 : auto id = idconf->get_sid();
110 :
111 0 : auto det_id = 1; // TODO Eric Flumerfelt <eflumerf@fnal.gov>, 08-Feb-2024: This is a magic number corresponding to kDAQ
112 0 : std::string uid("DLH-" + std::to_string(id));
113 0 : TLOG_DEBUG(7) << "creating OKS configuration object for Data Link Handler class " << dlhClass << ", id " << id;
114 0 : conffwk::ConfigObject dlhObj = obj_fac.create(dlhClass, uid);
115 0 : dlhObj.set_by_val<uint32_t>("source_id", id);
116 0 : dlhObj.set_by_val<uint32_t>("detector_id", det_id);
117 0 : dlhObj.set_by_val<bool>("post_processing_enabled", false);
118 0 : dlhObj.set_obj("module_configuration", &dlhConf->config_object());
119 :
120 : // Process special Network rules!
121 : // Looking for Fragment rules from DFAppplications in current Session
122 0 : auto sessionApps = session->enabled_applications();
123 0 : std::vector<conffwk::ConfigObject> fragOutObjs;
124 0 : for (auto app : sessionApps) {
125 0 : auto dfapp = app->cast<appmodel::DFApplication>();
126 0 : if (dfapp == nullptr)
127 0 : continue;
128 :
129 0 : auto dfNRules = dfapp->get_network_rules();
130 0 : for (auto rule : dfNRules) {
131 0 : auto descriptor = rule->get_descriptor();
132 0 : auto data_type = descriptor->get_data_type();
133 0 : if (data_type == "Fragment") {
134 0 : conffwk::ConfigObject frag_conn =
135 0 : obj_fac.create_net_obj(descriptor, dfapp->UID());
136 0 : fragOutObjs.push_back(frag_conn);
137 0 : } // If network rule has TriggerDecision type of data
138 0 : } // Loop over Apps network rules
139 0 : } // loop over Session specific Apps
140 :
141 : // start building the list of outputs
142 0 : std::vector<const conffwk::ConfigObject*> fh_output_objs;
143 0 : for (auto& fNet : fragOutObjs) {
144 0 : fh_output_objs.push_back(&fNet);
145 : }
146 :
147 : // Time Sync network connection
148 0 : if (dlhConf->get_generate_timesync()) {
149 0 : conffwk::ConfigObject tsNetObj = obj_fac.create_net_obj(tsNetDesc, std::to_string(id));
150 0 : fh_output_objs.push_back(&tsNetObj);
151 0 : }
152 0 : dlhObj.set_objs("outputs", fh_output_objs);
153 :
154 0 : conffwk::ConfigObject queueObj = obj_fac.create_queue_sid_obj(dlhInputQDesc, id);
155 0 : conffwk::ConfigObject faNetObj = obj_fac.create_net_obj(dlhReqInputNetDesc, UID());
156 :
157 0 : dlhObj.set_objs("inputs", { &queueObj, &faNetObj });
158 :
159 0 : modules.push_back(obj_fac.get_dal<DataHandlerModule>(uid));
160 :
161 0 : auto hsiServiceObj = hsiNetDesc->get_associated_service()->config_object();
162 0 : conffwk::ConfigObject hsiNetObj = obj_fac.create_net_obj(hsiNetDesc, "");
163 :
164 0 : std::string genuid("FakeHSI-" + std::to_string(id));
165 0 : conffwk::ConfigObject fakehsiObj =
166 0 : obj_fac.create("FakeHSIEventGeneratorModule", genuid);
167 0 : fakehsiObj.set_obj("configuration", &rdrConf->config_object());
168 0 : fakehsiObj.set_objs("outputs", { &queueObj, &hsiNetObj });
169 0 : if (tsNetDesc != nullptr) {
170 0 : conffwk::ConfigObject tsNetObjIn = obj_fac.create_net_obj(tsNetDesc, ".*");
171 0 : fakehsiObj.set_objs("inputs", { &tsNetObjIn });
172 0 : }
173 :
174 0 : modules.push_back(obj_fac.get_dal<FakeHSIEventGeneratorModule>(genuid));
175 :
176 0 : obj_fac.update_modules(modules);
177 0 : }
178 :
179 : } // namespace appmodel
180 : } // namespace dunedaq
|