otsdaq  v1_01_03
 All Classes Namespaces Functions
CoreSupervisorBase.cc
1 #include "otsdaq-core/CoreSupervisors/CoreSupervisorBase.h"
2 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
3 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
4 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
5 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
6 //#include "otsdaq-core/Singleton/Singleton.h"
7 //#include "otsdaq-core/WorkLoopManager/WorkLoopManager.h"
8 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
9 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
10 #include "otsdaq-core/ConfigurationInterface/ConfigurationTree.h"
11 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
12 #include "otsdaq-core/MessageFacility/MessageFacility.h"
13 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
14 #include "otsdaq-core/FiniteStateMachine/VStateMachine.h"
15 #include "otsdaq-core/FECore/FEVInterfacesManager.h"
16 
17 
18 #include <toolbox/fsm/FailedEvent.h>
19 
20 #include <xdaq/NamespaceURI.h>
21 #include <xoap/Method.h>
22 
23 #include <iostream>
24 
25 using namespace ots;
26 
27 //XDAQ_INSTANTIATOR_IMPL(CoreSupervisorBase)
28 
29 //========================================================================================================================
30 CoreSupervisorBase::CoreSupervisorBase(xdaq::ApplicationStub * s)
31 throw (xdaq::exception::Exception)
32 : xdaq::Application (s)
33 , SOAPMessenger (this)
34 , stateMachineWorkLoopManager_ (toolbox::task::bind(this, &CoreSupervisorBase::stateMachineThread, "StateMachine"))
35 , stateMachineSemaphore_ (toolbox::BSem::FULL)
36 , theConfigurationManager_ (new ConfigurationManager)//(Singleton<ConfigurationManager>::getInstance()) //I always load the full config but if I want to load a partial configuration (new ConfigurationManager)
37 , XDAQContextConfigurationName_ (theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getConfigurationName())
38 , supervisorConfigurationPath_ ("INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and supervisorApplicationUID_")
39 , supervisorContextUID_ ("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
40 , supervisorApplicationUID_ ("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
41 , supervisorClass_ (getApplicationDescriptor()->getClassName())
42 , supervisorClassNoNamespace_ (supervisorClass_.substr(supervisorClass_.find_last_of(":")+1, supervisorClass_.length()-supervisorClass_.find_last_of(":")))
43 {
44  __MOUT__ << "Begin!" << std::endl;
45  __MOUT__ << "Begin!" << std::endl;
46  __MOUT__ << "Begin!" << std::endl;
47  __MOUT__ << "Begin!" << std::endl;
48  __MOUT__ << "Begin!" << std::endl;
49  xgi::bind (this, &CoreSupervisorBase::Default, "Default" );
50  xgi::bind (this, &CoreSupervisorBase::stateMachineXgiHandler, "StateMachineXgiHandler");
51  xgi::bind (this, &CoreSupervisorBase::request, "Request");
52 
53  xoap::bind(this, &CoreSupervisorBase::stateMachineStateRequest, "StateMachineStateRequest", XDAQ_NS_URI );
54  xoap::bind(this, &CoreSupervisorBase::stateMachineErrorMessageRequest, "StateMachineErrorMessageRequest", XDAQ_NS_URI );
55  xoap::bind(this, &CoreSupervisorBase::macroMakerSupervisorRequest, "MacroMakerSupervisorRequest", XDAQ_NS_URI );
56 
57  try
58  {
59  supervisorContextUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getContextUID(getApplicationContext()->getContextDescriptor()->getURL());
60  }
61  catch(...)
62  {
63  __MOUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Context Group." <<
64  " The XDAQContextConfigurationName = " << XDAQContextConfigurationName_ <<
65  ". The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
66  throw;
67  }
68  try
69  {
70  supervisorApplicationUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getApplicationUID
71  (
72  getApplicationContext()->getContextDescriptor()->getURL(),
73  getApplicationDescriptor()->getLocalId()
74  );
75  }
76  catch(...)
77  {
78  __MOUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Application Group."
79  << " The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
80  throw;
81  }
82  supervisorConfigurationPath_ = "/" + supervisorContextUID_ + "/LinkToApplicationConfiguration/" + supervisorApplicationUID_ + "/LinkToSupervisorConfiguration";
83 
84  setStateMachineName(supervisorApplicationUID_);
85  __MOUT__ << "Done!" << std::endl;
86  __MOUT__ << "Done!" << std::endl;
87  __MOUT__ << "Done!" << std::endl;
88  __MOUT__ << "Done!" << std::endl;
89 
90  init();
91 }
92 
93 //========================================================================================================================
94 CoreSupervisorBase::~CoreSupervisorBase(void)
95 {
96  destroy();
97 }
98 //========================================================================================================================
99 void CoreSupervisorBase::init(void)
100 {
101  //This can be done in the constructor because when you start xdaq it loads the configuration that can't be changed while running!
102  __MOUT__ << "CONTEXT!" << std::endl;
103  __MOUT__ << "CONTEXT!" << std::endl;
104  __MOUT__ << "CONTEXT!" << std::endl;
105  supervisorDescriptorInfo_.init(getApplicationContext());
106  __MOUT__ << "Done!" << std::endl;
107  __MOUT__ << "Done!" << std::endl;
108  __MOUT__ << "Done!" << std::endl;
109  //RunControlStateMachine::reset();
110 }
111 
112 //========================================================================================================================
113 void CoreSupervisorBase::destroy(void)
114 {
115  for(auto& it: theStateMachineImplementation_)
116  delete it;
117  theStateMachineImplementation_.clear();
118 }
119 
120 //========================================================================================================================
121 void CoreSupervisorBase::Default(xgi::Input * in, xgi::Output * out )
122 throw (xgi::exception::Exception)
123 {
124 
125 
126  __MOUT__<< "Supervisor class " << supervisorClass_ << std::endl;
127 
128  *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/" << supervisorClassNoNamespace_ << "Supervisor.html?urn=" <<
129  this->getApplicationDescriptor()->getLocalId() << //getenv((theSupervisorClassNoNamespace_ + "_SUPERVISOR_ID").c_str()) <<
130  "'></frameset></html>";
131 }
132 
133 //========================================================================================================================
134 void CoreSupervisorBase::request(xgi::Input * in, xgi::Output * out )
135 throw (xgi::exception::Exception)
136 {
137 
138 
139  cgicc::Cgicc cgi(in);
140  std::string write = CgiDataUtilities::getOrPostData(cgi,"write");
141  std::string addr = CgiDataUtilities::getOrPostData(cgi,"addr");
142  std::string data = CgiDataUtilities::getOrPostData(cgi,"data");
143 
144  __MOUT__<< "write " << write << " addr: " << addr << " data: " << data << std::endl;
145 
146  unsigned long long int addr64,data64;
147  sscanf(addr.c_str(),"%llu",&addr64);
148  sscanf(data.c_str(),"%llu",&data64);
149  __MOUT__<< "write " << write << " addr: " << addr64 << " data: " << data64 << std::endl;
150 
151  *out << "done";
152 }
153 
154 //========================================================================================================================
155 void CoreSupervisorBase::stateMachineXgiHandler(xgi::Input * in, xgi::Output * out )
156 throw (xgi::exception::Exception)
157 {}
158 
159 //========================================================================================================================
160 void CoreSupervisorBase::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out )
161 throw (xgi::exception::Exception)
162 {}
163 
164 //========================================================================================================================
165 xoap::MessageReference CoreSupervisorBase::stateMachineXoapHandler(xoap::MessageReference message )
166 throw (xoap::exception::Exception)
167 {
168  __MOUT__<< "Soap Handler!" << std::endl;
169  stateMachineWorkLoopManager_.removeProcessedRequests();
170  stateMachineWorkLoopManager_.processRequest(message);
171  __MOUT__<< "Done - Soap Handler!" << std::endl;
172  return message;
173 }
174 
175 //========================================================================================================================
176 xoap::MessageReference CoreSupervisorBase::stateMachineResultXoapHandler(xoap::MessageReference message )
177 throw (xoap::exception::Exception)
178 {
179  __MOUT__<< "Soap Handler!" << std::endl;
180  //stateMachineWorkLoopManager_.removeProcessedRequests();
181  //stateMachineWorkLoopManager_.processRequest(message);
182  __MOUT__<< "Done - Soap Handler!" << std::endl;
183  return message;
184 }
185 
186 //========================================================================================================================
187 bool CoreSupervisorBase::stateMachineThread(toolbox::task::WorkLoop* workLoop)
188 {
189  stateMachineSemaphore_.take();
190  __MOUT__<< "Re-sending message..." << SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
191  std::string reply = send(this->getApplicationDescriptor(),stateMachineWorkLoopManager_.getMessage(workLoop));
192  stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
193  __MOUT__<< "Done with message" << std::endl;
194  stateMachineSemaphore_.give();
195  return false;//execute once and automatically remove the workloop so in WorkLoopManager the try workLoop->remove(job_) could be commented out
196  //return true;//go on and then you must do the workLoop->remove(job_) in WorkLoopManager
197 }
198 
199 //========================================================================================================================
200 xoap::MessageReference CoreSupervisorBase::stateMachineStateRequest(xoap::MessageReference message)
201 throw (xoap::exception::Exception)
202 {
203  __MOUT__<< "theStateMachine_.getCurrentStateName() = " << theStateMachine_.getCurrentStateName() << std::endl;
204  return SOAPUtilities::makeSOAPMessageReference(theStateMachine_.getCurrentStateName());
205 }
206 
207 //========================================================================================================================
208 xoap::MessageReference CoreSupervisorBase::stateMachineErrorMessageRequest(xoap::MessageReference message)
209 throw (xoap::exception::Exception)
210 {
211  __MOUT__<< "theStateMachine_.getErrorMessage() = " << theStateMachine_.getErrorMessage() << std::endl;
212 
213  SOAPParameters retParameters;
214  retParameters.addParameter("ErrorMessage",theStateMachine_.getErrorMessage());
215  return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply",retParameters);
216 }
217 
218 //========================================================================================================================
219 // macroMakerSupervisorRequest
220 // Handles all MacroMaker Requests:
221 // - GetInterfaces (returns interface type and id)
222 //
223 // Note: this code assumes a CoreSupervisorBase has only one
224 // FEVInterfacesManager in its vector of state machines
225 xoap::MessageReference CoreSupervisorBase::macroMakerSupervisorRequest(
226  xoap::MessageReference message)
227 throw (xoap::exception::Exception)
228 {
229  __MOUT__<< "$$$$$$$$$$$$$$$$$" << std::endl;
230 
231  //locate theFEInterfacesManager in state machines vector
232  FEVInterfacesManager* theFEInterfacesManager = 0;
233  for(unsigned int i = 0; i<theStateMachineImplementation_.size();++i)
234  {
235  try
236  {
237  theFEInterfacesManager =
238  dynamic_cast<FEVInterfacesManager*>(theStateMachineImplementation_[i]);
239  if(!theFEInterfacesManager) throw std::runtime_error(""); //dynamic_cast returns null pointer on failure
240  __MOUT__ << "State Machine " << i << " WAS of type FEVInterfacesManager" << std::endl;
241 
242  break;
243  }
244  catch(...)
245  {
246  __MOUT__ << "State Machine " << i << " was NOT of type FEVInterfacesManager" << std::endl;
247  }
248  }
249 
250 
251  __MOUT__ << "theFEInterfacesManager pointer = " << theFEInterfacesManager << std::endl;
252 
253  //receive request parameters
254  SOAPParameters parameters;
255  parameters.addParameter("Request");
256  parameters.addParameter("InterfaceID");
257 
258  //params for universal commands
259  parameters.addParameter("Address");
260  parameters.addParameter("Data");
261 
262  //params for running macros
263  parameters.addParameter("feMacroName");
264  parameters.addParameter("inputArgs");
265  parameters.addParameter("outputArgs");
266 
267  SOAPMessenger::receive(message, parameters);
268  std::string request = parameters.getValue("Request");
269  std::string addressStr = parameters.getValue("Address");
270  std::string dataStr = parameters.getValue("Data");
271  std::string InterfaceID = parameters.getValue("InterfaceID");
272 
273  __MOUT__<< "request: " << request << std::endl;
274 
275  __MOUT__<< "Address: " << addressStr << " Data: "
276  << dataStr << " InterfaceID: " << InterfaceID << std::endl;
277 
278  SOAPParameters retParameters;
279 
280  if(request == "GetInterfaces")
281  {
282  if(theFEInterfacesManager)
283  retParameters.addParameter("FEList",theFEInterfacesManager->getFEListString(
284  std::to_string(getApplicationDescriptor()->getLocalId())));
285  else
286  retParameters.addParameter("FEList","");
287 
288  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "Response",
289  retParameters);
290  }
291  else if(request == "UniversalWrite")
292  {
293  if(!theFEInterfacesManager)
294  {
295  __MOUT_INFO__ << "No FE Interface Manager! (So no write occurred)" << std::endl;
296  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "DataWritten",retParameters);
297  }
298 
299  // parameters interface index!
300  //unsigned int index = stoi(indexStr); // As long as the supervisor has only one interface, this index will remain 0?
301 
302 
303 
304  __MOUT__<< "theFEInterfacesManager->getInterfaceUniversalAddressSize(index) " <<
305  theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) << std::endl;
306  __MOUT__<< "theFEInterfacesManager->getInterfaceUniversalDataSize(index) " <<
307  theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) << std::endl;
308 
309  //Converting std::string to char*
310  //char address
311 
312  char tmpHex[3]; //for use converting hex to binary
313  tmpHex[2] = '\0';
314 
315 
316  __MOUT__<< "Translating address: ";
317 
318  char address[theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID)];
319 
320  if(addressStr.size()%2) //if odd, make even
321  addressStr = "0" + addressStr;
322  unsigned int i=0;
323  for(;i<addressStr.size() &&
324  i/2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) ; i+=2)
325  {
326  tmpHex[0] = addressStr[addressStr.size()-1-i-1];
327  tmpHex[1] = addressStr[addressStr.size()-1-i];
328  sscanf(tmpHex,"%hhX",(unsigned char*)&address[i/2]);
329  printf("%2.2X",(unsigned char)address[i/2]);
330  }
331  //finish and fill with 0s
332  for(;i/2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) ; i+=2)
333  {
334  address[i/2] = 0;
335  printf("%2.2X",(unsigned char)address[i/2]);
336  }
337 
338  std::cout << std::endl;
339 
340  __MOUT__<< "Translating data: ";
341 
342  char data[theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID)];
343 
344  if(dataStr.size()%2) //if odd, make even
345  dataStr = "0" + dataStr;
346 
347  i=0;
348  for(;i<dataStr.size() &&
349  i/2 < theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) ; i+=2)
350  {
351  tmpHex[0] = dataStr[dataStr.size()-1-i-1];
352  tmpHex[1] = dataStr[dataStr.size()-1-i];
353  sscanf(tmpHex,"%hhX",(unsigned char*)&data[i/2]);
354  printf("%2.2X",(unsigned char)data[i/2]);
355  }
356  //finish and fill with 0s
357  for(;i/2 < theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) ; i+=2)
358  {
359  data[i/2] = 0;
360  printf("%2.2X",(unsigned char)data[i/2]);
361  }
362 
363  std::cout << std::endl;
364 
365  //char* address = new char[addressStr.size() + 1];
366  //std::copy(addressStr.begin(), addressStr.end(), address);
367  // address[addressStr.size()] = '\0';
368  // char* data = new char[dataStr.size() + 1];
369  // std::copy(dataStr.begin(), dataStr.end(), data);
370  // data[dataStr.size()] = '\0';
371 
372  theFEInterfacesManager->universalWrite(InterfaceID,address,data);
373 
374  //delete[] address;
375  //delete[] data;
376 
377  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "DataWritten",retParameters);
378  }
379  else if(request == "UniversalRead")
380  {
381  if(!theFEInterfacesManager)
382  {
383  __MOUT_INFO__ << "No FE Interface Manager! (So no read occurred)" << std::endl;
384  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "aa",retParameters);
385  }
386 
387  // parameters interface index!
388  // parameter address and data
389  //unsigned int index = stoi(indexStr); // As long as the supervisor has only one interface, this index will remain 0?
390 
391  __MOUT__<< "theFEInterfacesManager->getInterfaceUniversalAddressSize(index) "
392  << theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) << std::endl;
393  __MOUT__<< "theFEInterfacesManager->getInterfaceUniversalDataSize(index) "
394  <<theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) << std::endl;
395 
396  char tmpHex[3]; //for use converting hex to binary
397  tmpHex[2] = '\0';
398 
399 
400  __MOUT__<< "Translating address: ";
401 
402  char address[theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID)];
403 
404  if(addressStr.size()%2) //if odd, make even
405  addressStr = "0" + addressStr;
406 
407  unsigned int i=0;
408  for(;i<addressStr.size() &&
409  i/2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) ; i+=2)
410  {
411  tmpHex[0] = addressStr[addressStr.size()-1-i-1];
412  tmpHex[1] = addressStr[addressStr.size()-1-i];
413  sscanf(tmpHex,"%hhX",(unsigned char*)&address[i/2]);
414  printf("%2.2X",(unsigned char)address[i/2]);
415  }
416  //finish and fill with 0s
417  for(;i/2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) ; i+=2)
418  {
419  address[i/2] = 0;
420  printf("%2.2X",(unsigned char)address[i/2]);
421  }
422 
423  std::cout << std::endl;
424 
425  unsigned int dataSz = theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID);
426  char data[dataSz];
427 
428 
429  // std::string result = theFEInterfacesManager->universalRead(index,address,data);
430  // __MOUT__<< result << std::endl << std::endl;
431 
432  if(theFEInterfacesManager->universalRead(InterfaceID, address, data) < 0)
433  {
434  retParameters.addParameter("dataResult","Time Out Error");
435  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "aa",retParameters);
436  }
437 
438  //if dataSz is less than 8 show what the unsigned number would be
439  if(dataSz <= 8)
440  {
441  std::string str8(data);
442  str8.resize(8);
443  __MOUT__<< "decResult[" << dataSz << " bytes]: " <<
444  *((unsigned long long *)(&str8[0])) << std::endl;
445 
446  }
447 
448  char hexResult[dataSz*2+1];
449  //go through each byte and convert it to hex value (i.e. 2 0-F chars)
450  //go backwards through source data since should be provided in host order
451  // (i.e. a cast to unsigned long long should acquire expected value)
452  for(unsigned int i=0;i<dataSz;++i)
453  {
454  sprintf(&hexResult[i*2],"%2.2X", (unsigned char)data[dataSz-1-i]);
455  }
456 
457  __MOUT__<< "hexResult[" << strlen(hexResult) << " nibbles]: " << std::string(hexResult) << std::endl;
458 
459 
460 
461  retParameters.addParameter("dataResult",hexResult);
462  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "aa",retParameters);
463 
464  }
465  else if(request == "GetInterfaceMacros")
466  {
467  if(theFEInterfacesManager)
468  retParameters.addParameter("FEMacros",theFEInterfacesManager->getFEMacrosString(
469  std::to_string(getApplicationDescriptor()->getLocalId())));
470  else
471  retParameters.addParameter("FEMacros","");
472 
473  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "Response",
474  retParameters);
475  }
476  else if(request == "RunInterfaceMacro")
477  {
478  if(!theFEInterfacesManager)
479  {
480  retParameters.addParameter("success","0");
481  retParameters.addParameter("outputArgs","");
482  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "Response",
483  retParameters);
484  }
485 
486  std::string feMacroName = parameters.getValue("feMacroName");
487  std::string inputArgs = parameters.getValue("inputArgs");
488  std::string outputArgs = parameters.getValue("outputArgs");
489 
490  //outputArgs must be filled with the proper argument names
491  // and then the response output values will be returned in the string.
492  bool success = true;
493  try
494  {
495  theFEInterfacesManager->runFEMacro(InterfaceID,feMacroName,inputArgs,outputArgs);
496  }
497  catch(std::runtime_error &e)
498  {
499  __SS__ << "In Supervisor with LID=" << getApplicationDescriptor()->getLocalId()
500  << " the FE Macro named '" << feMacroName << "' with tartget FE '"
501  << InterfaceID << "' failed. Here is the error:\n\n" << e.what() << std::endl;
502  __MOUT_ERR__ << "\n" << ss.str();
503  success = false;
504  outputArgs = ss.str();
505  }
506 
507 
508  retParameters.addParameter("success",success?"1":"0");
509  retParameters.addParameter("outputArgs",outputArgs);
510 
511  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "Response",
512  retParameters);
513  }
514  else
515  {
516  __MOUT_WARN__ << "Unrecognized request received! '" << request << "'" << std::endl;
517  }
518 
519 
520  return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ + "FailRequest",retParameters);
521 }
522 
523 //========================================================================================================================
524 void CoreSupervisorBase::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
525 throw (toolbox::fsm::exception::Exception)
526 {
527  __MOUT__ << "CoreSupervisorBase::stateInitial" << std::endl;
528 }
529 
530 //========================================================================================================================
531 void CoreSupervisorBase::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
532 throw (toolbox::fsm::exception::Exception)
533 {
534  __MOUT__ << "CoreSupervisorBase::stateHalted" << std::endl;
535 }
536 
537 //========================================================================================================================
538 void CoreSupervisorBase::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
539 throw (toolbox::fsm::exception::Exception)
540 {
541  __MOUT__ << "CoreSupervisorBase::stateRunning" << std::endl;
542 }
543 
544 //========================================================================================================================
545 void CoreSupervisorBase::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
546 throw (toolbox::fsm::exception::Exception)
547 {
548  __MOUT__ << "CoreSupervisorBase::stateConfigured" << std::endl;
549 }
550 
551 //========================================================================================================================
552 void CoreSupervisorBase::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
553 throw (toolbox::fsm::exception::Exception)
554 {
555  __MOUT__ << "CoreSupervisorBase::statePaused" << std::endl;
556 }
557 
558 //========================================================================================================================
559 void CoreSupervisorBase::inError (toolbox::fsm::FiniteStateMachine & fsm)
560 throw (toolbox::fsm::exception::Exception)
561 {
562  __MOUT__<< "Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
563  //rcmsStateNotifier_.stateChanged("Error", "");
564 }
565 
566 //========================================================================================================================
567 void CoreSupervisorBase::enteringError (toolbox::Event::Reference e)
568 throw (toolbox::fsm::exception::Exception)
569 {
570  __MOUT__<< "Fsm current state: " << theStateMachine_.getCurrentStateName()
571  << "\n\nError Message: " <<
572  theStateMachine_.getErrorMessage() << std::endl;
573  toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
574  std::ostringstream error;
575  error << "Failure performing transition from "
576  << failedEvent.getFromState()
577  << " to "
578  << failedEvent.getToState()
579  << " exception: " << failedEvent.getException().what();
580  __MOUT_ERR__<< error.str() << std::endl;
581  //diagService_->reportError(errstr.str(),DIAGERROR);
582 
583 }
584 
585 //========================================================================================================================
586 void CoreSupervisorBase::transitionConfiguring(toolbox::Event::Reference e)
587 throw (toolbox::fsm::exception::Exception)
588 {
589  __MOUT__ << "transitionConfiguring" << std::endl;
590 
591  std::pair<std::string /*group name*/, ConfigurationGroupKey> theGroup(
592  SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
593  getParameters().getValue("ConfigurationGroupName"),
594  ConfigurationGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
595  getParameters().getValue("ConfigurationGroupKey")));
596 
597  __MOUT__ << "Configuration group name: " << theGroup.first << " key: " <<
598  theGroup.second << std::endl;
599 
600  theConfigurationManager_->loadConfigurationGroup(
601  theGroup.first,
602  theGroup.second, true);
603 
604 
605  //Now that the configuration manager has all the necessary configurations I can create all objects dependent of the configuration
606 
607  try
608  {
609  for(auto& it: theStateMachineImplementation_)
610  it->configure();
611  }
612  catch(const std::runtime_error& e)
613  {
614  __SS__ << "Error was caught while configuring: " << e.what() << std::endl;
615  __MOUT_ERR__ << "\n" << ss.str();
616  theStateMachine_.setErrorMessage(ss.str());
617  throw toolbox::fsm::exception::Exception(
618  "Transition Error" /*name*/,
619  ss.str() /* message*/,
620  "CoreSupervisorBase::transitionConfiguring" /*module*/,
621  __LINE__ /*line*/,
622  __FUNCTION__ /*function*/
623  );
624  }
625 
626 }
627 
628 //========================================================================================================================
629 //transitionHalting
630 // Ignore errors if coming from Failed state
631 void CoreSupervisorBase::transitionHalting(toolbox::Event::Reference e)
632 throw (toolbox::fsm::exception::Exception)
633 {
634  __MOUT__ << "transitionHalting" << std::endl;
635 
636  for(auto& it: theStateMachineImplementation_)
637  {
638  try
639  {
640  it->halt();
641  }
642  catch(const std::runtime_error& e)
643  {
644  //if halting from Failed state, then ignore errors
645  if(theStateMachine_.getProvenanceStateName() ==
646  RunControlStateMachine::FAILED_STATE_NAME)
647  {
648  __MOUT_INFO__ << "Error was caught while halting (but ignoring because previous state was '" <<
649  RunControlStateMachine::FAILED_STATE_NAME << "'): " << e.what() << std::endl;
650  }
651  else //if not previously in Failed state, then fail
652  {
653  __SS__ << "Error was caught while halting: " << e.what() << std::endl;
654  __MOUT_ERR__ << "\n" << ss.str();
655  theStateMachine_.setErrorMessage(ss.str());
656  throw toolbox::fsm::exception::Exception(
657  "Transition Error" /*name*/,
658  ss.str() /* message*/,
659  "CoreSupervisorBase::transitionHalting" /*module*/,
660  __LINE__ /*line*/,
661  __FUNCTION__ /*function*/
662  );
663  }
664  }
665  }
666 }
667 
668 //========================================================================================================================
669 void CoreSupervisorBase::transitionInitializing(toolbox::Event::Reference e)
670 throw (toolbox::fsm::exception::Exception)
671 {
672  __MOUT__ << "transitionInitializing" << std::endl;
673 
674  // for(auto& it: theStateMachineImplementation_)
675  //it->initialize();
676 }
677 
678 //========================================================================================================================
679 void CoreSupervisorBase::transitionPausing(toolbox::Event::Reference e)
680 throw (toolbox::fsm::exception::Exception)
681 {
682  __MOUT__ << "transitionPausing" << std::endl;
683 
684  try
685  {
686  for(auto& it: theStateMachineImplementation_)
687  it->pause();
688  }
689  catch(const std::runtime_error& e)
690  {
691  __SS__ << "Error was caught while pausing: " << e.what() << std::endl;
692  __MOUT_ERR__ << "\n" << ss.str();
693  theStateMachine_.setErrorMessage(ss.str());
694  throw toolbox::fsm::exception::Exception(
695  "Transition Error" /*name*/,
696  ss.str() /* message*/,
697  "CoreSupervisorBase::transitionPausing" /*module*/,
698  __LINE__ /*line*/,
699  __FUNCTION__ /*function*/
700  );
701  }
702 }
703 
704 //========================================================================================================================
705 void CoreSupervisorBase::transitionResuming(toolbox::Event::Reference e)
706 throw (toolbox::fsm::exception::Exception)
707 {
708  //NOTE: I want to first start the data manager first if this is a FEDataManagerSupervisor
709 
710 
711  __MOUT__ << "transitionResuming" << std::endl;
712 
713  try
714  {
715  for(auto& it: theStateMachineImplementation_)
716  it->resume();
717  }
718  catch(const std::runtime_error& e)
719  {
720  __SS__ << "Error was caught while resuming: " << e.what() << std::endl;
721  __MOUT_ERR__ << "\n" << ss.str();
722  theStateMachine_.setErrorMessage(ss.str());
723  throw toolbox::fsm::exception::Exception(
724  "Transition Error" /*name*/,
725  ss.str() /* message*/,
726  "CoreSupervisorBase::transitionResuming" /*module*/,
727  __LINE__ /*line*/,
728  __FUNCTION__ /*function*/
729  );
730  }
731 }
732 
733 //========================================================================================================================
734 void CoreSupervisorBase::transitionStarting(toolbox::Event::Reference e)
735 throw (toolbox::fsm::exception::Exception)
736 {
737 
738  //NOTE: I want to first start the data manager first if this is a FEDataManagerSupervisor
739 
740  __MOUT__ << "transitionStarting" << std::endl;
741 
742  try
743  {
744  for(auto& it: theStateMachineImplementation_)
745  it->start(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue("RunNumber"));
746  }
747  catch(const std::runtime_error& e)
748  {
749  __SS__ << "Error was caught while starting: " << e.what() << std::endl;
750  __MOUT_ERR__ << "\n" << ss.str();
751  theStateMachine_.setErrorMessage(ss.str());
752  throw toolbox::fsm::exception::Exception(
753  "Transition Error" /*name*/,
754  ss.str() /* message*/,
755  "CoreSupervisorBase::transitionStarting" /*module*/,
756  __LINE__ /*line*/,
757  __FUNCTION__ /*function*/
758  );
759  }
760 }
761 
762 //========================================================================================================================
763 void CoreSupervisorBase::transitionStopping(toolbox::Event::Reference e)
764 throw (toolbox::fsm::exception::Exception)
765 {
766  __MOUT__ << "transitionStopping" << std::endl;
767 
768  try
769  {
770  for(auto& it: theStateMachineImplementation_)
771  it->stop();
772  }
773  catch(const std::runtime_error& e)
774  {
775  __SS__ << "Error was caught while pausing: " << e.what() << std::endl;
776  __MOUT_ERR__ << "\n" << ss.str();
777  theStateMachine_.setErrorMessage(ss.str());
778  throw toolbox::fsm::exception::Exception(
779  "Transition Error" /*name*/,
780  ss.str() /* message*/,
781  "CoreSupervisorBase::transitionStopping" /*module*/,
782  __LINE__ /*line*/,
783  __FUNCTION__ /*function*/
784  );
785  }
786 }