otsdaq  v1_01_02
 All Classes Namespaces Functions
XDAQContextConfiguration_configuration.cc
1 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
2 #include "otsdaq-core/Macros/ConfigurationPluginMacros.h"
3 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
4 
5 #include <iostream>
6 #include <fstream> // std::fstream
7 #include <stdio.h>
8 
9 using namespace ots;
10 
11 
12 #define XDAQ_RUN_FILE std::string(getenv("XDAQ_CONFIGURATION_DATA_PATH")) + "/"+ std::string(getenv("XDAQ_CONFIGURATION_XML")) + ".xml"
13 //#define XDAQ_SCRIPT std::string(getenv("XDAQ_CONFIGURATION_DATA_PATH")) + "/"+ "StartXDAQ_gen.sh"
14 //#define ARTDAQ_MPI_SCRIPT std::string(getenv("XDAQ_CONFIGURATION_DATA_PATH")) + "/"+ "StartMPI_gen.sh"
15 
16 //========================================================================================================================
17 XDAQContextConfiguration::XDAQContextConfiguration(void)
18 : ConfigurationBase("XDAQContextConfiguration")
19 {
21  //WARNING: the names used in C++ MUST match the Configuration INFO //
23 
24  // <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
25  // <ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ConfigurationInfo.xsd">
26  // <CONFIGURATION Name="XDAQContextConfiguration">
27  // <VIEW Name="XDAQ_CONTEXT_CONFIGURATION" Type="File,Database,DatabaseTest">
28  // <COLUMN Type="UID" Name="ContextUID" StorageName="CONTEXT_UID" DataType="VARCHAR2"/>
29  // <COLUMN Type="ChildLink-0" Name="LinkToApplicationConfiguration" StorageName="LINK_TO_APPLICATION_CONFIGURATION" DataType="VARCHAR2"/>
30  // <COLUMN Type="ChildLinkGroupID-0" Name="ApplicationGroupID" StorageName="APPLICATION_GROUP_ID" DataType="VARCHAR2"/>
31  // <COLUMN Type="OnOff" Name="Status" StorageName="STATUS" DataType="VARCHAR2"/>
32  // <COLUMN Type="Data" Name="Id" StorageName="ID" DataType="VARCHAR2"/>
33  // <COLUMN Type="Data" Name="Address" StorageName="ADDRESS" DataType="VARCHAR2"/>
34  // <COLUMN Type="Data" Name="Port" StorageName="PORT" DataType="VARCHAR2"/>
35  // <COLUMN Type="Comment" Name="CommentDescription" StorageName="COMMENT_DESCRIPTION" DataType="VARCHAR2"/>
36  // <COLUMN Type="Author" Name="Author" StorageName="AUTHOR" DataType="VARCHAR2"/>
37  // <COLUMN Type="Timestamp" Name="RecordInsertionTime" StorageName="RECORD_INSERTION_TIME" DataType="TIMESTAMP WITH TIMEZONE"/>
38  // </VIEW>
39  // </CONFIGURATION>
40  // </ROOT>
41 }
42 
43 //========================================================================================================================
44 XDAQContextConfiguration::~XDAQContextConfiguration(void)
45 {}
46 
47 //========================================================================================================================
48 void XDAQContextConfiguration::init(ConfigurationManager* configManager)
49 {
50  extractContexts(configManager);
51 
53  //generate xdaq run parameter file
54  std::fstream fs;
55  fs.open(XDAQ_RUN_FILE, std::fstream::out | std::fstream::trunc);
56  if(fs.fail())
57  {
58  __SS__ << "Failed to open XDAQ run file: " << XDAQ_RUN_FILE << std::endl;
59  throw std::runtime_error(ss.str());
60  }
61  outputXDAQXML((std::ostream &)fs);
62  fs.close();
63 
64 // /////////////////////////
65 // //generate mpi script file
66 // fs.open(ARTDAQ_MPI_SCRIPT, std::fstream::out | std::fstream::trunc);
67 // if(fs.fail())
68 // {
69 // __SS__ << "Failed to open ARTDAQ script file: " << ARTDAQ_MPI_SCRIPT << std::endl;
70 // throw std::runtime_error(ss.str());
71 // }
72 // outputARTDAQScript((std::ostream &)fs);
73 // fs.close();
74 //
75 // /////////////////////////
76 // //generate xdaq script file
77 // fs.open(XDAQ_SCRIPT, std::fstream::out | std::fstream::trunc);
78 // if(fs.fail())
79 // {
80 // __SS__ << "Failed to open XDAQ script file: " << XDAQ_SCRIPT << std::endl;
81 // throw std::runtime_error(ss.str());
82 // }
83 // outputXDAQScript((std::ostream &)fs);
84 // fs.close();
85 }
86 
87 //========================================================================================================================
88 //isARTDAQContext
89 bool XDAQContextConfiguration::isARTDAQContext(const std::string &contextUID)
90 {
91  return (contextUID.find("ART") == 0 ||
92  contextUID.find("ARTDAQ") == 0);
93 }
94 
95 //========================================================================================================================
96 //isARTDAQContext
97 // looks through all active artdaq contexts for UID
98 // throws exception if not found
99 //
100 // if contextUID == "X" (which happens automatically for broken link)
101 // then highest possible rank plus 1 is returned
102 unsigned int XDAQContextConfiguration::getARTDAQAppRank(const std::string &contextUID) const
103 {
104  // __MOUT__ << "artdaqContexts_.size() = " <<
105  // artdaqContexts_.size() << std::endl;
106 
107  unsigned int rank = 0;
108 
109  for(auto &i : artdaqBoardReaders_)
110  {
111  if(contexts_[i].contextUID_ == contextUID)
112  return rank;
113  ++rank;
114  }
115  for(auto &i : artdaqEventBuilders_)
116  {
117  if(contexts_[i].contextUID_ == contextUID)
118  return rank;
119  ++rank;
120  }
121  for(auto &i : artdaqAggregators_)
122  {
123  if(contexts_[i].contextUID_ == contextUID)
124  return rank;
125  ++rank;
126  }
127 
128  if(contextUID == "X")
129  return rank; //assume first undefined rank is desired
130 
131  __SS__ << "ARTDAQ rank could not be found for context UID '" <<
132  contextUID << "' - there were " << rank
133  << " active ARTDAQ context UID(s) checked." << std::endl;
134  __MOUT_ERR__ << "\n" << ss.str();
135  throw std::runtime_error(ss.str());
136  return -1; //should never happen!
137 }
138 
139 //========================================================================================================================
140 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getBoardReaderContexts() const
141 {
142  std::vector<const XDAQContext *> retVec;
143  for(auto &i : artdaqBoardReaders_)
144  retVec.push_back(&contexts_[i]);
145  return retVec;
146 }
147 //========================================================================================================================
148 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getEventBuilderContexts() const
149 {
150  std::vector<const XDAQContext *> retVec;
151  for(auto &i : artdaqEventBuilders_)
152  retVec.push_back(&contexts_[i]);
153  return retVec;
154 
155 }
156 //========================================================================================================================
157 std::vector<const XDAQContextConfiguration::XDAQContext *> XDAQContextConfiguration::getAggregatorContexts() const
158 {
159  std::vector<const XDAQContext *> retVec;
160  for(auto &i : artdaqAggregators_)
161  retVec.push_back(&contexts_[i]);
162  return retVec;
163 }
164 
165 //========================================================================================================================
166 ConfigurationTree XDAQContextConfiguration::getSupervisorConfigNode(ConfigurationManager *configManager,
167  const std::string &contextUID, const std::string &appUID) const
168 {
169  return configManager->__SELF_NODE__.getNode(
170  contextUID + "/" +
171  colContext_.colLinkToApplicationConfiguration_ + "/" +
172  appUID + "/" +
173  colApplication_.colLinkToSupervisorConfiguration_);
174 
175 
176  // auto supervisorConfigLink =
177  // appChild.second.getNode(colApplication_.colLinkToSupervisorConfiguration_);
178  //
179  // contexts_.back().applications_.back().supervisorConfigUID_ =
180  // supervisorConfigLink.getValue();
181  // __MOUT__ << "application supervisorConfigUID_ : " <<
182  // supervisorConfigLink.getValueAsString() << std::endl;
183  // if(!supervisorConfigLink.isDisconnected())
184  // {
185  // //add xdaq applications to this context
186  // auto supervisorConfigChildren = supervisorConfigLink.getChildren();
187  // for(auto supervisorConfigChild:supervisorConfigChildren)
188  // {
189  // __MOUT__ << "Loop: " << appChild.first << "/" <<
190  // supervisorConfigChild.first << std::endl;
191  // }
192  // }
193  // __MOUT__ << "application supervisorConfigUID_ : " <<
194  // contexts_.back().applic
195 }
196 
197 //========================================================================================================================
198 //extractContexts
199 // Could be called by other tables if they need to access the context.
200 // This doesn't re-write config files, it just re-makes constructs in software.
201 void XDAQContextConfiguration::extractContexts(ConfigurationManager* configManager)
202 {
203  __MOUT__ << "*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*&*" << std::endl;
204  __MOUT__ << configManager->__SELF_NODE__ << std::endl;
205 
206  // __MOUT__ << configManager->getNode(this->getConfigurationName()).getValueAsString()
207  // << std::endl;
208 
209  auto children = configManager->__SELF_NODE__.getChildren();
210 
211  contexts_.clear(); //reset
212  artdaqContexts_.clear();
213 
214  artdaqBoardReaders_.clear();
215  artdaqEventBuilders_.clear();
216  artdaqAggregators_.clear();
217 
218  for(auto &child:children)
219  {
220  contexts_.push_back(XDAQContext());
221  //__MOUT__ << child.first << std::endl;
222  // __MOUT__ << child.second.getNode(colContextUID_) << std::endl;
223 
224  contexts_.back().contextUID_ = child.first;
225 
226  contexts_.back().sourceConfig_ = child.second.getConfigurationName() + "_v" +
227  child.second.getConfigurationVersion().toString() + " @ " +
228  std::to_string(child.second.getConfigurationCreationTime());
229  child.second.getNode(colContext_.colContextUID_ ).getValue(contexts_.back().contextUID_);
230  child.second.getNode(colContext_.colStatus_ ).getValue(contexts_.back().status_);
231  child.second.getNode(colContext_.colId_ ).getValue(contexts_.back().id_);
232  child.second.getNode(colContext_.colAddress_ ).getValue(contexts_.back().address_);
233  child.second.getNode(colContext_.colPort_ ).getValue(contexts_.back().port_);
234 
235  //__MOUT__ << contexts_.back().address_ << std::endl;
236  auto appLink = child.second.getNode(colContext_.colLinkToApplicationConfiguration_);
237  if(appLink.isDisconnected())
238  {
239  __SS__ << "Application link is disconnected!" << std::endl;
240  throw std::runtime_error(ss.str());
241  }
242 
243  //add xdaq applications to this context
244  auto appChildren = appLink.getChildren();
245  for(auto appChild:appChildren)
246  {
247  //__MOUT__ << "Loop: " << child.first << "/" << appChild.first << std::endl;
248 
249  contexts_.back().applications_.push_back(XDAQApplication());
250 
251  contexts_.back().applications_.back().applicationGroupID_ = child.first;
252  contexts_.back().applications_.back().sourceConfig_ = appChild.second.getConfigurationName() + "_v" +
253  appChild.second.getConfigurationVersion().toString() + " @ " +
254  std::to_string(appChild.second.getConfigurationCreationTime());
255 
256  appChild.second.getNode(colApplication_.colApplicationUID_ ).getValue(contexts_.back().applications_.back().applicationUID_);
257  appChild.second.getNode(colApplication_.colStatus_ ).getValue(contexts_.back().applications_.back().status_);
258  appChild.second.getNode(colApplication_.colClass_ ).getValue(contexts_.back().applications_.back().class_);
259  appChild.second.getNode(colApplication_.colId_ ).getValue(contexts_.back().applications_.back().id_);
260  appChild.second.getNode(colApplication_.colInstance_ ).getValue(contexts_.back().applications_.back().instance_);
261  appChild.second.getNode(colApplication_.colNetwork_ ).getValue(contexts_.back().applications_.back().network_);
262  appChild.second.getNode(colApplication_.colGroup_ ).getValue(contexts_.back().applications_.back().group_);
263  appChild.second.getNode(colApplication_.colModule_ ).getValue(contexts_.back().applications_.back().module_);
264  }
265 
266  //check artdaq type
267  if(isARTDAQContext(contexts_.back().contextUID_))
268  {
269  artdaqContexts_.push_back(contexts_.size()-1);
270 
271  if(contexts_.back().applications_.size() != 1)
272  {
273  __SS__ << "ARTDAQ Context must only have one Application!" <<
274  contexts_.back().applications_.size() << " were found. " << std::endl;
275  throw std::runtime_error(ss.str());
276  }
277 
278  if(!contexts_.back().status_) continue; //skip if disabled
279 
280  if(contexts_.back().applications_[0].class_ == //if board reader
281  "ots::ARTDAQDataManagerSupervisor")
282  artdaqBoardReaders_.push_back(contexts_.size()-1);
283  else if(contexts_.back().applications_[0].class_ == //if event builder
284  "ots::EventBuilderApp")
285  artdaqEventBuilders_.push_back(contexts_.size()-1);
286  else if(contexts_.back().applications_[0].class_ == //if aggregator
287  "ots::AggregatorApp")
288  artdaqAggregators_.push_back(contexts_.size()-1);
289  else
290  {
291  __SS__ << "ARTDAQ Context must be have Application of an allowed class type:\n " <<
292  "\tots::ARTDAQDataManagerSupervisor\n" <<
293  "\tots::EventBuilderApp\n" <<
294  "\tots::AggregatorApp\n" << "\nClass found was " <<
295  contexts_.back().applications_[0].class_ << std::endl;
296  throw std::runtime_error(ss.str());
297  }
298 
299  }
300 
301  }
302 }
303 
304 //========================================================================================================================
305 //void XDAQContextConfiguration::outputXDAQScript(std::ostream &out)
306 //{
307  /*
308  the file will look something like this:
309  #!/bin/sh
310 
311  echo
312  echo
313 
314  echo "Launching XDAQ contexts..."
315 
316  #for each XDAQ context
317  xdaq.exe -p ${CONTEXT_PORT} -e ${XDAQ_ARGS} &
318 
319  */
320 
321 // out << "#!/bin/sh\n\n";
322 //
323 // out << "echo\necho\n\n";
324 //
325 // out << "echo \"Launching XDAQ contexts...\"\n\n";
326 // out << "#for each XDAQ context\n";
327 //
328 //
329 // std::stringstream ss;
330 // int count = 0;
331 // //for each non-"ART" or "ARTDAQ" context make a xdaq entry
332 // for(XDAQContext &context:contexts_)
333 // {
334 // if(isARTDAQContext(context.contextUID_))
335 // continue; //skip if UID does identify as artdaq
336 //
337 // if(!context.status_)
338 // continue; //skip if disabled
339 //
340 // //at this point we have a xdaq context.. so make an xdaq entry
341 //
342 // ++count;
343 // ss << "echo \"xdaq.exe -p " <<
344 // context.port_ << " -e ${XDAQ_ARGS} &\"\n";
345 // ss << "xdaq.exe -p " <<
346 // context.port_ << " -e ${XDAQ_ARGS} & " <<
347 // "#" << context.contextUID_ << "\n";
348 // }
349 //
350 //
351 // if(count == 0) //if no artdaq contexts at all
352 // {
353 // out << "echo \"No XDAQ (non-artdaq) contexts found.\"\n\n";
354 // out << "echo\necho\n";
355 // return;
356 // }
357 //
358 // out << ss.str();
359 //
360 // out << "\n\n";
361 //}
362 
364 //void XDAQContextConfiguration::outputARTDAQScript(std::ostream &out)
365 //{
366  /*
367  the file will look something like this:
368  #!/bin/sh
369 
370 
371  echo
372  echo
373  while [ 1 ]; do
374 
375  echo "Cleaning up old MPI instance..."
376  killall mpirun
377 
378 
379  echo "Starting mpi run..."
380  echo "$1"
381  echo
382  echo
383 
384  echo mpirun $1 \
385  -np 1 xdaq.exe -p ${ARTDAQ_BOARDREADER_PORT1} -e ${XDAQ_ARGS} : \
386  -np 1 xdaq.exe -p ${ARTDAQ_BOARDREADER_PORT2} -e ${XDAQ_ARGS} : \
387  -np 1 xdaq.exe -p ${ARTDAQ_BUILDER_PORT} -e ${XDAQ_ARGS} : \
388  -np 1 xdaq.exe -p ${ARTDAQ_AGGREGATOR_PORT} -e ${XDAQ_ARGS} &
389 
390  echo
391  echo
392 
393  ret=mpirun $1 \
394  -np 1 xdaq.exe -p ${ARTDAQ_BOARDREADER_PORT1} -e ${XDAQ_ARGS} : \
395  -np 1 xdaq.exe -p ${ARTDAQ_BOARDREADER_PORT2} -e ${XDAQ_ARGS} : \
396  -np 1 xdaq.exe -p ${ARTDAQ_BUILDER_PORT} -e ${XDAQ_ARGS} : \
397  -np 1 xdaq.exe -p ${ARTDAQ_AGGREGATOR_PORT} -e ${XDAQ_ARGS}
398 
399  if [ $ret -eq 0 ]; then
400  exit
401  fi
402 
403  done
404  */
405 
406 // __MOUT__ << artdaqContexts_.size() << " total artdaq context(s)." << std::endl;
407 // __MOUT__ << artdaqBoardReaders_.size() << " active artdaq board reader(s)." << std::endl;
408 // __MOUT__ << artdaqEventBuilders_.size() << " active artdaq event builder(s)." << std::endl;
409 // __MOUT__ << artdaqAggregators_.size() << " active artdaq aggregator(s)." << std::endl;
410 //
411 // out << "#!/bin/sh\n\n";
412 //
413 // out << "\techo\n\techo\n\n";
414 // //out << "while [ 1 ]; do\n\n";
415 //
416 // //out << "\techo \"Cleaning up old MPI instance...\"\n";
417 //
418 // out << "\techo \"" <<
419 // artdaqContexts_.size() << " artdaq Contexts." <<
420 // "\"\n";
421 // out << "\techo \"\t" <<
422 // artdaqBoardReaders_.size() << " artdaq board readers." <<
423 // "\"\n";
424 // out << "\techo \"\t" <<
425 // artdaqEventBuilders_.size() << " artdaq event builders." <<
426 // "\"\n";
427 // out << "\techo \"\t" <<
428 // artdaqAggregators_.size() << " artdaq aggregators_." <<
429 // "\"\n";
430 //
431 // //out << "\tkillall mpirun\n";
432 // out << "\techo\n\techo\n\n";
433 //
434 // out << "\techo \"Starting mpi run...\"\n";
435 // out << "\techo \"$1\"\n\techo\n\techo\n\n";
436 //
437 //
438 //
439 // std::stringstream ss,ssUID;
440 // int count = 0;
441 //
442 // //ss << "\tret=`mpirun $1 \\\n"; `
443 //
444 // ss << "\tmpirun $1 \\\n";
445 //
446 // //for each "ART" or "ARTDAQ" context make an mpi entry
447 // //make an mpi entry for board readers, then event builders, then aggregators
448 //
449 // for(auto &i:artdaqBoardReaders_)
450 // {
451 // if(count++) //add line breaks if not first context
452 // ss << ": \\\n";
453 //
454 // ss << " -np 1 xdaq.exe -p " <<
455 // contexts_[i].port_ << " -e ${XDAQ_ARGS} ";
456 //
457 // ssUID << "\n\t#board reader \t context.port_ \t " << contexts_[i].port_ <<
458 // ": \t" << contexts_[i].contextUID_;
459 // }
460 //
461 // for(auto &i:artdaqEventBuilders_)
462 // {
463 // if(count++) //add line breaks if not first context
464 // ss << ": \\\n";
465 //
466 // ss << " -np 1 xdaq.exe -p " <<
467 // contexts_[i].port_ << " -e ${XDAQ_ARGS} ";
468 //
469 // ssUID << "\n\t#event builder \t context.port_ \t " << contexts_[i].port_ <<
470 // ": \t" << contexts_[i].contextUID_;
471 // }
472 //
473 // for(auto &i:artdaqAggregators_)
474 // {
475 // if(count++) //add line breaks if not first context
476 // ss << ": \\\n";
477 //
478 // ss << " -np 1 xdaq.exe -p " <<
479 // contexts_[i].port_ << " -e ${XDAQ_ARGS} ";
480 //
481 // ssUID << "\n\t#aggregator \t context.port_ \t " << contexts_[i].port_ <<
482 // ": \t" << contexts_[i].contextUID_;
483 // }
484 //
485 //
486 // if(count == 0) //if no artdaq contexts at all
487 // {
488 // out << "\techo \"No ARTDAQ contexts found. So no mpirun necessary.\"\n\n";
489 // out << "\techo\necho\n";
490 // return;
491 // }
492 //
493 // out << "\techo \"" << ss.str() << "\""; //print mpirun
494 // out << "\t\n\techo\n\techo\n\n";
495 // out << ssUID.str() << "\n\n";
496 // out << ss.str(); //run mpirun
497 //
498 // out << "\n\n";
499 // //out << ""\tif [ ${ret:-1} -eq 0 ]; then\n\t\texit\n\tfi\n";
500 // //out << "\ndone\n";
501 //}
502 //
503 //========================================================================================================================
504 void XDAQContextConfiguration::outputXDAQXML(std::ostream &out)
505 {
506  //each generated context will look something like this:
507  //<xc:Context id="0" url="http://${SUPERVISOR_SERVER}:${PORT}">
510  //</xc:Context>
511 
512  //print xml header information and declare xc partition
513  out << "<?xml version='1.0'?>\n" <<
514  "<xc:Partition \txmlns:xsi\t= \"http://www.w3.org/2001/XMLSchema-instance\"\n" <<
515  "\t\txmlns:soapenc\t= \"http://schemas.xmlsoap.org/soap/encoding/\"\n" <<
516  "\t\txmlns:xc\t= \"http://xdaq.web.cern.ch/xdaq/xsd/2004/XMLConfiguration-30\">\n\n";
517 
518  //print partition open
519  //for each context
520  // open context
521  // for each app in context
522  // print application
523  // print module
524  // close context
525  //close partition
526 
527  char tmp[200];
528  for(XDAQContext &context:contexts_)
529  {
530 
531  //__MOUT__ << context.contextUID_ << std::endl;
532 
533  sprintf(tmp,"\t<!-- ContextUID='%s' sourceConfig='%s' -->",
534  context.contextUID_.c_str(), context.sourceConfig_.c_str());
535  out << tmp << "\n";
536 
537  if(!context.status_) //comment out if disabled
538  out << "\t<!--\n";
539 
540  sprintf(tmp,"\t<xc:Context id=\"%u\" url=\"%s:%u\">", context.id_, context.address_.c_str(), context.port_);
541  out << tmp << "\n\n";
542 
543  for(XDAQApplication &app:context.applications_)
544  {
545  //__MOUT__ << app.name_ << std::endl;
546 
547 
548  if(context.status_)
549  {
550  sprintf(tmp,"\t\t<!-- Application GroupID = '%s' UID='%s' sourceConfig='%s' -->",
551  app.applicationGroupID_.c_str(), app.applicationUID_.c_str(), app.sourceConfig_.c_str());
552  out << tmp << "\n";
553 
554  if(!app.status_) //comment out if disabled
555  out << "\t\t<!--\n";
556  }
557 
558  sprintf(tmp,"\t\t<xc:Application class=\"%s\" id=\"%u\" instance=\"%u\" network=\"%s\" group=\"%s\"/>\n",
559  app.class_.c_str(), app.id_, app.instance_, app.network_.c_str(), app.group_.c_str());
560  out << tmp;
561 
562  sprintf(tmp,"\t\t<xc:Module>%s</xc:Module>\n", app.module_.c_str());
563  out << tmp;
564 
565  if(context.status_ && !app.status_)
566  out << "\t\t-->\n";
567  out << "\n";
568  }
569 
570  out << "\t</xc:Context>\n";
571  if(!context.status_)
572  out << "\t-->\n";
573  out << "\n";
574  }
575 
576  out << "</xc:Partition>\n\n\n";
577 
578 }
579 
580 //========================================================================================================================
581 std::string XDAQContextConfiguration::getContextUID(const std::string &url) const
582 {
583  for(auto context: contexts_)
584  {
585  if(!context.status_) continue;
586 
587  if(url == context.address_ + ":" + std::to_string(context.port_))
588  return context.contextUID_;
589  }
590  return "";
591 }
592 
593 //========================================================================================================================
594 std::string XDAQContextConfiguration::getApplicationUID(const std::string &url, unsigned int id) const
595 {
596  for(auto context: contexts_)
597  {
598  if(!context.status_) continue;
599 
600  if(url == context.address_ + ":" + std::to_string(context.port_))
601  for(auto application: context.applications_)
602  {
603  if(!application.status_) continue;
604 
605  if(application.id_ == id)
606  {
607  return application.applicationUID_;
608  }
609  }
610  }
611  return "";
612 }
613 
614 DEFINE_OTS_CONFIGURATION(XDAQContextConfiguration)