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