00001 #include "otsdaq/DispatcherApp/DispatcherApp.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
00005 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
00006 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
00007
00008 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
00009 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00010 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
00011
00012 #include <toolbox/fsm/FailedEvent.h>
00013
00014 #include <xdaq/NamespaceURI.h>
00015 #include <xoap/Method.h>
00016
00017 #include "artdaq/DAQdata/Globals.hh"
00018 #include <memory>
00019 #include "messagefacility/MessageLogger/MessageLogger.h"
00020 #include "artdaq-core/Utilities/configureMessageFacility.hh"
00021 #include "cetlib/exception.h"
00022 #include "artdaq/BuildInfo/GetPackageBuildInfo.hh"
00023 #include "fhiclcpp/make_ParameterSet.h"
00024
00025 #include <fstream>
00026 #include <iostream>
00027 #include <cassert>
00028
00029 using namespace ots;
00030
00031 XDAQ_INSTANTIATOR_IMPL(DispatcherApp)
00032
00033
00034 DispatcherApp::DispatcherApp(xdaq::ApplicationStub * s) throw (xdaq::exception::Exception)
00035 : xdaq::Application(s)
00036 , SOAPMessenger(this)
00037 , stateMachineWorkLoopManager_(toolbox::task::bind(this, &DispatcherApp::stateMachineThread, "StateMachine"))
00038 , stateMachineSemaphore_(toolbox::BSem::FULL)
00039 , theConfigurationManager_(new ConfigurationManager)
00040 , XDAQContextConfigurationName_(theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getConfigurationName())
00041 , supervisorConfigurationPath_("INITIALIZED INSIDE THE CONTRUCTOR BECAUSE IT NEEDS supervisorContextUID_ and supervisorApplicationUID_")
00042 , supervisorContextUID_("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
00043 , supervisorApplicationUID_("INITIALIZED INSIDE THE CONTRUCTOR TO LAUNCH AN EXCEPTION")
00044 {
00045 INIT_MF("DispatcherApp");
00046 xgi::bind(this, &DispatcherApp::Default, "Default");
00047 xgi::bind(this, &DispatcherApp::stateMachineXgiHandler, "StateMachineXgiHandler");
00048
00049 xoap::bind(this, &DispatcherApp::stateMachineStateRequest, "StateMachineStateRequest", XDAQ_NS_URI);
00050 xoap::bind(this, &DispatcherApp::stateMachineErrorMessageRequest, "StateMachineErrorMessageRequest", XDAQ_NS_URI);
00051
00052 try
00053 {
00054 supervisorContextUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getContextUID(getApplicationContext()->getContextDescriptor()->getURL());
00055 }
00056 catch (...)
00057 {
00058 __COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Context Group." <<
00059 " The XDAQContextConfigurationName = " << XDAQContextConfigurationName_ <<
00060 ". The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
00061 throw;
00062 }
00063 try
00064 {
00065 supervisorApplicationUID_ = theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getApplicationUID
00066 (
00067 getApplicationContext()->getContextDescriptor()->getURL(),
00068 getApplicationDescriptor()->getLocalId()
00069 );
00070 }
00071 catch (...)
00072 {
00073 __COUT_ERR__ << "XDAQ Supervisor could not access it's configuration through the Configuration Application Group."
00074 << " The supervisorApplicationUID = " << supervisorApplicationUID_ << std::endl;
00075 throw;
00076 }
00077 supervisorConfigurationPath_ = "/" + supervisorContextUID_ + "/LinkToApplicationConfiguration/" + supervisorApplicationUID_ + "/LinkToSupervisorConfiguration";
00078
00079 setStateMachineName(supervisorApplicationUID_);
00080 init();
00081 }
00082
00083
00084 DispatcherApp::~DispatcherApp(void)
00085 {
00086 destroy();
00087 }
00088
00089 void DispatcherApp::init(void)
00090 {
00091 std::cout << __COUT_HDR_FL__ << "ARTDAQDispatcher SUPERVISOR INIT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
00092 allSupervisorInfo_.init(getApplicationContext());
00093 artdaq::configureMessageFacility("Dispatcher");
00094
00095
00096
00097 std::cout << __COUT_HDR_FL__ << "ARTDAQDispatcher SUPERVISOR INIT4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
00098 std::string name = "Dispatcher";
00099 unsigned short port = 5300;
00100
00101 artdaq::setMsgFacAppName(name, port);
00102
00103 mf::LogDebug(name + "Supervisor") << "artdaq version " <<
00104 artdaq::GetPackageBuildInfo::getPackageBuildInfo().getPackageVersion()
00105 << ", built " <<
00106 artdaq::GetPackageBuildInfo::getPackageBuildInfo().getBuildTimestamp();
00107
00108
00109 app_name = name;
00110 my_rank = this->getApplicationDescriptor()->getLocalId();
00111 theDispatcherInterface_ = new artdaq::DispatcherApp();
00112
00113 }
00114
00115
00116 void DispatcherApp::destroy(void)
00117 {
00118 delete theDispatcherInterface_;
00119 }
00120
00121
00122 void DispatcherApp::Default(xgi::Input * in, xgi::Output * out) throw (xgi::exception::Exception)
00123 {
00124
00125 *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/DispatcherApp.html?urn=" <<
00126 this->getApplicationDescriptor()->getLocalId() << "'></frameset></html>";
00127 }
00128
00129
00130 void DispatcherApp::stateMachineXgiHandler(xgi::Input * in, xgi::Output * out) throw (xgi::exception::Exception)
00131 {}
00132
00133
00134 void DispatcherApp::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out) throw (xgi::exception::Exception)
00135 {}
00136
00137
00138 xoap::MessageReference DispatcherApp::stateMachineXoapHandler(xoap::MessageReference message) throw (xoap::exception::Exception)
00139 {
00140 std::cout << __COUT_HDR_FL__ << "Soap Handler!" << std::endl;
00141 stateMachineWorkLoopManager_.removeProcessedRequests();
00142 stateMachineWorkLoopManager_.processRequest(message);
00143 std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << std::endl;
00144 return message;
00145 }
00146
00147
00148 xoap::MessageReference DispatcherApp::stateMachineResultXoapHandler(xoap::MessageReference message) throw (xoap::exception::Exception)
00149 {
00150 std::cout << __COUT_HDR_FL__ << "Soap Handler!" << std::endl;
00151
00152
00153 std::cout << __COUT_HDR_FL__ << "Done - Soap Handler!" << std::endl;
00154 return message;
00155 }
00156
00157
00158 bool DispatcherApp::stateMachineThread(toolbox::task::WorkLoop* workLoop)
00159 {
00160 stateMachineSemaphore_.take();
00161 std::cout << __COUT_HDR_FL__ << "Re-sending message..." << SOAPUtilities::translate(stateMachineWorkLoopManager_.getMessage(workLoop)).getCommand() << std::endl;
00162 std::string reply = send(this->getApplicationDescriptor(), stateMachineWorkLoopManager_.getMessage(workLoop));
00163 stateMachineWorkLoopManager_.report(workLoop, reply, 100, true);
00164 std::cout << __COUT_HDR_FL__ << "Done with message" << std::endl;
00165 stateMachineSemaphore_.give();
00166 return false;
00167
00168 }
00169
00170
00171 xoap::MessageReference DispatcherApp::stateMachineStateRequest(xoap::MessageReference message) throw (xoap::exception::Exception)
00172 {
00173 std::cout << __COUT_HDR_FL__ << theStateMachine_.getCurrentStateName() << std::endl;
00174 return SOAPUtilities::makeSOAPMessageReference(theStateMachine_.getCurrentStateName());
00175 }
00176
00177
00178 xoap::MessageReference DispatcherApp::stateMachineErrorMessageRequest(xoap::MessageReference message)
00179 throw (xoap::exception::Exception)
00180 {
00181 __COUT__ << "theStateMachine_.getErrorMessage() = " << theStateMachine_.getErrorMessage() << std::endl;
00182
00183 SOAPParameters retParameters;
00184 retParameters.addParameter("ErrorMessage", theStateMachine_.getErrorMessage());
00185 return SOAPUtilities::makeSOAPMessageReference("stateMachineErrorMessageRequestReply", retParameters);
00186 }
00187
00188
00189 void DispatcherApp::stateInitial(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
00190 {
00191
00192 }
00193
00194
00195 void DispatcherApp::stateHalted(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
00196 {
00197
00198 }
00199
00200
00201 void DispatcherApp::stateRunning(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
00202 {
00203
00204 }
00205
00206
00207 void DispatcherApp::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
00208 {
00209
00210 }
00211
00212
00213 void DispatcherApp::statePaused(toolbox::fsm::FiniteStateMachine& fsm) throw (toolbox::fsm::exception::Exception)
00214 {
00215
00216 }
00217
00218
00219 void DispatcherApp::inError(toolbox::fsm::FiniteStateMachine & fsm) throw (toolbox::fsm::exception::Exception)
00220 {
00221 std::cout << __COUT_HDR_FL__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00222
00223 }
00224
00225
00226 void DispatcherApp::enteringError(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00227 {
00228 std::cout << __COUT_HDR_FL__ << "Fsm current state: " << theStateMachine_.getCurrentStateName() << std::endl;
00229 toolbox::fsm::FailedEvent& failedEvent = dynamic_cast<toolbox::fsm::FailedEvent&>(*e);
00230 std::ostringstream error;
00231 error << "Failure performing transition from "
00232 << failedEvent.getFromState()
00233 << " to "
00234 << failedEvent.getToState()
00235 << " exception: " << failedEvent.getException().what();
00236 std::cout << __COUT_HDR_FL__ << error.str() << std::endl;
00237
00238
00239 }
00240
00241
00242 #define ARTDAQ_FCL_PATH std::string(getenv("USER_DATA")) + "/"+ "ARTDAQConfigurations/"
00243 #define ARTDAQ_FILE_PREAMBLE "aggregator"
00244
00245 void DispatcherApp::transitionConfiguring(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00246 {
00247
00248 std::cout << __COUT_HDR_FL__ << "ARTDAQDispatcher SUPERVISOR CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
00249 std::cout << __COUT_HDR_FL__ << SOAPUtilities::translate(theStateMachine_.getCurrentMessage()) << std::endl;
00250
00251 std::pair<std::string , ConfigurationGroupKey> theGroup(
00252 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
00253 getParameters().getValue("ConfigurationGroupName"),
00254 ConfigurationGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
00255 getParameters().getValue("ConfigurationGroupKey")));
00256
00257 __COUT__ << "Configuration group name: " << theGroup.first << " key: " <<
00258 theGroup.second << std::endl;
00259
00260 theConfigurationManager_->loadConfigurationGroup(
00261 theGroup.first,
00262 theGroup.second, true);
00263
00264
00265 std::string path = "";
00266 char* dirMRB = getenv("MRB_BUILDDIR");
00267 char* dirP = getenv("OTSDAQ_DIR");
00268
00269 if (dirMRB) { path = std::string(dirMRB) + "/otsdaq_demo/"; }
00270 else if (dirP) { path = std::string(dirP) + "/"; }
00271
00272
00273
00274
00275
00276
00277
00278
00279 fhicl::ParameterSet pset;
00280
00281
00282 std::string filename = ARTDAQ_FCL_PATH + ARTDAQ_FILE_PREAMBLE + "-";
00283 std::string uid = theConfigurationManager_->getNode(XDAQContextConfigurationName_).getNode(supervisorConfigurationPath_).getValue();
00284
00285 __COUT__ << "uid: " << uid << std::endl;
00286 for (unsigned int i = 0; i < uid.size(); ++i)
00287 if ((uid[i] >= 'a' && uid[i] <= 'z') ||
00288 (uid[i] >= 'A' && uid[i] <= 'Z') ||
00289 (uid[i] >= '0' && uid[i] <= '9'))
00290 filename += uid[i];
00291 filename += ".fcl";
00292
00293
00294 __COUT__ << std::endl;
00295 __COUT__ << std::endl;
00296 __COUT__ << "filename: " << filename << std::endl;
00297
00298 std::string fileFclString;
00299 {
00300 std::ifstream in(filename, std::ios::in | std::ios::binary);
00301 if (in)
00302 {
00303 std::string contents;
00304 in.seekg(0, std::ios::end);
00305 fileFclString.resize(in.tellg());
00306 in.seekg(0, std::ios::beg);
00307 in.read(&fileFclString[0], fileFclString.size());
00308 in.close();
00309 }
00310 }
00311
00312 __COUT__ << fileFclString << std::endl;
00313 fhicl::make_ParameterSet(fileFclString, pset);
00314
00315
00316
00317 theDispatcherInterface_->initialize(pset, 0, 0);
00318 mf::LogInfo("DispatcherInterface") << "ARTDAQDispatcher SUPERVISOR DONE CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
00319
00320 }
00321
00322
00323 void DispatcherApp::transitionHalting(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00324 {
00325
00326 }
00327
00328
00329 void DispatcherApp::transitionInitializing(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00330 {
00331
00332 }
00333
00334
00335 void DispatcherApp::transitionPausing(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00336 {
00337 theDispatcherInterface_->pause(0, 0);
00338 }
00339
00340
00341 void DispatcherApp::transitionResuming(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00342 {
00343 theDispatcherInterface_->resume(0, 0);
00344 }
00345
00346
00347 void DispatcherApp::transitionStarting(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00348 {
00349 art::RunID runId((art::RunNumber_t)boost::lexical_cast<art::RunNumber_t>(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue("RunNumber")));
00350 theDispatcherInterface_->start(runId, 0, 0);
00351 }
00352
00353
00354 void DispatcherApp::transitionStopping(toolbox::Event::Reference e) throw (toolbox::fsm::exception::Exception)
00355 {
00356 theDispatcherInterface_->stop(45, 0);
00357 theDispatcherInterface_->shutdown(45);
00358 }