otsdaq  v1_01_04
 All Classes Namespaces Functions
AggregatorApp.cc
1 #include "otsdaq/AggregatorApp/AggregatorApp.h"
2 #include "otsdaq/AggregatorApp/AggregatorInterface.h"
3 #include "otsdaq-core/MessageFacility/MessageFacility.h"
4 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
5 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
6 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
7 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
8 
9 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
10 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
11 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
12 
13 #include <toolbox/fsm/FailedEvent.h>
14 
15 #include <xdaq/NamespaceURI.h>
16 #include <xoap/Method.h>
17 
18 #include <memory>
19 #include "messagefacility/MessageLogger/MessageLogger.h"
20 #include "artdaq/DAQdata/configureMessageFacility.hh"
21 #include "artdaq/DAQrate/quiet_mpi.hh"
22 #include "cetlib/exception.h"
23 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
24 #include "fhiclcpp/make_ParameterSet.h"
25 
26 #include <fstream>
27 #include <iostream>
28 #include <cassert>
29 
30 using namespace ots;
31 
32 XDAQ_INSTANTIATOR_IMPL(AggregatorApp)
33 
34 //========================================================================================================================
35 AggregatorApp::AggregatorApp(xdaq::ApplicationStub * s) throw (xdaq::exception::Exception)
36 : xdaq::Application (s)
37 , SOAPMessenger (this)
38 , stateMachineWorkLoopManager_(toolbox::task::bind(this, &AggregatorApp::stateMachineThread, "StateMachine"))
39 , stateMachineSemaphore_ (toolbox::BSem::FULL)
40 , theConfigurationManager_ (new ConfigurationManager)//(Singleton<ConfigurationManager>::getInstance()) //I always load the full config but if I want to load a partial configuration (new ConfigurationManager)
41 , XDAQContextConfigurationName_(theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getConfigurationName())
42 , supervisorConfigurationPath_ ("INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and supervisorApplicationUID_")
43 , supervisorContextUID_ ("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
44 , supervisorApplicationUID_ ("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
45 {
46  INIT_MF("AggregatorApp");
47  xgi::bind (this, &AggregatorApp::Default, "Default" );
48  xgi::bind (this, &AggregatorApp::stateMachineXgiHandler, "StateMachineXgiHandler");
49 
50  xoap::bind(this, &AggregatorApp::stateMachineStateRequest, "StateMachineStateRequest", XDAQ_NS_URI );
51  xoap::bind(this, &AggregatorApp::stateMachineErrorMessageRequest, "StateMachineErrorMessageRequest", XDAQ_NS_URI );
52 
53  try
54  {
55  supervisorContextUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getContextUID(getApplicationContext()->getContextDescriptor()->getURL());
56  }
57  catch(...)
58  {
59  __COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Context Group." <<
60  " The XDAQContextConfigurationName = " << XDAQContextConfigurationName_ <<
61  ". The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
62  throw;
63  }
64  try
65  {
66  supervisorApplicationUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getApplicationUID
67  (
68  getApplicationContext()->getContextDescriptor()->getURL(),
69  getApplicationDescriptor()->getLocalId()
70  );
71  }
72  catch(...)
73  {
74  __COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Application Group."
75  << " The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
76  throw;
77  }
78  supervisorConfigurationPath_ = "/" + supervisorContextUID_ + "/LinkToApplicationConfiguration/" + supervisorApplicationUID_ + "/LinkToSupervisorConfiguration";
79 
80  setStateMachineName(supervisorApplicationUID_);
81  init();
82 }
83 
84 //========================================================================================================================
85 AggregatorApp::~AggregatorApp(void)
86 {
87  destroy();
88 }
89 //========================================================================================================================
90 void AggregatorApp::init(void)
91 {
92  std::cout << __COUT_HDR_FL__ << "ARTDAQAGGREGATOR SUPERVISOR INIT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
93  theSupervisorDescriptorInfo_.init(getApplicationContext());
94  artdaq::configureMessageFacility("aggregator");
95 
96  // initialization
97 
98  int const wanted_threading_level { MPI_THREAD_MULTIPLE };
99  //int const wanted_threading_level { MPI_THREAD_FUNNELED };
100 
101  MPI_Comm local_group_comm;
102 
103  try
104  {
105  mpiSentry_.reset( new artdaq::MPISentry(0, 0, wanted_threading_level, artdaq::TaskType::AggregatorTask, local_group_comm) );
106  }
107  catch (cet::exception& errormsg)
108  {
109  mf::LogError("AggregatorMain") << errormsg ;
110  mf::LogError("AggregatorMain") << "MPISentry error encountered in AggregatorMain; exiting...";
111  throw errormsg;
112  }
113 
114  std::cout << __COUT_HDR_FL__ << "ARTDAQAGGREGATOR SUPERVISOR INIT4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
115  std::string name = "Aggregator";
116  unsigned short port = 5300;
117 // artdaq::setMsgFacAppName(supervisorApplicationUID_, port);
118  artdaq::setMsgFacAppName(name, port);
119 // mf::LogDebug(supervisorApplicationUID_) << "artdaq version " <<
120  mf::LogDebug(name + "Supervisor") << "artdaq version " <<
121  artdaq::GetPackageBuildInfo::getPackageBuildInfo().getPackageVersion()
122  << ", built " <<
123  artdaq::GetPackageBuildInfo::getPackageBuildInfo().getBuildTimestamp();
124 
125  // create the AggregatorInterface
126  theAggregatorInterface_ = new AggregatorInterface(mpiSentry_->rank(), name );
127  //theAggregatorInterface_ = new AggregatorInterface(mpiSentry_->rank(), local_group_comm, supervisorApplicationUID_ );
128 }
129 
130 //========================================================================================================================
131 void AggregatorApp::destroy(void)
132 {
133  delete theAggregatorInterface_;
134  //called by destructor
135  mpiSentry_.reset();
136 }
137 
138 //========================================================================================================================
139 void AggregatorApp::Default(xgi::Input * in, xgi::Output * out ) throw (xgi::exception::Exception)
140 {
141 
142  *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/AggregatorApp.html?urn=" <<
143  this->getApplicationDescriptor()->getLocalId() << "'></frameset></html>";
144 }
145 
146 //========================================================================================================================
147 void AggregatorApp::stateMachineXgiHandler(xgi::Input * in, xgi::Output * out ) throw (xgi::exception::Exception)
148 {}
149 
150 //========================================================================================================================
151 void AggregatorApp::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out ) throw (xgi::exception::Exception)
152 {}
153 
154 //========================================================================================================================
155 xoap::MessageReference AggregatorApp::stateMachineXoapHandler(xoap::MessageReference message ) throw (xoap::exception::Exception)
156 {
157  std::cout << __COUT_HDR_FL__ << "Soap Handler!" << std::endl;
158  stateMachineWorkLoopManager_.removeProcessedRequests();
159  stateMachineWorkLoopManager_.processRequest(message);
160  std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << std::endl;
161  return message;
162 }
163 
164 //========================================================================================================================
165 xoap::MessageReference AggregatorApp::stateMachineResultXoapHandler(xoap::MessageReference message ) throw (xoap::exception::Exception)
166 {
167  std::cout << __COUT_HDR_FL__ << "Soap Handler!" << std::endl;
168  //stateMachineWorkLoopManager_.removeProcessedRequests();
169  //stateMachineWorkLoopManager_.processRequest(message);
170  std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << std::endl;
171  return message;
172 }
173 
174 //========================================================================================================================
175 bool AggregatorApp::stateMachineThread(toolbox::task::WorkLoop* workLoop)
176 {
177  stateMachineSemaphore_.take();
178  std::cout << __COUT_HDR_FL__ << "Re-sending message..." << SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
179  std::string reply = send(this->getApplicationDescriptor(),stateMachineWorkLoopManager_.getMessage(workLoop));
180  stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
181  std::cout << __COUT_HDR_FL__ << "Done with message" << std::endl;
182  stateMachineSemaphore_.give();
183  return false;//execute once and automatically remove the workloop so in WorkLoopManager the try workLoop->remove(job_) could be commented out
184  //return true;//go on and then you must do the workLoop->remove(job_) in WorkLoopManager
185 }
186 
187 //========================================================================================================================
188 xoap::MessageReference AggregatorApp::stateMachineStateRequest(xoap::MessageReference message) throw (xoap::exception::Exception)
189 {
190  std::cout << __COUT_HDR_FL__ << theStateMachine_.getCurrentStateName() << std::endl;
191  return SOAPUtilities::makeSOAPMessageReference(theStateMachine_.getCurrentStateName());
192 }
193 
194 //========================================================================================================================
195 xoap::MessageReference AggregatorApp::stateMachineErrorMessageRequest(xoap::MessageReference message)
196 throw (xoap::exception::Exception)
197 {
198  __COUT__<< "theStateMachine_.getErrorMessage() = " << theStateMachine_.getErrorMessage() << std::endl;
199 
200  SOAPParameters retParameters;
201  retParameters.addParameter("ErrorMessage",theStateMachine_.getErrorMessage());
202  return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply",retParameters);
203 }
204 
205 //========================================================================================================================
206 void AggregatorApp::stateInitial(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
207 {
208 
209 }
210 
211 //========================================================================================================================
212 void AggregatorApp::stateHalted(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
213 {
214 
215 }
216 
217 //========================================================================================================================
218 void AggregatorApp::stateRunning(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
219 {
220 
221 }
222 
223 //========================================================================================================================
224 void AggregatorApp::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
225 {
226 
227 }
228 
229 //========================================================================================================================
230 void AggregatorApp::statePaused(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
231 {
232 
233 }
234 
235 //========================================================================================================================
236 void AggregatorApp::inError (toolbox::fsm::FiniteStateMachine & fsm) throw (toolbox::fsm::exception::Exception)
237 {
238  std::cout << __COUT_HDR_FL__ << "Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
239  //rcmsStateNotifier_.stateChanged("Error", "");
240 }
241 
242 //========================================================================================================================
243 void AggregatorApp::enteringError (toolbox::Event::Reference e) 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 
259 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/"+ "ARTDAQConfigurations/"
260 #define ARTDAQ_FILE_PREAMBLE "aggregator"
261 //========================================================================================================================
262 void AggregatorApp::transitionConfiguring(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
263 {
264 
265  std::cout << __COUT_HDR_FL__ << "ARTDAQAGGREGATOR SUPERVISOR CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
266  std::cout << __COUT_HDR_FL__ << SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) << std::endl;
267 
268  std::pair<std::string /*group name*/, ConfigurationGroupKey> theGroup(
269  SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
270  getParameters().getValue("ConfigurationGroupName"),
271  ConfigurationGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
272  getParameters().getValue("ConfigurationGroupKey")));
273 
274  __COUT__ << "Configuration group name: " << theGroup.first << " key: " <<
275  theGroup.second << std::endl;
276 
277  theConfigurationManager_->loadConfigurationGroup(
278  theGroup.first,
279  theGroup.second, true);
280 
281 
282  std::string path = "";
283  char* dirMRB = getenv("MRB_BUILDDIR");
284  char* dirP = getenv("OTSDAQ_DIR");
285 
286  if(dirMRB) { path = std::string(dirMRB) + "/otsdaq_demo/"; }
287  else if(dirP) { path = std::string(dirP) + "/"; }
288 
289  //Now that the configuration manager has all the necessary configurations I can create all objects dependent of the configuration
290  //std::string configString = "daq:{aggregator:{event_builder_count:2 event_queue_depth:20 event_queue_wait_time:5 expected_events_per_bunch:1 file_duration:0 file_event_count:0 file_size_MB:0 first_event_builder_rank:2 mpi_buffer_count:8 print_event_store_stats:true xmlrpc_client_list:\";http://localhost:5603/RPC2,3;http://localhost:5604/RPC2,3;http://localhost:5605/RPC2,4;http://localhost:5606/RPC2,4;http://localhost:5601/RPC2,5;http://localhost:5602/RPC2,5\"} max_fragment_size_words:2.097152e6} outputs:{normalOutput:{fileName:\"/data/otsdata/data/artdaqots_r%06r_sr%02s_%to.root\" module_type:\"RootOutput\"}} physics:{my_output_modules:[\"normalOutput\"] p2:[\"BuildInfo\"] producers:{BuildInfo:{instance_name:\"ArtdaqOts\" module_type:\"ArtdaqOtsBuildInfo\"}}} process_name:\"DAQAG\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\"} user:{NetMonTransportServiceInterface:{max_fragment_size_words:2.097152e6 service_provider:\"NetMonTransportService\"}}} source:{module_type:\"NetMonInput\"}";
291  //ONLY 1 BOARD READER
292  // std::string configString = "daq:{aggregator:{event_builder_count:1 event_queue_depth:20 event_queue_wait_time:5 expected_events_per_bunch:1 file_duration:0 file_event_count:0 file_size_MB:0 first_event_builder_rank:1 mpi_buffer_count:8 print_event_store_stats:true xmlrpc_client_list:\";http://localhost:5100/RPC2,3;http://localhost:5101/RPC2,3;http://localhost:5200/RPC2,4;http://localhost:5201/RPC2,4;http://localhost:5300/RPC2,5;http://localhost:5301/RPC2,5\"} max_fragment_size_words:2.097152e6} outputs:{normalOutput:{fileName:\""+path+"artdaqots_r%06r_sr%02s_%to.root\" module_type:\"RootOutput\"}} physics:{my_output_modules:[\"normalOutput\"] p2:[\"BuildInfo\"] a1:[\"wf\"] producers:{BuildInfo:{instance_name:\"ArtdaqOts\" module_type:\"ArtdaqOtsBuildInfo\"}} analyzers:{wf: {module_type:\"WFViewer\" fragment_ids:[0] fragment_type_labels:[ \"DataGen\" ] prescale:60 write_to_file:true fileName:\""+path+"otsdaqdemo_onmon.root\"}}} process_name:\"DAQAG\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\" errorOnFailureToPut: false} NetMonTransportServiceInterface:{max_fragment_size_words:2097152 service_provider:\"NetMonTransportService\"}} source:{module_type:\"NetMonInput\"}";
293  //2 BOARD READERS
294  //std::string configString = "daq:{aggregator:{event_builder_count:1 event_queue_depth:20 event_queue_wait_time:5 expected_events_per_bunch:1 file_duration:0 file_event_count:0 file_size_MB:0 first_event_builder_rank:1 mpi_buffer_count:8 print_event_store_stats:true xmlrpc_client_list:\";http://localhost:5100/RPC2,3;http://localhost:5101/RPC2,3;http://localhost:5200/RPC2,4;http://localhost:5201/RPC2,4;http://localhost:5300/RPC2,5;http://localhost:5301/RPC2,5\"} max_fragment_size_words:2.097152e6} outputs:{normalOutput:{fileName:\""+path+"artdaqots_r%06r_sr%02s_%to.root\" module_type:\"RootOutput\"}} physics:{my_output_modules:[\"normalOutput\"] p2:[\"BuildInfo\"] a1:[\"wf\"] producers:{BuildInfo:{instance_name:\"ArtdaqOts\" module_type:\"ArtdaqOtsBuildInfo\"}} analyzers:{wf: {module_type:\"WFViewer\" fragment_ids:[0] fragment_type_labels:[ \"DataGen\" ] prescale:60 write_to_file:true fileName:\""+path+"otsdaqdemo_onmon.root\"}}} process_name:\"DAQAG\" services:{Timing:{summaryOnly:true} scheduler:{fileMode:\"NOMERGE\" errorOnFailureToPut: false} NetMonTransportServiceInterface:{max_fragment_size_words:2097152 service_provider:\"NetMonTransportService\"}} source:{module_type:\"NetMonInput\"}";
295 
296  fhicl::ParameterSet pset;
297  //fhicl::make_ParameterSet(configString, pset);
298 
299  std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
300  std::string uid = theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getValue();
301 
302  __COUT__ << "uid: " << uid << std::endl;
303  for(unsigned int i=0;i<uid.size();++i)
304  if((uid[i] >= 'a' && uid[i] <= 'z') ||
305  (uid[i] >= 'A' && uid[i] <= 'Z') ||
306  (uid[i] >= '0' && uid[i] <= '9')) //only allow alpha numeric in file name
307  filename += uid[i];
308  filename += ".fcl";
309 
310 
311  __COUT__ << std::endl;
312  __COUT__ << std::endl;
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 
329  __COUT__ << fileFclString << std::endl;
330  fhicl::make_ParameterSet(fileFclString, pset);
331  //fhicl::make_ParameterSet(theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getNode("ConfigurationString").getValue<std::string>(), pset);
332 
333 
334  theAggregatorInterface_->configure(pset);
335  mf::LogInfo("AggregatorInterface") << "ARTDAQAGGREGATOR SUPERVISOR DONE CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
336 
337 }
338 
339 //========================================================================================================================
340 void AggregatorApp::transitionHalting(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
341 {
342  theAggregatorInterface_->halt();
343 }
344 
345 //========================================================================================================================
346 void AggregatorApp::transitionInitializing(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
347 {
348 
349 }
350 
351 //========================================================================================================================
352 void AggregatorApp::transitionPausing(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
353 {
354  theAggregatorInterface_->pause();
355 }
356 
357 //========================================================================================================================
358 void AggregatorApp::transitionResuming(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
359 {
360  theAggregatorInterface_->resume();
361 }
362 
363 //========================================================================================================================
364 void AggregatorApp::transitionStarting(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
365 {
366  theAggregatorInterface_->start(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue("RunNumber"));
367 }
368 
369 //========================================================================================================================
370 void AggregatorApp::transitionStopping(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
371 {
372  theAggregatorInterface_->stop();
373  theAggregatorInterface_->halt();
374 }