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
00014
00015
00016
00017 XDAQContextConfiguration::XDAQContextConfiguration(void)
00018 : ConfigurationBase("XDAQContextConfiguration")
00019 {
00021
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 }
00042
00043
00044 XDAQContextConfiguration::~XDAQContextConfiguration(void)
00045 {}
00046
00047
00048 void XDAQContextConfiguration::init(ConfigurationManager* configManager)
00049 {
00050 extractContexts(configManager);
00051
00053
00054 std::fstream fs;
00055 fs.open(XDAQ_RUN_FILE, std::fstream::out | std::fstream::trunc);
00056 if(fs.fail())
00057 {
00058 __SS__ << "Failed to open XDAQ run file: " << XDAQ_RUN_FILE << std::endl;
00059 throw std::runtime_error(ss.str());
00060 }
00061 outputXDAQXML((std::ostream &)fs);
00062 fs.close();
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 }
00086
00087
00088
00089 bool XDAQContextConfiguration::isARTDAQContext(const std::string &contextUID)
00090 {
00091 return (contextUID.find("ART") == 0 ||
00092 contextUID.find("ARTDAQ") == 0);
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102 unsigned int XDAQContextConfiguration::getARTDAQAppRank(const std::string &contextUID) const
00103 {
00104
00105
00106
00107 unsigned int rank = 0;
00108
00109 for(auto &i : artdaqBoardReaders_)
00110 {
00111 if(contexts_[i].contextUID_ == contextUID)
00112 return rank;
00113 ++rank;
00114 }
00115 for(auto &i : artdaqEventBuilders_)
00116 {
00117 if(contexts_[i].contextUID_ == contextUID)
00118 return rank;
00119 ++rank;
00120 }
00121 for(auto &i : artdaqAggregators_)
00122 {
00123 if(contexts_[i].contextUID_ == contextUID)
00124 return rank;
00125 ++rank;
00126 }
00127
00128 if(contextUID == "X")
00129 return rank;
00130
00131 __SS__ << "ARTDAQ rank could not be found for context UID '" <<
00132 contextUID << "' - there were " << rank
00133 << " active ARTDAQ context UID(s) checked." << std::endl;
00134 __MOUT_ERR__ << "\n" << ss.str();
00135 throw std::runtime_error(ss.str());
00136 return -1;
00137 }
00138
00139
00140 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getBoardReaderContexts() const
00141 {
00142 std::vector<const XDAQContext *> retVec;
00143 for(auto &i : artdaqBoardReaders_)
00144 retVec.push_back(&contexts_[i]);
00145 return retVec;
00146 }
00147
00148 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getEventBuilderContexts() const
00149 {
00150 std::vector<const XDAQContext *> retVec;
00151 for(auto &i : artdaqEventBuilders_)
00152 retVec.push_back(&contexts_[i]);
00153 return retVec;
00154
00155 }
00156
00157 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getAggregatorContexts() const
00158 {
00159 std::vector<const XDAQContext *> retVec;
00160 for(auto &i : artdaqAggregators_)
00161 retVec.push_back(&contexts_[i]);
00162 return retVec;
00163 }
00164
00165
00166 ConfigurationTree XDAQContextConfiguration::getSupervisorConfigNode(ConfigurationManager *configManager,
00167 const std::string &contextUID, const std::string &appUID) const
00168 {
00169 return configManager->__SELF_NODE__.getNode(
00170 contextUID + "/" +
00171 colContext_.colLinkToApplicationConfiguration_ + "/" +
00172 appUID + "/" +
00173 colApplication_.colLinkToSupervisorConfiguration_);
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 }
00196
00197
00198
00199
00200
00201 void XDAQContextConfiguration::extractContexts(ConfigurationManager* configManager)
00202 {
00203 __MOUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl;
00204 __MOUT__ << configManager->__SELF_NODE__ << std::endl;
00205
00206
00207
00208
00209 auto children = configManager->__SELF_NODE__.getChildren();
00210
00211 contexts_.clear();
00212 artdaqContexts_.clear();
00213
00214 artdaqBoardReaders_.clear();
00215 artdaqEventBuilders_.clear();
00216 artdaqAggregators_.clear();
00217
00218 for(auto &child:children)
00219 {
00220 contexts_.push_back(XDAQContext());
00221
00222
00223
00224 contexts_.back().contextUID_ = child.first;
00225
00226 contexts_.back().sourceConfig_ = child.second.getConfigurationName() + "_v" +
00227 child.second.getConfigurationVersion().toString() + " @ " +
00228 std::to_string(child.second.getConfigurationCreationTime());
00229 child.second.getNode(colContext_.colContextUID_ ).getValue(contexts_.back().contextUID_);
00230 child.second.getNode(colContext_.colStatus_ ).getValue(contexts_.back().status_);
00231 child.second.getNode(colContext_.colId_ ).getValue(contexts_.back().id_);
00232 child.second.getNode(colContext_.colAddress_ ).getValue(contexts_.back().address_);
00233 child.second.getNode(colContext_.colPort_ ).getValue(contexts_.back().port_);
00234
00235
00236 auto appLink = child.second.getNode(colContext_.colLinkToApplicationConfiguration_);
00237 if(appLink.isDisconnected())
00238 {
00239 __SS__ << "Application link is disconnected!" << std::endl;
00240 throw std::runtime_error(ss.str());
00241 }
00242
00243
00244 auto appChildren = appLink.getChildren();
00245 for(auto appChild:appChildren)
00246 {
00247
00248
00249 contexts_.back().applications_.push_back(XDAQApplication());
00250
00251 contexts_.back().applications_.back().applicationGroupID_ = child.first;
00252 contexts_.back().applications_.back().sourceConfig_ = appChild.second.getConfigurationName() + "_v" +
00253 appChild.second.getConfigurationVersion().toString() + " @ " +
00254 std::to_string(appChild.second.getConfigurationCreationTime());
00255
00256 appChild.second.getNode(colApplication_.colApplicationUID_ ).getValue(contexts_.back().applications_.back().applicationUID_);
00257 appChild.second.getNode(colApplication_.colStatus_ ).getValue(contexts_.back().applications_.back().status_);
00258 appChild.second.getNode(colApplication_.colClass_ ).getValue(contexts_.back().applications_.back().class_);
00259 appChild.second.getNode(colApplication_.colId_ ).getValue(contexts_.back().applications_.back().id_);
00260
00261
00262 if(appChild.second.getNode(colApplication_.colInstance_ ).isDefaultValue())
00263 contexts_.back().applications_.back().instance_ = 1;
00264 else
00265 appChild.second.getNode(colApplication_.colInstance_ ).getValue(contexts_.back().applications_.back().instance_);
00266
00267 if(appChild.second.getNode(colApplication_.colNetwork_ ).isDefaultValue())
00268 contexts_.back().applications_.back().network_ = "local";
00269 else
00270 appChild.second.getNode(colApplication_.colNetwork_ ).getValue(contexts_.back().applications_.back().network_);
00271
00272 if(appChild.second.getNode(colApplication_.colGroup_ ).isDefaultValue())
00273 contexts_.back().applications_.back().group_ = "daq";
00274 else
00275 appChild.second.getNode(colApplication_.colGroup_ ).getValue(contexts_.back().applications_.back().group_);
00276
00277 appChild.second.getNode(colApplication_.colModule_ ).getValue(contexts_.back().applications_.back().module_);
00278 }
00279
00280
00281 if(isARTDAQContext(contexts_.back().contextUID_))
00282 {
00283 artdaqContexts_.push_back(contexts_.size()-1);
00284
00285 if(contexts_.back().applications_.size() != 1)
00286 {
00287 __SS__ << "ARTDAQ Context '" << contexts_.back().contextUID_ <<
00288 "' must have one Application! " <<
00289 contexts_.back().applications_.size() << " were found. " << std::endl;
00290 throw std::runtime_error(ss.str());
00291 }
00292
00293 if(!contexts_.back().status_) continue;
00294
00295 if(contexts_.back().applications_[0].class_ ==
00296 "ots::ARTDAQDataManagerSupervisor")
00297 artdaqBoardReaders_.push_back(contexts_.size()-1);
00298 else if(contexts_.back().applications_[0].class_ ==
00299 "ots::EventBuilderApp")
00300 artdaqEventBuilders_.push_back(contexts_.size()-1);
00301 else if(contexts_.back().applications_[0].class_ ==
00302 "ots::AggregatorApp")
00303 artdaqAggregators_.push_back(contexts_.size()-1);
00304 else
00305 {
00306 __SS__ << "ARTDAQ Context must be have Application of an allowed class type:\n " <<
00307 "\tots::ARTDAQDataManagerSupervisor\n" <<
00308 "\tots::EventBuilderApp\n" <<
00309 "\tots::AggregatorApp\n" << "\nClass found was " <<
00310 contexts_.back().applications_[0].class_ << std::endl;
00311 throw std::runtime_error(ss.str());
00312 }
00313
00314 }
00315
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
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 void XDAQContextConfiguration::outputXDAQXML(std::ostream &out)
00520 {
00521
00522
00525
00526
00527
00528 out << "<?xml version='1.0'?>\n" <<
00529 "<xc:Partition \txmlns:xsi\t= \"http://www.w3.org/2001/XMLSchema-instance\"\n" <<
00530 "\t\txmlns:soapenc\t= \"http://schemas.xmlsoap.org/soap/encoding/\"\n" <<
00531 "\t\txmlns:xc\t= \"http://xdaq.web.cern.ch/xdaq/xsd/2004/XMLConfiguration-30\">\n\n";
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 char tmp[200];
00543 for(XDAQContext &context:contexts_)
00544 {
00545
00546
00547
00548 sprintf(tmp,"\t<!-- ContextUID='%s' sourceConfig='%s' -->",
00549 context.contextUID_.c_str(), context.sourceConfig_.c_str());
00550 out << tmp << "\n";
00551
00552 if(!context.status_)
00553 out << "\t<!--\n";
00554
00555 sprintf(tmp,"\t<xc:Context id=\"%u\" url=\"%s:%u\">", context.id_, context.address_.c_str(), context.port_);
00556 out << tmp << "\n\n";
00557
00558 for(XDAQApplication &app:context.applications_)
00559 {
00560
00561
00562
00563 if(context.status_)
00564 {
00565 sprintf(tmp,"\t\t<!-- Application GroupID = '%s' UID='%s' sourceConfig='%s' -->",
00566 app.applicationGroupID_.c_str(), app.applicationUID_.c_str(), app.sourceConfig_.c_str());
00567 out << tmp << "\n";
00568
00569 if(!app.status_)
00570 out << "\t\t<!--\n";
00571 }
00572
00573 sprintf(tmp,"\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" network=\"%s\" group=\"%s\"/>\n",
00574 app.class_.c_str(), app.id_, app.instance_, app.network_.c_str(), app.group_.c_str());
00575 out << tmp;
00576
00577 sprintf(tmp,"\t\t<xc:Module>%s</xc:Module>\n", app.module_.c_str());
00578 out << tmp;
00579
00580 if(context.status_ && !app.status_)
00581 out << "\t\t-->\n";
00582 out << "\n";
00583 }
00584
00585 out << "\t</xc:Context>\n";
00586 if(!context.status_)
00587 out << "\t-->\n";
00588 out << "\n";
00589 }
00590
00591 out << "</xc:Partition>\n\n\n";
00592
00593 }
00594
00595
00596 std::string XDAQContextConfiguration::getContextUID(const std::string &url) const
00597 {
00598 for(auto context: contexts_)
00599 {
00600 if(!context.status_) continue;
00601
00602 if(url == context.address_ + ":" + std::to_string(context.port_))
00603 return context.contextUID_;
00604 }
00605 return "";
00606 }
00607
00608
00609 std::string XDAQContextConfiguration::getApplicationUID(const std::string &url, unsigned int id) const
00610 {
00611 for(auto context: contexts_)
00612 {
00613 if(!context.status_) continue;
00614
00615 if(url == context.address_ + ":" + std::to_string(context.port_))
00616 for(auto application: context.applications_)
00617 {
00618 if(!application.status_) continue;
00619
00620 if(application.id_ == id)
00621 {
00622 return application.applicationUID_;
00623 }
00624 }
00625 }
00626 return "";
00627 }
00628
00629 DEFINE_OTS_CONFIGURATION(XDAQContextConfiguration)