1 #include "otsdaq-utilities/Visualization/VisualSupervisor.h"
3 #include "otsdaq-core/DataManager/DataManagerSingleton.h"
4 #include "otsdaq-core/Macros/BinaryStringMacros.h"
10 #include "TBufferFile.h"
17 #include <TDirectory.h>
22 #include <TIterator.h>
25 #include <TBufferJSON.h>
31 #include <xdaq/NamespaceURI.h>
36 #define ROOT_BROWSER_PATH getenv("ROOT_BROWSER_PATH")
37 #define ROOT_DISPLAY_CONFIG_PATH getenv("ROOT_DISPLAY_CONFIG_PATH")
39 #define LIVEDQM_DIR std::string("LIVE_DQM")
40 #define PRE_MADE_ROOT_CFG_DIR std::string("Pre-made Views")
42 #define PRE_MADE_ROOT_CFG_FILE_EXT std::string(".rcfg")
44 #define PREFERENCES_PATH std::string(getenv("SERVICE_DATA_PATH")) + "/VisualizerData/"
45 #define PREFERENCES_FILE_EXT ".pref"
47 #define ROOT_VIEWER_PERMISSIONS_THRESHOLD 100
52 #define __MF_SUBJECT__ "Visualizer"
60 : CoreSupervisorBase (stub)
62 , loadedRunNumber_ (-1)
64 INIT_MF(
"VisualSupervisor");
65 __SUP_COUT__ << std::endl;
67 theDataManager_ = DataManagerSingleton::getInstance<VisualDataManager>
69 theConfigurationManager_->getNode(theConfigurationManager_->__GET_CONFIG__(XDAQContextConfiguration)->getConfigurationName()),
70 supervisorConfigurationPath_,
71 supervisorApplicationUID_
74 CoreSupervisorBase::theStateMachineImplementation_.push_back(theDataManager_);
76 __SUP_COUT__ <<
"Done instantiating Visual data manager." << std::endl;
82 mkdir(((std::string)PREFERENCES_PATH).c_str(), 0755);
86 VisualSupervisor::~VisualSupervisor(
void)
92 void VisualSupervisor::destroy(
void)
97 DataManagerSingleton::deleteInstance(CorePropertySupervisorBase::supervisorApplicationUID_);
98 theStateMachineImplementation_.pop_back();
121 void VisualSupervisor::setSupervisorPropertyDefaults()
123 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AllowNoLoginRequestTypes,
124 "setUserPreferences | getUserPreferences | getDirectoryContents | getRoot | getEvents");
126 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
127 "*=1 | rootAdminControls=100");
134 void VisualSupervisor::forceSupervisorPropertyValues()
136 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
137 "getRoot | getEvents");
138 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NoXmlWhiteSpaceRequestTypes,
139 "getRoot | getEvents");
145 void VisualSupervisor::request(
const std::string& requestType, cgicc::Cgicc& cgiIn,
146 HttpXmlDocument& xmlOut,
const WebUsers::RequestUserInfo& userInfo)
171 if(requestType ==
"getRawData")
173 __SUP_COUT__ << __E__;
176 __SUP_COUT__ <<
"Getting Raw data and converting to binary string" << __E__;
177 xmlOut.addBinaryStringToData(
"rawData",
178 theDataManager_->getRawData());
179 __SUP_COUT__ << __E__;
181 catch(std::exception
const& e){
182 __SUP_COUT__ <<
"ERROR! Exception while getting raw data. Incoming exception data..." << __E__;
183 __SUP_COUT__ << e.what() << __E__;
184 __SUP_COUT__ <<
"End Exception Data" << __E__;
188 __SUP_COUT__ <<
"ERROR! Something went wrong trying to get raw data." << __E__;
189 __SUP_COUT_INFO__ <<
"ERROR! Something went wrong trying to get raw data." << __E__;
192 else if (requestType ==
"setUserPreferences" && userInfo.username_ !=
"" )
194 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << std::endl;
195 std::string fullPath = (std::string)PREFERENCES_PATH + userInfo.username_ + PREFERENCES_FILE_EXT;
196 __SUP_COUT__ <<
"fullPath: " << fullPath << std::endl;
198 std::string radioSelect = CgiDataUtilities::getData(cgiIn,
"radioSelect");
199 std::string autoRefresh = CgiDataUtilities::getData(cgiIn,
"autoRefresh");
200 std::string autoHide = CgiDataUtilities::getData(cgiIn,
"autoHide");
201 std::string hardRefresh = CgiDataUtilities::getData(cgiIn,
"hardRefresh");
202 std::string autoRefreshPeriod = CgiDataUtilities::getData(cgiIn,
"autoRefreshPeriod");
204 __SUP_COUT__ <<
"radioSelect: " << radioSelect << std::endl;
205 __SUP_COUT__ <<
"autoRefresh: " << autoRefresh << std::endl;
206 __SUP_COUT__ <<
"autoHide: " << autoHide << std::endl;
207 __SUP_COUT__ <<
"hardRefresh: " << hardRefresh << std::endl;
208 __SUP_COUT__ <<
"autoRefreshPeriod: " << autoRefreshPeriod << std::endl;
212 FILE *fp = fopen(fullPath.c_str(),
"r");
219 sscanf(line,
"%*s %s",val);
220 if(radioSelect ==
"")
224 sscanf(line,
"%*s %s",val);
225 if(autoRefresh ==
"")
229 sscanf(line,
"%*s %s",val);
234 sscanf(line,
"%*s %s",val);
235 if(hardRefresh ==
"")
239 sscanf(line,
"%*s %s",val);
240 if(autoRefreshPeriod ==
"")
241 autoRefreshPeriod = val;
247 fp = fopen(fullPath.c_str(),
"w");
250 fprintf(fp,
"radioSelect %s\n",radioSelect.c_str());
251 fprintf(fp,
"autoRefresh %s\n",autoRefresh.c_str());
252 fprintf(fp,
"autoHide %s\n",autoHide.c_str());
253 fprintf(fp,
"hardRefresh %s\n",hardRefresh.c_str());
254 fprintf(fp,
"autoRefreshPeriod %s\n",autoRefreshPeriod.c_str());
258 __SUP_COUT_ERR__ <<
"Failure writing preferences to file: " << fullPath << std::endl;
260 else if (requestType ==
"getUserPreferences")
262 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << std::endl;
263 std::string fullPath = (std::string)PREFERENCES_PATH + userInfo.username_ + PREFERENCES_FILE_EXT;
264 __SUP_COUT__ <<
"fullPath: " << fullPath << std::endl;
266 FILE *fp = fopen(fullPath.c_str(),
"r");
274 sscanf(line,
"%*s %d",&val);
275 if(val < 0 || val > 3) val = 0;
276 xmlOut.addTextElementToData(
"radioSelect", std::to_string(val));
278 sscanf(line,
"%*s %d",&val);
279 xmlOut.addTextElementToData(
"autoRefresh", std::to_string(val));
281 sscanf(line,
"%*s %d",&val);
282 xmlOut.addTextElementToData(
"autoHide", std::to_string(val));
284 sscanf(line,
"%*s %d",&val);
285 xmlOut.addTextElementToData(
"hardRefresh", std::to_string(val));
287 sscanf(line,
"%*s %d",&val);
288 xmlOut.addTextElementToData(
"autoRefreshPeriod", std::to_string(val));
294 xmlOut.addTextElementToData(
"radioSelect",
"");
295 xmlOut.addTextElementToData(
"autoRefresh",
"");
296 xmlOut.addTextElementToData(
"autoHide",
"");
297 xmlOut.addTextElementToData(
"hardRefresh",
"");
298 xmlOut.addTextElementToData(
"autoRefreshPeriod",
"");
301 else if (requestType ==
"getDirectoryContents")
305 std::string rootpath = std::string(ROOT_BROWSER_PATH) +
"/";
306 std::string path = CgiDataUtilities::postData(cgiIn,
"Path");
307 __SUP_COUT__ << path << std::endl;
312 sprintf(permStr,
"%d",
313 userInfo.permissionLevel_ >=
314 CoreSupervisorBase::getSupervisorPropertyUserPermissionsThreshold(
"rootAdminControls")
316 xmlOut.addTextElementToData(
"permissions", permStr);
318 std::string dirpath = rootpath + path;
319 if(path ==
"/" + PRE_MADE_ROOT_CFG_DIR +
"/")
320 dirpath = ROOT_DISPLAY_CONFIG_PATH;
322 if(path.find(
"/" + PRE_MADE_ROOT_CFG_DIR +
"/") == 0)
323 dirpath = std::string(ROOT_DISPLAY_CONFIG_PATH) +
"/" + path.substr(PRE_MADE_ROOT_CFG_DIR.length()+2);
325 __SUP_COUT__ <<
"full path: " << dirpath << std::endl;
328 struct dirent *entry;
331 if( (pDIR=opendir(dirpath.c_str())) )
333 xmlOut.addTextElementToData(
"path", path);
340 if(theDataManager_->getLiveDQMHistos() != 0)
341 xmlOut.addTextElementToData(
"dir", LIVEDQM_DIR +
".root");
344 DIR *pRtDIR = opendir(ROOT_DISPLAY_CONFIG_PATH);
345 bool recheck =
false;
349 if(mkdir(ROOT_DISPLAY_CONFIG_PATH, S_IRWXU | (S_IRGRP | S_IXGRP) | (S_IROTH | S_IXOTH)))
350 __SUP_COUT__ <<
"Failed to make directory for pre made views: " << ROOT_DISPLAY_CONFIG_PATH << std::endl;
355 if(!recheck || (pRtDIR = opendir(ROOT_DISPLAY_CONFIG_PATH)))
357 xmlOut.addTextElementToData(
"dir", PRE_MADE_ROOT_CFG_DIR);
363 while((entry = readdir(pDIR)))
366 if( entry->d_name[0] !=
'.' && (entry->d_type == 0 ||
367 entry->d_type == 4 || entry->d_type == 8))
370 isNotRtCfg = std::string(entry->d_name).find(
".rcfg") == std::string::npos;
373 if(entry->d_type == 0)
376 DIR *pTmpDIR = opendir((dirpath + entry->d_name).c_str());
385 if((entry->d_type == 8 || (!isDir && entry->d_type == 0))
386 && std::string(entry->d_name).find(
".root") == std::string::npos
389 else if(entry->d_type == 4)
393 xmlOut.addTextElementToData(isDir?
"dir":
394 (isNotRtCfg?
"dir":
"file"),
401 __SUP_COUT__ <<
"Failed to access directory contents!" << std::endl;
403 else if (requestType ==
"getRoot")
407 std::string path = CgiDataUtilities::postData(cgiIn,
"RootPath");
408 std::string fullPath = std::string(getenv(
"ROOT_BROWSER_PATH")) + path;
412 std::string rootFileName = fullPath.substr(0,fullPath.find(
".root")+5);
413 std::string rootDirectoryName = rootFileName +
":" + fullPath.substr(fullPath.find(
".root")+5,fullPath.size()-fullPath.find(
".root")+5+1);
415 std::string::size_type LDQM_pos = path.find(
"/" + LIVEDQM_DIR +
".root/");
418 if(theDataManager_->getLiveDQMHistos() !=
nullptr && LDQM_pos == 0)
421 rootFile = theDataManager_->getLiveDQMHistos()->getFile();
423 __SUP_COUT__ <<
"File was closed." << std::endl;
427 rootDirectoryName = path.substr((
"/" + LIVEDQM_DIR +
".root").length());
431 rootFile = TFile::Open(rootFileName.c_str());
435 if(!rootFile || !rootFile->IsOpen())
437 __SUP_COUT__ <<
"Failed to access root file: " << rootFileName << std::endl;
441 xmlOut.addTextElementToData(
"path", path);
443 TDirectory* directory;
444 if((directory = rootFile->GetDirectory(rootDirectoryName.c_str())) == 0)
447 directory = rootFile;
451 TObject* histoClone =
nullptr;
452 TObject* histo = (TObject*)rootFile->Get(rootDirectoryName.c_str());
457 histoClone = histo->Clone();
458 TString json = TBufferJSON::ConvertToJSON(histoClone);
459 TBufferFile tBuffer(TBuffer::kWrite);
460 histoClone->Streamer(tBuffer);
464 std::string destination =
465 BinaryStringMacros::binaryToHexString(tBuffer.Buffer(), tBuffer.Length());
467 xmlOut.addTextElementToData(
"rootType", histoClone->ClassName());
468 xmlOut.addTextElementToData(
"rootData", destination);
469 xmlOut.addTextElementToData(
"rootJSON", json.Data());
473 __SUP_COUT_ERR__ <<
"Failed to access:-" << rootDirectoryName <<
"-" << std::endl;
478 __SUP_COUT__ <<
"directory found getting the content!" << std::endl;
479 TRegexp re(
"*", kTRUE);
483 TIter nextobj(directory->GetList());
484 while ((obj = (TObject *) nextobj()))
486 TString s = obj->GetName();
487 if (s.Index(re) == kNPOS)
489 __SUP_COUT__ <<
"Class Name: " << obj->IsA()->GetName() << std::endl;
490 xmlOut.addTextElementToData((std::string(obj->IsA()->GetName()).find(
"Directory") != std::string::npos)?
"dir":
"file", obj->GetName());
497 TIter next(directory->GetListOfKeys());
498 while ((key = (TKey *) next()))
500 TString s = key->GetName();
501 if (s.Index(re) == kNPOS)
503 __SUP_COUT__ <<
"Class Name: " << key->GetClassName() << std::endl;
504 xmlOut.addTextElementToData((std::string(key->GetClassName()).find(
"Directory") != std::string::npos)?
"dir":
"file", key->GetName());
508 if(LDQM_pos == std::string::npos)
512 else if (requestType ==
"getEvents")
514 int Run = atoi(cgiIn(
"run").c_str());
516 __SUP_COUT__ <<
"getEvents for run " << Run << std::endl;
518 if(Run != (
int)loadedRunNumber_ || loadedRunNumber_ == (
unsigned int)-1)
520 theDataManager_->load(
"Run1684.root",
"Monicelli");
521 loadedRunNumber_ = Run;
524 DOMElement* eventsParent = xmlOut.addTextElementToData(
"events",
"");
525 DOMElement* eventParent;
561 __SUP_COUT__ <<
"Done hits xml" << std::endl;
563 else if (requestType ==
"getGeometry")
565 __SUP_COUT__ <<
"getGeometry" << std::endl;
568 theDataManager_->load(
"Run1684.geo",
"Geometry");
570 __SUP_COUT__ <<
"getGeometry" << std::endl;
572 DOMElement* geometryParent = xmlOut.addTextElementToData(
"geometry",
"");
599 else if (requestType ==
"getRootConfig")
601 std::string path = CgiDataUtilities::postData(cgiIn,
"RootConfigPath");
602 __SUP_COUT__ <<
"path " << path << std::endl;
604 if(path.find(
"/" + PRE_MADE_ROOT_CFG_DIR +
"/") == 0)
606 path = std::string(ROOT_DISPLAY_CONFIG_PATH) +
"/" + path.substr(PRE_MADE_ROOT_CFG_DIR.length()+2);
607 __SUP_COUT__ <<
"mod path " << path << std::endl;
610 HttpXmlDocument cfgXml;
611 if(cfgXml.loadXmlDocument(path))
613 xmlOut.addTextElementToData(
"status",
"1");
614 xmlOut.copyDataChildren(cfgXml);
615 cfgXml.saveXmlDocument(path);
618 xmlOut.addTextElementToData(
"status",
"Failed. File to properly load config file.");
620 else if (requestType ==
"rootAdminControls")
629 std::string cmd = cgiIn(
"cmd");
634 std::string path = CgiDataUtilities::postData(cgiIn,
"path");
635 std::string name = CgiDataUtilities::postData(cgiIn,
"name");
636 __SUP_COUT__ <<
"cmd " << cmd << std::endl;
637 __SUP_COUT__ <<
"path " << path << std::endl;
638 __SUP_COUT__ <<
"name " << name << std::endl;
640 if(path.find(
"/" + PRE_MADE_ROOT_CFG_DIR +
"/") == 0)
642 path = std::string(ROOT_DISPLAY_CONFIG_PATH) +
"/" + path.substr(PRE_MADE_ROOT_CFG_DIR.length()+2) + name;
643 __SUP_COUT__ <<
"mod path " << path << std::endl;
648 if(mkdir(path.c_str(), S_IRWXU | (S_IRGRP | S_IXGRP) | (S_IROTH | S_IXOTH)))
649 xmlOut.addTextElementToData(
"status",
"Failed. Directory create rejected.");
651 xmlOut.addTextElementToData(
"status",
"1");
653 else if(cmd ==
"save")
655 path += PRE_MADE_ROOT_CFG_FILE_EXT;
657 bool useRunWildCard = atoi(CgiDataUtilities::postData(cgiIn,
"useRunWildCard").c_str());
658 std::string config = CgiDataUtilities::postData(cgiIn,
"config");
659 __SUP_COUT__ <<
"config " << config << std::endl;
660 __SUP_COUT__ <<
"useRunWildCard " << useRunWildCard << std::endl;
663 FILE *fp = fopen(path.c_str(),
"r");
667 xmlOut.addTextElementToData(
"status",
"Failed. File already exists.");
668 __SUP_COUT__ <<
" Failed. File already exists." << std::endl;
677 fp = fopen(path.c_str(),
"w");
678 fputs(config.c_str(),fp);
682 HttpXmlDocument cfgXml;
683 if(cfgXml.loadXmlDocument(path))
686 cfgXml.saveXmlDocument(path);
687 xmlOut.addTextElementToData(
"status",
"1");
691 xmlOut.addTextElementToData(
"status",
"Failed. Fatal. Improper file format.");
692 if(
remove(path.c_str()) != 0)
693 __SUP_COUT__ <<
"Failed. Could not remove poorly formed Root config file!" << std::endl;
698 else if(cmd ==
"delete")
701 if (rmdir(path.c_str()) == 0 ||
remove((path+PRE_MADE_ROOT_CFG_FILE_EXT).c_str()) == 0 )
702 xmlOut.addTextElementToData(
"status",
"1");
704 xmlOut.addTextElementToData(
"status",
"Failed. Target could not be deleted.");
707 xmlOut.addTextElementToData(
"status",
"Failed. Unrecognized command.");
710 xmlOut.addTextElementToData(
"status",
"Failed. Invalid path.");
716 __SUP_COUT__ <<
"requestType request, " << requestType <<
", not recognized." << std::endl;