1 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
2 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
12 #define XDAQ_RUN_FILE std::string(__ENV__("XDAQ_CONFIGURATION_DATA_PATH")) + "/" + std::string(__ENV__("XDAQ_CONFIGURATION_XML")) + ".xml"
13 #define APP_PRIORITY_FILE std::string(__ENV__("XDAQ_CONFIGURATION_DATA_PATH")) + "/" + "xdaqAppStateMachinePriority"
15 const std::string XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS =
"ots::Supervisor";
16 const std::string XDAQContextTable::GATEWAY_SUPERVISOR_CLASS =
"ots::GatewaySupervisor";
17 const std::string XDAQContextTable::WIZARD_SUPERVISOR_CLASS =
"ots::WizardSupervisor";
18 const std::string XDAQContextTable::ARTDAQ_SUPERVISOR_CLASS =
"ots::ARTDAQSupervisor";
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",
"ots::ECLSupervisor"};
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::ConfigurationGUISupervisor"};
26 const std::set<std::string> XDAQContextTable::CodeEditorTypeClassNames_ = {
"ots::CodeEditorSupervisor"};
27 const std::set<std::string> XDAQContextTable::VisualizerTypeClassNames_ = {
"ots::VisualSupervisor"};
28 const std::set<std::string> XDAQContextTable::SlowControlsTypeClassNames_ = {
"ots::SlowControlsDashboardSupervisor"};
32 std::make_pair(XDAQContextTable::GATEWAY_SUPERVISOR_CLASS,
"${OTSDAQ_LIB}/libGatewaySupervisor.so"),
33 std::make_pair(XDAQContextTable::ARTDAQ_SUPERVISOR_CLASS,
"${OTSDAQ_LIB}/libARTDAQSupervisor.so"),
34 std::make_pair(*(std::next(XDAQContextTable::FETypeClassNames_.begin(),2)),
"${OTSDAQ_LIB}/libCoreSupervisors.so"),
35 std::make_pair(*(std::next(XDAQContextTable::FETypeClassNames_.begin(),1)),
"${OTSDAQ_LIB}/libCoreSupervisors.so"),
36 std::make_pair(*(XDAQContextTable::FETypeClassNames_.begin()),
"${OTSDAQ_LIB}/libCoreSupervisors.so"),
37 std::make_pair(*(std::next(XDAQContextTable::DMTypeClassNames_.begin(),2)),
"${OTSDAQ_LIB}/libCoreSupervisors.so"),
38 std::make_pair(*(std::next(XDAQContextTable::DMTypeClassNames_.begin(),1)),
"${OTSDAQ_LIB}/libCoreSupervisors.so"),
39 std::make_pair(*(XDAQContextTable::DMTypeClassNames_.begin()),
"${OTSDAQ_LIB}/libCoreSupervisors.so"),
40 std::make_pair(*(std::next(XDAQContextTable::LogbookTypeClassNames_.begin(),1)),
"${OTSDAQ_UTILITIES_LIB}/libLogbook.so"),
41 std::make_pair(*(XDAQContextTable::LogbookTypeClassNames_.begin()),
"${OTSDAQ_UTILITIES_LIB}/libECLWriter.so"),
42 std::make_pair(*(XDAQContextTable::MacroMakerTypeClassNames_.begin()),
"${OTSDAQ_UTILITIES_LIB}/libMacroMaker.so"),
43 std::make_pair(*(XDAQContextTable::ChatTypeClassNames_.begin()),
"${OTSDAQ_UTILITIES_LIB}/libChat.so"),
44 std::make_pair(*(XDAQContextTable::ConsoleTypeClassNames_.begin()),
"${OTSDAQ_UTILITIES_LIB}/libConsole.so"),
45 std::make_pair(*(XDAQContextTable::ConfigurationGUITypeClassNames_.begin()),
"${OTSDAQ_UTILITIES_LIB}/libConfigurationGUI.so"),
46 std::make_pair(*(XDAQContextTable::CodeEditorTypeClassNames_.begin()),
"${OTSDAQ_LIB}/libCodeEditor.so"),
47 std::make_pair(*(XDAQContextTable::VisualizerTypeClassNames_.begin()),
"${OTSDAQ_UTILITIES_LIB}/libVisualization.so"),
48 std::make_pair(*(XDAQContextTable::SlowControlsTypeClassNames_.begin()),
"${OTSDAQ_UTILITIES_LIB}/libSlowControlsDashboard.so")
90 const unsigned int XDAQContextTable::XDAQApplication::GATEWAY_APP_ID = 200;
91 const unsigned int XDAQContextTable::XDAQApplication::WIZMODE_APP_ID = 290;
92 const unsigned int XDAQContextTable::XDAQApplication::WIZMODE_CONFIG_APP_ID = 280;
101 XDAQContextTable::XDAQContextTable(
void)
103 , artdaqSupervisorContext_((unsigned int)-1)
119 XDAQContextTable::~XDAQContextTable(
void) {}
130 if(!isFirstAppInContext)
137 fs.open(XDAQ_RUN_FILE, std::fstream::out | std::fstream::trunc);
140 __SS__ <<
"Failed to open XDAQ run file: " << XDAQ_RUN_FILE << __E__;
149 std::string XDAQContextTable::getContextAddress(
const std::string& contextUID,
152 if(contextUID ==
"X")
154 for(
auto& context : contexts_)
156 if(context.contextUID_ == contextUID)
159 return context.address_;
160 size_t i = context.address_.find(
"://");
161 if(i == std::string::npos)
165 return context.address_.substr(i);
175 if(artdaqSupervisorContext_ >= contexts_.size())
177 return &contexts_[artdaqSupervisorContext_];
184 return configManager->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
191 const std::string& contextUID,
192 const std::string& appUID)
194 return configManager->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
195 .
getNode(contextUID +
"/" + colContext_.colLinkToApplicationTable_ +
"/" +
202 const std::string& contextUID,
203 const std::string& appUID)
205 return configManager->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
207 XDAQContextTable::colContext_.colLinkToApplicationTable_ +
"/" + appUID +
208 "/" + XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
223 auto children = configManager->__SELF_NODE__.
getChildren();
226 artdaqSupervisorContext_ = (
unsigned int)-1;
231 std::set<
unsigned int > appIdSet;
233 for(
auto& child : children)
239 contexts_.back().contextUID_ = child.first;
241 contexts_.back().sourceConfig_ =
242 child.second.getTableName() +
"_v" +
243 child.second.getTableVersion().toString() +
" @ " +
244 std::to_string(child.second.getTableCreationTime());
245 child.second.getNode(colContext_.colContextUID_)
246 .getValue(contexts_.back().contextUID_);
247 child.second.getNode(colContext_.colStatus_).getValue(contexts_.back().status_);
248 child.second.getNode(colContext_.colId_).getValue(contexts_.back().id_);
249 child.second.getNode(colContext_.colAddress_).getValue(contexts_.back().address_);
250 child.second.getNode(colContext_.colPort_).getValue(contexts_.back().port_);
254 if(contexts_.back().port_ == 0)
255 contexts_.back().port_ = atoi(__ENV__(
"OTS_MAIN_PORT"));
256 if(contexts_.back().address_ ==
258 contexts_.back().address_ =
"http://" + std::string(__ENV__(
"HOSTNAME"));
259 if(contexts_.back().port_ < 1024 || contexts_.back().port_ > 49151)
261 __SS__ <<
"Illegal xdaq Context port: " << contexts_.back().port_
262 <<
". Port must be between 1024 and 49151." << __E__;
267 auto appLink = child.second.getNode(colContext_.colLinkToApplicationTable_);
268 if(appLink.isDisconnected())
270 __SS__ <<
"Application link is disconnected!" << __E__;
275 auto appChildren = appLink.getChildren();
276 for(
auto appChild : appChildren)
282 contexts_.back().applications_.back().applicationGroupID_ = child.first;
283 contexts_.back().applications_.back().sourceConfig_ =
284 appChild.second.getTableName() +
"_v" +
285 appChild.second.getTableVersion().toString() +
" @ " +
286 std::to_string(appChild.second.getTableCreationTime());
288 appChild.second.getNode(colApplication_.colApplicationUID_)
289 .getValue(contexts_.back().applications_.back().applicationUID_);
290 appChild.second.getNode(colApplication_.colStatus_)
291 .getValue(contexts_.back().applications_.back().status_);
292 appChild.second.getNode(colApplication_.colClass_)
293 .getValue(contexts_.back().applications_.back().class_);
294 appChild.second.getNode(colApplication_.colId_)
295 .getValue(contexts_.back().applications_.back().id_);
298 if(appChild.second.getNode(colApplication_.colId_).isDefaultValue() &&
299 (contexts_.back().applications_.back().class_ ==
300 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
301 contexts_.back().applications_.back().class_ ==
302 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS))
304 contexts_.back().applications_.back().id_ =
305 XDAQContextTable::XDAQApplication::GATEWAY_APP_ID;
309 if((contexts_.back().applications_.back().id_ ==
310 XDAQContextTable::XDAQApplication::GATEWAY_APP_ID &&
311 contexts_.back().applications_.back().class_ !=
312 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS &&
313 contexts_.back().applications_.back().class_ !=
314 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS) ||
315 (contexts_.back().applications_.back().id_ !=
316 XDAQContextTable::XDAQApplication::GATEWAY_APP_ID &&
317 (contexts_.back().applications_.back().class_ ==
318 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
319 contexts_.back().applications_.back().class_ ==
320 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)))
322 __SS__ <<
"XDAQ Application ID of "
323 << XDAQContextTable::XDAQApplication::GATEWAY_APP_ID
324 <<
" is reserved for the Gateway Supervisor's class '"
325 << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS
326 <<
".' There must be one and only one XDAQ supervisor application "
327 "specified with ID '"
328 << XDAQContextTable::XDAQApplication::GATEWAY_APP_ID
329 <<
"' and class '" << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS
330 <<
".' A conflict was found specifically at appName="
331 << contexts_.back().applications_.back().applicationUID_
332 <<
" with id=" << contexts_.back().applications_.back().id_
333 <<
" and class=" << contexts_.back().applications_.back().class_
339 if(contexts_.back().status_ && contexts_.back().applications_.back().status_)
342 if(appIdSet.find(contexts_.back().applications_.back().id_) !=
345 __SS__ <<
"XDAQ Application IDs are not unique; this could be due to "
346 "multiple instances of the same XDAQ application linked to "
348 "separate XDAQ Contexts (check all enabled XDAQ Contexts "
349 "for replicated application IDs). Specifically, there is a "
351 << contexts_.back().applications_.back().id_ <<
" appName="
352 << contexts_.back().applications_.back().applicationUID_
354 __COUT_ERR__ <<
"\n" << ss.str();
357 appIdSet.insert(contexts_.back().applications_.back().id_);
361 if(appChild.second.getNode(colApplication_.colInstance_).isDefaultValue())
362 contexts_.back().applications_.back().instance_ = 1;
364 appChild.second.getNode(colApplication_.colInstance_)
365 .getValue(contexts_.back().applications_.back().instance_);
367 if(appChild.second.getNode(colApplication_.colNetwork_).isDefaultValue())
368 contexts_.back().applications_.back().network_ =
"local";
370 appChild.second.getNode(colApplication_.colNetwork_)
371 .getValue(contexts_.back().applications_.back().network_);
373 if(appChild.second.getNode(colApplication_.colGroup_).isDefaultValue())
374 contexts_.back().applications_.back().group_ =
"daq";
376 appChild.second.getNode(colApplication_.colGroup_)
377 .getValue(contexts_.back().applications_.back().group_);
380 if(contexts_.back().applications_.back().class_ ==
381 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)
383 contexts_.back().applications_.back().class_ =
384 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS;
385 __COUT__ <<
"Fixing deprecated Supervisor class from "
386 << XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS <<
" to "
387 << (contexts_.back().applications_.back().class_);
390 if(contexts_.back().applications_.back().class_ ==
391 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS &&
392 contexts_.back().applications_.back().module_.find(
"libSupervisor.so") !=
395 __COUT__ <<
"Fixing deprecated Supervisor class from "
396 << contexts_.back().applications_.back().module_ <<
" to ";
397 contexts_.back().applications_.back().module_ =
398 contexts_.back().applications_.back().module_.substr(
400 contexts_.back().applications_.back().module_.size() -
401 std::string(
"Supervisor.so").size()) +
402 "GatewaySupervisor.so";
403 std::cout << contexts_.back().applications_.back().module_ << __E__;
411 if(contexts_.back().applications_.back().id_ ==
412 XDAQContextTable::XDAQApplication::
414 contexts_.back().applications_.back().module_ =
416 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS);
417 else if(appChild.second.getNode(colApplication_.colModule_)
420 contexts_.back().applications_.back().class_) !=
423 contexts_.back().applications_.back().module_ =
425 contexts_.back().applications_.back().class_);
426 __COUT__ <<
"Inferred module of '"
427 << contexts_.back().applications_.back().applicationUID_
428 <<
"' as '" << contexts_.back().applications_.back().module_
429 <<
"' based on class '"
430 << contexts_.back().applications_.back().class_ <<
"'" << __E__;
433 contexts_.back().applications_.back().module_ =
434 appChild.second.getNode(colApplication_.colModule_)
439 appChild.second.getNode(colApplication_.colConfigurePriority_)
440 .getValue(contexts_.back()
441 .applications_.back()
442 .stateMachineCommandPriority_[
"Configure"]);
443 appChild.second.getNode(colApplication_.colStartPriority_)
444 .getValue(contexts_.back()
445 .applications_.back()
446 .stateMachineCommandPriority_[
"Start"]);
447 appChild.second.getNode(colApplication_.colStopPriority_)
448 .getValue(contexts_.back()
449 .applications_.back()
450 .stateMachineCommandPriority_[
"Stop"]);
454 __COUT__ <<
"Ignoring missing state machine priorities..." << __E__;
457 auto appPropertyLink =
458 appChild.second.getNode(colApplication_.colLinkToPropertyTable_);
459 if(!appPropertyLink.isDisconnected())
463 auto appPropertyChildren = appPropertyLink.getChildren();
468 for(
auto appPropertyChild : appPropertyChildren)
470 contexts_.back().applications_.back().properties_.push_back(
472 contexts_.back().applications_.back().properties_.back().status_ =
473 appPropertyChild.second.getNode(colAppProperty_.colStatus_)
475 contexts_.back().applications_.back().properties_.back().name_ =
476 appPropertyChild.second.getNode(colAppProperty_.colPropertyName_)
477 .getValue<std::string>();
478 contexts_.back().applications_.back().properties_.back().type_ =
479 appPropertyChild.second.getNode(colAppProperty_.colPropertyType_)
480 .getValue<std::string>();
481 contexts_.back().applications_.back().properties_.back().value_ =
482 appPropertyChild.second.getNode(colAppProperty_.colPropertyValue_)
483 .getValue<std::string>();
496 if(!contexts_.back().status_)
499 for(
auto& app : contexts_.back().applications_)
502 "ots::ARTDAQSupervisor" &&
505 __COUT__ <<
"Found " << app.class_ <<
" in context '"
506 << contexts_.back().contextUID_ <<
"'" << __E__;
508 if(artdaqSupervisorContext_ < contexts_.size())
510 __SS__ <<
"Error! Only one artdaq Supervisor is allowed to be "
512 <<
"two encountered in context '"
513 << contexts_[artdaqSupervisorContext_].contextUID_
514 <<
"' and '" << contexts_.back().contextUID_ <<
"'..."
517 artdaqSupervisorContext_ = (
unsigned int)-1;
522 artdaqSupervisorContext_ = contexts_.size() - 1;
544 out <<
"<?xml version='1.0'?>\n"
545 <<
"<xc:Partition \txmlns:xsi\t= \"http://www.w3.org/2001/XMLSchema-instance\"\n"
546 <<
"\t\txmlns:soapenc\t= \"http://schemas.xmlsoap.org/soap/encoding/\"\n"
547 <<
"\t\txmlns:xc\t= "
548 "\"http://xdaq.web.cern.ch/xdaq/xsd/2004/XMLConfiguration-30\">\n\n";
565 "\t<!-- ContextUID='%s' sourceConfig='%s' -->",
566 context.contextUID_.c_str(),
567 context.sourceConfig_.c_str());
574 "\t<xc:Context id=\"%u\" url=\"%s:%u\">",
576 context.address_.c_str(),
578 out << tmp <<
"\n\n";
588 "\t\t<!-- Application GroupID = '%s' UID='%s' sourceConfig='%s' -->",
589 app.applicationGroupID_.c_str(),
590 app.applicationUID_.c_str(),
591 app.sourceConfig_.c_str());
598 if(app.class_ ==
"ots::GatewaySupervisor")
601 "\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" "
602 "network=\"%s\" icon=\"/WebPath/images/otsdaqIcons/logo_square.png\" "
603 "icon16x16=\"/WebPath/images/otsdaqIcons/favicon-16x16.png\" "
608 app.network_.c_str(),
612 "\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" "
613 "network=\"%s\" group=\"%s\">\n",
617 app.network_.c_str(),
622 int foundColon = app.class_.rfind(
':');
627 __SS__ <<
"Illegal XDAQApplication class name value of '" << app.class_
628 <<
"' - please check the entry for app ID = " << app.id_ << __E__;
631 out <<
"\t\t\t<properties xmlns=\"urn:xdaq-application:"
632 << app.class_.substr(foundColon) <<
"\" xsi:type=\"soapenc:Struct\">\n";
637 if(appProperty.type_ ==
"ots::SupervisorProperty")
640 if(!appProperty.status_)
641 out <<
"\t\t\t\t<!--\n";
644 "\t\t\t\t<%s xsi:type=\"%s\">%s</%s>\n",
645 appProperty.name_.c_str(),
646 appProperty.type_.c_str(),
647 appProperty.value_.c_str(),
648 appProperty.name_.c_str());
651 if(!appProperty.status_)
652 out <<
"\t\t\t\t-->\n";
654 out <<
"\t\t\t</properties>\n";
657 out <<
"\t\t</xc:Application>\n";
659 sprintf(tmp,
"\t\t<xc:Module>%s</xc:Module>\n", app.module_.c_str());
662 if(context.status_ && !app.status_)
669 out <<
"\t</xc:Context>\n";
676 out <<
"</xc:Partition>\n\n\n";
682 for(
auto context : contexts_)
687 if(url == context.address_ +
":" + std::to_string(context.port_))
688 return context.contextUID_;
694 std::string XDAQContextTable::getApplicationUID(
const std::string& url,
695 unsigned int id)
const
698 for(
auto context : contexts_)
709 if(url == context.address_ +
":" + std::to_string(context.port_))
710 for(
auto application : context.applications_)
713 if(!application.status_)
716 if(application.id_ ==
id)
718 return application.applicationUID_;
729 const std::string& appUID,
730 bool allowOffContexts )
const
734 auto childrenMap = configManager->__SELF_NODE__.
getChildren();
736 for(
auto& context : childrenMap)
738 if(!allowOffContexts &&
739 !context.second.getNode(XDAQContextTable::colContext_.colStatus_)
744 XDAQContextTable::colContext_.colLinkToApplicationTable_);
749 for(
auto& app : appMap)
751 if(!allowOffContexts &&
752 !app.second.getNode(XDAQContextTable::colApplication_.colStatus_)
756 if(app.first == appUID)
757 return context.first;
761 __SS__ <<
"Application '" << appUID <<
"' search found no parent context!" << __E__;
773 auto childrenMap = configManager->__SELF_NODE__.
getChildren();
775 for(
auto& context : childrenMap)
777 if(!context.second.getNode(XDAQContextTable::colContext_.colStatus_)
782 XDAQContextTable::colContext_.colLinkToApplicationTable_);
787 for(
auto& app : appMap)
789 if(!app.second.getNode(XDAQContextTable::colApplication_.colStatus_)
793 std::string className =
794 app.second.getNode(XDAQContextTable::colApplication_.colClass_)
795 .getValue<std::string>();
796 if(className == XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
797 className == XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)
798 return context.first;
802 __SS__ <<
"Gateway Application search found no parent context!" << __E__;
bool isOwnerFirstAppInContext(void)
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
"root/parent/parent/"
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
bool isDisconnected(void) const
ConfigurationTree getNode(const std::string &nodeName, bool doNotThrowOnBrokenUIDLinks=false) const
navigating between nodes
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
void outputXDAQXML(std::ostream &out)
void init(ConfigurationManager *configManager)
Methods.
static const std::map< std::string, std::string > AppClassModuleLookup_
NOTE!!! std::next + offset reads std::set from right-to-left above (end to beginning)
std::string getContextUID(const std::string &url) const
std::string getContextOfApplication(ConfigurationManager *configManager, const std::string &appUID, bool allowOffContexts=false) const
only considers ON contexts and applications, unless off contexts allows
void extractContexts(ConfigurationManager *configManager)
std::string getContextOfGateway(ConfigurationManager *configManager) const
only considers ON contexts and applications
const XDAQContext * getTheARTDAQSupervisorContext(void) const
artdaq specific get methods
defines used also by OtsConfigurationWizardSupervisor
XDAQ App Property Column names.
XDAQ Context Column names.
static const uint8_t DEFAULT_PRIORITY