otsdaq  v2_00_00
EventBuilderApp.cc
1 #include "otsdaq/EventBuilderApp/EventBuilderApp.h"
2 #include "otsdaq-core/MessageFacility/MessageFacility.h"
3 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
4 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
5 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
6 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
7 
8 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
9 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
10 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.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 "messagefacility/MessageLogger/MessageLogger.h"
19 #include "artdaq-core/Utilities/configureMessageFacility.hh"
20 #include "cetlib/exception.h"
21 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
22 #include "fhiclcpp/make_ParameterSet.h"
23 
24 #include <fstream>
25 #include <iostream>
26 #include <cassert>
27 
28 using namespace ots;
29 
30 XDAQ_INSTANTIATOR_IMPL(EventBuilderApp)
31 
32 //========================================================================================================================
33 EventBuilderApp::EventBuilderApp(xdaq::ApplicationStub* stub)
34 throw (xdaq::exception::Exception)
35 : xdaq::Application (stub)
36 , SOAPMessenger (this)
37 , stateMachineWorkLoopManager_ (toolbox::task::bind(this, &EventBuilderApp::stateMachineThread, "StateMachine"))
38 , stateMachineSemaphore_ (toolbox::BSem::FULL)
39 , theConfigurationManager_ (new ConfigurationManager)//(Singleton<ConfigurationManager>::getInstance()) //I always load the full config but if I want to load a partial configuration (new ConfigurationManager)
40 , XDAQContextConfigurationName_(theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getConfigurationName())
41 , supervisorConfigurationPath_ ("INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and supervisorApplicationUID_")
42 , supervisorContextUID_ ("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
43 , supervisorApplicationUID_ ("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
44 //, theConfigurationGroupKey_ (nullptr)
45 //, supervisorInstance_ (this->getApplicationDescriptor()->getInstance())
46 // theFEWInterfacesManager_ (theConfigurationManager_,this->getApplicationDescriptor()->getInstance())
47 {
48  INIT_MF("EventBuilderApp");
49  xgi::bind (this, &EventBuilderApp::Default, "Default" );
50  xgi::bind (this, &EventBuilderApp::stateMachineXgiHandler, "StateMachineXgiHandler");
51 
52  xoap::bind(this, &EventBuilderApp::stateMachineStateRequest, "StateMachineStateRequest", XDAQ_NS_URI );
53  xoap::bind(this, &EventBuilderApp::stateMachineErrorMessageRequest, "StateMachineErrorMessageRequest", XDAQ_NS_URI );
54 
55  try
56  {
57  supervisorContextUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getContextUID(getApplicationContext()->getContextDescriptor()->getURL());
58  }
59  catch(...)
60  {
61  __COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Context Group." <<
62  " The XDAQContextConfigurationName = " << XDAQContextConfigurationName_ <<
63  ". The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
64  throw;
65  }
66  try
67  {
68  supervisorApplicationUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getApplicationUID
69  (
70  getApplicationContext()->getContextDescriptor()->getURL(),
71  getApplicationDescriptor()->getLocalId()
72  );
73  }
74  catch(...)
75  {
76  __COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Application Group."
77  << " The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
78  throw;
79  }
80  supervisorConfigurationPath_ = "/" + supervisorContextUID_ + "/LinkToApplicationConfiguration/" + supervisorApplicationUID_ + "/LinkToSupervisorConfiguration";
81 
82  setStateMachineName(supervisorApplicationUID_);
83  init();
84 }
85 
86 //========================================================================================================================
87 EventBuilderApp::~EventBuilderApp(void)
88 {
89  destroy();
90 }
91 //========================================================================================================================
92 void EventBuilderApp::init(void)
93 {
94  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR INIT START!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
95  allSupervisorInfo_.init(getApplicationContext());
96 
97  artdaq::configureMessageFacility("eventbuilder");
98 
99  // initialization
100 
101  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR NO ERRORS MAKING MSG FACILITY!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
102  std::string name = "Builder";
103  unsigned short port = 5200;
104  //artdaq::setMsgFacAppName(supervisorApplicationUID_, port);
105  artdaq::setMsgFacAppName(name, port);
106  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR MSG FACILITY DONE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
107  mf::LogDebug(name + "Supervisor") << "artdaq version " <<
108 // mf::LogDebug(supervisorApplicationUID_) << " artdaq version " <<
109  artdaq::GetPackageBuildInfo::getPackageBuildInfo().getPackageVersion()
110  << ", built " <<
111  artdaq::GetPackageBuildInfo::getPackageBuildInfo().getBuildTimestamp();
112 
113  // create the EventBuilderInterface
114  app_name = name;
115  my_rank = this->getApplicationDescriptor()->getLocalId();
116  theARTDAQEventBuilderInterfaces_[0] = new artdaq::EventBuilderApp( );
117  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR INIT DONE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
118 }
119 
120 //========================================================================================================================
121 void EventBuilderApp::destroy(void)
122 {
123 }
124 
125 //========================================================================================================================
126 void EventBuilderApp::Default(xgi::Input * in, xgi::Output * out )
127 throw (xgi::exception::Exception)
128 {
129 
130  *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/EventBuilderApp.html?urn=" <<
131  this->getApplicationDescriptor()->getLocalId() <<"'></frameset></html>";
132 }
133 
134 //========================================================================================================================
135 void EventBuilderApp::stateMachineXgiHandler(xgi::Input * in, xgi::Output * out )
136 throw (xgi::exception::Exception)
137 {}
138 
139 //========================================================================================================================
140 void EventBuilderApp::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out )
141 throw (xgi::exception::Exception)
142 {}
143 
144 //========================================================================================================================
145 xoap::MessageReference EventBuilderApp::stateMachineXoapHandler(xoap::MessageReference message )
146 throw (xoap::exception::Exception)
147 {
148  std::cout << __COUT_HDR_FL__ << "Soap Handler!" << std::endl;
149  stateMachineWorkLoopManager_.removeProcessedRequests();
150  stateMachineWorkLoopManager_.processRequest(message);
151  std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << std::endl;
152  return message;
153 }
154 
155 //========================================================================================================================
156 xoap::MessageReference EventBuilderApp::stateMachineResultXoapHandler(xoap::MessageReference message )
157 throw (xoap::exception::Exception)
158 {
159  std::cout << __COUT_HDR_FL__ << "Soap Handler!" << std::endl;
160  //stateMachineWorkLoopManager_.removeProcessedRequests();
161  //stateMachineWorkLoopManager_.processRequest(message);
162  std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << std::endl;
163  return message;
164 }
165 
166 //========================================================================================================================
167 bool EventBuilderApp::stateMachineThread(toolbox::task::WorkLoop* workLoop)
168 {
169  stateMachineSemaphore_.take();
170  std::cout << __COUT_HDR_FL__ << "Re-sending message..." << SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
171  std::string reply = send(this->getApplicationDescriptor(),stateMachineWorkLoopManager_.getMessage(workLoop));
172  stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
173  std::cout << __COUT_HDR_FL__ << "Done with message" << std::endl;
174  stateMachineSemaphore_.give();
175  return false;//execute once and automatically remove the workloop so in WorkLoopManager the try workLoop->remove(job_) could be commented out
176  //return true;//go on and then you must do the workLoop->remove(job_) in WorkLoopManager
177 }
178 
179 //========================================================================================================================
180 xoap::MessageReference EventBuilderApp::stateMachineStateRequest(xoap::MessageReference message)
181 throw (xoap::exception::Exception)
182 {
183  std::cout << __COUT_HDR_FL__ << theStateMachine_.getCurrentStateName() << std::endl;
184  return SOAPUtilities::makeSOAPMessageReference(theStateMachine_.getCurrentStateName());
185 }
186 
187 //========================================================================================================================
188 xoap::MessageReference EventBuilderApp::stateMachineErrorMessageRequest(xoap::MessageReference message)
189 throw (xoap::exception::Exception)
190 {
191  __COUT__<< "theStateMachine_.getErrorMessage() = " << theStateMachine_.getErrorMessage() << std::endl;
192 
193  SOAPParameters retParameters;
194  retParameters.addParameter("ErrorMessage",theStateMachine_.getErrorMessage());
195  return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply",retParameters);
196 }
197 
198 //========================================================================================================================
199 void EventBuilderApp::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
200 throw (toolbox::fsm::exception::Exception)
201 {
202 
203 }
204 
205 //========================================================================================================================
206 void EventBuilderApp::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
207 throw (toolbox::fsm::exception::Exception)
208 {
209 
210 }
211 
212 //========================================================================================================================
213 void EventBuilderApp::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
214 throw (toolbox::fsm::exception::Exception)
215 {
216 
217 }
218 
219 //========================================================================================================================
220 void EventBuilderApp::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
221 throw (toolbox::fsm::exception::Exception)
222 {
223 
224 }
225 
226 //========================================================================================================================
227 void EventBuilderApp::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
228 throw (toolbox::fsm::exception::Exception)
229 {
230 
231 }
232 
233 //========================================================================================================================
234 void EventBuilderApp::inError (toolbox::fsm::FiniteStateMachine & fsm)
235 throw (toolbox::fsm::exception::Exception)
236 {
237  std::cout << __COUT_HDR_FL__ << "Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
238  //rcmsStateNotifier_.stateChanged("Error", "");
239 }
240 
241 //========================================================================================================================
242 void EventBuilderApp::enteringError (toolbox::Event::Reference e)
243 throw (toolbox::fsm::exception::Exception)
244 {
245  std::cout << __COUT_HDR_FL__ << "Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
246  toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
247  std::ostringstream error;
248  error << "Failure performing transition from "
249  << failedEvent.getFromState()
250  << " to "
251  << failedEvent.getToState()
252  << " exception: " << failedEvent.getException().what();
253  std::cout << __COUT_HDR_FL__ << error.str() << std::endl;
254  //diagService_->reportError(errstr.str(),DIAGERROR);
255 
256 }
257 
258 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/"+ "ARTDAQConfigurations/"
259 #define ARTDAQ_FILE_PREAMBLE "builder"
260 
261 //========================================================================================================================
262 void EventBuilderApp::transitionConfiguring(toolbox::Event::Reference e)
263 throw (toolbox::fsm::exception::Exception)
264 {
265 
266  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
267  std::cout << __COUT_HDR_FL__ << SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) << std::endl;
268 
269 
270  std::pair<std::string /*group name*/, ConfigurationGroupKey> theGroup(
271  SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
272  getParameters().getValue("ConfigurationGroupName"),
273  ConfigurationGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
274  getParameters().getValue("ConfigurationGroupKey")));
275 
276  __COUT__ << "Configuration group name: " << theGroup.first << " key: " <<
277  theGroup.second << std::endl;
278 
279  theConfigurationManager_->loadConfigurationGroup(
280  theGroup.first,
281  theGroup.second, true);
282 
283  //theConfigurationManager_->setupEventBuilderAppConfiguration(theConfigurationGroupKey_,supervisorInstance_);
284 
285  //Now that the configuration manager has all the necessary configurations I can create all objects dependent of the configuration
286  //std::string configString = "daq:{event_builder:{expected_fragments_per_event:2 first_fragment_receiver_rank:0 fragment_receiver_count:2 mpi_buffer_count:16 print_event_store_stats:true send_triggers:true trigger_port:5001 use_art:true verbose:false} max_fragment_size_words:2.097152e6} outputs:{netMonOutput:{module_type:\"NetMonOutput\"}} physics:{my_output_modules:[\"netMonOutput\"]} process_name:\"DAQ\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\"} user:{NetMonTransportServiceInterface:{data_receiver_count:1 first_data_receiver_rank:4 max_fragment_size_words:2.097152e6 mpi_buffer_count:8 service_provider:\"NetMonTransportService\"}}} source:{fragment_type_map:[[1,\"UDP\"]] module_type:\"RawInput\" resume_after_timeout:true waiting_time:900}";
287 
288  //ONLY 1 BOARD READER IN THE SYSTEM
289  //std::string configString = "daq:{event_builder:{expected_fragments_per_event:1 first_fragment_receiver_rank:0 fragment_receiver_count:1 mpi_buffer_count:16 print_event_store_stats:true send_triggers:true trigger_port:5001 use_art:true verbose:false} max_fragment_size_words:2.097152e6} outputs:{netMonOutput:{module_type:\"RootMPIOutput\"}} physics:{analyzers:{wf: {module_type:\"WFViewer\" fragment_ids:[0] fragment_type_labels:[ \"DataGen\" ] prescale:60 write_to_file:true fileName:\"/tmp/otsdaqdemo_onmon_evb.root\"}} a1:[\"wf\"] my_output_modules:[\"netMonOutput\"]} process_name:\"DAQ\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\" errorOnFailureToPut: false} user:{NetMonTransportServiceInterface:{data_receiver_count:1 first_data_receiver_rank:2 max_fragment_size_words:2.097152e6 mpi_buffer_count:8 service_provider:\"NetMonTransportService\"}}} source:{fragment_type_map:[[1,\"UDP\"], [4,\"DataGen\"]] module_type:\"RawInput\" resume_after_timeout:true waiting_time:900}";
290 
291  //2 BOARD READERS IN THE SYSTEM
292  //std::string configString = "daq:{event_builder:{expected_fragments_per_event:1 first_fragment_receiver_rank:0 fragment_receiver_count:1 mpi_buffer_count:16 print_event_store_stats:true send_triggers:true trigger_port:5001 use_art:true verbose:false} max_fragment_size_words:2.097152e6} outputs:{netMonOutput:{module_type:\"RootMPIOutput\"}} physics:{analyzers:{wf: {module_type:\"WFViewer\" fragment_ids:[0] fragment_type_labels:[ \"DataGen\" ] prescale:60 write_to_file:true fileName:\"/tmp/otsdaqdemo_onmon_evb.root\"}} a1:[\"wf\"] my_output_modules:[\"netMonOutput\"]} process_name:\"DAQ\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\" errorOnFailureToPut: false} user:{NetMonTransportServiceInterface:{data_receiver_count:1 first_data_receiver_rank:2 max_fragment_size_words:2.097152e6 mpi_buffer_count:8 service_provider:\"NetMonTransportService\"}}} source:{fragment_type_map:[[1,\"UDP\"], [4,\"DataGen\"]] module_type:\"RawInput\" resume_after_timeout:true waiting_time:900}";
293 
294  //__COUT__ << configString << std::endl;
295  __COUT__ << std::endl;
296  __COUT__ << std::endl;
297  //__COUT__ << theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getNode("ConfigurationString").getValue<std::string>() << std::endl;
298  fhicl::ParameterSet pset;
299  //fhicl::make_ParameterSet(configString, pset);
300 
301 
302  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
303  std::string uid = theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getValue();
304 
305  __COUT__ << "uid: " << uid << std::endl;
306  for(unsigned int i=0;i<uid.size();++i)
307  if((uid[i] >= 'a' && uid[i] <= 'z') ||
308  (uid[i] >= 'A' && uid[i] <= 'Z') ||
309  (uid[i] >= '0' && uid[i] <= '9')) //only allow alpha numeric in file name
310  filename += uid[i];
311  filename += ".fcl";
312 
313  __COUT__ << "filename: " << filename << std::endl;
314 
315  std::string fileFclString;
316  {
317  std::ifstream in(filename, std::ios::in | std::ios::binary);
318  if (in)
319  {
320  std::string contents;
321  in.seekg(0, std::ios::end);
322  fileFclString.resize(in.tellg());
323  in.seekg(0, std::ios::beg);
324  in.read(&fileFclString[0], fileFclString.size());
325  in.close();
326  }
327  }
328  __COUT__ << fileFclString << std::endl;
329 
330  try
331  {
332  fhicl::make_ParameterSet(fileFclString, pset);
333 
334  //fhicl::make_ParameterSet(theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getNode("ConfigurationString").getValue<std::string>(), pset);
335 
336  for(auto it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
337  it->second->initialize(pset,0,0);
338  }
339  catch(const cet::coded_exception<fhicl::error, &fhicl::detail::translate>& e)
340  {
341  __SS__ << "Error was caught while configuring: " << e.what() << std::endl;
342  __COUT_ERR__ << "\n" << ss.str();
343  theStateMachine_.setErrorMessage(ss.str());
344  throw toolbox::fsm::exception::Exception(
345  "Transition Error" /*name*/,
346  ss.str() /* message*/,
347  "EventBuilderApp::transitionConfiguring" /*module*/,
348  __LINE__ /*line*/,
349  __FUNCTION__ /*function*/
350  );
351  }
352 
353  std::cout << __COUT_HDR_FL__ << "ARTDAQBUILDER SUPERVISOR DONE CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
354 
355 }
356 
357 //========================================================================================================================
358 void EventBuilderApp::transitionHalting(toolbox::Event::Reference e)
359 throw (toolbox::fsm::exception::Exception)
360 {
361 
362  // for(auto it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
363  // it->second->shutdown(0);
364 }
365 
366 //========================================================================================================================
367 void EventBuilderApp::transitionInitializing(toolbox::Event::Reference e)
368 throw (toolbox::fsm::exception::Exception)
369 {
370 
371 }
372 
373 //========================================================================================================================
374 void EventBuilderApp::transitionPausing(toolbox::Event::Reference e)
375 throw (toolbox::fsm::exception::Exception)
376 {
377 
378  for(auto it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
379  it->second->pause(0, 0);
380 }
381 
382 //========================================================================================================================
383 void EventBuilderApp::transitionResuming(toolbox::Event::Reference e)
384 throw (toolbox::fsm::exception::Exception)
385 {
386 
387  for(auto it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
388  it->second->resume(0, 0);
389 }
390 
391 //========================================================================================================================
392 void EventBuilderApp::transitionStarting(toolbox::Event::Reference e)
393 throw (toolbox::fsm::exception::Exception)
394 {
395 
396  art::RunID runId((art::RunNumber_t)boost::lexical_cast<art::RunNumber_t>(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue("RunNumber")));
397  for(auto it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
398  it->second->start(runId, 0, 0);
399 }
400 
401 //========================================================================================================================
402 void EventBuilderApp::transitionStopping(toolbox::Event::Reference e)
403 throw (toolbox::fsm::exception::Exception)
404 {
405 
406  for(auto it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
407  it->second->stop(45, 0);
408 
409  for(auto it=theARTDAQEventBuilderInterfaces_.begin(); it!=theARTDAQEventBuilderInterfaces_.end(); it++)
410  it->second->shutdown(45);
411 }