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;
37 XDAQContextTable::XDAQContextTable(
void)
46 XDAQContextTable::~XDAQContextTable(
void) {}
52 extractContexts(configManager);
54 bool isFirstAppInContext = configManager->isOwnerFirstAppInContext();
57 if(!isFirstAppInContext)
64 fs.open(XDAQ_RUN_FILE, std::fstream::out | std::fstream::trunc);
67 __SS__ <<
"Failed to open XDAQ run file: " << XDAQ_RUN_FILE << __E__;
76 std::string XDAQContextTable::getContextAddress(
const std::string& contextUID,
bool wantHttp)
const
80 for(
auto& context : contexts_)
82 if(context.contextUID_ == contextUID)
85 return context.address_;
86 auto address = context.address_;
87 if(address.find(
"http://") == 0)
89 address = address.replace(0, 7,
"");
91 if(address.find(
"https://") == 0)
93 address = address.replace(0, 8,
"");
104 if(artdaqSupervisorContext_ >= contexts_.size())
106 return &contexts_[artdaqSupervisorContext_];
112 return configManager->getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME).getNode(contextUID);
118 return configManager->getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
119 .getNode(contextUID +
"/" + colContext_.colLinkToApplicationTable_ +
"/" + appUID);
125 return configManager->getNode(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME)
126 .getNode(contextUID +
"/" + XDAQContextTable::colContext_.colLinkToApplicationTable_ +
"/" + appUID +
"/" +
127 XDAQContextTable::colApplication_.colLinkToSupervisorTable_);
142 auto children = configManager->__SELF_NODE__.getChildren();
145 artdaqSupervisorContext_ = (
unsigned int)-1;
150 std::set<
unsigned int > appIdSet;
152 for(
auto& child : children)
154 contexts_.push_back(XDAQContext());
158 contexts_.back().contextUID_ = child.first;
160 contexts_.back().sourceConfig_ =
161 child.second.getTableName() +
"_v" + child.second.getTableVersion().toString() +
" @ " + std::to_string(child.second.getTableCreationTime());
162 child.second.getNode(colContext_.colContextUID_).getValue(contexts_.back().contextUID_);
163 child.second.getNode(colContext_.colStatus_).getValue(contexts_.back().status_);
164 child.second.getNode(colContext_.colId_).getValue(contexts_.back().id_);
165 child.second.getNode(colContext_.colAddress_).getValue(contexts_.back().address_);
166 child.second.getNode(colContext_.colPort_).getValue(contexts_.back().port_);
170 if(contexts_.back().port_ < 1024 || contexts_.back().port_ > 49151)
172 __SS__ <<
"Illegal xdaq Context port: " << contexts_.back().port_ <<
". Port must be between 1024 and 49151." << __E__;
177 auto appLink = child.second.getNode(colContext_.colLinkToApplicationTable_);
178 if(appLink.isDisconnected())
180 __SS__ <<
"Application link is disconnected!" << __E__;
185 auto appChildren = appLink.getChildren();
186 for(
auto appChild : appChildren)
190 contexts_.back().applications_.push_back(XDAQApplication());
192 contexts_.back().applications_.back().applicationGroupID_ = child.first;
193 contexts_.back().applications_.back().sourceConfig_ = appChild.second.getTableName() +
"_v" + appChild.second.getTableVersion().toString() +
" @ " +
194 std::to_string(appChild.second.getTableCreationTime());
196 appChild.second.getNode(colApplication_.colApplicationUID_).getValue(contexts_.back().applications_.back().applicationUID_);
197 appChild.second.getNode(colApplication_.colStatus_).getValue(contexts_.back().applications_.back().status_);
198 appChild.second.getNode(colApplication_.colClass_).getValue(contexts_.back().applications_.back().class_);
199 appChild.second.getNode(colApplication_.colId_).getValue(contexts_.back().applications_.back().id_);
202 if((contexts_.back().applications_.back().id_ == 200 &&
203 contexts_.back().applications_.back().class_ != XDAQContextTable::GATEWAY_SUPERVISOR_CLASS &&
204 contexts_.back().applications_.back().class_ != XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS) ||
205 (contexts_.back().applications_.back().id_ != 200 &&
206 (contexts_.back().applications_.back().class_ == XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
207 contexts_.back().applications_.back().class_ == XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)))
209 __SS__ <<
"XDAQ Application ID of 200 is reserved for the Gateway "
211 << XDAQContextTable::GATEWAY_SUPERVISOR_CLASS <<
". Conflict specifically at id=" << contexts_.back().applications_.back().id_
212 <<
" appName=" << contexts_.back().applications_.back().applicationUID_ << __E__;
217 if(contexts_.back().status_ && contexts_.back().applications_.back().status_)
220 if(appIdSet.find(contexts_.back().applications_.back().id_) != appIdSet.end())
222 __SS__ <<
"XDAQ Application IDs are not unique. Specifically at id=" << contexts_.back().applications_.back().id_
223 <<
" appName=" << contexts_.back().applications_.back().applicationUID_ << __E__;
224 __COUT_ERR__ <<
"\n" << ss.str();
227 appIdSet.insert(contexts_.back().applications_.back().id_);
231 if(appChild.second.getNode(colApplication_.colInstance_).isDefaultValue())
232 contexts_.back().applications_.back().instance_ = 1;
234 appChild.second.getNode(colApplication_.colInstance_).getValue(contexts_.back().applications_.back().instance_);
236 if(appChild.second.getNode(colApplication_.colNetwork_).isDefaultValue())
237 contexts_.back().applications_.back().network_ =
"local";
239 appChild.second.getNode(colApplication_.colNetwork_).getValue(contexts_.back().applications_.back().network_);
241 if(appChild.second.getNode(colApplication_.colGroup_).isDefaultValue())
242 contexts_.back().applications_.back().group_ =
"daq";
244 appChild.second.getNode(colApplication_.colGroup_).getValue(contexts_.back().applications_.back().group_);
246 appChild.second.getNode(colApplication_.colModule_).getValue(contexts_.back().applications_.back().module_);
249 if(contexts_.back().applications_.back().class_ == XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)
251 contexts_.back().applications_.back().class_ = XDAQContextTable::GATEWAY_SUPERVISOR_CLASS;
252 __COUT__ <<
"Fixing deprecated Supervisor class from " << XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS <<
" to "
253 << (contexts_.back().applications_.back().class_);
255 if(contexts_.back().applications_.back().module_.find(
"libSupervisor.so") != std::string::npos)
257 __COUT__ <<
"Fixing deprecated Supervisor class from " << contexts_.back().applications_.back().module_ <<
" to ";
258 contexts_.back().applications_.back().module_ =
259 contexts_.back().applications_.back().module_.substr(
260 0, contexts_.back().applications_.back().module_.size() - std::string(
"Supervisor.so").size()) +
261 "GatewaySupervisor.so";
262 std::cout << contexts_.back().applications_.back().module_ << __E__;
267 appChild.second.getNode(colApplication_.colConfigurePriority_)
268 .getValue(contexts_.back().applications_.back().stateMachineCommandPriority_[
"Configure"]);
269 appChild.second.getNode(colApplication_.colStartPriority_)
270 .getValue(contexts_.back().applications_.back().stateMachineCommandPriority_[
"Start"]);
271 appChild.second.getNode(colApplication_.colStopPriority_).getValue(contexts_.back().applications_.back().stateMachineCommandPriority_[
"Stop"]);
275 __COUT__ <<
"Ignoring missing state machine priorities..." << __E__;
278 auto appPropertyLink = appChild.second.getNode(colApplication_.colLinkToPropertyTable_);
279 if(!appPropertyLink.isDisconnected())
283 auto appPropertyChildren = appPropertyLink.getChildren();
288 for(
auto appPropertyChild : appPropertyChildren)
290 contexts_.back().applications_.back().properties_.push_back(XDAQApplicationProperty());
291 contexts_.back().applications_.back().properties_.back().status_ =
292 appPropertyChild.second.getNode(colAppProperty_.colStatus_).getValue<
bool>();
293 contexts_.back().applications_.back().properties_.back().name_ =
294 appPropertyChild.second.getNode(colAppProperty_.colPropertyName_).getValue<std::string>();
295 contexts_.back().applications_.back().properties_.back().type_ =
296 appPropertyChild.second.getNode(colAppProperty_.colPropertyType_).getValue<std::string>();
297 contexts_.back().applications_.back().properties_.back().value_ =
298 appPropertyChild.second.getNode(colAppProperty_.colPropertyValue_).getValue<std::string>();
311 if(!contexts_.back().status_)
314 for(
auto& app : contexts_.back().applications_)
317 "ots::ARTDAQSupervisor" &&
320 __COUT__ <<
"Found " << app.class_ <<
" in context '" << contexts_.back().contextUID_ <<
"'" << __E__;
322 if(artdaqSupervisorContext_ < contexts_.size())
324 __SS__ <<
"Error! Only one artdaq Supervisor is allowed to be active - "
325 <<
"two encountered in context '" << contexts_[artdaqSupervisorContext_].contextUID_ <<
"' and '" << contexts_.back().contextUID_
328 artdaqSupervisorContext_ = (
unsigned int)-1;
333 artdaqSupervisorContext_ = contexts_.size() - 1;
355 out <<
"<?xml version='1.0'?>\n"
356 <<
"<xc:Partition \txmlns:xsi\t= \"http://www.w3.org/2001/XMLSchema-instance\"\n"
357 <<
"\t\txmlns:soapenc\t= \"http://schemas.xmlsoap.org/soap/encoding/\"\n"
358 <<
"\t\txmlns:xc\t= "
359 "\"http://xdaq.web.cern.ch/xdaq/xsd/2004/XMLConfiguration-30\">\n\n";
375 sprintf(tmp,
"\t<!-- ContextUID='%s' sourceConfig='%s' -->", context.contextUID_.c_str(), context.sourceConfig_.c_str());
381 sprintf(tmp,
"\t<xc:Context id=\"%u\" url=\"%s:%u\">", context.id_, context.address_.c_str(), context.port_);
382 out << tmp <<
"\n\n";
391 "\t\t<!-- Application GroupID = '%s' UID='%s' sourceConfig='%s' -->",
392 app.applicationGroupID_.c_str(),
393 app.applicationUID_.c_str(),
394 app.sourceConfig_.c_str());
402 "\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" "
403 "network=\"%s\" group=\"%s\">\n",
407 app.network_.c_str(),
412 int foundColon = app.class_.rfind(
':');
417 __SS__ <<
"Illegal XDAQApplication class name value of '" << app.class_ <<
"' - please check the entry for app ID = " << app.id_ << __E__;
420 out <<
"\t\t\t<properties xmlns=\"urn:xdaq-application:" << app.class_.substr(foundColon) <<
"\" xsi:type=\"soapenc:Struct\">\n";
425 if(appProperty.type_ ==
"ots::SupervisorProperty")
428 if(!appProperty.status_)
429 out <<
"\t\t\t\t<!--\n";
432 "\t\t\t\t<%s xsi:type=\"%s\">%s</%s>\n",
433 appProperty.name_.c_str(),
434 appProperty.type_.c_str(),
435 appProperty.value_.c_str(),
436 appProperty.name_.c_str());
439 if(!appProperty.status_)
440 out <<
"\t\t\t\t-->\n";
442 out <<
"\t\t\t</properties>\n";
445 out <<
"\t\t</xc:Application>\n";
447 sprintf(tmp,
"\t\t<xc:Module>%s</xc:Module>\n", app.module_.c_str());
450 if(context.status_ && !app.status_)
457 out <<
"\t</xc:Context>\n";
464 out <<
"</xc:Partition>\n\n\n";
468 std::string XDAQContextTable::getContextUID(
const std::string& url)
const
470 for(
auto context : contexts_)
475 if(url == context.address_ +
":" + std::to_string(context.port_))
476 return context.contextUID_;
482 std::string XDAQContextTable::getApplicationUID(
const std::string& url,
unsigned int id)
const
485 for(
auto context : contexts_)
496 if(url == context.address_ +
":" + std::to_string(context.port_))
497 for(
auto application : context.applications_)
500 if(!application.status_)
503 if(application.id_ ==
id)
505 return application.applicationUID_;
514 std::string XDAQContextTable::getContextOfApplication(
ConfigurationManager* configManager,
const std::string& appUID)
const
518 auto childrenMap = configManager->__SELF_NODE__.getChildren();
520 for(
auto& context : childrenMap)
522 if(!context.second.getNode(XDAQContextTable::colContext_.colStatus_).getValue<
bool>())
525 ConfigurationTree appLink = context.second.getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_);
526 if(appLink.isDisconnected())
continue;
528 auto appMap = appLink.getChildren();
529 for(
auto& app : appMap)
531 if(!app.second.getNode(XDAQContextTable::colApplication_.colStatus_).getValue<
bool>())
534 if(app.first == appUID)
535 return context.first;
539 __SS__ <<
"Application '" << appUID <<
"' search found no parent context!" << __E__;
549 auto childrenMap = configManager->__SELF_NODE__.getChildren();
551 for(
auto& context : childrenMap)
553 if(!context.second.getNode(XDAQContextTable::colContext_.colStatus_).getValue<
bool>())
556 ConfigurationTree appLink = context.second.getNode(XDAQContextTable::colContext_.colLinkToApplicationTable_);
557 if(appLink.isDisconnected())
continue;
559 auto appMap = appLink.getChildren();
560 for(
auto& app : appMap)
562 if(!app.second.getNode(XDAQContextTable::colApplication_.colStatus_).getValue<
bool>())
565 std::string className = app.second.getNode(XDAQContextTable::colApplication_.colClass_).getValue<std::string>();
566 if(className ==XDAQContextTable::GATEWAY_SUPERVISOR_CLASS ||
567 className == XDAQContextTable::DEPRECATED_SUPERVISOR_CLASS)
568 return context.first;
572 __SS__ <<
"Gateway Application search found no parent context!" << __E__;
void outputXDAQXML(std::ostream &out)