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