00001 #include "otsdaq/DataLoggerApp/DataLoggerApp.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutMacros.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)
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 )
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 )
00132 {}
00133
00134
00135 void DataLoggerApp::stateMachineResultXgiHandler(xgi::Input* in, xgi::Output* out )
00136 {}
00137
00138
00139 xoap::MessageReference DataLoggerApp::stateMachineXoapHandler(xoap::MessageReference message )
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 )
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)
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 {
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 DataLoggerApp::stateInitial(toolbox::fsm::FiniteStateMachine& fsm)
00190 {
00191
00192 }
00193
00194
00195 void DataLoggerApp::stateHalted(toolbox::fsm::FiniteStateMachine& fsm)
00196 {
00197
00198 }
00199
00200
00201 void DataLoggerApp::stateRunning(toolbox::fsm::FiniteStateMachine& fsm)
00202 {
00203
00204 }
00205
00206
00207 void DataLoggerApp::stateConfigured(toolbox::fsm::FiniteStateMachine& fsm)
00208 {
00209
00210 }
00211
00212
00213 void DataLoggerApp::statePaused(toolbox::fsm::FiniteStateMachine& fsm)
00214 {
00215
00216 }
00217
00218
00219 void DataLoggerApp::inError (toolbox::fsm::FiniteStateMachine & fsm)
00220 {
00221 std::cout << __COUT_HDR_FL__ << "Fsm current state: " << theStateMachine_.getCurrentStateName()<< std::endl;
00222
00223 }
00224
00225
00226 void DataLoggerApp::enteringError (toolbox::Event::Reference e)
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 DataLoggerApp::transitionConfiguring(toolbox::Event::Reference e)
00246 {
00247
00248 std::cout << __COUT_HDR_FL__ << "ARTDAQDataLogger 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 theDataLoggerInterface_->initialize(pset, 0, 0);
00318 mf::LogInfo("DataLoggerInterface") << "ARTDAQDataLogger SUPERVISOR DONE CONFIGURING!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!";
00319
00320 }
00321
00322
00323 void DataLoggerApp::transitionHalting(toolbox::Event::Reference e)
00324 {
00325
00326 }
00327
00328
00329 void DataLoggerApp::transitionInitializing(toolbox::Event::Reference e)
00330 {
00331
00332 }
00333
00334
00335 void DataLoggerApp::transitionPausing(toolbox::Event::Reference e)
00336 {
00337 theDataLoggerInterface_->pause(0, 0);
00338 }
00339
00340
00341 void DataLoggerApp::transitionResuming(toolbox::Event::Reference e)
00342 {
00343 theDataLoggerInterface_->resume(0, 0);
00344 }
00345
00346
00347 void DataLoggerApp::transitionStarting(toolbox::Event::Reference e)
00348 {
00349 auto runnumber= SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue("RunNumber");
00350 try {
00351 art::RunID runId((art::RunNumber_t)boost::lexical_cast<art::RunNumber_t>(runnumber));
00352 theDataLoggerInterface_->start(runId,0,0);
00353 }
00354 catch(const boost::exception& e)
00355 {
00356 std::cerr << "Error parsing string to art::RunNumber_t: " << runnumber << std::endl;
00357 exit(1);
00358 }
00359 }
00360
00361
00362 void DataLoggerApp::transitionStopping(toolbox::Event::Reference e)
00363 {
00364 theDataLoggerInterface_->stop(0,0);
00365 theDataLoggerInterface_->shutdown(0);
00366 }