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