00001 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
00002 #include "otsdaq-core/Macros/ConfigurationPluginMacros.h"
00003 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00004
00005 #include <iostream>
00006 #include <fstream>
00007 #include <stdio.h>
00008
00009 using namespace ots;
00010
00011
00012 #define XDAQ_RUN_FILE std::string(getenv("XDAQ_CONFIGURATION_DATA_PATH")) + "/" + std::string(getenv("XDAQ_CONFIGURATION_XML")) + ".xml"
00013 #define APP_PRIORITY_FILE std::string(getenv("XDAQ_CONFIGURATION_DATA_PATH")) + "/" + "xdaqAppStateMachinePriority"
00014
00015
00016
00017
00018 const std::string XDAQContextConfiguration::DEPRECATED_SUPERVISOR_CLASS = "ots::Supervisor";
00019 const std::string XDAQContextConfiguration::GATEWAY_SUPERVISOR_CLASS = "ots::GatewaySupervisor";
00020 const std::string XDAQContextConfiguration::WIZARD_SUPERVISOR_CLASS = "ots::WizardSupervisor";
00021 const std::set<std::string> XDAQContextConfiguration::FETypeClassNames_ = {"ots::FESupervisor", "ots::FEDataManagerSupervisor", "ots::ARTDAQFEDataManagerSupervisor"};
00022 const std::set<std::string> XDAQContextConfiguration::DMTypeClassNames_ = {"ots::DataManagerSupervisor", "ots::FEDataManagerSupervisor", "ots::ARTDAQFEDataManagerSupervisor"};
00023 const std::set<std::string> XDAQContextConfiguration::LogbookTypeClassNames_ = {"ots::LogbookSupervisor"};
00024 const std::set<std::string> XDAQContextConfiguration::MacroMakerTypeClassNames_ = {"ots::MacroMakerSupervisor"};
00025 const std::set<std::string> XDAQContextConfiguration::ChatTypeClassNames_ = {"ots::ChatSupervisor"};
00026 const std::set<std::string> XDAQContextConfiguration::ConsoleTypeClassNames_ = {"ots::ConsoleSupervisor"};
00027 const std::set<std::string> XDAQContextConfiguration::ConfigurationGUITypeClassNames_ = {"ots::ConfigurationGUISupervisor"};
00028
00029 const std::string XDAQContextConfiguration::ARTDAQ_OFFSET_PORT = "OffsetPort";
00030
00031
00032 XDAQContextConfiguration::XDAQContextConfiguration(void)
00033 : ConfigurationBase("XDAQContextConfiguration")
00034 {
00036
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 }
00058
00059
00060 XDAQContextConfiguration::~XDAQContextConfiguration(void)
00061 {}
00062
00063
00064 void XDAQContextConfiguration::init(ConfigurationManager* configManager)
00065 {
00066 extractContexts(configManager);
00067
00068 {
00070
00071 std::fstream fs;
00072 fs.open(XDAQ_RUN_FILE, std::fstream::out | std::fstream::trunc);
00073 if (fs.fail())
00074 {
00075 __SS__ << "Failed to open XDAQ run file: " << XDAQ_RUN_FILE << std::endl;
00076 throw std::runtime_error(ss.str());
00077 }
00078 outputXDAQXML((std::ostream &)fs);
00079 fs.close();
00080 }
00081 }
00082
00083
00084
00085 bool XDAQContextConfiguration::isARTDAQContext(const std::string &contextUID)
00086 {
00087 return (contextUID.find("ART") == 0 ||
00088 contextUID.find("ARTDAQ") == 0);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098 unsigned int XDAQContextConfiguration::getARTDAQAppRank(const std::string &contextUID) const
00099 {
00100
00101
00102
00103 if (artdaqBoardReaders_.size() == 0 &&
00104 artdaqEventBuilders_.size() == 0 &&
00105 artdaqAggregators_.size() == 0)
00106 {
00107 __COUT_WARN__ << "Assuming since there are 0 active ARTDAQ context UID(s), we can ignore rank failure." << std::endl;
00108 return -1;
00109 }
00110
00111
00112 auto localGetRank = [](const XDAQContext& context) -> unsigned int {
00113 if(context.applications_.size() != 1)
00114 {
00115 __SS__ << "Invalid number of ARTDAQ applications in context '" <<
00116 context.contextUID_ <<
00117 ".' Must be 1. Currently is " << context.applications_.size() << "." << __E__;
00118 __SS_THROW__;
00119 }
00120
00121 return context.applications_[0].id_;
00122 };
00123
00124
00125 for (auto &i : artdaqBoardReaders_)
00126 if (contexts_[i].contextUID_ == contextUID)
00127 return localGetRank(contexts_[i]);
00128
00129 for (auto &i : artdaqEventBuilders_)
00130 if (contexts_[i].contextUID_ == contextUID)
00131 return localGetRank(contexts_[i]);
00132
00133 for (auto &i : artdaqAggregators_)
00134 if (contexts_[i].contextUID_ == contextUID)
00135 return localGetRank(contexts_[i]);
00136
00137
00138
00139
00140
00141
00142 __SS__ << "ARTDAQ rank could not be found for context UID '" <<
00143 contextUID << ".'" << std::endl;
00144 __SS_THROW__;
00145 }
00146
00147
00148 std::string XDAQContextConfiguration::getContextAddress(const std::string &contextUID, bool wantHttp) const
00149 {
00150 if (contextUID == "X") return "";
00151 for (auto& context : contexts_)
00152 {
00153 if (context.contextUID_ == contextUID)
00154 {
00155 if (wantHttp) return context.address_;
00156 auto address = context.address_;
00157 if (address.find("http://") == 0) { address = address.replace(0,7, ""); }
00158 if (address.find("https://") == 0) { address = address.replace(0,8, ""); }
00159 return address;
00160 }
00161 }
00162 return "";
00163 }
00164
00165 unsigned int XDAQContextConfiguration::getARTDAQDataPort(const ConfigurationManager *configManager,
00166 const std::string &contextUID) const
00167 {
00168 if (contextUID == "X") return 0;
00169 for (auto& context : contexts_)
00170 {
00171 if (context.contextUID_ == contextUID)
00172 {
00173 if(context.applications_.size() != 1)
00174 {
00175 __SS__ << "Invalid number of ARTDAQ applications in context '" <<
00176 contextUID <<
00177 ".' Must be 1. Currently is " << context.applications_.size() << "." << __E__;
00178 __SS_THROW__;
00179 }
00180
00181 if(context.applications_[0].class_ == "ots::ARTDAQDataManagerSupervisor")
00182 {
00183 auto processors = getSupervisorConfigNode(configManager,
00184 context.contextUID_, context.applications_[0].applicationUID_).getNode(
00185 "LinkToDataManagerConfiguration").getChildren()[0].second.getNode(
00186 "LinkToDataBufferConfiguration").getChildren();
00187
00188 std::string processorType;
00189
00190
00191 for(auto& processor : processors)
00192 {
00193 processorType = processor.second.getNode(
00194 "ProcessorPluginName").getValue<std::string>();
00195 __COUTV__(processorType);
00196
00197 if(processorType == "ARTDAQConsumer" ||
00198 processorType == "ARTDAQProducer")
00199 return processor.second.getNode(
00200 "LinkToProcessorConfiguration").getNode(
00201 XDAQContextConfiguration::ARTDAQ_OFFSET_PORT).getValue<unsigned int>();
00202 }
00203
00204 __SS__ << "No ARTDAQ processor was found while looking for data port." << __E__;
00205 __SS_THROW__;
00206 }
00207
00208 return getSupervisorConfigNode(configManager,
00209 context.contextUID_, context.applications_[0].applicationUID_).getNode(
00210 XDAQContextConfiguration::ARTDAQ_OFFSET_PORT).getValue<unsigned int>();
00211 }
00212 }
00213 return 0;
00214 }
00215
00216
00217
00218 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getBoardReaderContexts() const
00219 {
00220 std::vector<const XDAQContext *> retVec;
00221 for (auto &i : artdaqBoardReaders_)
00222 retVec.push_back(&contexts_[i]);
00223 return retVec;
00224 }
00225
00226 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getEventBuilderContexts() const
00227 {
00228 std::vector<const XDAQContext *> retVec;
00229 for (auto &i : artdaqEventBuilders_)
00230 retVec.push_back(&contexts_[i]);
00231 return retVec;
00232
00233 }
00234
00235 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getAggregatorContexts() const
00236 {
00237 std::vector<const XDAQContext *> retVec;
00238 for (auto &i : artdaqAggregators_)
00239 retVec.push_back(&contexts_[i]);
00240 return retVec;
00241 }
00242
00243
00244 ConfigurationTree XDAQContextConfiguration::getContextNode(const ConfigurationManager *configManager,
00245 const std::string &contextUID) const
00246 {
00247 return configManager->__SELF_NODE__.getNode(
00248 contextUID);
00249 }
00250
00251
00252 ConfigurationTree XDAQContextConfiguration::getApplicationNode(const ConfigurationManager *configManager,
00253 const std::string &contextUID, const std::string &appUID) const
00254 {
00255 return configManager->__SELF_NODE__.getNode(
00256 contextUID + "/" +
00257 colContext_.colLinkToApplicationConfiguration_ + "/" +
00258 appUID);
00259 }
00260
00261
00262 ConfigurationTree XDAQContextConfiguration::getSupervisorConfigNode(const ConfigurationManager *configManager,
00263 const std::string &contextUID, const std::string &appUID) const
00264 {
00265 return configManager->__SELF_NODE__.getNode(
00266 contextUID + "/" +
00267 colContext_.colLinkToApplicationConfiguration_ + "/" +
00268 appUID + "/" +
00269 colApplication_.colLinkToSupervisorConfiguration_);
00270 }
00271
00272
00273
00274
00275
00276
00277 void XDAQContextConfiguration::extractContexts(ConfigurationManager* configManager)
00278 {
00279
00280
00281
00282
00283
00284
00285 auto children = configManager->__SELF_NODE__.getChildren();
00286
00287 contexts_.clear();
00288
00289
00290 artdaqBoardReaders_.clear();
00291 artdaqEventBuilders_.clear();
00292 artdaqAggregators_.clear();
00293
00294
00295
00296 std::set<unsigned int > appIdSet;
00297
00298 for (auto &child : children)
00299 {
00300 contexts_.push_back(XDAQContext());
00301
00302
00303
00304 contexts_.back().contextUID_ = child.first;
00305
00306 contexts_.back().sourceConfig_ = child.second.getConfigurationName() + "_v" +
00307 child.second.getConfigurationVersion().toString() + " @ " +
00308 std::to_string(child.second.getConfigurationCreationTime());
00309 child.second.getNode(colContext_.colContextUID_).getValue(contexts_.back().contextUID_);
00310 child.second.getNode(colContext_.colStatus_).getValue(contexts_.back().status_);
00311 child.second.getNode(colContext_.colId_).getValue(contexts_.back().id_);
00312 child.second.getNode(colContext_.colAddress_).getValue(contexts_.back().address_);
00313 child.second.getNode(colContext_.colPort_).getValue(contexts_.back().port_);
00314
00315
00316
00317 auto appLink = child.second.getNode(colContext_.colLinkToApplicationConfiguration_);
00318 if (appLink.isDisconnected())
00319 {
00320 __SS__ << "Application link is disconnected!" << std::endl;
00321 throw std::runtime_error(ss.str());
00322 }
00323
00324
00325 auto appChildren = appLink.getChildren();
00326 for (auto appChild : appChildren)
00327 {
00328
00329
00330 contexts_.back().applications_.push_back(XDAQApplication());
00331
00332 contexts_.back().applications_.back().applicationGroupID_ = child.first;
00333 contexts_.back().applications_.back().sourceConfig_ = appChild.second.getConfigurationName() + "_v" +
00334 appChild.second.getConfigurationVersion().toString() + " @ " +
00335 std::to_string(appChild.second.getConfigurationCreationTime());
00336
00337 appChild.second.getNode(colApplication_.colApplicationUID_).getValue(contexts_.back().applications_.back().applicationUID_);
00338 appChild.second.getNode(colApplication_.colStatus_).getValue(contexts_.back().applications_.back().status_);
00339 appChild.second.getNode(colApplication_.colClass_).getValue(contexts_.back().applications_.back().class_);
00340 appChild.second.getNode(colApplication_.colId_).getValue(contexts_.back().applications_.back().id_);
00341
00342
00343 if((contexts_.back().applications_.back().id_ == 200 &&
00344 contexts_.back().applications_.back().class_ != XDAQContextConfiguration::GATEWAY_SUPERVISOR_CLASS &&
00345 contexts_.back().applications_.back().class_ != XDAQContextConfiguration::DEPRECATED_SUPERVISOR_CLASS) ||
00346 (contexts_.back().applications_.back().id_ != 200 &&
00347 (contexts_.back().applications_.back().class_ == XDAQContextConfiguration::GATEWAY_SUPERVISOR_CLASS ||
00348 contexts_.back().applications_.back().class_ == XDAQContextConfiguration::DEPRECATED_SUPERVISOR_CLASS)))
00349 {
00350 __SS__ << "XDAQ Application ID of 200 is reserved for the Gateway Supervisor " <<
00351 XDAQContextConfiguration::GATEWAY_SUPERVISOR_CLASS << ". Conflict specifically at id=" <<
00352 contexts_.back().applications_.back().id_ << " appName=" <<
00353 contexts_.back().applications_.back().applicationUID_ << std::endl;
00354 __SS_THROW__;
00355 }
00356
00357
00358 if(contexts_.back().status_ && contexts_.back().applications_.back().status_)
00359 {
00360
00361 if(appIdSet.find(contexts_.back().applications_.back().id_) != appIdSet.end())
00362 {
00363 __SS__ << "XDAQ Application IDs are not unique. Specifically at id=" <<
00364 contexts_.back().applications_.back().id_ << " appName=" <<
00365 contexts_.back().applications_.back().applicationUID_ << std::endl;
00366 __COUT_ERR__ << "\n" << ss.str();
00367 throw std::runtime_error(ss.str());
00368 }
00369 appIdSet.insert(contexts_.back().applications_.back().id_);
00370 }
00371
00372
00373 if (appChild.second.getNode(colApplication_.colInstance_).isDefaultValue())
00374 contexts_.back().applications_.back().instance_ = 1;
00375 else
00376 appChild.second.getNode(colApplication_.colInstance_).getValue(contexts_.back().applications_.back().instance_);
00377
00378 if (appChild.second.getNode(colApplication_.colNetwork_).isDefaultValue())
00379 contexts_.back().applications_.back().network_ = "local";
00380 else
00381 appChild.second.getNode(colApplication_.colNetwork_).getValue(contexts_.back().applications_.back().network_);
00382
00383 if (appChild.second.getNode(colApplication_.colGroup_).isDefaultValue())
00384 contexts_.back().applications_.back().group_ = "daq";
00385 else
00386 appChild.second.getNode(colApplication_.colGroup_).getValue(contexts_.back().applications_.back().group_);
00387
00388 appChild.second.getNode(colApplication_.colModule_).getValue(contexts_.back().applications_.back().module_);
00389
00390 try
00391 {
00392 appChild.second.getNode(colApplication_.colConfigurePriority_).getValue(contexts_.back().applications_.back().stateMachineCommandPriority_["Configure"]);
00393 appChild.second.getNode(colApplication_.colStartPriority_).getValue(contexts_.back().applications_.back().stateMachineCommandPriority_["Start"]);
00394 appChild.second.getNode(colApplication_.colStopPriority_).getValue(contexts_.back().applications_.back().stateMachineCommandPriority_["Stop"]);
00395 }
00396 catch(...)
00397 {
00398 __COUT__ << "Ignoring missing state machine priorities..." << __E__;
00399 }
00400
00401
00402 auto appPropertyLink = appChild.second.getNode(colApplication_.colLinkToPropertyConfiguration_);
00403 if (!appPropertyLink.isDisconnected())
00404 {
00405
00406
00407 auto appPropertyChildren = appPropertyLink.getChildren();
00408
00409
00410
00411 for (auto appPropertyChild : appPropertyChildren)
00412 {
00413 contexts_.back().applications_.back().properties_.push_back(XDAQApplicationProperty());
00414 contexts_.back().applications_.back().properties_.back().status_ =
00415 appPropertyChild.second.getNode(colAppProperty_.colStatus_).getValue<bool>();
00416 contexts_.back().applications_.back().properties_.back().name_ =
00417 appPropertyChild.second.getNode(colAppProperty_.colPropertyName_).getValue<std::string>();
00418 contexts_.back().applications_.back().properties_.back().type_ =
00419 appPropertyChild.second.getNode(colAppProperty_.colPropertyType_).getValue<std::string>();
00420 contexts_.back().applications_.back().properties_.back().value_ =
00421 appPropertyChild.second.getNode(colAppProperty_.colPropertyValue_).getValue<std::string>();
00422
00423
00424 }
00425 }
00426
00427
00428 }
00429
00430
00431 if (isARTDAQContext(contexts_.back().contextUID_))
00432 {
00433
00434
00435 if (contexts_.back().applications_.size() != 1)
00436 {
00437 __SS__ << "ARTDAQ Context '" << contexts_.back().contextUID_ <<
00438 "' must have one Application! " <<
00439 contexts_.back().applications_.size() << " were found. " << std::endl;
00440 throw std::runtime_error(ss.str());
00441 }
00442
00443 if (!contexts_.back().status_) continue;
00444
00445 if (contexts_.back().applications_[0].class_ ==
00446 "ots::ARTDAQDataManagerSupervisor")
00447 artdaqBoardReaders_.push_back(contexts_.size() - 1);
00448 else if (contexts_.back().applications_[0].class_ ==
00449 "ots::EventBuilderApp")
00450 artdaqEventBuilders_.push_back(contexts_.size() - 1);
00451 else if (contexts_.back().applications_[0].class_ ==
00452 "ots::DataLoggerApp" ||
00453 contexts_.back().applications_[0].class_ ==
00454 "ots::DispatcherApp")
00455 artdaqAggregators_.push_back(contexts_.size() - 1);
00456 else
00457 {
00458 __SS__ << "ARTDAQ Context must be have Application of an allowed class type:\n " <<
00459 "\tots::ARTDAQDataManagerSupervisor\n" <<
00460 "\tots::EventBuilderApp\n" <<
00461 "\tots::DataLoggerApp\n" <<
00462 "\tots::DispatcherApp\n" <<
00463 "\nClass found was " <<
00464 contexts_.back().applications_[0].class_ << std::endl;
00465 throw std::runtime_error(ss.str());
00466 }
00467
00468 }
00469
00470 }
00471 }
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 void XDAQContextConfiguration::outputXDAQXML(std::ostream &out)
00696 {
00697
00698
00701
00702
00703
00704 out << "<?xml version='1.0'?>\n" <<
00705 "<xc:Partition \txmlns:xsi\t= \"http://www.w3.org/2001/XMLSchema-instance\"\n" <<
00706 "\t\txmlns:soapenc\t= \"http://schemas.xmlsoap.org/soap/encoding/\"\n" <<
00707 "\t\txmlns:xc\t= \"http://xdaq.web.cern.ch/xdaq/xsd/2004/XMLConfiguration-30\">\n\n";
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718 char tmp[200];
00719 for (XDAQContext &context : contexts_)
00720 {
00721
00722
00723
00724 sprintf(tmp, "\t<!-- ContextUID='%s' sourceConfig='%s' -->",
00725 context.contextUID_.c_str(), context.sourceConfig_.c_str());
00726 out << tmp << "\n";
00727
00728 if (!context.status_)
00729 out << "\t<!--\n";
00730
00731 sprintf(tmp, "\t<xc:Context id=\"%u\" url=\"%s:%u\">", context.id_, context.address_.c_str(), context.port_);
00732 out << tmp << "\n\n";
00733
00734 for (XDAQApplication &app : context.applications_)
00735 {
00736
00737
00738
00739 if (context.status_)
00740 {
00741 sprintf(tmp, "\t\t<!-- Application GroupID = '%s' UID='%s' sourceConfig='%s' -->",
00742 app.applicationGroupID_.c_str(), app.applicationUID_.c_str(), app.sourceConfig_.c_str());
00743 out << tmp << "\n";
00744
00745 if (!app.status_)
00746 out << "\t\t<!--\n";
00747 }
00748
00749 sprintf(tmp, "\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" network=\"%s\" group=\"%s\">\n",
00750 app.class_.c_str(), app.id_, app.instance_, app.network_.c_str(), app.group_.c_str());
00751 out << tmp;
00752
00754 int foundColon = app.class_.rfind(':');
00755 if (foundColon >= 0) ++foundColon;
00756 else
00757 {
00758 __SS__ << "Illegal XDAQApplication class name value of '" << app.class_
00759 << "' - please check the entry for app ID = " << app.id_ << __E__;
00760 throw std::runtime_error(ss.str());
00761 }
00762 out << "\t\t\t<properties xmlns=\"urn:xdaq-application:" <<
00763 app.class_.substr(foundColon) <<
00764 "\" xsi:type=\"soapenc:Struct\">\n";
00765
00766
00767 for (XDAQApplicationProperty &appProperty : app.properties_)
00768 {
00769
00770 if (appProperty.type_ == "ots::SupervisorProperty") continue;
00771
00772 if (!appProperty.status_)
00773 out << "\t\t\t\t<!--\n";
00774
00775 sprintf(tmp, "\t\t\t\t<%s xsi:type=\"%s\">%s</%s>\n",
00776 appProperty.name_.c_str(),
00777 appProperty.type_.c_str(),
00778 appProperty.value_.c_str(),
00779 appProperty.name_.c_str());
00780 out << tmp;
00781
00782 if (!appProperty.status_)
00783 out << "\t\t\t\t-->\n";
00784 }
00785 out << "\t\t\t</properties>\n";
00787
00788 out << "\t\t</xc:Application>\n";
00789
00790
00791 sprintf(tmp, "\t\t<xc:Module>%s</xc:Module>\n", app.module_.c_str());
00792 out << tmp;
00793
00794 if (context.status_ && !app.status_)
00795 out << "\t\t-->\n";
00796 out << "\n";
00797
00798
00799 }
00800
00801 out << "\t</xc:Context>\n";
00802 if (!context.status_)
00803 out << "\t-->\n";
00804 out << "\n";
00805 }
00806
00807
00808 out << "</xc:Partition>\n\n\n";
00809
00810 }
00811
00812
00813 std::string XDAQContextConfiguration::getContextUID(const std::string &url) const
00814 {
00815 for (auto context : contexts_)
00816 {
00817 if (!context.status_) continue;
00818
00819 if (url == context.address_ + ":" + std::to_string(context.port_))
00820 return context.contextUID_;
00821 }
00822 return "";
00823 }
00824
00825
00826 std::string XDAQContextConfiguration::getApplicationUID(const std::string &url, unsigned int id) const
00827 {
00828
00829 for (auto context : contexts_)
00830 {
00831
00832
00833
00834
00835 if (!context.status_) continue;
00836
00837
00838 if (url == context.address_ + ":" + std::to_string(context.port_))
00839 for (auto application : context.applications_)
00840 {
00841
00842 if (!application.status_) continue;
00843
00844 if (application.id_ == id)
00845 {
00846 return application.applicationUID_;
00847 }
00848 }
00849 }
00850 return "";
00851 }
00852
00853 DEFINE_OTS_CONFIGURATION(XDAQContextConfiguration)