Line data Source code
1 : /**
2 : * @file CIBApplication.cpp
3 : *
4 : * Implementation of CIBApplication'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 : #include "conffwk/Configuration.hpp"
12 : #include "oks/kernel.hpp"
13 : #include "logging/Logging.hpp"
14 :
15 : #include "confmodel/DetectorToDaqConnection.hpp"
16 : #include "confmodel/DetDataSender.hpp"
17 :
18 : #include "ConfigObjectFactory.hpp"
19 : #include "appmodel/appmodelIssues.hpp"
20 : #include "appmodel/CIBApplication.hpp"
21 : #include "appmodel/CIBoardConf.hpp"
22 : #include "appmodel/CIBConf.hpp"
23 : #include "appmodel/CIBModule.hpp"
24 :
25 : #include "appmodel/DataHandlerConf.hpp"
26 : #include "appmodel/QueueConnectionRule.hpp"
27 : #include "appmodel/QueueDescriptor.hpp"
28 : #include "appmodel/NetworkConnectionDescriptor.hpp"
29 : #include "appmodel/NetworkConnectionRule.hpp"
30 : #include "appmodel/SourceIDConf.hpp"
31 : #include "appmodel/DFApplication.hpp"
32 : #include "appmodel/DataHandlerModule.hpp"
33 :
34 : #include <string>
35 : #include <vector>
36 : #include <bitset>
37 : #include <iostream>
38 : #include <fmt/core.h>
39 : #include <set>
40 :
41 : using namespace dunedaq;
42 : using namespace dunedaq::appmodel;
43 :
44 : std::vector<const confmodel::Resource*>
45 0 : CIBApplication::contained_resources() const {
46 0 : std::vector<const confmodel::Resource*> resources;
47 0 : resources.push_back(dynamic_cast<const confmodel::Resource *>(get_board())); // NOLINT(runtime/rtti)
48 0 : return resources;
49 0 : }
50 :
51 :
52 : void
53 0 : CIBApplication::generate_modules(const confmodel::Session* session) const
54 : {
55 0 : std::vector<const confmodel::DaqModule*> modules;
56 :
57 0 : ConfigObjectFactory obj_fac(this);
58 :
59 0 : auto dlhConf = get_link_handler();
60 0 : auto dlhClass = dlhConf->get_template_for();
61 :
62 0 : const QueueDescriptor* dlhInputQDesc = nullptr;
63 :
64 0 : for (auto rule : get_queue_rules()) {
65 0 : auto destination_class = rule->get_destination_class();
66 0 : if (destination_class == "DataHandlerModule" || destination_class == dlhClass) {
67 0 : dlhInputQDesc = rule->get_descriptor();
68 : }
69 0 : }
70 :
71 0 : const NetworkConnectionDescriptor* dlhReqInputNetDesc = nullptr;
72 0 : const NetworkConnectionDescriptor* tsNetDesc = nullptr;
73 0 : const NetworkConnectionDescriptor* hsiNetDesc = nullptr;
74 :
75 0 : for (auto rule : get_network_rules()) {
76 0 : auto endpoint_class = rule->get_endpoint_class();
77 0 : auto data_type = rule->get_descriptor()->get_data_type();
78 :
79 0 : if (endpoint_class == "DataHandlerModule" || endpoint_class == dlhClass) {
80 0 : if (data_type == "TimeSync") {
81 0 : tsNetDesc = rule->get_descriptor();
82 : }
83 0 : if (data_type == "DataRequest") {
84 0 : dlhReqInputNetDesc = rule->get_descriptor();
85 : }
86 : }
87 0 : if (data_type == "HSIEvent") {
88 0 : hsiNetDesc = rule->get_descriptor();
89 : }
90 0 : }
91 :
92 0 : auto CIB_conf = get_generator();
93 0 : if (CIB_conf == nullptr) {
94 : throw(BadConf(ERS_HERE, "No CIBModule configuration given"));
95 : }
96 0 : if (dlhInputQDesc == nullptr) {
97 0 : throw(BadConf(ERS_HERE, "No DLH data input queue descriptor given"));
98 : }
99 0 : if (dlhReqInputNetDesc == nullptr) {
100 0 : throw(BadConf(ERS_HERE, "No DLH request input network descriptor given"));
101 : }
102 0 : if (hsiNetDesc == nullptr) {
103 0 : throw(BadConf(ERS_HERE, "No HSIEvent output network descriptor given"));
104 : }
105 :
106 : // Process special Network rules!
107 : // Looking for Fragment rules from DFAppplications in current Session
108 0 : auto sessionApps = session->enabled_applications();
109 0 : std::vector<conffwk::ConfigObject> fragOutObjs;
110 0 : for (auto app : sessionApps) {
111 0 : auto dfapp = app->cast<appmodel::DFApplication>();
112 0 : if (dfapp == nullptr)
113 0 : continue;
114 :
115 0 : auto dfNRules = dfapp->get_network_rules();
116 0 : for (auto rule : dfNRules) {
117 0 : auto descriptor = rule->get_descriptor();
118 0 : auto data_type = descriptor->get_data_type();
119 0 : if (data_type == "Fragment") {
120 0 : std::string dreqNetUid(descriptor->get_uid_base() + dfapp->UID());
121 0 : conffwk::ConfigObject frag_conn = obj_fac.create_net_obj(descriptor, dreqNetUid);
122 0 : fragOutObjs.push_back(frag_conn);
123 0 : } // If network rule has Fragment type of data
124 0 : } // Loop over Apps network rules
125 0 : } // loop over Session specific Apps
126 :
127 : // start building the list of outputs
128 0 : std::vector<const conffwk::ConfigObject*> fh_output_objs;
129 0 : for (auto& fNet : fragOutObjs) {
130 0 : fh_output_objs.push_back(&fNet);
131 : }
132 :
133 0 : std::vector<conffwk::ConfigObject> CIB_module_outputs;
134 0 : auto source_id = get_source_id();
135 :
136 0 : int id = static_cast<int>(source_id->get_sid());
137 :
138 : // ----------------------------
139 : // create DLH
140 : // ----------------------------
141 0 : int det_id = 1; // TODO Eric Flumerfelt <eflumerf@fnal.gov>, 08-Feb-2024: This is a magic number corresponding to kDAQ // NOLINT(readability/todo)
142 0 : TLOG() << "creating OKS configuration object for CIB Data Link Handler class " << dlhClass << ", id " << id;
143 0 : std::string uid("DLH-CIB");
144 0 : conffwk::ConfigObject dlhObj = obj_fac.create( dlhClass, uid );
145 0 : dlhObj.set_by_val<uint32_t>("source_id", static_cast<uint32_t>(id)); // NOLINT(build/unsigned)
146 0 : dlhObj.set_by_val<uint32_t>("detector_id", static_cast<uint32_t>(det_id)); // NOLINT(build/unsigned)
147 0 : dlhObj.set_by_val<bool>("post_processing_enabled", false);
148 0 : dlhObj.set_obj("module_configuration", &dlhConf->config_object());
149 :
150 0 : auto net_objc(fh_output_objs);
151 :
152 0 : conffwk::ConfigObject tsNetObj;
153 : // Time Sync network connection
154 0 : if (dlhConf->get_generate_timesync()) {
155 0 : std::string tsStreamUid = tsNetDesc->get_uid_base() + std::to_string(id);
156 0 : tsNetObj = obj_fac.create_net_obj(tsNetDesc, tsStreamUid);
157 0 : net_objc.push_back(&tsNetObj);
158 0 : }
159 :
160 0 : dlhObj.set_objs("outputs", net_objc);
161 :
162 : // create Queues from CIB to DLH
163 0 : std::string dataQueueUid(dlhInputQDesc->get_uid_base() + std::string("CIB"));
164 0 : conffwk::ConfigObject queueObj = obj_fac.create_queue_sid_obj(dlhInputQDesc, id);
165 0 : queueObj.rename(dataQueueUid);
166 :
167 0 : CIB_module_outputs.push_back(queueObj);
168 :
169 : // Create network connections to DLHs
170 0 : conffwk::ConfigObject faNetObj = obj_fac.create_net_obj(dlhReqInputNetDesc, UID());
171 :
172 0 : dlhObj.set_objs("inputs", { &queueObj, &faNetObj });
173 :
174 0 : modules.push_back(obj_fac.get_dal<appmodel::DataHandlerModule>(uid));
175 :
176 0 : conffwk::ConfigObject hsiNetObj = obj_fac.create_net_obj(hsiNetDesc, "");
177 0 : CIB_module_outputs.push_back(hsiNetObj);
178 :
179 0 : auto board = get_board();
180 :
181 0 : conffwk::ConfigObject module_obj = obj_fac.create( "CIBModule", "CIB-module");
182 0 : module_obj.set_obj("configuration", & CIB_conf -> config_object() );
183 0 : module_obj.set_obj("board", & board -> config_object() );
184 :
185 0 : std::vector<const conffwk::ConfigObject*> CIB_module_output_ptrs;
186 0 : for ( const auto & o : CIB_module_outputs ) {
187 0 : CIB_module_output_ptrs.push_back( & o );
188 : }
189 :
190 0 : module_obj.set_objs("outputs", CIB_module_output_ptrs);
191 :
192 0 : auto module = obj_fac.get_dal<appmodel::CIBModule>(module_obj.UID());
193 :
194 0 : modules.push_back(module);
195 :
196 0 : obj_fac.update_modules(modules);
197 : // return modules;
198 0 : } // NOLINT
199 :
200 0 : nlohmann::json CIBoardConf::get_cib_json(const dunedaq::confmodel::Session &session, std::optional<std::string> socket_host, std::optional<uint16_t> socket_port) const
201 : {
202 :
203 : // shut up compiler!
204 0 : (void)session; // unused parameter
205 0 : nlohmann::json json;
206 0 : json["sockets"] = nlohmann::json::object();
207 0 : if (socket_host.has_value())
208 : {
209 0 : json["sockets"]["receiver"] = nlohmann::json::object();
210 0 : json["sockets"]["receiver"]["host"] = socket_host.value();
211 0 : json["sockets"]["receiver"]["port"] = socket_port.value(); // NOLINT(build/unsigned)
212 : }
213 : else
214 : {
215 0 : json["sockets"]["receiver"] = nlohmann::json::object();
216 0 : json["sockets"]["receiver"]["host"] = get_receiver_host();
217 0 : json["sockets"]["receiver"]["port"] = get_receiver_port(); // NOLINT(build/unsigned)
218 : }
219 :
220 0 : TLOG() << "JSON frag : [" << json.dump() << "] " ;
221 :
222 0 : return json;
223 0 : }
|