00001 #include "otsdaq-utilities/ECLWriter/ECLSupervisor.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutMacros.h"
00004 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
00005 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
00006 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
00007 #include "otsdaq-core/SOAPUtilities/SOAPParameters.h"
00008 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
00009 #include "otsdaq-core/ConfigurationInterface/ConfigurationManager.h"
00010 #include "otsdaq-core/ConfigurationPluginDataFormats/XDAQContextConfiguration.h"
00011 #include "otsdaq-core/ConfigurationDataFormats/ConfigurationGroupKey.h"
00012
00013 #include "otsdaq-utilities/ECLWriter/ECLConnection.h"
00014
00015 #include <dirent.h>
00016 #include <sys/stat.h>
00017
00018 #include <xdaq/NamespaceURI.h>
00019
00020 #include <iostream>
00021 #include <iomanip>
00022
00023 using namespace ots;
00024
00025 #undef __MF_SUBJECT__
00026 #define __MF_SUBJECT__ "ECL"
00027
00028 XDAQ_INSTANTIATOR_IMPL(ECLSupervisor)
00029
00030
00031 ECLSupervisor::ECLSupervisor(xdaq::ApplicationStub * s)
00032 : CoreSupervisorBase(s)
00033 , theConfigurationManager_(new ConfigurationManager)
00034 , supervisorContextUID_(theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getContextUID(getApplicationContext()->getContextDescriptor()->getURL()))
00035 , supervisorApplicationUID_(theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getApplicationUID
00036 (
00037 getApplicationContext()->getContextDescriptor()->getURL(),
00038 getApplicationDescriptor()->getLocalId()
00039 ))
00040 , supervisorConfigurationPath_("/" + supervisorContextUID_ + "/LinkToApplicationTable/" + supervisorApplicationUID_ + "/LinkToSupervisorTable")
00041 {
00042 INIT_MF("ECLSupervisor");
00043 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00044 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00045 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00046 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00047 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00048 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00049 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00050 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00051 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00052 __COUT__ << __PRETTY_FUNCTION__ << std::endl;
00053
00054
00055 __COUT__ << __PRETTY_FUNCTION__ << "done data manager" << std::endl;
00056
00057 init();
00058 }
00059
00060
00061 ECLSupervisor::~ECLSupervisor(void)
00062 {
00063 destroy();
00064 }
00065
00066 void ECLSupervisor::init(void)
00067 {
00068
00069
00070 }
00071
00072
00073 void ECLSupervisor::destroy(void)
00074 {
00075
00076 delete theConfigurationManager_;
00077 }
00078
00079
00080 void ECLSupervisor::defaultPage(xgi::Input * in, xgi::Output * out)
00081
00082 {
00083
00084
00085 *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/ECL.html?urn=" <<
00086 this->getApplicationDescriptor()->getLocalId() << "'></frameset></html>";
00087
00088 }
00089
00090
00091 void ECLSupervisor::transitionConfiguring(toolbox::Event::Reference e)
00092
00093 {
00094
00095
00096 {
00097
00098
00099
00100 std::pair<std::string , ConfigurationGroupKey> theGroup(
00101 SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
00102 getParameters().getValue("ConfigurationGroupName"),
00103 ConfigurationGroupKey(SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).
00104 getParameters().getValue("ConfigurationGroupKey")));
00105
00106 __COUT__ << "Configuration group name: " << theGroup.first << " key: " <<
00107 theGroup.second << std::endl;
00108
00109 theConfigurationManager_->loadConfigurationGroup(
00110 theGroup.first,
00111 theGroup.second, true);
00112
00113
00114 ConfigurationTree configLinkNode = theConfigurationManager_->getSupervisorConfigurationNode(
00115 supervisorContextUID_, supervisorApplicationUID_);
00116
00117 ECLUser = configLinkNode.getNode("ECLUserName").getValue<std::string>();
00118 ECLHost = configLinkNode.getNode("ECLInstanceURL").getValue<std::string>();
00119 ECLPwd = configLinkNode.getNode("ECLPassword").getValue<std::string>();
00120 ExperimentName = configLinkNode.getNode("ExperimentName").getValue<std::string>();
00121
00122 }
00123
00124
00125
00126
00127 }
00128
00129
00130 void ECLSupervisor::transitionStarting(toolbox::Event::Reference e)
00131
00132 {
00133 try
00134 {
00135 __COUT_INFO__ << "ECLSupervisor sending Start Run log message to ECL" << std::endl;
00136 run = SOAPUtilities::translate(theStateMachine_.getCurrentMessage()).getParameters().getValue("RunNumber");
00137 run_start = std::chrono::steady_clock::now();
00138 duration_ms = 0;
00139 Write(WriteState::kStart);
00140 }
00141 catch (...)
00142 {
00143 __COUT_INFO__ << "ERROR! Couldn't Start the ECLSupervisor" << std::endl;
00144 }
00145 }
00146
00147
00148 void ECLSupervisor::transitionStopping(toolbox::Event::Reference e)
00149
00150 {
00151 try
00152 {
00153 __COUT_INFO__ << "ECLSupervisor sending Stop Run log message to ECL" << std::endl;
00154 Write(WriteState::kStop);
00155 }
00156 catch (...)
00157 {
00158 __COUT_INFO__ << "ERROR! Couldn't Stop the ECLSupervisor" << std::endl;
00159 }
00160 }
00161
00162
00163
00164 void ECLSupervisor::transitionPausing(toolbox::Event::Reference e)
00165
00166 {
00167 try
00168 {
00169 __COUT_INFO__ << "ECLSupervisor sending Pause Run log message to ECL" << std::endl;
00170 Write(WriteState::kPause);
00171 duration_ms += std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - run_start).count();
00172 }
00173 catch (...)
00174 {
00175 __COUT_INFO__ << "ERROR! Couldn't Pause the ECLSupervisor" << std::endl;
00176 }
00177 }
00178
00179
00180 void ECLSupervisor::transitionResuming(toolbox::Event::Reference e)
00181
00182 {
00183 try
00184 {
00185 __COUT_INFO__ << "ECLSupervisor sending Resume Run log message to ECL" << std::endl;
00186 run_start = std::chrono::steady_clock::now();
00187 Write(WriteState::kResume);
00188 }
00189 catch (...)
00190 {
00191 __COUT_INFO__ << "ERROR! Couldn't Resume the ECLSupervisor" << std::endl;
00192 }
00193 }
00194
00195 void ECLSupervisor::enteringError(toolbox::Event::Reference e)
00196 {
00197 try
00198 {
00199 __COUT_INFO__ << "ECLSupervisor sending Error log message to ECL" << std::endl;
00200 Write(WriteState::kError);
00201 }
00202 catch (...)
00203 {
00204 __COUT_INFO__ << "ERROR! Couldn't Error the ECLSupervisor" << std::endl;
00205 }
00206 }
00207
00208
00209
00210
00211
00212 xoap::MessageReference ECLSupervisor::MakeSystemLogbookEntry(xoap::MessageReference msg)
00213
00214 {
00215 SOAPParameters parameters("EntryText");
00216
00217
00218 SOAPUtilities::receive(msg, parameters);
00219 std::string EntryText = parameters.getValue("EntryText");
00220
00221 __COUT__ << "Received External Supervisor System Entry " << EntryText << std::endl;
00222
00223 std::string retStr = "Success";
00224
00225 ECLEntry_t eclEntry;
00226 eclEntry.author(ECLUser);
00227 eclEntry.category("Facility/DAQ");
00228 Form_t form;
00229 Field_t field;
00230 Form_t::field_sequence fields;
00231 std::string users = theRemoteWebUsers_.getActiveUserList(allSupervisorInfo_.getGatewayDescriptor());
00232
00233 form.name("OTSDAQ System Logbook Entry");
00234
00235 field = Field_t(EscapeECLString(ExperimentName), "Experiment");
00236 fields.push_back(field);
00237
00238 field = Field_t(EscapeECLString(run), "RunNumber");
00239 fields.push_back(field);
00240
00241 field = Field_t(EscapeECLString(users), "ActiveUsers");
00242 fields.push_back(field);
00243
00244 field = Field_t(EscapeECLString(EntryText), "Entry");
00245 fields.push_back(field);
00246
00247 ECLConnection eclConn(ECLUser, ECLPwd, ECLHost);
00248 if (!eclConn.Post(eclEntry)) {
00249 retStr = "Failure";
00250 }
00251
00252
00253 SOAPParameters retParameters("Status", retStr);
00254
00255 return SOAPUtilities::makeSOAPMessageReference("LogbookEntryStatusResponse", retParameters);
00256 }
00257
00258
00259 int ECLSupervisor::Write(WriteState state)
00260 {
00261 ECLEntry_t eclEntry;
00262 eclEntry.author(ECLUser);
00263 eclEntry.category("Facility/DAQ");
00264 Form_t form;
00265 Field_t field;
00266 Form_t::field_sequence fields;
00267 std::string users = theRemoteWebUsers_.getActiveUserList(allSupervisorInfo_.getGatewayDescriptor());
00268
00269 switch(state)
00270 {
00271 case WriteState::kStart: form.name("OTSDAQ Start Run");break;
00272 case WriteState::kStop: form.name("OTSDAQ Stop Run"); break;
00273 case WriteState::kResume: form.name("OTSDAQ Resume Run"); break;
00274 case WriteState::kPause: form.name("OTSDAQ Pause Run"); break;
00275 case WriteState::kError: form.name("OTSDAQ Run Error"); break;
00276 }
00277
00278 field = Field_t(EscapeECLString(ExperimentName), "Experiment");
00279 fields.push_back(field);
00280
00281 field = Field_t(EscapeECLString(run), "RunNumber");
00282 fields.push_back(field);
00283
00284 field = Field_t(EscapeECLString(users), "ActiveUsers");
00285 fields.push_back(field);
00286
00287
00288 if(state != WriteState::kStart && state != WriteState::kResume) {
00289 int dur = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - run_start).count() + duration_ms;
00290 int dur_s = dur / 1000;
00291 dur = dur % 1000;
00292 int dur_m = dur_s / 60;
00293 dur_s = dur_s % 60;
00294 int dur_h = dur_m / 60;
00295 dur_m = dur_m % 60;
00296
00297 std::ostringstream dur_ss;
00298 dur_ss << std::setw(2) << std::setfill('0') << dur_h
00299 << ":" << std::setw(2) << std::setfill('0') << dur_m
00300 << ":" << std::setw(2) << std::setfill('0') << dur_s
00301 << "." << dur;
00302
00303 field = Field_t(EscapeECLString(dur_ss.str()), "Duration");
00304 fields.push_back(field);
00305 }
00306
00307 form.field(fields);
00308
00309 eclEntry.form(form);
00310
00311 ECLConnection eclConn(ECLUser, ECLPwd, ECLHost);
00312 if (!eclConn.Post(eclEntry)) {
00313 return -1;
00314 }
00315
00316 return 0;
00317 }
00318
00319
00320
00321 std::string ECLSupervisor::EscapeECLString(std::string input)
00322 {
00323 std::string output = input;
00324 size_t pos = output.find('&');
00325 while (pos != std::string::npos)
00326 {
00327 output = output.replace(pos, 1, "&");
00328 pos = output.find('&', pos + 2);
00329 }
00330
00331 pos = output.find('"');
00332 while (pos != std::string::npos)
00333 {
00334 output = output.replace(pos, 1, """);
00335 pos = output.find('"', pos + 1);
00336 }
00337
00338 pos = output.find('\'');
00339 while (pos != std::string::npos)
00340 {
00341 output = output.replace(pos, 1, "'");
00342 pos = output.find('\'', pos + 1);
00343 }
00344
00345 pos = output.find('<');
00346 while (pos != std::string::npos)
00347 {
00348 output = output.replace(pos, 1, "<");
00349 pos = output.find('<', pos + 1);
00350 }
00351
00352 pos = output.find('>');
00353 while (pos != std::string::npos)
00354 {
00355 output = output.replace(pos, 1, ">");
00356 pos = output.find('>', pos + 1);
00357 }
00358
00359 return output;
00360 }
00361
00362
00363