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