1 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
2 #include "otsdaq/Macros/TablePluginMacros.h"
3 #include "otsdaq/TablePlugins/XDAQContextTable.h"
13 #define XDAQ_RUN_FILE std::string(__ENV__("XDAQ_CONFIGURATION_DATA_PATH")) + "/" + std::string(__ENV__("XDAQ_CONFIGURATION_XML")) + ".xml"
14 #define APP_PRIORITY_FILE std::string(__ENV__("XDAQ_CONFIGURATION_DATA_PATH")) + "/" + "xdaqAppStateMachinePriority"
16 const std::string XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS =
"ots::Supervisor";
17 const std::string XDAQContextTable::GATEWAY_SUPERVISOR_CLASS =
"ots::GatewaySupervisor";
18 const std::string XDAQContextTable::WIZARD_SUPERVISOR_CLASS =
"ots::WizardSupervisor";
19 const std::set<std::string> XDAQContextTable::FETypeClassNames_ = {
"ots::FESupervisor",
"ots::FEDataManagerSupervisor",
"ots::ARTDAQFEDataManagerSupervisor"};
20 const std::set<std::string> XDAQContextTable::DMTypeClassNames_ = {
"ots::DataManagerSupervisor",
"ots::FEDataManagerSupervisor",
"ots::ARTDAQFEDataManagerSupervisor"};
21 const std::set<std::string> XDAQContextTable::LogbookTypeClassNames_ = {
"ots::LogbookSupervisor"};
22 const std::set<std::string> XDAQContextTable::MacroMakerTypeClassNames_ = {
"ots::MacroMakerSupervisor"};
23 const std::set<std::string> XDAQContextTable::ChatTypeClassNames_ = {
"ots::ChatSupervisor"};
24 const std::set<std::string> XDAQContextTable::ConsoleTypeClassNames_ = {
"ots::ConsoleSupervisor"};
25 const std::set<std::string> XDAQContextTable::ConfigurationGUITypeClassNames_ = {
"ots::TableGUISupervisor"};
28 const uint8_t XDAQContextTable::XDAQApplication::DEFAULT_PRIORITY = 100;
34 const std::string XDAQContextTable::XDAQ_CONTEXT_TABLE =
"XDAQContextTable";
48 XDAQContextTable::~XDAQContextTable(
void) {}
54 extractContexts(configManager);
56 bool isFirstAppInContext = configManager->isOwnerFirstAppInContext();
59 if(!isFirstAppInContext)
67 fs.open(XDAQ_RUN_FILE, std::fstream::out | std::fstream::trunc);
70 __SS__ <<
"Failed to open XDAQ run file: " << XDAQ_RUN_FILE << __E__;
79 std::string XDAQContextTable::getContextAddress(
const std::string& contextUID,
84 for(
auto& context : contexts_)
86 if(context.contextUID_ == contextUID)
89 return context.address_;
90 auto address = context.address_;
91 if(address.find(
"http://") == 0)
93 address = address.replace(0, 7,
"");
95 if(address.find(
"https://") == 0)
97 address = address.replace(0, 8,
"");
106 std::vector<const XDAQContextTable::XDAQContext*>
107 XDAQContextTable::getARTDAQSupervisorContexts()
const
109 std::vector<const XDAQContext*> retVec;
110 for(
auto& i : artdaqSupervisors_)
111 retVec.push_back(&contexts_[i]);
119 return configManager->getNode(XDAQContextTable::XDAQ_CONTEXT_TABLE).getNode(contextUID);
125 const std::string& contextUID,
126 const std::string& appUID)
128 return configManager->getNode(XDAQContextTable::XDAQ_CONTEXT_TABLE).getNode(
129 contextUID +
"/" + colContext_.colLinkToApplicationTable_ +
"/" + appUID);
135 const std::string& contextUID,
136 const std::string& appUID)
138 return configManager->getNode(XDAQContextTable::XDAQ_CONTEXT_TABLE).getNode(
139 contextUID +
"/" + XDAQContextTable::colContext_.colLinkToApplicationTable_ +
141 XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
156 auto children = configManager->__SELF_NODE__.getChildren();
161 artdaqSupervisors_.clear();
163 artdaqBoardReaders_.clear();
171 std::set<
unsigned int > appIdSet;
173 for(
auto& child : children)
175 contexts_.push_back(XDAQContext());
179 contexts_.back().contextUID_ = child.first;
181 contexts_.back().sourceConfig_ =
182 child.second.getTableName() +
"_v" +
183 child.second.getTableVersion().toString() +
" @ " +
184 std::to_string(child.second.getTableCreationTime());
185 child.second.getNode(colContext_.colContextUID_)
186 .getValue(contexts_.back().contextUID_);
187 child.second.getNode(colContext_.colStatus_).getValue(contexts_.back().status_);
188 child.second.getNode(colContext_.colId_).getValue(contexts_.back().id_);
189 child.second.getNode(colContext_.colAddress_).getValue(contexts_.back().address_);
190 child.second.getNode(colContext_.colPort_).getValue(contexts_.back().port_);
194 if(contexts_.back().port_ < 1024 || contexts_.back().port_ > 49151)
196 __SS__ <<
"Illegal xdaq Context port: " << contexts_.back().port_
197 <<
". Port must be between 1024 and 49151." << __E__;
202 auto appLink = child.second.getNode(colContext_.colLinkToApplicationTable_);
203 if(appLink.isDisconnected())
205 __SS__ <<
"Application link is disconnected!" << __E__;
210 auto appChildren = appLink.getChildren();
211 for(
auto appChild : appChildren)
215 contexts_.back().applications_.push_back(XDAQApplication());
217 contexts_.back().applications_.back().applicationGroupID_ = child.first;
218 contexts_.back().applications_.back().sourceConfig_ =
219 appChild.second.getTableName() +
"_v" +
220 appChild.second.getTableVersion().toString() +
" @ " +
221 std::to_string(appChild.second.getTableCreationTime());
223 appChild.second.getNode(colApplication_.colApplicationUID_)
224 .getValue(contexts_.back().applications_.back().applicationUID_);
225 appChild.second.getNode(colApplication_.colStatus_)
226 .getValue(contexts_.back().applications_.back().status_);
227 appChild.second.getNode(colApplication_.colClass_)
228 .getValue(contexts_.back().applications_.back().class_);
229 appChild.second.getNode(colApplication_.colId_)
230 .getValue(contexts_.back().applications_.back().id_);
233 if((contexts_.back().applications_.back().id_ == 200 &&
234 contexts_.back().applications_.back().class_ !=
235 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS &&
236 contexts_.back().applications_.back().class_ !=
237 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS) ||
238 (contexts_.back().applications_.back().id_ != 200 &&
239 (contexts_.back().applications_.back().class_ ==
240 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
241 contexts_.back().applications_.back().class_ ==
242 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)))
244 __SS__ <<
"XDAQ Application ID of 200 is reserved for the Gateway "
246 << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS
247 <<
". Conflict specifically at id="
248 << contexts_.back().applications_.back().id_ <<
" appName="
249 << contexts_.back().applications_.back().applicationUID_ << __E__;
254 if(contexts_.back().status_ && contexts_.back().applications_.back().status_)
257 if(appIdSet.find(contexts_.back().applications_.back().id_) !=
260 __SS__ <<
"XDAQ Application IDs are not unique. Specifically at id="
261 << contexts_.back().applications_.back().id_ <<
" appName="
262 << contexts_.back().applications_.back().applicationUID_
264 __COUT_ERR__ <<
"\n" << ss.str();
267 appIdSet.insert(contexts_.back().applications_.back().id_);
271 if(appChild.second.getNode(colApplication_.colInstance_).isDefaultValue())
272 contexts_.back().applications_.back().instance_ = 1;
274 appChild.second.getNode(colApplication_.colInstance_)
275 .getValue(contexts_.back().applications_.back().instance_);
277 if(appChild.second.getNode(colApplication_.colNetwork_).isDefaultValue())
278 contexts_.back().applications_.back().network_ =
"local";
280 appChild.second.getNode(colApplication_.colNetwork_)
281 .getValue(contexts_.back().applications_.back().network_);
283 if(appChild.second.getNode(colApplication_.colGroup_).isDefaultValue())
284 contexts_.back().applications_.back().group_ =
"daq";
286 appChild.second.getNode(colApplication_.colGroup_)
287 .getValue(contexts_.back().applications_.back().group_);
289 appChild.second.getNode(colApplication_.colModule_)
290 .getValue(contexts_.back().applications_.back().module_);
293 if(contexts_.back().applications_.back().class_ ==
294 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)
296 contexts_.back().applications_.back().class_ =
297 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS;
298 __COUT__ <<
"Fixing deprecated Supervisor class from "
299 << XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS <<
" to "
300 << (contexts_.back().applications_.back().class_);
302 if(contexts_.back().applications_.back().module_.find(
"libSupervisor.so") !=
305 __COUT__ <<
"Fixing deprecated Supervisor class from "
306 << contexts_.back().applications_.back().module_ <<
" to ";
307 contexts_.back().applications_.back().module_ =
308 contexts_.back().applications_.back().module_.substr(
310 contexts_.back().applications_.back().module_.size() -
311 std::string(
"Supervisor.so").size()) +
312 "GatewaySupervisor.so";
313 std::cout << contexts_.back().applications_.back().module_ << __E__;
318 appChild.second.getNode(colApplication_.colConfigurePriority_)
319 .getValue(contexts_.back()
320 .applications_.back()
321 .stateMachineCommandPriority_[
"Configure"]);
322 appChild.second.getNode(colApplication_.colStartPriority_)
323 .getValue(contexts_.back()
324 .applications_.back()
325 .stateMachineCommandPriority_[
"Start"]);
326 appChild.second.getNode(colApplication_.colStopPriority_)
327 .getValue(contexts_.back()
328 .applications_.back()
329 .stateMachineCommandPriority_[
"Stop"]);
333 __COUT__ <<
"Ignoring missing state machine priorities..." << __E__;
336 auto appPropertyLink =
337 appChild.second.getNode(colApplication_.colLinkToPropertyTable_);
338 if(!appPropertyLink.isDisconnected())
342 auto appPropertyChildren = appPropertyLink.getChildren();
347 for(
auto appPropertyChild : appPropertyChildren)
349 contexts_.back().applications_.back().properties_.push_back(
350 XDAQApplicationProperty());
351 contexts_.back().applications_.back().properties_.back().status_ =
352 appPropertyChild.second.getNode(colAppProperty_.colStatus_)
354 contexts_.back().applications_.back().properties_.back().name_ =
355 appPropertyChild.second.getNode(colAppProperty_.colPropertyName_)
356 .getValue<std::string>();
357 contexts_.back().applications_.back().properties_.back().type_ =
358 appPropertyChild.second.getNode(colAppProperty_.colPropertyType_)
359 .getValue<std::string>();
360 contexts_.back().applications_.back().properties_.back().value_ =
361 appPropertyChild.second.getNode(colAppProperty_.colPropertyValue_)
362 .getValue<std::string>();
387 if(!contexts_.back().status_)
397 for(
auto& app : contexts_.back().applications_)
400 "ots::ARTDAQSupervisor")
402 __COUT__ <<
"Found " << app.class_ <<
" in context '" <<
403 contexts_.back().id_ <<
"'" << __E__;
404 artdaqSupervisors_.push_back(contexts_.size() - 1);
449 out <<
"<?xml version='1.0'?>\n"
450 <<
"<xc:Partition \txmlns:xsi\t= \"http://www.w3.org/2001/XMLSchema-instance\"\n"
451 <<
"\t\txmlns:soapenc\t= \"http://schemas.xmlsoap.org/soap/encoding/\"\n"
452 <<
"\t\txmlns:xc\t= "
453 "\"http://xdaq.web.cern.ch/xdaq/xsd/2004/XMLConfiguration-30\">\n\n";
470 "\t<!-- ContextUID='%s' sourceConfig='%s' -->",
471 context.contextUID_.c_str(),
472 context.sourceConfig_.c_str());
479 "\t<xc:Context id=\"%u\" url=\"%s:%u\">",
481 context.address_.c_str(),
483 out << tmp <<
"\n\n";
493 "\t\t<!-- Application GroupID = '%s' UID='%s' sourceConfig='%s' -->",
494 app.applicationGroupID_.c_str(),
495 app.applicationUID_.c_str(),
496 app.sourceConfig_.c_str());
504 "\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" "
505 "network=\"%s\" group=\"%s\">\n",
509 app.network_.c_str(),
514 int foundColon = app.class_.rfind(
':');
519 __SS__ <<
"Illegal XDAQApplication class name value of '" << app.class_
520 <<
"' - please check the entry for app ID = " << app.id_ << __E__;
523 out <<
"\t\t\t<properties xmlns=\"urn:xdaq-application:"
524 << app.class_.substr(foundColon) <<
"\" xsi:type=\"soapenc:Struct\">\n";
529 if(appProperty.type_ ==
"ots::SupervisorProperty")
532 if(!appProperty.status_)
533 out <<
"\t\t\t\t<!--\n";
536 "\t\t\t\t<%s xsi:type=\"%s\">%s</%s>\n",
537 appProperty.name_.c_str(),
538 appProperty.type_.c_str(),
539 appProperty.value_.c_str(),
540 appProperty.name_.c_str());
543 if(!appProperty.status_)
544 out <<
"\t\t\t\t-->\n";
546 out <<
"\t\t\t</properties>\n";
549 out <<
"\t\t</xc:Application>\n";
551 sprintf(tmp,
"\t\t<xc:Module>%s</xc:Module>\n", app.module_.c_str());
554 if(context.status_ && !app.status_)
561 out <<
"\t</xc:Context>\n";
568 out <<
"</xc:Partition>\n\n\n";
572 std::string XDAQContextTable::getContextUID(
const std::string& url)
const
574 for(
auto context : contexts_)
579 if(url == context.address_ +
":" + std::to_string(context.port_))
580 return context.contextUID_;
586 std::string XDAQContextTable::getApplicationUID(
const std::string& url,
587 unsigned int id)
const
590 for(
auto context : contexts_)
601 if(url == context.address_ +
":" + std::to_string(context.port_))
602 for(
auto application : context.applications_)
605 if(!application.status_)
608 if(application.id_ ==
id)
610 return application.applicationUID_;
void outputXDAQXML(std::ostream &out)