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"
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"
18 #include <toolbox/fsm/FailedEvent.h>
20 #include <xdaq/NamespaceURI.h>
21 #include <xoap/Method.h>
30 CoreSupervisorBase::CoreSupervisorBase(xdaq::ApplicationStub * s)
31 throw (xdaq::exception::Exception)
32 : xdaq::Application (s)
34 , stateMachineWorkLoopManager_ (toolbox::task::bind(
this, &CoreSupervisorBase::stateMachineThread,
"StateMachine"))
35 , stateMachineSemaphore_ (toolbox::BSem::FULL)
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(
":")))
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");
53 xoap::bind(
this, &CoreSupervisorBase::stateMachineStateRequest,
"StateMachineStateRequest", XDAQ_NS_URI );
54 xoap::bind(
this, &CoreSupervisorBase::macroMakerSupervisorRequest,
"MacroMakerSupervisorRequest", XDAQ_NS_URI );
58 supervisorContextUID_ = theConfigurationManager_->__GET_CONFIG__(
XDAQContextConfiguration)->getContextUID(getApplicationContext()->getContextDescriptor()->getURL());
62 __MOUT_ERR__ <<
"XDAQ Supervisor could not access it's configuration through the Configuration Context Group." <<
63 " The XDAQContextConfigurationName = " << XDAQContextConfigurationName_ <<
64 ". The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
71 getApplicationContext()->getContextDescriptor()->getURL(),
72 getApplicationDescriptor()->getLocalId()
77 __MOUT_ERR__ <<
"XDAQ Supervisor could not access it's configuration through the Configuration Application Group."
78 <<
" The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
81 supervisorConfigurationPath_ =
"/" + supervisorContextUID_ +
"/LinkToApplicationConfiguration/" + supervisorApplicationUID_ +
"/LinkToSupervisorConfiguration";
83 setStateMachineName(supervisorApplicationUID_);
84 __MOUT__ <<
"Done!" << std::endl;
85 __MOUT__ <<
"Done!" << std::endl;
86 __MOUT__ <<
"Done!" << std::endl;
87 __MOUT__ <<
"Done!" << std::endl;
93 CoreSupervisorBase::~CoreSupervisorBase(
void)
98 void CoreSupervisorBase::init(
void)
101 __MOUT__ <<
"CONTEXT!" << std::endl;
102 __MOUT__ <<
"CONTEXT!" << std::endl;
103 __MOUT__ <<
"CONTEXT!" << std::endl;
104 supervisorDescriptorInfo_.init(getApplicationContext());
105 __MOUT__ <<
"Done!" << std::endl;
106 __MOUT__ <<
"Done!" << std::endl;
107 __MOUT__ <<
"Done!" << std::endl;
112 void CoreSupervisorBase::destroy(
void)
114 for(
auto& it: theStateMachineImplementation_)
116 theStateMachineImplementation_.clear();
120 void CoreSupervisorBase::Default(xgi::Input * in, xgi::Output * out )
121 throw (xgi::exception::Exception)
125 __MOUT__<<
"Supervisor class " << supervisorClass_ << std::endl;
127 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/" << supervisorClassNoNamespace_ <<
"Supervisor.html?urn=" <<
128 this->getApplicationDescriptor()->getLocalId() <<
129 "'></frameset></html>";
133 void CoreSupervisorBase::request(xgi::Input * in, xgi::Output * out )
134 throw (xgi::exception::Exception)
138 cgicc::Cgicc cgi(in);
139 std::string write = CgiDataUtilities::getOrPostData(cgi,
"write");
140 std::string addr = CgiDataUtilities::getOrPostData(cgi,
"addr");
141 std::string data = CgiDataUtilities::getOrPostData(cgi,
"data");
143 __MOUT__<<
"write " << write <<
" addr: " << addr <<
" data: " << data << std::endl;
145 unsigned long long int addr64,data64;
146 sscanf(addr.c_str(),
"%llu",&addr64);
147 sscanf(data.c_str(),
"%llu",&data64);
148 __MOUT__<<
"write " << write <<
" addr: " << addr64 <<
" data: " << data64 << std::endl;
154 void CoreSupervisorBase::stateMachineXgiHandler(xgi::Input * in, xgi::Output * out )
155 throw (xgi::exception::Exception)
159 void CoreSupervisorBase::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out )
160 throw (xgi::exception::Exception)
164 xoap::MessageReference CoreSupervisorBase::stateMachineXoapHandler(xoap::MessageReference message )
165 throw (xoap::exception::Exception)
167 __MOUT__<<
"Soap Handler!" << std::endl;
168 stateMachineWorkLoopManager_.removeProcessedRequests();
169 stateMachineWorkLoopManager_.processRequest(message);
170 __MOUT__<<
"Done - Soap Handler!" << std::endl;
175 xoap::MessageReference CoreSupervisorBase::stateMachineResultXoapHandler(xoap::MessageReference message )
176 throw (xoap::exception::Exception)
178 __MOUT__<<
"Soap Handler!" << std::endl;
181 __MOUT__<<
"Done - Soap Handler!" << std::endl;
186 bool CoreSupervisorBase::stateMachineThread(toolbox::task::WorkLoop* workLoop)
188 stateMachineSemaphore_.take();
189 __MOUT__<<
"Re-sending message..." << SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
190 std::string reply = send(this->getApplicationDescriptor(),stateMachineWorkLoopManager_.getMessage(workLoop));
191 stateMachineWorkLoopManager_.report(workLoop, reply, 100,
true);
192 __MOUT__<<
"Done with message" << std::endl;
193 stateMachineSemaphore_.give();
199 xoap::MessageReference CoreSupervisorBase::stateMachineStateRequest(xoap::MessageReference message)
200 throw (xoap::exception::Exception)
202 __MOUT__<< theStateMachine_.getCurrentStateName() << std::endl;
203 return SOAPUtilities::makeSOAPMessageReference(theStateMachine_.getCurrentStateName());
213 xoap::MessageReference CoreSupervisorBase::macroMakerSupervisorRequest(
214 xoap::MessageReference message)
215 throw (xoap::exception::Exception)
217 __MOUT__<<
"$$$$$$$$$$$$$$$$$" << std::endl;
221 for(
unsigned int i = 0; i<theStateMachineImplementation_.size();++i)
225 theFEInterfacesManager =
227 if(!theFEInterfacesManager)
throw std::runtime_error(
"");
228 __MOUT__ <<
"State Machine " << i <<
" WAS of type FEVInterfacesManager" << std::endl;
234 __MOUT__ <<
"State Machine " << i <<
" was NOT of type FEVInterfacesManager" << std::endl;
239 __MOUT__ <<
"theFEInterfacesManager pointer = " << theFEInterfacesManager << std::endl;
243 parameters.addParameter(
"Request");
244 parameters.addParameter(
"InterfaceID");
247 parameters.addParameter(
"Address");
248 parameters.addParameter(
"Data");
251 parameters.addParameter(
"feMacroName");
252 parameters.addParameter(
"inputArgs");
253 parameters.addParameter(
"outputArgs");
255 SOAPMessenger::receive(message, parameters);
256 std::string request = parameters.getValue(
"Request");
257 std::string addressStr = parameters.getValue(
"Address");
258 std::string dataStr = parameters.getValue(
"Data");
259 std::string InterfaceID = parameters.getValue(
"InterfaceID");
261 __MOUT__<<
"request: " << request << std::endl;
263 __MOUT__<<
"Address: " << addressStr <<
" Data: "
264 << dataStr <<
" InterfaceID: " << InterfaceID << std::endl;
268 if(request ==
"GetInterfaces")
270 if(theFEInterfacesManager)
271 retParameters.addParameter(
"FEList",theFEInterfacesManager->getFEListString(
272 std::to_string(getApplicationDescriptor()->getLocalId())));
274 retParameters.addParameter(
"FEList",
"");
276 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"Response",
279 else if(request ==
"UniversalWrite")
281 if(!theFEInterfacesManager)
283 __MOUT_INFO__ <<
"No FE Interface Manager! (So no write occurred)" << std::endl;
284 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"DataWritten",retParameters);
292 __MOUT__<<
"theFEInterfacesManager->getInterfaceUniversalAddressSize(index) " <<
293 theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) << std::endl;
294 __MOUT__<<
"theFEInterfacesManager->getInterfaceUniversalDataSize(index) " <<
295 theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) << std::endl;
304 __MOUT__<<
"Translating address: ";
306 char address[theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID)];
308 if(addressStr.size()%2)
309 addressStr =
"0" + addressStr;
311 for(;i<addressStr.size() &&
312 i/2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) ; i+=2)
314 tmpHex[0] = addressStr[addressStr.size()-1-i-1];
315 tmpHex[1] = addressStr[addressStr.size()-1-i];
316 sscanf(tmpHex,
"%hhX",(
unsigned char*)&address[i/2]);
317 printf(
"%2.2X",(
unsigned char)address[i/2]);
320 for(;i/2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) ; i+=2)
323 printf(
"%2.2X",(
unsigned char)address[i/2]);
326 std::cout << std::endl;
328 __MOUT__<<
"Translating data: ";
330 char data[theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID)];
333 dataStr =
"0" + dataStr;
336 for(;i<dataStr.size() &&
337 i/2 < theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) ; i+=2)
339 tmpHex[0] = dataStr[dataStr.size()-1-i-1];
340 tmpHex[1] = dataStr[dataStr.size()-1-i];
341 sscanf(tmpHex,
"%hhX",(
unsigned char*)&data[i/2]);
342 printf(
"%2.2X",(
unsigned char)data[i/2]);
345 for(;i/2 < theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) ; i+=2)
348 printf(
"%2.2X",(
unsigned char)data[i/2]);
351 std::cout << std::endl;
360 theFEInterfacesManager->universalWrite(InterfaceID,address,data);
365 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"DataWritten",retParameters);
367 else if(request ==
"UniversalRead")
369 if(!theFEInterfacesManager)
371 __MOUT_INFO__ <<
"No FE Interface Manager! (So no read occurred)" << std::endl;
372 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"aa",retParameters);
379 __MOUT__<<
"theFEInterfacesManager->getInterfaceUniversalAddressSize(index) "
380 << theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) << std::endl;
381 __MOUT__<<
"theFEInterfacesManager->getInterfaceUniversalDataSize(index) "
382 <<theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID) << std::endl;
388 __MOUT__<<
"Translating address: ";
390 char address[theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID)];
392 if(addressStr.size()%2)
393 addressStr =
"0" + addressStr;
396 for(;i<addressStr.size() &&
397 i/2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) ; i+=2)
399 tmpHex[0] = addressStr[addressStr.size()-1-i-1];
400 tmpHex[1] = addressStr[addressStr.size()-1-i];
401 sscanf(tmpHex,
"%hhX",(
unsigned char*)&address[i/2]);
402 printf(
"%2.2X",(
unsigned char)address[i/2]);
405 for(;i/2 < theFEInterfacesManager->getInterfaceUniversalAddressSize(InterfaceID) ; i+=2)
408 printf(
"%2.2X",(
unsigned char)address[i/2]);
411 std::cout << std::endl;
413 unsigned int dataSz = theFEInterfacesManager->getInterfaceUniversalDataSize(InterfaceID);
420 if(theFEInterfacesManager->universalRead(InterfaceID, address, data) < 0)
422 retParameters.addParameter(
"dataResult",
"Time Out Error");
423 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"aa",retParameters);
429 std::string str8(data);
431 __MOUT__<<
"decResult[" << dataSz <<
" bytes]: " <<
432 *((
unsigned long long *)(&str8[0])) << std::endl;
436 char hexResult[dataSz*2+1];
440 for(
unsigned int i=0;i<dataSz;++i)
442 sprintf(&hexResult[i*2],
"%2.2X", (
unsigned char)data[dataSz-1-i]);
445 __MOUT__<<
"hexResult[" << strlen(hexResult) <<
" nibbles]: " << std::string(hexResult) << std::endl;
449 retParameters.addParameter(
"dataResult",hexResult);
450 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"aa",retParameters);
453 else if(request ==
"GetInterfaceMacros")
455 if(theFEInterfacesManager)
456 retParameters.addParameter(
"FEMacros",theFEInterfacesManager->getFEMacrosString(
457 std::to_string(getApplicationDescriptor()->getLocalId())));
459 retParameters.addParameter(
"FEMacros",
"");
461 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"Response",
464 else if(request ==
"RunInterfaceMacro")
466 if(!theFEInterfacesManager)
468 retParameters.addParameter(
"success",
"0");
469 retParameters.addParameter(
"outputArgs",
"");
470 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"Response",
474 std::string feMacroName = parameters.getValue(
"feMacroName");
475 std::string inputArgs = parameters.getValue(
"inputArgs");
476 std::string outputArgs = parameters.getValue(
"outputArgs");
483 theFEInterfacesManager->runFEMacro(InterfaceID,feMacroName,inputArgs,outputArgs);
485 catch(std::runtime_error &e)
487 __SS__ <<
"In Supervisor with LID=" << getApplicationDescriptor()->getLocalId()
488 <<
" the FE Macro named '" << feMacroName <<
"' with tartget FE '"
489 << InterfaceID <<
"' failed. Here is the error:\n\n" << e.what() << std::endl;
490 __MOUT_ERR__ <<
"\n" << ss.str();
492 outputArgs = ss.str();
496 retParameters.addParameter(
"success",success?
"1":
"0");
497 retParameters.addParameter(
"outputArgs",outputArgs);
499 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"Response",
504 __MOUT_WARN__ <<
"Unrecognized request received! '" << request <<
"'" << std::endl;
508 return SOAPUtilities::makeSOAPMessageReference(supervisorClassNoNamespace_ +
"FailRequest",retParameters);
512 void CoreSupervisorBase::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
513 throw (toolbox::fsm::exception::Exception)
515 __MOUT__ <<
"CoreSupervisorBase::stateInitial" << std::endl;
519 void CoreSupervisorBase::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
520 throw (toolbox::fsm::exception::Exception)
522 __MOUT__ <<
"CoreSupervisorBase::stateHalted" << std::endl;
526 void CoreSupervisorBase::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
527 throw (toolbox::fsm::exception::Exception)
529 __MOUT__ <<
"CoreSupervisorBase::stateRunning" << std::endl;
533 void CoreSupervisorBase::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
534 throw (toolbox::fsm::exception::Exception)
536 __MOUT__ <<
"CoreSupervisorBase::stateConfigured" << std::endl;
540 void CoreSupervisorBase::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
541 throw (toolbox::fsm::exception::Exception)
543 __MOUT__ <<
"CoreSupervisorBase::statePaused" << std::endl;
547 void CoreSupervisorBase::inError (toolbox::fsm::FiniteStateMachine & fsm)
548 throw (toolbox::fsm::exception::Exception)
550 __MOUT__<<
"Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
555 void CoreSupervisorBase::enteringError (toolbox::Event::Reference e)
556 throw (toolbox::fsm::exception::Exception)
558 __MOUT__<<
"Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
559 toolbox::fsm::FailedEvent& failedEvent =
dynamic_cast<toolbox::fsm::FailedEvent&
>(*e);
560 std::ostringstream error;
561 error <<
"Failure performing transition from "
562 << failedEvent.getFromState()
564 << failedEvent.getToState()
565 <<
" exception: " << failedEvent.getException().what();
566 __MOUT__<< error.str() << std::endl;
572 void CoreSupervisorBase::transitionConfiguring(toolbox::Event::Reference e)
573 throw (toolbox::fsm::exception::Exception)
577 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
578 getParameters().getValue(
"ConfigurationGroupName"),
580 getParameters().getValue(
"ConfigurationGroupKey")));
582 __MOUT__ <<
"Configuration group name: " << theGroup.first <<
" key: " <<
583 theGroup.second << std::endl;
585 theConfigurationManager_->loadConfigurationGroup(
587 theGroup.second,
true);
591 for(
auto& it: theStateMachineImplementation_)
597 void CoreSupervisorBase::transitionHalting(toolbox::Event::Reference e)
598 throw (toolbox::fsm::exception::Exception)
601 for(
auto& it: theStateMachineImplementation_)
606 void CoreSupervisorBase::transitionInitializing(toolbox::Event::Reference e)
607 throw (toolbox::fsm::exception::Exception)
615 void CoreSupervisorBase::transitionPausing(toolbox::Event::Reference e)
616 throw (toolbox::fsm::exception::Exception)
619 for(
auto& it: theStateMachineImplementation_)
624 void CoreSupervisorBase::transitionResuming(toolbox::Event::Reference e)
625 throw (toolbox::fsm::exception::Exception)
629 for(
auto it = theStateMachineImplementation_.rbegin(); it != theStateMachineImplementation_.rend(); it++)
634 void CoreSupervisorBase::transitionStarting(toolbox::Event::Reference e)
635 throw (toolbox::fsm::exception::Exception)
639 for(
auto it = theStateMachineImplementation_.rbegin(); it != theStateMachineImplementation_.rend(); it++)
640 (*it)->start(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue(
"RunNumber"));
644 void CoreSupervisorBase::transitionStopping(toolbox::Event::Reference e)
645 throw (toolbox::fsm::exception::Exception)
648 for(
auto& it: theStateMachineImplementation_)