otsdaq  v2_03_00
DispatcherApp.cc
1 #include "otsdaq/DispatcherApp/DispatcherApp.h"
2 //#include "otsdaq-core/Macros/CoutMacros.h"
3 //#include "otsdaq-core/MessageFacility/MessageFacility.h"
4 //#include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
5 //#include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
6 //#include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
7 //
8 //#include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
9 //#include "otsdaq-core/TablePluginDataFormats/XDAQContextTable.h"
10 //
11 //#include <toolbox/fsm/FailedEvent.h>
12 //
13 //#include <xdaq/NamespaceURI.h>
14 //#include <xoap/Method.h>
15 
16 //#include <memory>
17 #include "artdaq-core/Utilities/configureMessageFacility.hh"
18 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
19 #include "artdaq/DAQdata/Globals.hh"
20 #include "cetlib_except/exception.h"
21 #include "fhiclcpp/make_ParameterSet.h"
22 //#include "messagefacility/MessageLogger/MessageLogger.h"
23 
24 //#include <cassert>
25 //#include <fstream>
26 //#include <iostream>
27 //#include "otsdaq-core/TableCore/TableGroupKey.h"
28 
29 using namespace ots;
30 
31 XDAQ_INSTANTIATOR_IMPL(DispatcherApp)
32 
33 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/" + "ARTDAQConfigurations/"
34 #define ARTDAQ_FILE_PREAMBLE "aggregator"
35 
36 //========================================================================================================================
37 DispatcherApp::DispatcherApp(xdaq::ApplicationStub* s) : CoreSupervisorBase(s)
38 // : xdaq::Application(s)
39 // , SOAPMessenger(this)
40 // , stateMachineWorkLoopManager_(
41 // toolbox::task::bind(this, &DispatcherApp::stateMachineThread, "StateMachine"))
42 // , stateMachineSemaphore_(toolbox::BSem::FULL)
43 // , theConfigurationManager_(
44 // new ConfigurationManager) //(Singleton<ConfigurationManager>::getInstance())
45 // ////I always load the full config but if I want to
46 // // load a partial configuration (new
47 // // ConfigurationManager)
48 // , XDAQContextTableName_(
49 // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName())
50 // , supervisorConfigurationPath_(
51 // "INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and
52 // " "supervisorApplicationUID_")
53 // , supervisorContextUID_("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
54 // , supervisorApplicationUID_(
55 // "INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
56 {
57  __SUP_COUT__ << "Constructor." << __E__;
58 
59  INIT_MF("DispatcherApp");
60 
61  // xgi::bind(this, &DispatcherApp::Default, "Default");
62  // xgi::bind(this, &DispatcherApp::stateMachineXgiHandler, "StateMachineXgiHandler");
63  //
64  // xoap::bind(this,
65  // &DispatcherApp::stateMachineStateRequest,
66  // "StateMachineStateRequest",
67  // XDAQ_NS_URI);
68  // xoap::bind(this,
69  // &DispatcherApp::stateMachineErrorMessageRequest,
70  // "StateMachineErrorMessageRequest",
71  // XDAQ_NS_URI);
72  //
73  // try
74  // {
75  // supervisorContextUID_ =
76  // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
77  // ->getContextUID(
78  // getApplicationContext()->getContextDescriptor()->getURL());
79  // }
80  // catch(...)
81  // {
82  // __COUT_ERR__
83  // << "XDAQ Supervisor could not access it's configuration through "
84  // "the Configuration Manager."
85  // << ". The getApplicationContext()->getContextDescriptor()->getURL() = "
86  // << getApplicationContext()->getContextDescriptor()->getURL() << __E__;
87  // throw;
88  // }
89  // try
90  // {
91  // supervisorApplicationUID_ =
92  // theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
93  // ->getApplicationUID(
94  // getApplicationContext()->getContextDescriptor()->getURL(),
95  // getApplicationDescriptor()->getLocalId());
96  // }
97  // catch(...)
98  // {
99  // __COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through "
100  // "the Configuration Manager."
101  // << " The supervisorContextUID_ = " << supervisorContextUID_
102  // << ". The supervisorApplicationUID = " <<
103  // supervisorApplicationUID_
104  // << __E__;
105  // throw;
106  // }
107  // supervisorConfigurationPath_ = "/" + supervisorContextUID_ +
108  // "/LinkToApplicationTable/" +
109  // supervisorApplicationUID_ +
110  //"/LinkToSupervisorTable";
111  //
112  // setStateMachineName(supervisorApplicationUID_);
113  __SUP_COUT__ << "Constructed." << __E__;
114 } // end constructor()
115 
116 //========================================================================================================================
117 DispatcherApp::~DispatcherApp(void)
118 {
119  __SUP_COUT__ << "Destructor." << __E__;
120  destroy();
121  __SUP_COUT__ << "Destructed." << __E__;
122 } // end destructor()
123 
124 //========================================================================================================================
125 void DispatcherApp::init(void)
126 {
127  __SUP_COUT__ << "Initializing..." << __E__;
128 
129  // allSupervisorInfo_.init(getApplicationContext());
130 
131  artdaq::configureMessageFacility("Dispatcher");
132  __SUP_COUT__ << "artdaq MF configured." << __E__;
133 
134  // initialization
135 
136  std::string name = "Dispatcher";
137  unsigned short port = 5300;
138  // artdaq::setMsgFacAppName(supervisorApplicationUID_, port);
139  artdaq::setMsgFacAppName(name, port);
140  // mf::LogDebug(supervisorApplicationUID_) << "artdaq version " <<
141  TLOG(TLVL_DEBUG, name + "Supervisor")
142  << "artdaq version "
143  << artdaq::GetPackageBuildInfo::getPackageBuildInfo().getPackageVersion()
144  << ", built "
145  << artdaq::GetPackageBuildInfo::getPackageBuildInfo().getBuildTimestamp();
146 
147  // create the DispatcherInterface
148  app_name = name;
149  my_rank = this->getApplicationDescriptor()->getLocalId();
150  theDispatcherInterface_.reset(new artdaq::DispatcherApp());
151  // theDispatcherInterface_ = new DispatcherInterface(mpiSentry_->rank(),
152  // local_group_comm, supervisorApplicationUID_ );
153 
154  __SUP_COUT__ << "Initialized." << __E__;
155 } // end init()
156 
157 //========================================================================================================================
158 void DispatcherApp::destroy(void)
159 {
160  __SUP_COUT__ << "Destroying..." << __E__;
161  theDispatcherInterface_.reset(nullptr);
162  __SUP_COUT__ << "Destroyed." << __E__;
163 } // end destroy()
164 //
166 // void DispatcherApp::Default(xgi::Input* in, xgi::Output* out)
167 //{
168 // *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
169 // "src='/WebPath/html/DispatcherApp.html?urn="
170 // << this->getApplicationDescriptor()->getLocalId() << "'></frameset></html>";
171 //}
172 //
174 // void DispatcherApp::stateMachineXgiHandler(xgi::Input* in, xgi::Output* out) {}
175 //
177 // void DispatcherApp::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out) {}
178 //
180 // xoap::MessageReference DispatcherApp::stateMachineXoapHandler(
181 // xoap::MessageReference message)
182 //{
183 // std::cout << __COUT_HDR_FL__ << "Soap Handler!" << __E__;
184 // stateMachineWorkLoopManager_.removeProcessedRequests();
185 // stateMachineWorkLoopManager_.processRequest(message);
186 // std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << __E__;
187 // return message;
188 //}
189 //
191 // xoap::MessageReference DispatcherApp::stateMachineResultXoapHandler(
192 // xoap::MessageReference message)
193 //{
194 // std::cout << __COUT_HDR_FL__ << "Soap Handler!" << __E__;
195 // // stateMachineWorkLoopManager_.removeProcessedRequests();
196 // // stateMachineWorkLoopManager_.processRequest(message);
197 // std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << __E__;
198 // return message;
199 //}
200 //
202 // bool DispatcherApp::stateMachineThread(toolbox::task::WorkLoop* workLoop)
203 //{
204 // stateMachineSemaphore_.take();
205 // std::cout << __COUT_HDR_FL__ << "Re-sending message..."
206 // << SOAPUtilities::translate(
207 // stateMachineWorkLoopManager_.getMessage(workLoop))
208 // .getCommand()
209 // << __E__;
210 // std::string reply = send(this->getApplicationDescriptor(),
211 // stateMachineWorkLoopManager_.getMessage(workLoop));
212 // stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
213 // std::cout << __COUT_HDR_FL__ << "Done with message" << __E__;
214 // stateMachineSemaphore_.give();
215 // return false; // execute once and automatically remove the workloop so in
216 // // WorkLoopManager the try workLoop->remove(job_) could be commented
217 // // out return true;//go on and then you must do the
218 // // workLoop->remove(job_) in WorkLoopManager
219 //}
220 //
222 // xoap::MessageReference DispatcherApp::stateMachineStateRequest(
223 // xoap::MessageReference message)
224 //{
225 // std::cout << __COUT_HDR_FL__ << theStateMachine_.getCurrentStateName() << __E__;
226 // return SOAPUtilities::makeSOAPMessageReference(
227 // theStateMachine_.getCurrentStateName());
228 //}
229 //
231 // xoap::MessageReference DispatcherApp::stateMachineErrorMessageRequest(
232 // xoap::MessageReference message)
233 //
234 //{
235 // __COUT__ << "theStateMachine_.getErrorMessage() = "
236 // << theStateMachine_.getErrorMessage() << __E__;
237 //
238 // SOAPParameters retParameters;
239 // retParameters.addParameter("ErrorMessage", theStateMachine_.getErrorMessage());
240 // return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply",
241 // retParameters);
242 //}
243 //
245 // void DispatcherApp::stateInitial(toolbox::fsm::FiniteStateMachine& fsm) {}
246 //
248 // void DispatcherApp::stateHalted(toolbox::fsm::FiniteStateMachine& fsm) {}
249 //
251 // void DispatcherApp::stateRunning(toolbox::fsm::FiniteStateMachine& fsm) {}
252 //
254 // void DispatcherApp::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) {}
255 //
257 // void DispatcherApp::statePaused(toolbox::fsm::FiniteStateMachine& fsm) {}
258 //
260 // void DispatcherApp::inError(toolbox::fsm::FiniteStateMachine& fsm)
261 //{
262 // std::cout << __COUT_HDR_FL__
263 // << "Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
264 // // rcmsStateNotifier_.stateChanged("Error", "");
265 //}
266 //
268 // void DispatcherApp::enteringError(toolbox::Event::Reference e)
269 //{
270 // std::cout << __COUT_HDR_FL__
271 // << "Fsm current state: " << theStateMachine_.getCurrentStateName() << __E__;
272 // toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
273 // std::ostringstream error;
274 // error << "Failure performing transition from " << failedEvent.getFromState() << " to "
275 // << failedEvent.getToState()
276 // << " exception: " << failedEvent.getException().what();
277 // std::cout << __COUT_HDR_FL__ << error.str() << __E__;
278 // // diagService_->reportError(errstr.str(),DIAGERROR);
279 //}
280 
281 //========================================================================================================================
282 void DispatcherApp::transitionConfiguring(toolbox::Event::Reference e)
283 {
284  __SUP_COUT__ << "Configuring..." << __E__;
285 
286  __SUP_COUT__ << SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
287  << __E__;
288 
289  std::pair<std::string /*group name*/, TableGroupKey> theGroup(
290  SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
291  .getParameters()
292  .getValue("ConfigurationTableGroupName"),
293  TableGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
294  .getParameters()
295  .getValue("ConfigurationTableGroupKey")));
296 
297  __SUP_COUT__ << "Configuration group name: " << theGroup.first
298  << " key: " << theGroup.second << __E__;
299 
300  theConfigurationManager_->loadTableGroup(theGroup.first, theGroup.second, true);
301 
302  // load fcl string from dedicated file
303  fhicl::ParameterSet pset;
304 
305  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
306  const std::string& uid = CorePropertySupervisorBase::getSupervisorUID();
307 
308  __SUP_COUTV__(uid);
309  for(unsigned int i = 0; i < uid.size(); ++i)
310  if((uid[i] >= 'a' && uid[i] <= 'z') || (uid[i] >= 'A' && uid[i] <= 'Z') ||
311  (uid[i] >= '0' && uid[i] <= '9')) // only allow alpha numeric in file name
312  filename += uid[i];
313  filename += ".fcl";
314 
315  __SUP_COUTV__(filename);
316 
317  std::string fileFclString;
318  {
319  std::ifstream in(filename, std::ios::in | std::ios::binary);
320  if(in)
321  {
322  std::string contents;
323  in.seekg(0, std::ios::end);
324  fileFclString.resize(in.tellg());
325  in.seekg(0, std::ios::beg);
326  in.read(&fileFclString[0], fileFclString.size());
327  in.close();
328  }
329  }
330 
331  __SUP_COUTV__(fileFclString);
332 
333  try
334  {
335  fhicl::make_ParameterSet(fileFclString, pset);
336  theDispatcherInterface_->initialize(pset, 0, 0);
337  }
338  catch(const cet::coded_exception<fhicl::error, &fhicl::detail::translate>& e)
339  {
340  __SUP_SS__ << "Error was caught while configuring: " << e.what() << __E__;
341  __SUP_COUT_ERR__ << "\n" << ss.str();
342  theStateMachine_.setErrorMessage(ss.str());
343  throw toolbox::fsm::exception::Exception(
344  "Transition Error" /*name*/,
345  ss.str() /* message*/,
346  "DispatcherApp::transitionConfiguring" /*module*/,
347  __LINE__ /*line*/,
348  __FUNCTION__ /*function*/
349  );
350  }
351 
352  __SUP_COUT__ << "Configured." << __E__;
353 } // end transitionConfiguring()
354 
355 //========================================================================================================================
356 void DispatcherApp::transitionHalting(toolbox::Event::Reference e)
357 {
358  __SUP_COUT__ << "Halting..." << __E__;
359  try
360  {
361  theDispatcherInterface_->stop(45, 0);
362  }
363  catch(...)
364  {
365  // It is okay for this to fail, esp. if already stopped...
366  __SUP_COUT__ << "Ignoring error on halt." << __E__;
367  }
368 
369  try
370  {
371  theDispatcherInterface_->shutdown(45);
372  }
373  catch(...)
374  {
375  __SUP_COUT_ERR__ << "Error occurred during shutdown! State="
376  << theDispatcherInterface_->status();
377  }
378 
379  init();
380 
381  __SUP_COUT__ << "Halted." << __E__;
382 } // end transitionHalting()
383 
384 //========================================================================================================================
385 void DispatcherApp::transitionInitializing(toolbox::Event::Reference e)
386 {
387  __SUP_COUT__ << "Initializing..." << __E__;
388  init();
389  __SUP_COUT__ << "Initialized." << __E__;
390 } // end transitionInitializing()
391 
392 //========================================================================================================================
393 void DispatcherApp::transitionPausing(toolbox::Event::Reference e)
394 {
395  __SUP_COUT__ << "Pausing..." << __E__;
396  theDispatcherInterface_->pause(0, 0);
397  __SUP_COUT__ << "Paused." << __E__;
398 } // end transitionPausing()
399 
400 //========================================================================================================================
401 void DispatcherApp::transitionResuming(toolbox::Event::Reference e)
402 {
403  __SUP_COUT__ << "Resuming..." << __E__;
404  theDispatcherInterface_->resume(0, 0);
405  __SUP_COUT__ << "Resumed." << __E__;
406 } // end transitionResuming()
407 
408 //========================================================================================================================
409 void DispatcherApp::transitionStarting(toolbox::Event::Reference e)
410 {
411  __SUP_COUT__ << "Starting..." << __E__;
412 
413  auto runNumber = SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
414  .getParameters()
415  .getValue("RunNumber");
416  try
417  {
418  art::RunID runId(
419  (art::RunNumber_t)boost::lexical_cast<art::RunNumber_t>(runNumber));
420  theDispatcherInterface_->start(runId, 0, 0);
421  }
422  catch(const boost::exception& e)
423  {
424  __SUP_SS__ << "Error parsing string to art::RunNumber_t: " << runNumber << __E__;
425  __SUP_SS_THROW__;
426  }
427  __SUP_COUT__ << "Started." << __E__;
428 } // end transitionStarting()
429 
430 //========================================================================================================================
431 void DispatcherApp::transitionStopping(toolbox::Event::Reference e)
432 {
433  __SUP_COUT__ << "Stopping..." << __E__;
434  theDispatcherInterface_->stop(45, 0);
435  __SUP_COUT__ << "Stopped." << __E__;
436 } // end transitionStopping()