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;
99 XDAQContextTable::XDAQContextTable(
void)
101 , artdaqSupervisorContext_((unsigned int)-1)
117 XDAQContextTable::~XDAQContextTable(
void) {}
125 bool isFirstAppInContext = configManager->isOwnerFirstAppInContext();
128 if(!isFirstAppInContext)
135 fs.open(XDAQ_RUN_FILE, std::fstream::out | std::fstream::trunc);
138 __SS__ <<
"Failed to open XDAQ run file: " << XDAQ_RUN_FILE << __E__;
147 std::string XDAQContextTable::getContextAddress(
const std::string& contextUID,
150 if(contextUID ==
"X")
152 for(
auto& context : contexts_)
154 if(context.contextUID_ == contextUID)
157 return context.address_;
158 size_t i = context.address_.find(
"://");
159 if(i == std::string::npos)
163 return context.address_.substr(i);
173 if(artdaqSupervisorContext_ >= contexts_.size())
175 return &contexts_[artdaqSupervisorContext_];
182 return configManager->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
189 const std::string& contextUID,
190 const std::string& appUID)
192 return configManager->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
193 .
getNode(contextUID +
"/" + colContext_.colLinkToApplicationTable_ +
"/" +
200 const std::string& contextUID,
201 const std::string& appUID)
203 return configManager->
getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
205 XDAQContextTable::colContext_.colLinkToApplicationTable_ +
"/" + appUID +
206 "/" + XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
221 auto children = configManager->__SELF_NODE__.
getChildren();
224 artdaqSupervisorContext_ = (
unsigned int)-1;
229 std::set<
unsigned int > appIdSet;
231 for(
auto& child : children)
237 contexts_.back().contextUID_ = child.first;
239 contexts_.back().sourceConfig_ =
240 child.second.getTableName() +
"_v" +
241 child.second.getTableVersion().toString() +
" @ " +
242 std::to_string(child.second.getTableCreationTime());
243 child.second.getNode(colContext_.colContextUID_)
244 .getValue(contexts_.back().contextUID_);
245 child.second.getNode(colContext_.colStatus_).getValue(contexts_.back().status_);
246 child.second.getNode(colContext_.colId_).getValue(contexts_.back().id_);
247 child.second.getNode(colContext_.colAddress_).getValue(contexts_.back().address_);
248 child.second.getNode(colContext_.colPort_).getValue(contexts_.back().port_);
252 if(contexts_.back().port_ == 0)
253 contexts_.back().port_ = atoi(__ENV__(
"OTS_MAIN_PORT"));
254 if(contexts_.back().address_ ==
256 contexts_.back().address_ =
"http://" + std::string(__ENV__(
"HOSTNAME"));
257 if(contexts_.back().port_ < 1024 || contexts_.back().port_ > 49151)
259 __SS__ <<
"Illegal xdaq Context port: " << contexts_.back().port_
260 <<
". Port must be between 1024 and 49151." << __E__;
265 auto appLink = child.second.getNode(colContext_.colLinkToApplicationTable_);
266 if(appLink.isDisconnected())
268 __SS__ <<
"Application link is disconnected!" << __E__;
273 auto appChildren = appLink.getChildren();
274 for(
auto appChild : appChildren)
280 contexts_.back().applications_.back().applicationGroupID_ = child.first;
281 contexts_.back().applications_.back().sourceConfig_ =
282 appChild.second.getTableName() +
"_v" +
283 appChild.second.getTableVersion().toString() +
" @ " +
284 std::to_string(appChild.second.getTableCreationTime());
286 appChild.second.getNode(colApplication_.colApplicationUID_)
287 .getValue(contexts_.back().applications_.back().applicationUID_);
288 appChild.second.getNode(colApplication_.colStatus_)
289 .getValue(contexts_.back().applications_.back().status_);
290 appChild.second.getNode(colApplication_.colClass_)
291 .getValue(contexts_.back().applications_.back().class_);
292 appChild.second.getNode(colApplication_.colId_)
293 .getValue(contexts_.back().applications_.back().id_);
296 if(appChild.second.getNode(colApplication_.colId_).isDefaultValue() &&
297 (contexts_.back().applications_.back().class_ ==
298 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
299 contexts_.back().applications_.back().class_ ==
300 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS))
302 contexts_.back().applications_.back().id_ =
303 XDAQContextTable::XDAQApplication::GATEWAY_APP_ID;
307 if((contexts_.back().applications_.back().id_ ==
308 XDAQContextTable::XDAQApplication::GATEWAY_APP_ID &&
309 contexts_.back().applications_.back().class_ !=
310 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS &&
311 contexts_.back().applications_.back().class_ !=
312 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS) ||
313 (contexts_.back().applications_.back().id_ !=
314 XDAQContextTable::XDAQApplication::GATEWAY_APP_ID &&
315 (contexts_.back().applications_.back().class_ ==
316 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
317 contexts_.back().applications_.back().class_ ==
318 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)))
320 __SS__ <<
"XDAQ Application ID of "
321 << XDAQContextTable::XDAQApplication::GATEWAY_APP_ID
322 <<
" is reserved for the Gateway Supervisor's class '"
323 << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS
324 <<
".' There must be one and only one XDAQ supervisor application "
325 "specified with ID '"
326 << XDAQContextTable::XDAQApplication::GATEWAY_APP_ID
327 <<
"' and class '" << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS
328 <<
".' A conflict was found specifically at appName="
329 << contexts_.back().applications_.back().applicationUID_
330 <<
" with id=" << contexts_.back().applications_.back().id_
331 <<
" and class=" << contexts_.back().applications_.back().class_
337 if(contexts_.back().status_ && contexts_.back().applications_.back().status_)
340 if(appIdSet.find(contexts_.back().applications_.back().id_) !=
343 __SS__ <<
"XDAQ Application IDs are not unique; this could be due to "
344 "multiple instances of the same XDAQ application linked to "
346 "seperate XDAQ Contexts (check all enabled XDAQ Contexts "
347 "for replicated application IDs). Specifically, there is a "
349 << contexts_.back().applications_.back().id_ <<
" appName="
350 << contexts_.back().applications_.back().applicationUID_
352 __COUT_ERR__ <<
"\n" << ss.str();
355 appIdSet.insert(contexts_.back().applications_.back().id_);
359 if(appChild.second.getNode(colApplication_.colInstance_).isDefaultValue())
360 contexts_.back().applications_.back().instance_ = 1;
362 appChild.second.getNode(colApplication_.colInstance_)
363 .getValue(contexts_.back().applications_.back().instance_);
365 if(appChild.second.getNode(colApplication_.colNetwork_).isDefaultValue())
366 contexts_.back().applications_.back().network_ =
"local";
368 appChild.second.getNode(colApplication_.colNetwork_)
369 .getValue(contexts_.back().applications_.back().network_);
371 if(appChild.second.getNode(colApplication_.colGroup_).isDefaultValue())
372 contexts_.back().applications_.back().group_ =
"daq";
374 appChild.second.getNode(colApplication_.colGroup_)
375 .getValue(contexts_.back().applications_.back().group_);
378 if(contexts_.back().applications_.back().class_ ==
379 XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)
381 contexts_.back().applications_.back().class_ =
382 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS;
383 __COUT__ <<
"Fixing deprecated Supervisor class from "
384 << XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS <<
" to "
385 << (contexts_.back().applications_.back().class_);
388 if(contexts_.back().applications_.back().class_ ==
389 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS &&
390 contexts_.back().applications_.back().module_.find(
"libSupervisor.so") !=
393 __COUT__ <<
"Fixing deprecated Supervisor class from "
394 << contexts_.back().applications_.back().module_ <<
" to ";
395 contexts_.back().applications_.back().module_ =
396 contexts_.back().applications_.back().module_.substr(
398 contexts_.back().applications_.back().module_.size() -
399 std::string(
"Supervisor.so").size()) +
400 "GatewaySupervisor.so";
401 std::cout << contexts_.back().applications_.back().module_ << __E__;
409 if(contexts_.back().applications_.back().id_ ==
410 XDAQContextTable::XDAQApplication::
412 contexts_.back().applications_.back().module_ =
414 XDAQContextTable::GATEWAY_SUPERVISOR_CLASS);
415 else if(appChild.second.getNode(colApplication_.colModule_)
418 contexts_.back().applications_.back().class_) !=
421 contexts_.back().applications_.back().module_ =
423 contexts_.back().applications_.back().class_);
424 __COUT__ <<
"Inferred module of '"
425 << contexts_.back().applications_.back().applicationUID_
426 <<
"' as '" << contexts_.back().applications_.back().module_
427 <<
"' based on class '"
428 << contexts_.back().applications_.back().class_ <<
"'" << __E__;
431 contexts_.back().applications_.back().module_ =
432 appChild.second.getNode(colApplication_.colModule_)
437 appChild.second.getNode(colApplication_.colConfigurePriority_)
438 .getValue(contexts_.back()
439 .applications_.back()
440 .stateMachineCommandPriority_[
"Configure"]);
441 appChild.second.getNode(colApplication_.colStartPriority_)
442 .getValue(contexts_.back()
443 .applications_.back()
444 .stateMachineCommandPriority_[
"Start"]);
445 appChild.second.getNode(colApplication_.colStopPriority_)
446 .getValue(contexts_.back()
447 .applications_.back()
448 .stateMachineCommandPriority_[
"Stop"]);
452 __COUT__ <<
"Ignoring missing state machine priorities..." << __E__;
455 auto appPropertyLink =
456 appChild.second.getNode(colApplication_.colLinkToPropertyTable_);
457 if(!appPropertyLink.isDisconnected())
461 auto appPropertyChildren = appPropertyLink.getChildren();
466 for(
auto appPropertyChild : appPropertyChildren)
468 contexts_.back().applications_.back().properties_.push_back(
470 contexts_.back().applications_.back().properties_.back().status_ =
471 appPropertyChild.second.getNode(colAppProperty_.colStatus_)
473 contexts_.back().applications_.back().properties_.back().name_ =
474 appPropertyChild.second.getNode(colAppProperty_.colPropertyName_)
475 .getValue<std::string>();
476 contexts_.back().applications_.back().properties_.back().type_ =
477 appPropertyChild.second.getNode(colAppProperty_.colPropertyType_)
478 .getValue<std::string>();
479 contexts_.back().applications_.back().properties_.back().value_ =
480 appPropertyChild.second.getNode(colAppProperty_.colPropertyValue_)
481 .getValue<std::string>();
494 if(!contexts_.back().status_)
497 for(
auto& app : contexts_.back().applications_)
500 "ots::ARTDAQSupervisor" &&
503 __COUT__ <<
"Found " << app.class_ <<
" in context '"
504 << contexts_.back().contextUID_ <<
"'" << __E__;
506 if(artdaqSupervisorContext_ < contexts_.size())
508 __SS__ <<
"Error! Only one artdaq Supervisor is allowed to be "
510 <<
"two encountered in context '"
511 << contexts_[artdaqSupervisorContext_].contextUID_
512 <<
"' and '" << contexts_.back().contextUID_ <<
"'..."
515 artdaqSupervisorContext_ = (
unsigned int)-1;
520 artdaqSupervisorContext_ = contexts_.size() - 1;
542 out <<
"<?xml version='1.0'?>\n"
543 <<
"<xc:Partition \txmlns:xsi\t= \"http://www.w3.org/2001/XMLSchema-instance\"\n"
544 <<
"\t\txmlns:soapenc\t= \"http://schemas.xmlsoap.org/soap/encoding/\"\n"
545 <<
"\t\txmlns:xc\t= "
546 "\"http://xdaq.web.cern.ch/xdaq/xsd/2004/XMLConfiguration-30\">\n\n";
563 "\t<!-- ContextUID='%s' sourceConfig='%s' -->",
564 context.contextUID_.c_str(),
565 context.sourceConfig_.c_str());
572 "\t<xc:Context id=\"%u\" url=\"%s:%u\">",
574 context.address_.c_str(),
576 out << tmp <<
"\n\n";
586 "\t\t<!-- Application GroupID = '%s' UID='%s' sourceConfig='%s' -->",
587 app.applicationGroupID_.c_str(),
588 app.applicationUID_.c_str(),
589 app.sourceConfig_.c_str());
596 if(app.class_ ==
"ots::GatewaySupervisor")
599 "\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" "
600 "network=\"%s\" icon=\"/WebPath/images/otsdaqIcons/logo_square.png\" "
601 "icon16x16=\"/WebPath/images/otsdaqIcons/favicon-16x16.png\" "
606 app.network_.c_str(),
610 "\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" "
611 "network=\"%s\" group=\"%s\">\n",
615 app.network_.c_str(),
620 int foundColon = app.class_.rfind(
':');
625 __SS__ <<
"Illegal XDAQApplication class name value of '" << app.class_
626 <<
"' - please check the entry for app ID = " << app.id_ << __E__;
629 out <<
"\t\t\t<properties xmlns=\"urn:xdaq-application:"
630 << app.class_.substr(foundColon) <<
"\" xsi:type=\"soapenc:Struct\">\n";
635 if(appProperty.type_ ==
"ots::SupervisorProperty")
638 if(!appProperty.status_)
639 out <<
"\t\t\t\t<!--\n";
642 "\t\t\t\t<%s xsi:type=\"%s\">%s</%s>\n",
643 appProperty.name_.c_str(),
644 appProperty.type_.c_str(),
645 appProperty.value_.c_str(),
646 appProperty.name_.c_str());
649 if(!appProperty.status_)
650 out <<
"\t\t\t\t-->\n";
652 out <<
"\t\t\t</properties>\n";
655 out <<
"\t\t</xc:Application>\n";
657 sprintf(tmp,
"\t\t<xc:Module>%s</xc:Module>\n", app.module_.c_str());
660 if(context.status_ && !app.status_)
667 out <<
"\t</xc:Context>\n";
674 out <<
"</xc:Partition>\n\n\n";
680 for(
auto context : contexts_)
685 if(url == context.address_ +
":" + std::to_string(context.port_))
686 return context.contextUID_;
692 std::string XDAQContextTable::getApplicationUID(
const std::string& url,
693 unsigned int id)
const
696 for(
auto context : contexts_)
707 if(url == context.address_ +
":" + std::to_string(context.port_))
708 for(
auto application : context.applications_)
711 if(!application.status_)
714 if(application.id_ ==
id)
716 return application.applicationUID_;
726 const std::string& appUID)
const
730 auto childrenMap = configManager->__SELF_NODE__.
getChildren();
732 for(
auto& context : childrenMap)
734 if(!context.second.getNode(XDAQContextTable::colContext_.colStatus_)
739 XDAQContextTable::colContext_.colLinkToApplicationTable_);
744 for(
auto& app : appMap)
746 if(!app.second.getNode(XDAQContextTable::colApplication_.colStatus_)
750 if(app.first == appUID)
751 return context.first;
755 __SS__ <<
"Application '" << appUID <<
"' search found no parent context!" << __E__;
767 auto childrenMap = configManager->__SELF_NODE__.
getChildren();
769 for(
auto& context : childrenMap)
771 if(!context.second.getNode(XDAQContextTable::colContext_.colStatus_)
776 XDAQContextTable::colContext_.colLinkToApplicationTable_);
781 for(
auto& app : appMap)
783 if(!app.second.getNode(XDAQContextTable::colApplication_.colStatus_)
787 std::string className =
788 app.second.getNode(XDAQContextTable::colApplication_.colClass_)
789 .getValue<std::string>();
790 if(className == XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
791 className == XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)
792 return context.first;
796 __SS__ <<
"Gateway Application search found no parent context!" << __E__;
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
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
std::string getContextOfApplication(ConfigurationManager *configManager, const std::string &appUID) const
only considers ON contexts and applications
XDAQ App Property Column names.
XDAQ Context Column names.
static const uint8_t DEFAULT_PRIORITY