1 #include "otsdaq-utilities/ConfigurationGUI/ConfigurationGUISupervisor.h"
3 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/MessageFacility/MessageFacility.h"
6 #include "otsdaq/TablePlugins/IterateTable.h"
7 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
9 #include <boost/stacktrace.hpp>
11 #include "otsdaq/GatewaySupervisor/GatewaySupervisor.h"
12 #include "otsdaq/TablePlugins/ARTDAQTableBase/ARTDAQTableBase.h"
13 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
15 #include <xdaq/NamespaceURI.h>
24 #define __MF_SUBJECT__ "CfgGUI"
26 #define TABLE_INFO_PATH std::string(__ENV__("TABLE_INFO_PATH")) + "/"
27 #define TABLE_INFO_EXT std::string("Info.xml")
29 #define ARTDAQ_CONFIG_LAYOUTS_PATH \
30 std::string(__ENV__("SERVICE_DATA_PATH")) + "/ConfigurationGUI_artdaqLayouts/"
44 : CoreSupervisorBase(stub)
46 __SUP_COUT__ <<
"Constructor started." << __E__;
51 mkdir(((std::string)ARTDAQ_CONFIG_LAYOUTS_PATH).c_str(), 0755);
54 __SUP_COUT__ <<
"Constructor complete." << __E__;
58 ConfigurationGUISupervisor::~ConfigurationGUISupervisor(
void) { destroy(); }
61 void ConfigurationGUISupervisor::init(
void)
63 __SUP_COUT__ <<
"Initializing..." << __E__;
65 __SUP_COUT__ <<
"Activating saved context, which may prepare for normal mode..."
76 __SUP_COUT__ <<
"Done with test context." << __E__;
80 __COUT_WARN__ <<
"Failed test context group activation. otsdaq, in Normal mode, "
81 "will not launch when this test fails. "
82 <<
"Check the active context group from within Wizard Mode."
88 void ConfigurationGUISupervisor::destroy(
void)
90 __SUP_COUT__ <<
"Destructing..." << __E__;
93 for(std::map<std::string, ConfigurationManagerRW*>::iterator it =
94 userConfigurationManagers_.begin();
95 it != userConfigurationManagers_.end();
101 userConfigurationManagers_.clear();
103 if(ConfigurationInterface::getInstance() !=
nullptr)
104 delete ConfigurationInterface::getInstance();
109 void ConfigurationGUISupervisor::defaultPage(xgi::Input* in, xgi::Output* out)
111 cgicc::Cgicc cgiIn(in);
112 std::string configWindowName =
113 CgiDataUtilities::getData(cgiIn,
"configWindowName");
114 if(configWindowName ==
"tableEditor")
115 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
116 "src='/WebPath/html/ConfigurationTableEditor.html?urn="
117 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
118 if(configWindowName ==
"iterate")
119 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
120 "src='/WebPath/html/Iterate.html?urn="
121 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
123 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
124 "src='/WebPath/html/ConfigurationGUI.html?urn="
125 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
133 CorePropertySupervisorBase::setSupervisorProperty(
134 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
135 "*=10 | deleteTreeNodeRecords=255 | saveTableInfo=255 | "
136 "deleteTableInfo=255");
137 CorePropertySupervisorBase::setSupervisorProperty(
138 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
141 CorePropertySupervisorBase::setSupervisorProperty(
142 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
"get*");
150 CorePropertySupervisorBase::addSupervisorProperty(
151 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
152 "getActiveTableGroups");
153 CorePropertySupervisorBase::setSupervisorProperty(
154 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
159 void ConfigurationGUISupervisor::request(
const std::string& requestType,
161 HttpXmlDocument& xmlOut,
162 const WebUsers::RequestUserInfo& userInfo)
167 __COUTTV__(requestType);
232 std::string refresh = CgiDataUtilities::getData(cgiIn,
"refresh");
235 ConfigurationManagerRW* cfgMgr =
236 refreshUserSession(userInfo.username_, (refresh ==
"1"));
238 if(requestType ==
"saveTableInfo")
240 std::string tableName =
241 CgiDataUtilities::getData(cgiIn,
"tableName");
242 std::string columnCSV =
243 CgiDataUtilities::postData(cgiIn,
"columnCSV");
244 std::string allowOverwrite =
245 CgiDataUtilities::getData(cgiIn,
"allowOverwrite");
246 std::string tableDescription =
247 CgiDataUtilities::postData(cgiIn,
"tableDescription");
248 std::string columnChoicesCSV =
249 CgiDataUtilities::postData(cgiIn,
"columnChoicesCSV");
251 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
252 __SUP_COUT__ <<
"columnCSV: " << columnCSV << __E__;
253 __SUP_COUT__ <<
"tableDescription: " << tableDescription << __E__;
254 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << __E__;
255 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << __E__;
257 if(!allSupervisorInfo_.isWizardMode())
259 __SUP_SS__ <<
"Improper permissions for saving table info." << __E__;
260 xmlOut.addTextElementToData(
"Error", ss.str());
263 handleSaveTableInfoXML(xmlOut,
269 allowOverwrite ==
"1");
271 else if(requestType ==
"deleteTableInfo")
273 std::string tableName =
274 CgiDataUtilities::getData(cgiIn,
"tableName");
275 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
276 handleDeleteTableInfoXML(xmlOut, cfgMgr, tableName);
278 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
279 requestType ==
"flattenToSystemAliases")
282 __SUP_COUT_WARN__ << requestType <<
" command received! " << __E__;
283 __COUT_WARN__ << requestType <<
" command received! " << __E__;
286 __SUP_COUT_INFO__ <<
"Launching " << requestType <<
"... " << __E__;
288 __SUP_COUT__ <<
"Extracting target context hostnames... " << __E__;
289 std::vector<std::string> hostnames;
292 if(requestType ==
"flattenToSystemAliases" &&
293 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
295 hostnames.push_back(__ENV__(
"OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER"));
296 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
304 const XDAQContextTable* contextTable =
305 cfgMgr->__GET_CONFIG__(XDAQContextTable);
307 auto contexts = contextTable->getContexts();
309 for(
const auto& context : contexts)
316 for(i = 0; i < context.address_.size(); ++i)
317 if(context.address_[i] ==
'/')
319 hostnames.push_back(context.address_.substr(j));
320 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
325 __SUP_SS__ <<
"The Configuration Manager could not be initialized to "
332 catch(
const std::exception& e)
334 ss <<
"Exception message: " << e.what();
340 __SUP_COUT_ERR__ <<
"\n" << ss.str();
345 if(hostnames.size() == 0)
347 __SUP_SS__ <<
"No hostnames found to launch command '" + requestType +
348 "'... Is there a valid Context group activated?"
350 __SUP_COUT_ERR__ <<
"\n" << ss.str();
352 xmlOut.addTextElementToData(
"Error", ss.str());
355 for(
const auto& hostname : hostnames)
357 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
358 "/StartOTS_action_" + hostname +
".cmd");
359 FILE* fp = fopen(fn.c_str(),
"w");
362 if(requestType ==
"gatewayLaunchOTS")
363 fprintf(fp,
"LAUNCH_OTS");
364 else if(requestType ==
"gatewayLaunchWiz")
365 fprintf(fp,
"LAUNCH_WIZ");
366 else if(requestType ==
"flattenToSystemAliases")
368 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
376 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << __E__;
379 else if(requestType ==
"versionTracking" || requestType ==
"getVersionTracking")
382 if(requestType ==
"getVersionTracking")
385 type = CgiDataUtilities::getData(cgiIn,
"Type");
386 __SUP_COUT__ <<
"type: " << type << __E__;
389 xmlOut.addTextElementToData(
390 "versionTrackingStatus",
391 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
392 else if(type ==
"ON")
394 ConfigurationInterface::setVersionTrackingEnabled(
true);
395 xmlOut.addTextElementToData(
396 "versionTrackingStatus",
397 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
399 else if(type ==
"OFF")
401 ConfigurationInterface::setVersionTrackingEnabled(
false);
402 xmlOut.addTextElementToData(
403 "versionTrackingStatus",
404 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
407 else if(requestType ==
"getColumnTypes")
410 std::vector<std::string> allTypes = TableViewColumnInfo::getAllTypesForGUI();
411 std::vector<std::string> allDataTypes =
412 TableViewColumnInfo::getAllDataTypesForGUI();
413 std::map<std::pair<std::string, std::string>, std::string> allDefaults =
414 TableViewColumnInfo::getAllDefaultsForGUI();
416 for(
const auto& type : allTypes)
417 xmlOut.addTextElementToData(
"columnTypeForGUI", type);
418 for(
const auto& dataType : allDataTypes)
419 xmlOut.addTextElementToData(
"columnDataTypeForGUI", dataType);
421 for(
const auto& colDefault : allDefaults)
423 xmlOut.addTextElementToData(
"columnDefaultDataType", colDefault.first.first);
424 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
425 colDefault.first.second);
426 xmlOut.addTextElementToData(
"columnDefaultValue", colDefault.second);
430 else if(requestType ==
"getGroupAliases")
435 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
437 __SUP_COUT__ <<
"reloadActive: " << reloadActive << __E__;
442 cfgMgr->clearAllCachedVersions();
443 cfgMgr->restoreActiveTableGroups(
true);
445 catch(std::runtime_error& e)
447 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what()))
449 __SUP_COUT_ERR__ <<
"\n" << ss.str();
450 xmlOut.addTextElementToData(
"Error", ss.str());
454 __SUP_SS__ << (
"Error loading active groups!\n\n") << __E__;
459 catch(
const std::exception& e)
461 ss <<
"Exception message: " << e.what();
466 __SUP_COUT_ERR__ <<
"\n" << ss.str();
467 xmlOut.addTextElementToData(
"Error", ss.str());
471 handleGroupAliasesXML(xmlOut, cfgMgr);
473 else if(requestType ==
"setGroupAliasInActiveBackbone")
475 std::string groupAliasCSV =
476 CgiDataUtilities::getData(cgiIn,
"groupAlias");
477 std::string groupNameCSV =
478 CgiDataUtilities::getData(cgiIn,
"groupName");
479 std::string groupKeyCSV =
480 CgiDataUtilities::getData(cgiIn,
"groupKey");
482 __SUP_COUTV__(groupAliasCSV);
483 __SUP_COUTV__(groupNameCSV);
484 __SUP_COUTV__(groupKeyCSV);
486 handleSetGroupAliasInBackboneXML(
487 xmlOut, cfgMgr, groupAliasCSV, groupNameCSV, groupKeyCSV, userInfo.username_);
489 else if(requestType ==
"setTableAliasInActiveBackbone")
491 std::string tableAlias =
492 CgiDataUtilities::getData(cgiIn,
"tableAlias");
493 std::string tableName =
494 CgiDataUtilities::getData(cgiIn,
"tableName");
495 std::string version = CgiDataUtilities::getData(cgiIn,
"version");
497 __SUP_COUT__ <<
"tableAlias: " << tableAlias << __E__;
498 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
499 __SUP_COUT__ <<
"version: " << version << __E__;
501 handleSetTableAliasInBackboneXML(xmlOut,
505 TableVersion(version),
508 else if(requestType ==
"setAliasOfGroupMembers")
510 std::string versionAlias =
511 CgiDataUtilities::getData(cgiIn,
"versionAlias");
512 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
513 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
515 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
516 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
517 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
519 handleAliasGroupMembersInBackboneXML(xmlOut,
523 TableGroupKey(groupKey),
526 else if(requestType ==
"getVersionAliases")
528 handleVersionAliasesXML(xmlOut, cfgMgr);
530 else if(requestType ==
"getTableGroups")
532 bool doNotReturnMembers =
533 CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1
537 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << __E__;
538 handleTableGroupsXML(xmlOut, cfgMgr, !doNotReturnMembers);
540 else if(requestType ==
"getTableGroupType")
542 std::string tableList =
543 CgiDataUtilities::postData(cgiIn,
"tableList");
544 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
546 handleGetTableGroupTypeXML(xmlOut, cfgMgr, tableList);
548 else if(requestType ==
"getTables")
550 handleTablesXML(xmlOut, cfgMgr);
552 else if(requestType ==
"getContextMemberNames")
554 std::set<std::string> members = cfgMgr->getContextMemberNames();
556 for(
auto& member : members)
557 xmlOut.addTextElementToData(
"ContextMember", member);
559 else if(requestType ==
"getBackboneMemberNames")
561 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
563 for(
auto& member : members)
564 xmlOut.addTextElementToData(
"BackboneMember", member);
566 else if(requestType ==
"getIterateMemberNames")
568 std::set<std::string> members = cfgMgr->getIterateMemberNames();
570 for(
auto& member : members)
571 xmlOut.addTextElementToData(
"IterateMember", member);
573 else if(requestType ==
"getSpecificTableGroup")
575 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
576 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
578 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
579 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
581 ConfigurationSupervisorBase::handleGetTableGroupXML(
582 xmlOut, cfgMgr, groupName, TableGroupKey(groupKey));
584 else if(requestType ==
"saveNewTableGroup")
586 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
587 bool ignoreWarnings =
588 CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
589 bool allowDuplicates =
590 CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
591 bool lookForEquivalent =
592 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
593 std::string tableList =
594 CgiDataUtilities::postData(cgiIn,
"tableList");
595 std::string comment =
596 CgiDataUtilities::getData(cgiIn,
"groupComment");
598 __SUP_COUT__ <<
"saveNewTableGroup: " << groupName << __E__;
599 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
600 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
601 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << __E__;
602 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
603 __SUP_COUT__ <<
"comment: " << comment << __E__;
605 ConfigurationSupervisorBase::handleCreateTableGroupXML(xmlOut,
614 else if(requestType ==
"getSpecificTable")
616 std::string tableName =
617 CgiDataUtilities::getData(cgiIn,
"tableName");
618 std::string versionStr = CgiDataUtilities::getData(cgiIn,
"version");
619 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
620 int chunkSize = CgiDataUtilities::getDataAsInt(cgiIn,
"chunkSize");
623 std::string allowIllegalColumns =
624 CgiDataUtilities::getData(cgiIn,
"allowIllegalColumns");
625 __SUP_COUT__ <<
"allowIllegalColumns: " << (allowIllegalColumns ==
"1") << __E__;
627 std::string rawData = CgiDataUtilities::getData(cgiIn,
"rawData");
628 __SUP_COUT__ <<
"rawData: " << (rawData ==
"1") << __E__;
630 __SUP_COUT__ <<
"getSpecificTable: " << tableName <<
" versionStr: " << versionStr
631 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset
634 TableVersion version;
635 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
637 if(allTableInfo.find(tableName) != allTableInfo.end())
639 if(versionStr ==
"" &&
640 allTableInfo.at(tableName).versions_.size())
643 auto it = allTableInfo.at(tableName).versions_.rbegin();
644 if(it->isScratchVersion())
648 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
651 std::map<std::string ,
652 std::map<std::string , TableVersion>>
653 versionAliases = cfgMgr->getVersionAliases();
655 std::string versionAlias;
656 versionAlias = versionStr.substr(
657 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
668 if(versionAliases.find(tableName) != versionAliases.end() &&
669 versionAliases[tableName].find(versionAlias) !=
670 versionAliases[tableName].end())
672 version = versionAliases[tableName][versionAlias];
673 __SUP_COUT__ <<
"version alias translated to: " << version << __E__;
678 << versionStr.substr(
679 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
680 <<
"'was not found in active version aliases!" << __E__;
683 version = atoi(versionStr.c_str());
686 __SUP_COUT__ <<
"version: " << version << __E__;
688 handleGetTableXML(xmlOut,
691 TableVersion(version),
692 (allowIllegalColumns ==
"1"),
695 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
697 else if(requestType ==
"saveSpecificTable")
699 std::string tableName =
700 CgiDataUtilities::getData(cgiIn,
"tableName");
701 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
702 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
703 bool sourceTableAsIs =
704 CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
705 bool lookForEquivalent =
706 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
707 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
708 std::string comment =
709 CgiDataUtilities::getData(cgiIn,
"tableComment");
711 std::string data = CgiDataUtilities::postData(cgiIn,
"data");
715 __SUP_COUT__ <<
"tableName: " << tableName <<
" version: " << version
716 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset
718 __SUP_COUT__ <<
"comment: " << comment << __E__;
719 __SUP_COUT__ <<
"data: " << data << __E__;
720 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << __E__;
721 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
723 ConfigurationSupervisorBase::handleCreateTableXML(xmlOut,
726 TableVersion(version),
735 else if(requestType ==
"clearTableTemporaryVersions")
737 std::string tableName =
738 CgiDataUtilities::getData(cgiIn,
"tableName");
739 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
743 cfgMgr->eraseTemporaryVersion(tableName);
745 catch(std::runtime_error& e)
747 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
748 xmlOut.addTextElementToData(
749 "Error",
"Error clearing temporary views!\n " + std::string(e.what()));
753 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
754 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
757 else if(requestType ==
"clearTableCachedVersions")
759 std::string tableName =
760 CgiDataUtilities::getData(cgiIn,
"tableName");
761 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
766 cfgMgr->clearAllCachedVersions();
768 cfgMgr->clearCachedVersions(tableName);
772 catch(std::runtime_error& e)
774 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
775 xmlOut.addTextElementToData(
776 "Error",
"Error clearing cached views!\n " + std::string(e.what()));
780 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
781 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
784 else if(requestType ==
"getTreeView")
786 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
787 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
788 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
789 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
790 std::string filterList = CgiDataUtilities::postData(cgiIn,
"filterList");
791 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
792 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
793 std::string diffGroup = CgiDataUtilities::getData(cgiIn,
"diffGroup");
794 std::string diffGroupKey = CgiDataUtilities::getData(cgiIn,
"diffGroupKey");
796 __SUP_COUTT__ <<
"tableGroup: " << tableGroup << __E__;
797 __SUP_COUTT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
798 __SUP_COUTT__ <<
"startPath: " << startPath << __E__;
799 __SUP_COUTT__ <<
"depth: " << depth << __E__;
800 __SUP_COUTT__ <<
"hideStatusFalse: " << hideStatusFalse << __E__;
801 __SUP_COUTT__ <<
"modifiedTables: " << modifiedTables << __E__;
802 __SUP_COUTT__ <<
"filterList: " << filterList << __E__;
804 handleFillTreeViewXML(xmlOut,
807 TableGroupKey(tableGroupKey),
814 TableGroupKey(diffGroupKey));
816 else if(requestType ==
"getTreeNodeCommonFields")
818 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
819 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
820 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
821 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
822 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
823 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
824 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
826 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
827 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
828 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
829 __SUP_COUT__ <<
"depth: " << depth << __E__;
832 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
833 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
834 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
836 handleFillTreeNodeCommonFieldsXML(xmlOut,
839 TableGroupKey(tableGroupKey),
846 else if(requestType ==
"getUniqueFieldValuesForRecords")
848 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
849 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
850 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
851 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
852 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
853 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
855 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
856 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
857 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
858 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
859 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
860 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
862 handleFillUniqueFieldValuesForRecordsXML(xmlOut,
865 TableGroupKey(tableGroupKey),
871 else if(requestType ==
"getTreeNodeFieldValues")
873 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
874 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
875 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
876 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
877 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
878 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
880 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
881 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
882 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
883 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
884 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
885 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
887 handleFillGetTreeNodeFieldValuesXML(xmlOut,
890 TableGroupKey(tableGroupKey),
896 else if(requestType ==
"setTreeNodeFieldValues")
898 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
899 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
900 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
901 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
902 std::string fieldList = CgiDataUtilities::postData(cgiIn,
"fieldList");
903 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
904 std::string valueList = CgiDataUtilities::postData(cgiIn,
"valueList");
906 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
907 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
908 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
909 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
910 __SUP_COUT__ <<
"valueList: " << valueList << __E__;
911 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
912 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
914 handleFillSetTreeNodeFieldValuesXML(xmlOut,
917 TableGroupKey(tableGroupKey),
925 else if(requestType ==
"addTreeNodeRecords")
927 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
928 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
929 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
930 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
931 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
933 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
934 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
935 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
936 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
937 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
939 handleFillCreateTreeNodeRecordsXML(xmlOut,
942 TableGroupKey(tableGroupKey),
948 else if(requestType ==
"deleteTreeNodeRecords")
950 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
951 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
952 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
953 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
954 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
956 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
957 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
958 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
959 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
960 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
962 handleFillDeleteTreeNodeRecordsXML(xmlOut,
965 TableGroupKey(tableGroupKey),
970 else if(requestType ==
"renameTreeNodeRecords")
972 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
973 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
974 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
975 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
976 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
977 std::string newRecordList = CgiDataUtilities::postData(cgiIn,
"newRecordList");
979 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
980 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
981 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
982 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
983 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
984 __SUP_COUTV__(newRecordList);
986 handleFillRenameTreeNodeRecordsXML(xmlOut,
989 TableGroupKey(tableGroupKey),
995 else if(requestType ==
"copyTreeNodeRecords")
997 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
998 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
999 std::string startPath = CgiDataUtilities::postData(cgiIn,
"startPath");
1000 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
1001 std::string recordList = CgiDataUtilities::postData(cgiIn,
"recordList");
1002 unsigned int numberOfCopies =
1003 CgiDataUtilities::getDataAsInt(cgiIn,
"numberOfCopies");
1007 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1008 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1009 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1010 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1011 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1012 __SUP_COUTV__(numberOfCopies);
1014 handleFillCopyTreeNodeRecordsXML(xmlOut,
1017 TableGroupKey(tableGroupKey),
1023 else if(requestType ==
"getTableStructureStatusAsJSON")
1025 std::string tableGroup = CgiDataUtilities::getData(cgiIn,
"tableGroup");
1026 std::string tableGroupKey = CgiDataUtilities::getData(cgiIn,
"tableGroupKey");
1027 std::string tableName = CgiDataUtilities::getData(cgiIn,
"tableName");
1028 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
1030 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1031 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1032 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1033 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1036 setupActiveTablesXML(xmlOut,
1039 TableGroupKey(tableGroupKey),
1045 xmlOut.addTextElementToData(
1046 "StructureStatusAsJSON",
1047 cfgMgr->getTableByName(tableName)->getStructureStatusAsJSON(cfgMgr));
1049 catch(
const std::runtime_error& e)
1051 __SUP_SS__ <<
"The table plugin feature getStructureStatusAsJSON(), does not "
1052 "seem to be supported for the table '"
1054 <<
".' Make sure you have the expected table plugin in your path, "
1055 "or contact system admins."
1057 ss <<
"Here is the error: " << e.what() << __E__;
1061 else if(requestType ==
"getArtdaqNodes")
1063 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
1065 __SUP_COUTV__(modifiedTables);
1067 handleGetArtdaqNodeRecordsXML(xmlOut, cfgMgr, modifiedTables);
1069 else if(requestType ==
"saveArtdaqNodes")
1071 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
1072 std::string nodeString = CgiDataUtilities::postData(cgiIn,
"nodeString");
1073 std::string subsystemString =
1074 CgiDataUtilities::postData(cgiIn,
"subsystemString");
1076 __SUP_COUTV__(modifiedTables);
1077 __SUP_COUTV__(nodeString);
1078 __SUP_COUTV__(subsystemString);
1080 handleSaveArtdaqNodeRecordsXML(
1081 nodeString, subsystemString, xmlOut, cfgMgr, modifiedTables);
1083 else if(requestType ==
"getArtdaqNodeLayout")
1085 std::string contextGroupName =
1086 CgiDataUtilities::getData(cgiIn,
"contextGroupName");
1087 std::string contextGroupKey = CgiDataUtilities::getData(cgiIn,
"contextGroupKey");
1089 __SUP_COUTV__(contextGroupName);
1090 __SUP_COUTV__(contextGroupKey);
1092 handleLoadArtdaqNodeLayoutXML(
1093 xmlOut, cfgMgr, contextGroupName, TableGroupKey(contextGroupKey));
1095 else if(requestType ==
"saveArtdaqNodeLayout")
1097 std::string layout = CgiDataUtilities::postData(cgiIn,
"layout");
1098 std::string contextGroupName =
1099 CgiDataUtilities::getData(cgiIn,
"contextGroupName");
1100 std::string contextGroupKey = CgiDataUtilities::getData(cgiIn,
"contextGroupKey");
1102 __SUP_COUTV__(layout);
1103 __SUP_COUTV__(contextGroupName);
1104 __SUP_COUTV__(contextGroupKey);
1106 handleSaveArtdaqNodeLayoutXML(
1107 xmlOut, cfgMgr, layout, contextGroupName, TableGroupKey(contextGroupKey));
1109 else if(requestType ==
"getAffectedActiveGroups")
1111 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
1112 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1113 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
1114 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1115 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
1116 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
1118 handleGetAffectedGroupsXML(
1119 xmlOut, cfgMgr, groupName, TableGroupKey(groupKey), modifiedTables);
1121 else if(requestType ==
"saveTreeNodeEdit")
1123 std::string editNodeType = CgiDataUtilities::getData(cgiIn,
"editNodeType");
1124 std::string targetTable = CgiDataUtilities::getData(cgiIn,
"targetTable");
1125 std::string targetTableVersion =
1126 CgiDataUtilities::getData(cgiIn,
"targetTableVersion");
1127 std::string targetUID = CgiDataUtilities::getData(cgiIn,
"targetUID");
1128 std::string targetColumn = CgiDataUtilities::getData(cgiIn,
"targetColumn");
1129 std::string newValue = CgiDataUtilities::postData(cgiIn,
"newValue");
1131 __SUP_COUT__ <<
"editNodeType: " << editNodeType << __E__;
1132 __SUP_COUT__ <<
"targetTable: " << targetTable << __E__;
1133 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << __E__;
1134 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
1135 __SUP_COUT__ <<
"targetColumn: " << targetColumn << __E__;
1136 __SUP_COUT__ <<
"newValue: " << newValue << __E__;
1138 handleSaveTreeNodeEditXML(xmlOut,
1141 TableVersion(targetTableVersion),
1143 StringMacros::decodeURIComponent(targetUID),
1144 StringMacros::decodeURIComponent(targetColumn),
1146 userInfo.username_);
1148 else if(requestType ==
"getLinkToChoices")
1150 std::string linkToTableName = CgiDataUtilities::getData(cgiIn,
"linkToTableName");
1151 std::string linkToTableVersion =
1152 CgiDataUtilities::getData(cgiIn,
"linkToTableVersion");
1153 std::string linkIdType = CgiDataUtilities::getData(cgiIn,
"linkIdType");
1154 std::string linkIndex = StringMacros::decodeURIComponent(
1155 CgiDataUtilities::getData(cgiIn,
"linkIndex"));
1156 std::string linkInitId = CgiDataUtilities::getData(cgiIn,
"linkInitId");
1158 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << __E__;
1159 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << __E__;
1160 __SUP_COUT__ <<
"linkIdType: " << linkIdType << __E__;
1161 __SUP_COUT__ <<
"linkIndex: " << linkIndex << __E__;
1162 __SUP_COUT__ <<
"linkInitId: " << linkInitId << __E__;
1164 handleGetLinkToChoicesXML(xmlOut,
1167 TableVersion(linkToTableVersion),
1172 else if(requestType ==
"activateTableGroup")
1174 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
1175 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1176 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
1178 __SUP_COUT__ <<
"Activating group: " << groupName <<
"(" << groupKey <<
")"
1180 __SUP_COUTV__(ignoreWarnings);
1183 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
1184 xmlOut.addTextElementToData(
"AttemptedGroupActivationName", groupName);
1185 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey", groupKey);
1189 std::string accumulatedErrors, groupTypeString;
1194 cfgMgr->activateTableGroup(
1195 groupName, TableGroupKey(groupKey), &accumulatedErrors, &groupTypeString);
1197 if(accumulatedErrors !=
"")
1201 __SS__ <<
"Throwing exception on accumulated errors: "
1202 << accumulatedErrors << __E__;
1206 __COUT_WARN__ <<
"Ignoring warnings so ignoring this error:"
1207 << accumulatedErrors << __E__;
1208 __COUT_WARN__ <<
"Done ignoring the above error(s)." << __E__;
1210 xmlOut.addTextElementToData(
"AttemptedGroupActivationType", groupTypeString);
1212 catch(std::runtime_error& e)
1217 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1218 xmlOut.addTextElementToData(
1220 "Error activating table group '" + groupName +
"(" + groupKey +
")" +
1221 ".' Please see details below:\n\n" + std::string(e.what()));
1222 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1223 <<
" (" << groupKey <<
")" << __E__;
1226 cfgMgr->destroyTableGroup(groupName,
true);
1232 catch(cet::exception& e)
1238 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1239 xmlOut.addTextElementToData(
"Error",
1240 "Error activating table group '" + groupName +
1241 "(" + groupKey +
")" +
"!'\n\n" +
1242 std::string(e.what()));
1243 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1244 <<
" (" << groupKey <<
")" << __E__;
1247 cfgMgr->destroyTableGroup(groupName,
true);
1255 __SUP_COUT__ <<
"Unknown error detected!" << __E__;
1258 cfgMgr->destroyTableGroup(groupName,
true);
1267 else if(requestType ==
"getActiveTableGroups")
1269 else if(requestType ==
"copyViewToCurrentColumns")
1271 std::string tableName =
1272 CgiDataUtilities::getData(cgiIn,
"tableName");
1273 std::string sourceVersion = CgiDataUtilities::getData(cgiIn,
"sourceVersion");
1275 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1276 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << __E__;
1277 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << __E__;
1280 TableVersion newTemporaryVersion;
1283 newTemporaryVersion =
1284 cfgMgr->copyViewToCurrentColumns(tableName, TableVersion(sourceVersion));
1286 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << __E__;
1288 catch(std::runtime_error& e)
1290 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1291 xmlOut.addTextElementToData(
"Error",
1292 "Error copying view from '" + tableName +
"_v" +
1293 sourceVersion +
"'! " +
1294 std::string(e.what()));
1298 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1299 xmlOut.addTextElementToData(
1301 "Error copying view from '" + tableName +
"_v" + sourceVersion +
"'! ");
1304 handleGetTableXML(xmlOut, cfgMgr, tableName, newTemporaryVersion);
1306 else if(requestType ==
"getLastTableGroups")
1309 std::map<std::string ,
1310 std::tuple<std::string ,
1315 theRemoteWebUsers_.getLastTableGroups(theGroups);
1317 for(
const auto& theGroup : theGroups)
1319 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupName",
1320 std::get<0>(theGroup.second));
1321 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupKey",
1322 std::get<1>(theGroup.second).toString());
1323 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupTime",
1324 std::get<2>(theGroup.second));
1357 handleOtherSubsystemActiveGroups(xmlOut, cfgMgr,
false );
1359 else if(requestType ==
"getSubsytemTableGroups")
1361 std::string subsystem =
1362 CgiDataUtilities::getData(cgiIn,
"subsystem");
1363 __SUP_COUTV__(subsystem);
1364 handleOtherSubsystemActiveGroups(
1365 xmlOut, cfgMgr,
true , subsystem);
1367 else if(requestType ==
"diffWithActiveGroup")
1369 std::string groupName =
1370 CgiDataUtilities::getData(cgiIn,
"groupName");
1371 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1372 __SUP_COUTV__(groupName);
1373 __SUP_COUTV__(groupKey);
1376 xmlOut, cfgMgr, groupName, TableGroupKey(groupKey));
1378 else if(requestType ==
"diffWithGroupKey")
1380 std::string groupName =
1381 CgiDataUtilities::getData(cgiIn,
"groupName");
1382 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1383 std::string diffKey = CgiDataUtilities::getData(cgiIn,
"diffKey");
1384 std::string diffGroupName =
1385 CgiDataUtilities::getData(cgiIn,
"diffGroupName");
1386 __SUP_COUTV__(groupName);
1387 __SUP_COUTV__(groupKey);
1388 __SUP_COUTV__(diffKey);
1389 __SUP_COUTV__(diffGroupName);
1391 handleGroupDiff(xmlOut,
1394 TableGroupKey(groupKey),
1395 TableGroupKey(diffKey),
1398 else if(requestType ==
"diffTableVersions")
1400 std::string tableName =
1401 CgiDataUtilities::getData(cgiIn,
"tableName");
1402 std::string vA = CgiDataUtilities::getData(cgiIn,
"vA");
1403 std::string vB = CgiDataUtilities::getData(cgiIn,
"vB");
1404 __SUP_COUTV__(tableName);
1408 TableVersion versionA, versionB;
1409 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
1412 if(allTableInfo.find(tableName) != allTableInfo.end())
1414 if(vA.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1417 std::map<std::string ,
1418 std::map<std::string , TableVersion>>
1419 versionAliases = cfgMgr->getVersionAliases();
1421 std::string versionAlias;
1423 vA.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1425 if(versionAliases.find(tableName) != versionAliases.end() &&
1426 versionAliases[tableName].find(versionAlias) !=
1427 versionAliases[tableName].end())
1429 versionA = versionAliases[tableName][versionAlias];
1430 __SUP_COUT__ <<
"version alias translated to: " << versionA << __E__;
1433 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1434 <<
"'was not found in active version aliases!"
1438 versionA = atoi(vA.c_str());
1440 if(vB.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1443 std::map<std::string ,
1444 std::map<std::string , TableVersion>>
1445 versionAliases = cfgMgr->getVersionAliases();
1447 std::string versionAlias;
1449 vB.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1451 if(versionAliases.find(tableName) != versionAliases.end() &&
1452 versionAliases[tableName].find(versionAlias) !=
1453 versionAliases[tableName].end())
1455 versionB = versionAliases[tableName][versionAlias];
1456 __SUP_COUT__ <<
"version alias translated to: " << versionB << __E__;
1459 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1460 <<
"'was not found in active version aliases!"
1464 versionB = atoi(vB.c_str());
1468 versionA = atoi(vA.c_str());
1469 versionB = atoi(vB.c_str());
1472 __SUP_COUTV__(versionA);
1473 __SUP_COUTV__(versionB);
1475 handleTableDiff(xmlOut, cfgMgr, tableName, versionA, versionB);
1477 else if(requestType ==
"savePlanCommandSequence")
1479 std::string planName = CgiDataUtilities::getData(cgiIn,
"planName");
1480 std::string commands =
1481 CgiDataUtilities::postData(cgiIn,
"commands");
1482 std::string modifiedTables = CgiDataUtilities::postData(cgiIn,
"modifiedTables");
1483 std::string groupName = CgiDataUtilities::getData(cgiIn,
"groupName");
1484 std::string groupKey = CgiDataUtilities::getData(cgiIn,
"groupKey");
1486 __SUP_COUTV__(modifiedTables);
1487 __SUP_COUTV__(planName);
1488 __SUP_COUTV__(commands);
1489 __SUP_COUTV__(groupName);
1490 __SUP_COUTV__(groupKey);
1492 handleSavePlanCommandSequenceXML(xmlOut,
1495 TableGroupKey(groupKey),
1501 else if(requestType ==
"mergeGroups")
1503 std::string groupANameContext =
1504 CgiDataUtilities::getData(cgiIn,
"groupANameContext");
1505 std::string groupAKeyContext =
1506 CgiDataUtilities::getData(cgiIn,
"groupAKeyContext");
1507 std::string groupBNameContext =
1508 CgiDataUtilities::getData(cgiIn,
"groupBNameContext");
1509 std::string groupBKeyContext =
1510 CgiDataUtilities::getData(cgiIn,
"groupBKeyContext");
1511 std::string groupANameConfig =
1512 CgiDataUtilities::getData(cgiIn,
"groupANameConfig");
1513 std::string groupAKeyConfig = CgiDataUtilities::getData(cgiIn,
"groupAKeyConfig");
1514 std::string groupBNameConfig =
1515 CgiDataUtilities::getData(cgiIn,
"groupBNameConfig");
1516 std::string groupBKeyConfig = CgiDataUtilities::getData(cgiIn,
"groupBKeyConfig");
1517 std::string mergeApproach = CgiDataUtilities::getData(cgiIn,
"mergeApproach");
1519 __SUP_COUTV__(groupANameContext);
1520 __SUP_COUTV__(groupAKeyContext);
1521 __SUP_COUTV__(groupBNameContext);
1522 __SUP_COUTV__(groupBKeyContext);
1523 __SUP_COUTV__(groupANameConfig);
1524 __SUP_COUTV__(groupAKeyConfig);
1525 __SUP_COUTV__(groupBNameConfig);
1526 __SUP_COUTV__(groupBKeyConfig);
1527 __SUP_COUTV__(mergeApproach);
1529 handleMergeGroupsXML(xmlOut,
1532 TableGroupKey(groupAKeyContext),
1534 TableGroupKey(groupBKeyContext),
1536 TableGroupKey(groupAKeyConfig),
1538 TableGroupKey(groupBKeyConfig),
1544 __SUP_SS__ <<
"requestType '" << requestType <<
"' request not recognized."
1546 __SUP_COUT__ <<
"\n" << ss.str();
1547 xmlOut.addTextElementToData(
"Error", ss.str());
1550 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1552 ConfigurationSupervisorBase::getConfigurationStatusXML(
1553 xmlOut, cfgMgr, userInfo.username_);
1554 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1557 catch(
const std::runtime_error& e)
1559 __SS__ <<
"A fatal error occurred while handling the request '" << requestType
1560 <<
".' Error: " << e.what() << __E__;
1561 __COUT_ERR__ <<
"\n" << ss.str();
1562 xmlOut.addTextElementToData(
"Error", ss.str());
1567 xmlOut.addTextElementToData(
1569 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1573 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1578 __SS__ <<
"An unknown fatal error occurred while handling the request '"
1579 << requestType <<
".'" << __E__;
1584 catch(
const std::exception& e)
1586 ss <<
"Exception message: " << e.what();
1591 __COUT_ERR__ <<
"\n" << ss.str();
1592 xmlOut.addTextElementToData(
"Error", ss.str());
1597 xmlOut.addTextElementToData(
1599 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1603 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1616 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(
1617 HttpXmlDocument& xmlOut,
1618 ConfigurationManagerRW* cfgMgr,
1619 const std::string& rootGroupName,
1620 const TableGroupKey& rootGroupKey,
1621 const std::string& modifiedTables)
1632 std::map<std::string, std::pair<std::string, TableGroupKey>> consideredGroups =
1633 cfgMgr->getActiveTableGroups();
1637 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT].second.isInvalid())
1639 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
1640 if(cfgMgr->getFailedTableGroups().find(
1641 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT) !=
1642 cfgMgr->getFailedTableGroups().end())
1644 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1645 cfgMgr->getFailedTableGroups().at(
1646 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT);
1648 else if(cfgMgr->getFailedTableGroups().find(
1649 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1650 cfgMgr->getFailedTableGroups().end())
1652 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1653 cfgMgr->getFailedTableGroups().at(
1654 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1657 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION]
1658 .second.isInvalid())
1660 __SUP_COUT__ <<
"Finding a table group to consider..." << __E__;
1661 if(cfgMgr->getFailedTableGroups().find(
1662 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION) !=
1663 cfgMgr->getFailedTableGroups().end())
1665 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1666 cfgMgr->getFailedTableGroups().at(
1667 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION);
1669 else if(cfgMgr->getFailedTableGroups().find(
1670 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1671 cfgMgr->getFailedTableGroups().end())
1673 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1674 cfgMgr->getFailedTableGroups().at(
1675 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1679 __SUP_COUTV__(StringMacros::mapToString(consideredGroups));
1684 std::map<std::string , TableVersion > rootGroupMemberMap;
1686 cfgMgr->loadTableGroup(rootGroupName,
1689 &rootGroupMemberMap,
1697 const std::string& groupType = cfgMgr->getTypeNameOfGroup(rootGroupMemberMap);
1699 consideredGroups[groupType] =
1700 std::pair<std::string, TableGroupKey>(rootGroupName, rootGroupKey);
1702 catch(
const std::runtime_error& e)
1705 if(rootGroupName.size())
1707 __SUP_SS__ <<
"Failed to determine type of table group for " << rootGroupName
1708 <<
"(" << rootGroupKey <<
")! " << e.what() << __E__;
1709 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1714 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1715 "name - assuming this was intentional."
1721 if(rootGroupName.size())
1723 __SUP_COUT_ERR__ <<
"Failed to determine type of table group for "
1724 << rootGroupName <<
"(" << rootGroupKey <<
")!" << __E__;
1729 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1730 "name - assuming this was intentional."
1734 std::map<std::string ,
1735 std::pair<
bool , TableVersion >>
1737 std::map<std::string ,
1738 std::pair<
bool , TableVersion >>::iterator
1739 modifiedTablesMapIt;
1741 std::istringstream f(modifiedTables);
1742 std::string table, version;
1743 while(getline(f, table,
','))
1745 getline(f, version,
',');
1746 modifiedTablesMap.insert(
1749 std::pair<bool /*foundAffectedGroup*/, TableVersion /*version*/>>(
1751 std::make_pair(
false , TableVersion(version))));
1753 __SUP_COUT__ << modifiedTables << __E__;
1754 for(
auto& pair : modifiedTablesMap)
1755 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second.second
1760 xercesc::DOMElement* parentEl;
1761 std::string groupComment;
1762 std::vector<std::string> orderedGroupTypes(
1763 {ConfigurationManager::GROUP_TYPE_NAME_CONTEXT,
1764 ConfigurationManager::GROUP_TYPE_NAME_BACKBONE,
1765 ConfigurationManager::GROUP_TYPE_NAME_ITERATE,
1766 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION});
1767 for(
auto groupType : orderedGroupTypes)
1769 if(consideredGroups.find(groupType) == consideredGroups.end())
1772 const std::pair<std::string, TableGroupKey>& group = consideredGroups[groupType];
1774 if(group.second.isInvalid())
1777 __SUP_COUT__ <<
"Considering " << groupType <<
" group " << group.first <<
" ("
1778 << group.second <<
")" << __E__;
1782 std::map<std::string , TableVersion > memberMap;
1783 cfgMgr->loadTableGroup(group.first,
1794 __SUP_COUT__ <<
"groupComment = " << groupComment << __E__;
1796 for(
auto& table : memberMap)
1798 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
1801 table.second != (*modifiedTablesMapIt).second.second)
1803 __SUP_COUT__ <<
"Affected by " << (*modifiedTablesMapIt).first <<
":"
1804 << (*modifiedTablesMapIt).second.second << __E__;
1806 memberMap[table.first] = (*modifiedTablesMapIt).second.second;
1807 (*modifiedTablesMapIt).second.first =
true;
1811 if(groupType == ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
1813 __SUP_COUT__ <<
"Considering mockup tables for Configuration Group..."
1815 for(
auto& table : modifiedTablesMap)
1817 if(table.second.first)
1820 if(table.second.second.isMockupVersion() &&
1821 memberMap.find(table.first) == memberMap.end())
1823 __SUP_COUT__ <<
"Found mockup table '" << table.first
1824 <<
"' for Configuration Group." << __E__;
1825 memberMap[table.first] = table.second.second;
1833 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1834 xmlOut.addTextElementToParent(
"GroupName", group.first, parentEl);
1835 xmlOut.addTextElementToParent(
"GroupKey", group.second.toString(), parentEl);
1836 xmlOut.addTextElementToParent(
"GroupComment", groupComment, parentEl);
1838 for(
auto& table : memberMap)
1840 xmlOut.addTextElementToParent(
"MemberName", table.first, parentEl);
1841 xmlOut.addTextElementToParent(
1842 "MemberVersion", table.second.toString(), parentEl);
1847 catch(std::runtime_error& e)
1849 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1850 xmlOut.addTextElementToData(
1851 "Error",
"Error getting affected groups! " + std::string(e.what()));
1855 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1856 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
1867 void ConfigurationGUISupervisor::setupActiveTablesXML(
1868 HttpXmlDocument& xmlOut,
1869 ConfigurationManagerRW* cfgMgr,
1870 const std::string& groupName,
1871 const TableGroupKey& groupKey,
1872 const std::string& modifiedTables,
1874 bool doGetGroupInfo,
1875 std::map<std::string /*name*/, TableVersion /*version*/>* returnMemberMap,
1876 bool outputActiveTables,
1877 std::string* accumulatedErrors)
1880 xmlOut.addTextElementToData(
"tableGroup", groupName);
1881 xmlOut.addTextElementToData(
"tableGroupKey", groupKey.toString());
1883 bool usingActiveGroups = (groupName ==
"" || groupKey.isInvalid());
1889 __SUP_COUT__ <<
"Refreshing all table info, ignoring warnings..." << __E__;
1890 std::string accumulatedWarnings =
"";
1891 cfgMgr->getAllTableInfo(
true ,
1892 &accumulatedWarnings,
1899 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
1901 std::map<std::string , TableVersion > modifiedTablesMap;
1902 std::map<std::string , TableVersion >::iterator
1903 modifiedTablesMapIt;
1905 if(usingActiveGroups)
1908 __SUP_COUT__ <<
"Using active groups." << __E__;
1912 __SUP_COUT__ <<
"Loading group '" << groupName <<
"(" << groupKey <<
")'"
1915 std::string groupComment, groupAuthor, tableGroupCreationTime, groupType;
1918 cfgMgr->loadTableGroup(groupName,
1924 doGetGroupInfo ? &groupComment : 0,
1925 doGetGroupInfo ? &groupAuthor : 0,
1926 doGetGroupInfo ? &tableGroupCreationTime : 0,
1928 doGetGroupInfo ? &groupType : 0);
1932 xmlOut.addTextElementToData(
"tableGroupComment", groupComment);
1933 xmlOut.addTextElementToData(
"tableGroupAuthor", groupAuthor);
1934 xmlOut.addTextElementToData(
"tableGroupCreationTime", tableGroupCreationTime);
1935 xmlOut.addTextElementToData(
"tableGroupType", groupType);
1938 if(accumulatedErrors && *accumulatedErrors !=
"")
1939 __SUP_COUTV__(*accumulatedErrors);
1944 std::istringstream f(modifiedTables);
1945 std::string table, version;
1946 while(getline(f, table,
','))
1948 getline(f, version,
',');
1949 modifiedTablesMap.insert(
1950 std::pair<std::string /*name*/, TableVersion /*version*/>(
1951 table, TableVersion(version)));
1954 for(
auto& pair : modifiedTablesMap)
1955 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
1960 std::map<std::string, TableVersion> allActivePairs = cfgMgr->getActiveVersions();
1961 xmlOut.addTextElementToData(
"DefaultNoLink",
1962 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
1965 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
1966 for(
const auto& tablePair : allActivePairs)
1967 orderedTableSet.emplace(tablePair.first);
1969 std::map<std::string, TableInfo>::const_iterator tableInfoIt;
1970 for(
auto& orderedTableName : orderedTableSet)
1972 tableInfoIt = allTableInfo.find(orderedTableName);
1973 if(tableInfoIt == allTableInfo.end())
1975 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
1980 if(outputActiveTables)
1981 xmlOut.addTextElementToData(
"ActiveTableName", orderedTableName);
1985 if((modifiedTablesMapIt = modifiedTablesMap.find(orderedTableName)) !=
1986 modifiedTablesMap.end())
1988 __SUP_COUT__ <<
"Found modified table " << (*modifiedTablesMapIt).first
1989 <<
": trying... " << (*modifiedTablesMapIt).second << __E__;
1993 tableInfoIt->second.tablePtr_->setActiveView(
1994 (*modifiedTablesMapIt).second);
1998 __SUP_SS__ <<
"Modified table version v" << (*modifiedTablesMapIt).second
1999 <<
" failed. Reverting to v"
2000 << tableInfoIt->second.tablePtr_->getView().getVersion() <<
"."
2002 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << __E__;
2003 xmlOut.addTextElementToData(
2005 "Error setting up active tables!\n\n" + std::string(ss.str()));
2009 if(outputActiveTables)
2011 xmlOut.addTextElementToData(
2012 "ActiveTableVersion",
2013 tableInfoIt->second.tablePtr_->getView().getVersion().toString());
2014 xmlOut.addTextElementToData(
2015 "ActiveTableComment",
2016 tableInfoIt->second.tablePtr_->getView().getAuthor() +
": " +
2017 tableInfoIt->second.tablePtr_->getView().getComment());
2022 catch(std::runtime_error& e)
2024 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what()))
2026 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2027 xmlOut.addTextElementToData(
"Error", ss.str());
2032 __SUP_SS__ << (
"Error setting up active tables!\n\n") << __E__;
2037 catch(
const std::exception& e)
2039 ss <<
"Exception message: " << e.what();
2044 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2045 xmlOut.addTextElementToData(
"Error", ss.str());
2064 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(
2065 HttpXmlDocument& xmlOut,
2066 ConfigurationManagerRW* cfgMgr,
2067 const std::string& groupName,
2068 const TableGroupKey& groupKey,
2069 const std::string& startPath,
2070 const std::string& modifiedTables,
2071 const std::string& recordList,
2072 const std::string& author)
2075 setupActiveTablesXML(xmlOut,
2087 ConfigurationTree targetNode = cfgMgr->getNode(startPath);
2088 TableBase* table = cfgMgr->getTableByName(targetNode.getTableName());
2090 __SUP_COUT__ << table->getTableName() << __E__;
2091 TableVersion temporaryVersion;
2100 bool firstSave =
true;
2103 TableView backupView(targetNode.getTableName());
2107 std::istringstream f(recordList);
2108 std::string recordUID;
2110 while(getline(f, recordUID,
','))
2112 recordUID = StringMacros::decodeURIComponent(recordUID);
2114 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2118 if(!(temporaryVersion = targetNode.getTableVersion())
2119 .isTemporaryVersion())
2121 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2123 temporaryVersion = table->createTemporaryView(temporaryVersion);
2124 cfgMgr->saveNewTable(targetNode.getTableName(),
2128 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2132 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2138 backupView.copy(table->getView(), temporaryVersion, author);
2147 unsigned int row = table->getViewP()->addRow(
2153 unsigned int col = table->getViewP()->getColStatus();
2154 table->getViewP()->setURIEncodedValue(
"1", row, col);
2161 table->getViewP()->setURIEncodedValue(
2162 recordUID, row, table->getViewP()->getColUID());
2170 table->getViewP()->init();
2174 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
2175 __SUP_COUT__ <<
"Before:" << __E__;
2176 table->getViewP()->print();
2177 table->getViewP()->copy(backupView, temporaryVersion, author);
2178 __SUP_COUT__ <<
"After:" << __E__;
2179 table->getViewP()->print();
2185 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2187 catch(std::runtime_error& e)
2189 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what()))
2191 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2192 xmlOut.addTextElementToData(
"Error", ss.str());
2196 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << __E__;
2201 catch(
const std::exception& e)
2203 ss <<
"Exception message: " << e.what();
2208 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2209 xmlOut.addTextElementToData(
"Error", ss.str());
2216 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(
2217 HttpXmlDocument& xmlOut, ConfigurationManagerRW* cfgMgr)
2221 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
2222 std::map<std::string, TableVersion> allActivePairs = cfgMgr->getActiveVersions();
2223 for(
auto& activePair : allActivePairs)
2225 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
2226 xmlOut.addTextElementToData(
"NewActiveTableVersion",
2227 allTableInfo.at(activePair.first)
2228 .tablePtr_->getView()
2231 xmlOut.addTextElementToData(
2232 "NewActiveTableComment",
2233 allTableInfo.at(activePair.first).tablePtr_->getView().getAuthor() +
": " +
2234 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
2237 catch(std::runtime_error& e)
2239 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
2240 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2241 xmlOut.addTextElementToData(
"Error", ss.str());
2245 __SUP_SS__ << (
"Error!\n\n") << __E__;
2250 catch(
const std::exception& e)
2252 ss <<
"Exception message: " << e.what();
2257 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2258 xmlOut.addTextElementToData(
"Error", ss.str());
2276 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(
2277 HttpXmlDocument& xmlOut,
2278 ConfigurationManagerRW* cfgMgr,
2279 const std::string& groupName,
2280 const TableGroupKey& groupKey,
2281 const std::string& startPath,
2282 const std::string& modifiedTables,
2283 const std::string& recordList)
2286 setupActiveTablesXML(xmlOut,
2298 ConfigurationTree targetNode = cfgMgr->getNode(startPath);
2299 TableBase* table = cfgMgr->getTableByName(targetNode.getTableName());
2301 __SUP_COUT__ << table->getTableName() << __E__;
2302 TableVersion temporaryVersion;
2311 bool firstSave =
true;
2315 std::istringstream f(recordList);
2316 std::string recordUID;
2319 while(getline(f, recordUID,
','))
2321 recordUID = StringMacros::decodeURIComponent(recordUID);
2323 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2327 if(!(temporaryVersion = targetNode.getTableVersion())
2328 .isTemporaryVersion())
2330 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2332 temporaryVersion = table->createTemporaryView(temporaryVersion);
2333 cfgMgr->saveNewTable(targetNode.getTableName(),
2337 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2341 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2352 table->getViewP()->findRow(table->getViewP()->getColUID(), recordUID);
2353 table->getViewP()->deleteRow(row);
2358 table->getViewP()->init();
2360 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2362 catch(std::runtime_error& e)
2364 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << __E__;
2365 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2366 xmlOut.addTextElementToData(
"Error", ss.str());
2370 __SUP_SS__ << (
"Error removing record(s)!\n\n") << __E__;
2375 catch(
const std::exception& e)
2377 ss <<
"Exception message: " << e.what();
2382 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2383 xmlOut.addTextElementToData(
"Error", ss.str());
2403 void ConfigurationGUISupervisor::handleFillRenameTreeNodeRecordsXML(
2404 HttpXmlDocument& xmlOut,
2405 ConfigurationManagerRW* cfgMgr,
2406 const std::string& groupName,
2407 const TableGroupKey& groupKey,
2408 const std::string& startPath,
2409 const std::string& modifiedTables,
2410 const std::string& recordList,
2411 const std::string& newRecordList)
2414 setupActiveTablesXML(xmlOut,
2426 ConfigurationTree targetNode = cfgMgr->getNode(startPath);
2427 TableBase* table = cfgMgr->getTableByName(targetNode.getTableName());
2429 __SUP_COUT__ << table->getTableName() << __E__;
2430 TableVersion temporaryVersion;
2440 std::vector<std::string> recordArray =
2441 StringMacros::getVectorFromString(recordList);
2442 std::vector<std::string> newRecordArray =
2443 StringMacros::getVectorFromString(newRecordList);
2445 __SUP_COUTV__(StringMacros::vectorToString(recordArray));
2446 __SUP_COUTV__(StringMacros::vectorToString(newRecordArray));
2448 if(recordArray.size() == 0 || recordArray.size() != newRecordArray.size())
2451 <<
"Invalid record size vs new record name size, they must be the same: "
2452 << recordArray.size() <<
" vs " << newRecordArray.size() << __E__;
2458 if(!(temporaryVersion = targetNode.getTableVersion()).isTemporaryVersion())
2460 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2462 temporaryVersion = table->createTemporaryView(temporaryVersion);
2463 cfgMgr->saveNewTable(targetNode.getTableName(),
2467 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2470 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2477 for(
unsigned int i = 0; i < recordArray.size(); ++i)
2479 row = table->getViewP()->findRow(
2480 table->getViewP()->getColUID(),
2481 StringMacros::decodeURIComponent(recordArray[i]));
2483 table->getViewP()->setValueAsString(
2484 newRecordArray[i], row, table->getViewP()->getColUID());
2487 table->getViewP()->init();
2489 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2491 catch(std::runtime_error& e)
2493 __SUP_SS__ << (
"Error renaming record(s)!\n\n" + std::string(e.what())) << __E__;
2494 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2495 xmlOut.addTextElementToData(
"Error", ss.str());
2499 __SUP_SS__ << (
"Error renaming record(s)!\n\n") << __E__;
2504 catch(
const std::exception& e)
2506 ss <<
"Exception message: " << e.what();
2511 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2512 xmlOut.addTextElementToData(
"Error", ss.str());
2533 void ConfigurationGUISupervisor::handleFillCopyTreeNodeRecordsXML(
2534 HttpXmlDocument& xmlOut,
2535 ConfigurationManagerRW* cfgMgr,
2536 const std::string& groupName,
2537 const TableGroupKey& groupKey,
2538 const std::string& startPath,
2539 const std::string& modifiedTables,
2540 const std::string& recordList,
2541 unsigned int numberOfCopies )
2547 setupActiveTablesXML(xmlOut,
2559 ConfigurationTree targetNode = cfgMgr->getNode(startPath);
2560 TableBase* table = cfgMgr->getTableByName(targetNode.getTableName());
2562 __SUP_COUT__ << table->getTableName() << __E__;
2563 TableVersion temporaryVersion;
2573 std::vector<std::string> recordArray =
2574 StringMacros::getVectorFromString(recordList);
2575 __SUP_COUTV__(StringMacros::vectorToString(recordArray));
2579 if(!(temporaryVersion = targetNode.getTableVersion()).isTemporaryVersion())
2581 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2583 temporaryVersion = table->createTemporaryView(temporaryVersion);
2584 cfgMgr->saveNewTable(targetNode.getTableName(),
2588 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2591 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2598 for(
const auto& recordUID : recordArray)
2600 row = table->getViewP()->findRow(table->getViewP()->getColUID(),
2601 StringMacros::decodeURIComponent(recordUID));
2602 for(
unsigned int i = 0; i < numberOfCopies; ++i)
2603 table->getViewP()->copyRows(
2604 cfgMgr->getUsername(),
2613 table->getViewP()->init();
2615 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2617 catch(std::runtime_error& e)
2619 __SUP_SS__ << (
"Error copying record(s)!\n\n" + std::string(e.what())) << __E__;
2620 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2621 xmlOut.addTextElementToData(
"Error", ss.str());
2625 __SUP_SS__ << (
"Error copying record(s)!\n\n") << __E__;
2630 catch(
const std::exception& e)
2632 ss <<
"Exception message: " << e.what();
2637 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2638 xmlOut.addTextElementToData(
"Error", ss.str());
2659 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(
2660 HttpXmlDocument& xmlOut,
2661 ConfigurationManagerRW* cfgMgr,
2662 const std::string& groupName,
2663 const TableGroupKey& groupKey,
2664 const std::string& startPath,
2665 const std::string& modifiedTables,
2666 const std::string& recordList,
2667 const std::string& fieldList,
2668 const std::string& valueList,
2669 const std::string& author)
2672 setupActiveTablesXML(xmlOut,
2687 std::vector<std::string > fieldPaths;
2690 std::istringstream f(fieldList);
2691 std::string fieldPath;
2692 while(getline(f, fieldPath,
','))
2694 fieldPaths.push_back(StringMacros::decodeURIComponent(fieldPath));
2696 __SUP_COUT__ << fieldList << __E__;
2697 for(
const auto& field : fieldPaths)
2698 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2701 std::vector<std::string > fieldValues;
2704 std::istringstream f(valueList);
2705 std::string fieldValue;
2706 while(getline(f, fieldValue,
','))
2708 fieldValues.push_back(fieldValue);
2713 if(valueList.size() && valueList[valueList.size() - 1] ==
',')
2714 fieldValues.push_back(
"");
2716 __SUP_COUT__ << valueList << __E__;
2717 for(
const auto& value : fieldValues)
2718 __SUP_COUT__ <<
"fieldValue " << value << __E__;
2721 if(fieldPaths.size() != fieldValues.size())
2724 __THROW__(ss.str() +
"Mismatch in fields and values array size!");
2730 TableVersion temporaryVersion;
2731 std::istringstream f(recordList);
2732 std::string recordUID;
2735 while(getline(f, recordUID,
','))
2737 recordUID = StringMacros::decodeURIComponent(recordUID);
2740 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2743 for(i = 0; i < fieldPaths.size(); ++i)
2745 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << __E__;
2746 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << __E__;
2750 ConfigurationTree targetNode =
2751 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
2786 __SUP_COUT__ <<
"Getting table " << targetNode.getFieldTableName()
2790 table = cfgMgr->getTableByName(
2791 targetNode.getFieldTableName());
2792 if(!(temporaryVersion = table->getViewP()->getVersion())
2793 .isTemporaryVersion())
2797 table->createTemporaryView(table->getViewP()->getVersion());
2798 cfgMgr->saveNewTable(table->getTableName(),
2803 __SUP_COUT__ <<
"Created temporary version "
2804 << table->getTableName() <<
"-v" << temporaryVersion
2808 __SUP_COUT__ <<
"Using temporary version " << table->getTableName()
2809 <<
"-v" << temporaryVersion << __E__;
2813 table->getViewP()->setURIEncodedValue(fieldValues[i],
2814 targetNode.getFieldRow(),
2815 targetNode.getFieldColumn(),
2824 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2826 catch(std::runtime_error& e)
2828 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what()))
2830 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2831 xmlOut.addTextElementToData(
"Error", ss.str());
2835 __SUP_SS__ << (
"Error setting field values!\n\n") << __E__;
2840 catch(
const std::exception& e)
2842 ss <<
"Exception message: " << e.what();
2847 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2848 xmlOut.addTextElementToData(
"Error", ss.str());
2867 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(
2868 HttpXmlDocument& xmlOut,
2869 ConfigurationManagerRW* cfgMgr,
2870 const std::string& groupName,
2871 const TableGroupKey& groupKey,
2872 const std::string& startPath,
2873 const std::string& modifiedTables,
2874 const std::string& recordList,
2875 const std::string& fieldList)
2878 setupActiveTablesXML(
2879 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
2886 std::vector<std::string > fieldPaths;
2889 std::istringstream f(fieldList);
2890 std::string fieldPath;
2891 while(getline(f, fieldPath,
','))
2893 fieldPaths.push_back(StringMacros::decodeURIComponent(fieldPath));
2895 __SUP_COUT__ << fieldList << __E__;
2900 std::istringstream f(recordList);
2901 std::string recordUID;
2902 while(getline(f, recordUID,
','))
2904 recordUID = StringMacros::decodeURIComponent(recordUID);
2906 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2908 xercesc::DOMElement* parentEl =
2909 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2912 for(
const auto& fieldPath : fieldPaths)
2917 ConfigurationTree node =
2918 cfgMgr->getNode(startPath +
"/" + recordUID +
"/" + fieldPath);
2920 xmlOut.addTextElementToParent(
"FieldPath", fieldPath, parentEl);
2922 xmlOut.addTextElementToParent(
2924 node.getValueAsString(
true ),
2930 catch(std::runtime_error& e)
2932 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what()))
2934 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2935 xmlOut.addTextElementToData(
"Error", ss.str());
2939 __SUP_SS__ << (
"Error getting field values!\n\n") << __E__;
2944 catch(
const std::exception& e)
2946 ss <<
"Exception message: " << e.what();
2951 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2952 xmlOut.addTextElementToData(
"Error", ss.str());
2975 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(
2976 HttpXmlDocument& xmlOut,
2977 ConfigurationManagerRW* cfgMgr,
2978 const std::string& groupName,
2979 const TableGroupKey& groupKey,
2980 const std::string& startPath,
2982 const std::string& modifiedTables,
2983 const std::string& recordList,
2984 const std::string& fieldList)
2987 setupActiveTablesXML(
2988 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
2992 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
2996 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
2997 __SUP_COUT__ << ss.str();
3006 std::vector<ConfigurationTree::RecordField> retFieldList;
3009 ConfigurationTree startNode = cfgMgr->getNode(startPath);
3010 if(startNode.isLinkNode() && startNode.isDisconnected())
3012 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3018 std::vector<std::string > fieldAcceptList, fieldRejectList;
3023 std::istringstream f(fieldList);
3024 std::string fieldPath, decodedFieldPath;
3025 while(getline(f, fieldPath,
','))
3027 decodedFieldPath = StringMacros::decodeURIComponent(fieldPath);
3029 if(decodedFieldPath[0] ==
'!')
3030 fieldRejectList.push_back(decodedFieldPath.substr(1));
3032 fieldAcceptList.push_back(decodedFieldPath);
3034 __SUP_COUT__ << fieldList << __E__;
3035 for(
auto& field : fieldAcceptList)
3036 __SUP_COUT__ <<
"fieldAcceptList " << field << __E__;
3037 for(
auto& field : fieldRejectList)
3038 __SUP_COUT__ <<
"fieldRejectList " << field << __E__;
3042 std::vector<std::string > records;
3043 if(recordList ==
"*")
3046 records = startNode.getChildrenNames();
3047 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3048 for(
auto& record : records)
3049 __SUP_COUT__ <<
"recordList " << record << __E__;
3051 else if(recordList !=
"")
3055 std::istringstream f(recordList);
3056 std::string recordStr;
3057 while(getline(f, recordStr,
','))
3059 records.push_back(StringMacros::decodeURIComponent(recordStr));
3061 __SUP_COUT__ << recordList << __E__;
3062 for(
auto& record : records)
3063 __SUP_COUT__ <<
"recordList " << record << __E__;
3068 retFieldList = startNode.getCommonFields(
3069 records, fieldAcceptList, fieldRejectList, depth);
3073 xercesc::DOMElement* parentTypeEl;
3074 for(
const auto& fieldInfo : retFieldList)
3076 xmlOut.addTextElementToParent(
3077 "FieldTableName", fieldInfo.tableName_, parentEl);
3078 xmlOut.addTextElementToParent(
3079 "FieldColumnName", fieldInfo.columnName_, parentEl);
3080 xmlOut.addTextElementToParent(
3081 "FieldRelativePath", fieldInfo.relativePath_, parentEl);
3082 xmlOut.addTextElementToParent(
3083 "FieldColumnType", fieldInfo.columnInfo_->getType(), parentEl);
3084 xmlOut.addTextElementToParent(
3085 "FieldColumnDataType", fieldInfo.columnInfo_->getDataType(), parentEl);
3086 xmlOut.addTextElementToParent(
"FieldColumnDefaultValue",
3087 fieldInfo.columnInfo_->getDefaultValue(),
3091 xmlOut.addTextElementToParent(
"FieldColumnDataChoices",
"", parentEl);
3094 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
3095 xmlOut.addTextElementToParent(
3096 "FieldColumnDataChoice",
3097 fieldInfo.columnInfo_->getDefaultValue(),
3099 for(
const auto& dataChoice : dataChoices)
3100 xmlOut.addTextElementToParent(
3101 "FieldColumnDataChoice", dataChoice, parentTypeEl);
3104 catch(std::runtime_error& e)
3106 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
3108 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3109 xmlOut.addTextElementToData(
"Error", ss.str());
3113 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
3118 catch(
const std::exception& e)
3120 ss <<
"Exception message: " << e.what();
3125 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3126 xmlOut.addTextElementToData(
"Error", ss.str());
3158 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(
3159 HttpXmlDocument& xmlOut,
3160 ConfigurationManagerRW* cfgMgr,
3161 const std::string& groupName,
3162 const TableGroupKey& groupKey,
3163 const std::string& startPath,
3164 const std::string& modifiedTables,
3165 const std::string& recordList,
3166 const std::string& fieldList)
3169 setupActiveTablesXML(
3170 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3176 if(startPath ==
"/")
3179 ConfigurationTree startNode = cfgMgr->getNode(startPath);
3180 if(startNode.isLinkNode() && startNode.isDisconnected())
3182 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3183 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3188 std::vector<std::string > records;
3189 if(recordList ==
"*")
3192 records = startNode.getChildrenNames();
3193 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3194 for(
auto& record : records)
3195 __SUP_COUT__ <<
"recordList " << record << __E__;
3197 else if(recordList !=
"")
3201 std::istringstream f(recordList);
3202 std::string recordStr;
3203 while(getline(f, recordStr,
','))
3205 records.push_back(StringMacros::decodeURIComponent(recordStr));
3207 __SUP_COUT__ << recordList << __E__;
3208 for(
auto& record : records)
3209 __SUP_COUT__ <<
"recordList " << record << __E__;
3214 std::vector<std::string > fieldsToGet;
3219 if(fieldList ==
"AUTO")
3224 __SUP_COUT__ <<
"Getting AUTO filter fields!" << __E__;
3226 std::vector<ConfigurationTree::RecordField> retFieldList;
3227 std::vector<std::string > fieldAcceptList,
3229 fieldRejectList.push_back(
"*" + TableViewColumnInfo::COL_NAME_COMMENT);
3230 retFieldList = startNode.getCommonFields(
3231 records, fieldAcceptList, fieldRejectList, 5,
true );
3233 for(
const auto& retField : retFieldList)
3234 fieldsToGet.push_back(retField.relativePath_ + retField.columnName_);
3238 std::istringstream f(fieldList);
3239 std::string fieldPath;
3240 while(getline(f, fieldPath,
','))
3242 fieldsToGet.push_back(StringMacros::decodeURIComponent(fieldPath));
3244 __SUP_COUTV__(fieldList);
3248 __SUP_COUTV__(StringMacros::vectorToString(fieldsToGet));
3252 ConfigurationTree startNode = cfgMgr->getNode(startPath);
3253 std::string fieldGroupIDChildLinkIndex;
3254 for(
auto& field : fieldsToGet)
3256 __SUP_COUTV__(field);
3258 xercesc::DOMElement* parentEl =
3259 xmlOut.addTextElementToData(
"field", field);
3265 std::set<std::string > uniqueValues =
3266 startNode.getUniqueValuesForField(
3267 records, field, &fieldGroupIDChildLinkIndex);
3269 if(fieldGroupIDChildLinkIndex !=
"")
3270 xmlOut.addTextElementToParent(
3271 "childLinkIndex", fieldGroupIDChildLinkIndex, parentEl);
3273 for(
auto& uniqueValue : uniqueValues)
3275 __SUP_COUT__ <<
"uniqueValue " << uniqueValue << __E__;
3277 xmlOut.addTextElementToParent(
"uniqueValue", uniqueValue, parentEl);
3282 catch(std::runtime_error& e)
3284 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
3286 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3287 xmlOut.addTextElementToData(
"Error", ss.str());
3291 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
3296 catch(
const std::exception& e)
3298 ss <<
"Exception message: " << e.what();
3303 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3304 xmlOut.addTextElementToData(
"Error", ss.str());
3328 void ConfigurationGUISupervisor::handleFillTreeViewXML(
3329 HttpXmlDocument& xmlOut,
3330 ConfigurationManagerRW* cfgMgr,
3331 const std::string& groupName,
3332 const TableGroupKey& groupKey,
3333 const std::string& startPath,
3335 bool hideStatusFalse,
3336 const std::string& modifiedTables,
3337 const std::string& filterList,
3338 const std::string& diffGroupName ,
3339 const TableGroupKey& diffGroupKey )
3341 __SUP_COUTT__ <<
"get Tree View: " << groupName <<
"(" << groupKey <<
")" << __E__;
3373 bool doDiff = (diffGroupName !=
"" && !diffGroupKey.isInvalid());
3375 std::map<std::string , TableVersion > diffMemberMap;
3376 ConfigurationManagerRW tmpCfgMgr(
"TreeDiff");
3377 ConfigurationManagerRW* diffCfgMgr = &tmpCfgMgr;
3378 std::string diffAccumulateErrors;
3385 for(
auto& activeTable : cfgMgr->getActiveVersions())
3386 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3389 cfgMgr->loadTableGroup(diffGroupName,
3402 for(
auto& activeTable : cfgMgr->getActiveVersions())
3403 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3406 __SUP_COUTT__ <<
"Diff Group tables loaded." << __E__;
3407 diffCfgMgr->copyTableGroupFromCache(
3408 *cfgMgr, diffMemberMap, diffGroupName, diffGroupKey);
3409 __SUP_COUTT__ <<
"Diff Group tables copied to local diff config manager."
3413 for(
auto& memberPair : diffMemberMap)
3414 diffCfgMgr->getTableByName(memberPair.first)
3415 ->setActiveView(memberPair.second);
3417 for(
const auto& lastGroupLoaded : cfgMgr->getLastTableGroups())
3418 __SUP_COUT__ <<
"cfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3419 << lastGroupLoaded.second.first.first <<
"("
3420 << lastGroupLoaded.second.first.second <<
")";
3422 for(
const auto& lastGroupLoaded : diffCfgMgr->getLastTableGroups())
3423 __SUP_COUT__ <<
"diffCfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3424 << lastGroupLoaded.second.first.first <<
"("
3425 << lastGroupLoaded.second.first.second <<
")";
3428 if(diffCfgMgr->getLastTableGroups().size() == 1)
3430 __SUP_COUT__ <<
"Type already loaded to diff = "
3431 << diffCfgMgr->getLastTableGroups().begin()->first << __E__;
3434 auto groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3435 if(diffCfgMgr->getLastTableGroups().begin()->first ==
3436 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT)
3437 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION;
3438 else if(diffCfgMgr->getLastTableGroups().begin()->first ==
3439 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
3440 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3443 <<
"Loading " << groupTypeToLoad
3444 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first <<
"("
3445 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second
3448 diffCfgMgr->copyTableGroupFromCache(
3450 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second,
3451 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first,
3452 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second);
3455 for(
auto& memberPair :
3456 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second)
3457 diffCfgMgr->getTableByName(memberPair.first)
3458 ->setActiveView(memberPair.second);
3465 for(
auto& activeTable : cfgMgr->getActiveVersions())
3466 __SUP_COUTT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3468 for(
auto& activeTable : diffCfgMgr->getActiveVersions())
3469 __SUP_COUTT__ <<
"diffCfgMgr " << activeTable.first <<
"-v"
3470 << activeTable.second << __E__;
3472 __SUP_COUTT__ <<
"Diff Group tables are setup: " << diffAccumulateErrors << __E__;
3477 bool usingActiveGroups = (groupName ==
"" || groupKey.isInvalid());
3478 std::map<std::string , TableVersion > memberMap;
3480 std::string accumulatedErrors =
"";
3481 setupActiveTablesXML(xmlOut,
3493 if(memberMap.size() >
3494 ConfigurationManager::contextMemberNames_.size() + 1
3495 && startPath ==
"/")
3497 __COUTT__ <<
"Checking for orphaned tables..." << __E__;
3500 std::set<std::string > linkingTables;
3501 for(
const auto& tableInfo : cfgMgr->getAllTableInfo())
3505 __COUT_TYPE__(TLVL_DEBUG + 30)
3506 << __COUT_HDR__ <<
"Table " << tableInfo.first << __E__;
3507 if(!tableInfo.second.tablePtr_->isActive())
3510 __COUT_TYPE__(TLVL_DEBUG + 30)
3511 << __COUT_HDR__ <<
"Table active " << tableInfo.first << __E__;
3513 const TableView& view = tableInfo.second.tablePtr_->getView();
3515 bool addedThisTable =
false;
3516 for(
unsigned int col = 0; col < view.getNumberOfColumns(); ++col)
3518 if(!view.getColumnInfo(col).isChildLink())
3521 __COUT_TYPE__(TLVL_DEBUG + 30)
3522 << __COUT_HDR__ <<
"Table " << tableInfo.first
3523 <<
" col: " << view.getColumnInfo(col).getName() << __E__;
3525 for(
unsigned int r = 0; r < view.getNumberOfRows(); ++r)
3527 if(view.getDataView()[r][col] ==
"" ||
3528 view.getDataView()[r][col] ==
3529 TableViewColumnInfo::DATATYPE_STRING_DEFAULT)
3534 linkingTables.emplace(tableInfo.first);
3535 addedThisTable =
true;
3537 linkingTables.emplace(
3538 view.getDataView()[r][col]);
3542 __COUTTV__(StringMacros::setToString(linkingTables));
3544 std::string missingTables =
"";
3545 for(
const auto& member : memberMap)
3548 if(linkingTables.find(member.first) != linkingTables.end())
3551 if(missingTables.size())
3552 missingTables +=
", ";
3553 missingTables += member.first;
3556 if(missingTables.size())
3558 __COUTV__(missingTables);
3559 std::stringstream ss;
3560 ss <<
"The following member tables of table group '" << groupName <<
"("
3562 <<
")' were identified as possibly orphaned (i.e. no active tables link "
3563 "to these tables, and these tables have no links to other tables):\n\n"
3564 << missingTables <<
"." << __E__;
3565 xmlOut.addTextElementToData(
"NoTreeLinkWarning", ss.str());
3569 if(accumulatedErrors !=
"")
3571 xmlOut.addTextElementToData(
"Warning", accumulatedErrors);
3573 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors
3576 __SUP_COUT__ <<
"Active table versions: "
3577 << StringMacros::mapToString(cfgMgr->getActiveVersions()) << __E__;
3581 __SUP_COUTT__ <<
"Active tables are setup. No issues found." << __E__;
3582 __SUP_COUTT__ <<
"Active table versions: "
3583 << StringMacros::mapToString(cfgMgr->getActiveVersions()) << __E__;
3588 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
3593 std::vector<std::pair<std::string, ConfigurationTree>> rootMap;
3594 std::map<std::string, ConfigurationTree> diffRootMap;
3596 if(startPath ==
"/")
3600 std::string accumulateTreeErrs;
3602 if(usingActiveGroups)
3603 rootMap = cfgMgr->getChildren(0, &accumulateTreeErrs);
3605 rootMap = cfgMgr->getChildren(&memberMap, &accumulateTreeErrs);
3610 diffCfgMgr->getChildrenMap(&diffMemberMap, &diffAccumulateErrors);
3611 __SUP_COUTV__(diffRootMap.size());
3612 for(
auto& diffChild : diffRootMap)
3613 __SUP_COUTV__(diffChild.first);
3616 __SUP_COUTV__(accumulateTreeErrs);
3618 if(accumulateTreeErrs !=
"")
3619 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
3623 ConfigurationTree startNode =
3624 cfgMgr->getNode(startPath,
true );
3625 if(startNode.isLinkNode() && startNode.isDisconnected())
3627 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
3632 std::map<std::string , std::string > filterMap;
3633 StringMacros::getMapFromString(
3636 std::set<char>({
';'}) ,
3637 std::set<char>({
'='}) );
3639 __COUTV__(StringMacros::mapToString(filterMap));
3641 rootMap = cfgMgr->getNode(startPath).getChildren(filterMap);
3647 ConfigurationTree diffStartNode = diffCfgMgr->getNode(
3650 if(diffStartNode.isLinkNode() && diffStartNode.isDisconnected())
3651 __SUP_COUTT__ <<
"Diff Group disconnected node." << __E__;
3654 diffCfgMgr->getNode(startPath).getChildrenMap(filterMap);
3656 catch(
const std::runtime_error& e)
3659 __SUP_COUTT__ <<
"Diff Group node does not exist." << __E__;
3666 for(
auto& treePair : rootMap)
3668 treePair.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
3672 __SUP_COUTT__ <<
"Diff Tree recursive handling." << __E__;
3675 std::set<std::string > rootMapToSearch;
3676 for(
const auto& rootMember : rootMap)
3677 rootMapToSearch.emplace(rootMember.first);
3679 std::stringstream rootSs;
3680 for(
const auto& rootMember : rootMap)
3681 rootSs <<
", " << rootMember.first;
3684 std::stringstream diffRootSs;
3685 for(
const auto& diffMember : diffRootMap)
3687 diffRootSs <<
", " << diffMember.first <<
":"
3688 << diffMember.second.getNodeType();
3689 if(rootMapToSearch.find(diffMember.first) ==
3693 std::stringstream missingSs;
3694 missingSs << diffMember.first <<
3696 " <<< Only in " << diffGroupName <<
"(" << diffGroupKey
3698 xmlOut.addTextElementToParent(
3699 "diffNodeMissing", missingSs.str(), parentEl);
3702 if(diffMember.second.getNodeType() ==
"UIDLinkNode")
3706 << StringMacros::mapToString(diffCfgMgr->getActiveVersions())
3710 << StringMacros::mapToString(cfgMgr->getActiveVersions())
3713 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3714 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3716 __SUP_COUTT__ <<
"\t\t" << diffMember.second.getValueName() <<
": "
3717 << diffMember.second.getValueAsString() << __E__;
3719 __SUP_COUTT__ << diffMember.second.nodeDump();
3723 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3724 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3727 for(
auto& treePair : rootMap)
3729 if(diffRootMap.find(treePair.first) == diffRootMap.end())
3731 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3733 ConfigurationTree rootNode(diffCfgMgr,
nullptr );
3744 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3746 recursiveTreeToXML(treePair.second,
3751 diffRootMap.at(treePair.first));
3756 catch(std::runtime_error& e)
3758 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << __E__;
3759 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3760 xmlOut.addTextElementToData(
"Error", ss.str());
3764 __SUP_SS__ <<
"Error detected generating XML tree!" << __E__;
3769 catch(
const std::exception& e)
3771 ss <<
"Exception message: " << e.what();
3776 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3777 xmlOut.addTextElementToData(
"Error", ss.str());
3787 void ConfigurationGUISupervisor::recursiveTreeToXML(
3788 const ConfigurationTree& t,
3790 HttpXmlDocument& xmlOut,
3791 xercesc::DOMElement* parentEl,
3792 bool hideStatusFalse,
3793 std::optional<std::reference_wrapper<const ConfigurationTree>> diffTree)
3795 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ << t.getValueAsString() << __E__;
3799 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ <<
"\t" << t.getValueName() <<
": "
3800 << t.getValueAsString() << __E__;
3802 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueName(), parentEl);
3803 if(diffTree.has_value() &&
3804 t.getValueName() != TableViewColumnInfo::COL_NAME_COMMENT &&
3805 t.getValueName() != TableViewColumnInfo::COL_NAME_AUTHOR &&
3806 t.getValueName() != TableViewColumnInfo::COL_NAME_CREATION)
3808 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ <<
"\t\t diff type "
3809 << diffTree->get().getNodeType() << __E__;
3811 if(diffTree->get().isValueNode())
3813 __COUT_TYPE__(TLVL_DEBUG + 30)
3814 << __COUT_HDR__ <<
"\t" << diffTree->get().getValueAsString() <<
" ? "
3815 << t.getValueAsString() << __E__;
3816 __COUT_TYPE__(TLVL_DEBUG + 30)
3817 << __COUT_HDR__ <<
"\t" << diffTree->get().getTableName() <<
"-v"
3818 << diffTree->get().getTableVersion() <<
" ? " << t.getTableName()
3819 <<
"-v" << t.getTableVersion() << __E__;
3821 if(t.getValueAsString() != diffTree->get().getValueAsString())
3823 std::stringstream missingSs;
3824 auto diffGroupPair =
3825 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3826 diffTree->get().getTableName());
3827 missingSs <<
"<<< '" << diffTree->get().getValueAsString() <<
"' in "
3828 << diffGroupPair.first <<
"(" << diffGroupPair.second
3830 xmlOut.addTextElementToParent(
"nodeDiff", missingSs.str(), parentEl);
3835 std::stringstream missingSs;
3837 auto diffGroupPair =
3838 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3840 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
3841 << diffGroupPair.second <<
") >>>";
3842 xmlOut.addTextElementToParent(
"nodeDiff", missingSs.str(), parentEl);
3845 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ <<
"\t" << t.getValueName()
3846 <<
": " << t.getValueAsString() << __E__;
3850 xmlOut.addTextElementToParent(
"value", t.getValueAsString(), parentEl);
3851 parentEl = xmlOut.addTextElementToParent(
"valueType", t.getValueType(), parentEl);
3855 if(t.getValueType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
3856 t.getValueType() == TableViewColumnInfo::TYPE_BITMAP_DATA)
3858 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ << t.getValueType() << __E__;
3860 std::vector<std::string> choices = t.getFixedChoices();
3861 for(
const auto& choice : choices)
3862 xmlOut.addTextElementToParent(
"fixedChoice", choice, parentEl);
3867 __COUT_TYPE__(TLVL_DEBUG + 30)
3868 << __COUT_HDR__ <<
"\t" << t.getValueAsString() << __E__;
3872 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ <<
"\t\t" << t.getValueName()
3873 <<
": " << t.getValueAsString() << __E__;
3877 parentEl = xmlOut.addTextElementToParent(
"node", t.getValueName(), parentEl);
3879 if(diffTree.has_value())
3881 __COUT_TYPE__(TLVL_DEBUG + 30) << __COUT_HDR__ <<
"\t\t diff type "
3882 << diffTree->get().getNodeType() << __E__;
3887 __COUT_TYPE__(TLVL_DEBUG + 30)
3888 << __COUT_HDR__ <<
"" << t.getValueAsString() << __E__;
3889 std::stringstream missingSs;
3891 auto diffGroupPair =
3892 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3893 t.getParentTableName());
3894 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
3895 << diffGroupPair.second <<
") >>>";
3896 xmlOut.addTextElementToParent(
"nodeDiff", missingSs.str(), parentEl);
3898 else if(t.isDisconnected() != diffTree->get().isDisconnected())
3900 __COUT_TYPE__(TLVL_DEBUG + 30)
3901 << __COUT_HDR__ <<
"\t\t diff isDisconnected "
3902 << diffTree->get().isDisconnected() << __E__;
3904 std::stringstream missingSs;
3906 auto diffGroupPair =
3907 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3908 t.getParentTableName());
3909 missingSs <<
"<<< Link is "
3910 << (diffTree->get().isDisconnected() ?
"DISCONNECTED"
3912 <<
" in " << diffGroupPair.first <<
"("
3913 << diffGroupPair.second <<
") >>>";
3914 xmlOut.addTextElementToParent(
"nodeDiff", missingSs.str(), parentEl);
3916 else if(!t.isDisconnected() &&
3917 t.isUIDLinkNode() != diffTree->get().isUIDLinkNode())
3919 __COUT_TYPE__(TLVL_DEBUG + 30)
3920 << __COUT_HDR__ <<
"" << t.getValueAsString() << __E__;
3921 std::stringstream missingSs;
3923 auto diffGroupPair =
3924 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3925 t.getParentTableName());
3926 missingSs <<
"<<< Link is "
3927 << (diffTree->get().isUIDLinkNode() ?
"a UID Link"
3929 <<
" in " << diffGroupPair.first <<
"("
3930 << diffGroupPair.second <<
") >>>";
3931 xmlOut.addTextElementToParent(
"nodeDiff", missingSs.str(), parentEl);
3933 else if(!t.isDisconnected() && t.isUIDLinkNode() &&
3934 t.getValueAsString() !=
3935 diffTree->get().getValueAsString())
3937 __COUT_TYPE__(TLVL_DEBUG + 30)
3938 << __COUT_HDR__ <<
"" << t.getValueAsString() << __E__;
3939 std::stringstream missingSs;
3941 auto diffGroupPair =
3942 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3943 t.getParentTableName());
3944 missingSs <<
"<<< Link to '" << diffTree->get().getValueAsString()
3945 <<
"' in " << diffGroupPair.first <<
"("
3946 << diffGroupPair.second <<
") >>>";
3947 xmlOut.addTextElementToParent(
"nodeDiff", missingSs.str(), parentEl);
3949 else if(!t.isDisconnected() && !t.isUIDLinkNode())
3951 __COUT_TYPE__(TLVL_DEBUG + 30)
3952 << __COUT_HDR__ <<
"" << t.getValueAsString() << __E__;
3953 std::stringstream missingSs;
3955 auto tchildren = t.getChildrenMap();
3956 auto dtchildren = diffTree->get().getChildrenMap();
3957 missingSs <<
"<<< Group link";
3958 if(tchildren.size() != dtchildren.size())
3959 missingSs <<
" has " << tchildren.size() <<
" vs "
3960 << dtchildren.size() <<
" children..";
3961 for(
auto& tchild : tchildren)
3962 if(dtchildren.find(tchild.first) == dtchildren.end())
3963 missingSs <<
" '" << tchild.first <<
"' missing..";
3964 for(
auto& dtchild : dtchildren)
3965 if(tchildren.find(dtchild.first) == tchildren.end())
3966 missingSs <<
" '" << dtchild.first <<
"' present...";
3969 if(missingSs.str().length() > std::string(
"<<< Group link").length())
3971 auto diffGroupPair =
3973 .getConfigurationManager()
3974 ->getGroupOfLoadedTable(diffTree->get().getTableName());
3975 missingSs <<
" in " << diffGroupPair.first <<
"("
3976 << diffGroupPair.second <<
") >>>";
3977 xmlOut.addTextElementToParent(
3978 "nodeDiff", missingSs.str(), parentEl);
3982 __COUT_TYPE__(TLVL_DEBUG + 30)
3983 << __COUT_HDR__ <<
"" << t.getValueAsString() << __E__;
3986 if(t.isDisconnected())
3988 __COUT_TYPE__(TLVL_DEBUG + 30)
3989 << __COUT_HDR__ << t.getValueName() << __E__;
3995 xmlOut.addTextElementToParent(
"valueType", t.getValueType(), parentEl);
3998 xmlOut.addTextElementToParent(
3999 (t.isGroupLinkNode() ?
"Group" :
"U") + std::string(
"ID"),
4000 t.getDisconnectedLinkID(),
4002 xmlOut.addTextElementToParent(
4003 "LinkTableName", t.getDisconnectedTableName(), parentEl);
4004 xmlOut.addTextElementToParent(
4005 "LinkIndex", t.getChildLinkIndex(), parentEl);
4008 xercesc::DOMElement* choicesParentEl =
4009 xmlOut.addTextElementToParent(
"fixedChoices",
"", parentEl);
4013 std::vector<std::string> choices = t.getFixedChoices();
4014 __COUT_TYPE__(TLVL_DEBUG + 30)
4015 << __COUT_HDR__ <<
"choices.size() " << choices.size() << __E__;
4017 for(
const auto& choice : choices)
4018 xmlOut.addTextElementToParent(
"fixedChoice", choice, choicesParentEl);
4029 xmlOut.addTextElementToParent(
4030 (t.isGroupLinkNode() ?
"Group" :
"U") + std::string(
"ID"),
4031 t.getValueAsString(),
4034 xmlOut.addTextElementToParent(
"LinkTableName", t.getTableName(), parentEl);
4035 xmlOut.addTextElementToParent(
"LinkIndex", t.getChildLinkIndex(), parentEl);
4039 xercesc::DOMElement* choicesParentEl =
4040 xmlOut.addTextElementToParent(
"fixedChoices",
"", parentEl);
4041 std::vector<std::string> choices = t.getFixedChoices();
4043 for(
const auto& choice : choices)
4044 xmlOut.addTextElementToParent(
"fixedChoice", choice, choicesParentEl);
4049 __COUT_TYPE__(TLVL_DEBUG + 30)
4050 << __COUT_HDR__ <<
"\t\t" << t.getValueAsString() << __E__;
4051 bool returnNode =
true;
4053 if(t.isUIDNode() && hideStatusFalse)
4054 returnNode = t.isEnabled();
4059 xmlOut.addTextElementToParent(
"node", t.getValueAsString(), parentEl);
4061 xmlOut.addTextElementToParent(
"comment",
4062 t.getAuthor() +
": " + t.getComment(), parentEl);
4064 if(diffTree.has_value())
4066 __COUT_TYPE__(TLVL_DEBUG + 30)
4067 << __COUT_HDR__ <<
"\t\t diff type "
4068 << diffTree->get().getNodeType() << __E__;
4073 __COUT_TYPE__(TLVL_DEBUG + 30)
4074 << __COUT_HDR__ <<
"" << t.getValueAsString() << __E__;
4078 auto diffGroupPair =
4080 .getConfigurationManager()
4081 ->getGroupOfLoadedTable(t.getTableName());
4082 missingSs <<
"<<< Not in " << diffGroupPair.first <<
"("
4083 << diffGroupPair.second <<
") >>>";
4084 xmlOut.addTextElementToParent(
4085 "nodeDiff", missingSs.str(), parentEl);
4088 __COUT_TYPE__(TLVL_DEBUG + 30)
4089 << __COUT_HDR__ <<
"" << t.getValueAsString() << __E__;
4100 __COUT_TYPE__(TLVL_DEBUG + 30)
4101 << __COUT_HDR__ <<
"\t\t\t" << t.getValueAsString() << __E__;
4102 auto C = t.getChildren();
4121 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(
4122 HttpXmlDocument& xmlOut,
4123 ConfigurationManagerRW* cfgMgr,
4124 const std::string& linkToTableName,
4125 const TableVersion& linkToTableVersion,
4126 const std::string& linkIdType,
4127 const std::string& linkIndex,
4128 const std::string& linkInitId)
4141 const std::string& tableName = linkToTableName;
4142 const TableVersion& version = linkToTableVersion;
4143 TableBase* table = cfgMgr->getTableByName(tableName);
4146 table->setActiveView(version);
4150 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
4151 << version << __E__;
4152 cfgMgr->getVersionedTableByName(tableName, version);
4155 if(version != table->getViewVersion())
4157 __SUP_SS__ <<
"Target table version (" << version
4158 <<
") is not the currently active version (" << table->getViewVersion()
4159 <<
". Try refreshing the tree." << __E__;
4160 __SUP_COUT_WARN__ << ss.str();
4164 __SUP_COUT__ <<
"Active version is " << table->getViewVersion() << __E__;
4166 if(linkIdType ==
"UID")
4169 unsigned int col = table->getView().getColUID();
4170 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4171 xmlOut.addTextElementToData(
"linkToChoice",
4172 table->getView().getDataView()[row][col]);
4174 else if(linkIdType ==
"GroupID")
4180 __SUP_COUTV__(linkIndex);
4181 __SUP_COUTV__(linkInitId);
4183 std::set<std::string> setOfGroupIDs =
4184 table->getView().getSetOfGroupIDs(linkIndex);
4189 bool foundInitId =
false;
4190 for(
const auto& groupID : setOfGroupIDs)
4192 if(!foundInitId && linkInitId == groupID)
4195 xmlOut.addTextElementToData(
"linkToChoice", groupID);
4199 xmlOut.addTextElementToData(
"linkToChoice", linkInitId);
4202 unsigned int col = table->getView().getColUID();
4203 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4205 xmlOut.addTextElementToData(
"groupChoice",
4206 table->getView().getDataView()[row][col]);
4207 if(table->getView().isEntryInGroup(row, linkIndex, linkInitId))
4208 xmlOut.addTextElementToData(
"groupMember",
4209 table->getView().getDataView()[row][col]);
4214 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType <<
".'" << __E__;
4218 catch(std::runtime_error& e)
4220 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << __E__;
4221 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4222 xmlOut.addTextElementToData(
"Error", ss.str());
4226 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << __E__;
4231 catch(
const std::exception& e)
4233 ss <<
"Exception message: " << e.what();
4238 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4239 xmlOut.addTextElementToData(
"Error", ss.str());
4244 void ConfigurationGUISupervisor::handleMergeGroupsXML(
4245 HttpXmlDocument& xmlOut,
4246 ConfigurationManagerRW* cfgMgr,
4247 const std::string& groupANameContext,
4248 const TableGroupKey& groupAKeyContext,
4249 const std::string& groupBNameContext,
4250 const TableGroupKey& groupBKeyContext,
4251 const std::string& groupANameConfig,
4252 const TableGroupKey& groupAKeyConfig,
4253 const std::string& groupBNameConfig,
4254 const TableGroupKey& groupBKeyConfig,
4255 const std::string& author,
4256 const std::string& mergeApproach)
4259 __SUP_COUT__ <<
"Merging context group pair " << groupANameContext <<
" ("
4260 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4261 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4262 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4263 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4279 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" ||
4280 mergeApproach ==
"Skip"))
4282 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
4286 std::map<std::string , TableVersion > memberMapAContext,
4287 memberMapBContext, memberMapAConfig, memberMapBConfig;
4290 bool skippingContextPair =
false;
4291 bool skippingConfigPair =
false;
4292 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
4293 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
4295 skippingContextPair =
true;
4296 __SUP_COUTV__(skippingContextPair);
4298 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
4299 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
4301 skippingConfigPair =
true;
4302 __SUP_COUTV__(skippingConfigPair);
4306 if(!skippingContextPair)
4308 cfgMgr->loadTableGroup(groupANameContext,
4320 __SUP_COUTV__(StringMacros::mapToString(memberMapAContext));
4322 cfgMgr->loadTableGroup(groupBNameContext,
4335 __SUP_COUTV__(StringMacros::mapToString(memberMapBContext));
4339 if(!skippingConfigPair)
4341 cfgMgr->loadTableGroup(groupANameConfig,
4353 __SUP_COUTV__(StringMacros::mapToString(memberMapAConfig));
4355 cfgMgr->loadTableGroup(groupBNameConfig,
4368 __SUP_COUTV__(StringMacros::mapToString(memberMapBConfig));
4376 std::map<std::pair<std::string , std::string >,
4380 std::pair<std::string ,
4381 std::pair<std::string , std::string >>,
4383 groupidConversionMap;
4385 std::stringstream mergeReport;
4386 mergeReport <<
"======================================" << __E__;
4387 mergeReport <<
"Time of merge: " << StringMacros::getTimestampString() << __E__;
4388 mergeReport <<
"Merging context group pair " << groupANameContext <<
" ("
4389 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4390 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4391 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4392 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4393 mergeReport <<
"======================================" << __E__;
4397 for(
unsigned int i = 0; i < 2; ++i)
4399 if(i == 0 && mergeApproach !=
"Rename")
4403 for(
unsigned int j = 0; j < 2; ++j)
4405 if(j == 0 && skippingContextPair)
4407 __COUT__ <<
"Skipping context pair..." << __E__;
4410 else if(j == 1 && skippingConfigPair)
4412 __COUT__ <<
"Skipping table pair..." << __E__;
4416 std::map<std::string , TableVersion >& memberMapAref =
4417 j == 0 ? memberMapAContext : memberMapAConfig;
4419 std::map<std::string , TableVersion >& memberMapBref =
4420 j == 0 ? memberMapBContext : memberMapBConfig;
4423 __COUT__ <<
"Context pair..." << __E__;
4425 __COUT__ <<
"Table pair..." << __E__;
4427 __COUT__ <<
"Starting member map B scan." << __E__;
4428 for(
const auto& bkey : memberMapBref)
4430 __SUP_COUTV__(bkey.first);
4432 if(memberMapAref.find(bkey.first) == memberMapAref.end())
4434 mergeReport <<
"\n'" << mergeApproach <<
"'-Missing table '"
4435 << bkey.first <<
"' A=v" << -1 <<
", adding B=v"
4436 << bkey.second << __E__;
4439 memberMapAref[bkey.first] = bkey.second;
4441 else if(memberMapAref[bkey.first] != bkey.second)
4444 __SUP_COUTV__(memberMapAref[bkey.first]);
4445 __SUP_COUTV__(bkey.second);
4448 TableBase* table = cfgMgr->getTableByName(bkey.first);
4450 __SUP_COUT__ <<
"Got table." << __E__;
4452 TableVersion newVersion = table->mergeViews(
4454 ->getVersionedTableByName(bkey.first,
4455 memberMapAref[bkey.first])
4457 cfgMgr->getVersionedTableByName(bkey.first, bkey.second)
4463 groupidConversionMap,
4466 table->getTableName() ==
4467 ConfigurationManager::
4468 XDAQ_APPLICATION_TABLE_NAME
4474 __SUP_COUTV__(newVersion);
4481 ConfigurationSupervisorBase::saveModifiedVersionXML(
4492 catch(std::runtime_error& e)
4495 <<
"There was an error saving the '"
4496 << table->getTableName()
4497 <<
"' merge result to a persistent table version. "
4498 <<
"Perhaps you can modify this table in one of the "
4499 "groups to resolve this issue, and then re-merge."
4500 << __E__ << e.what();
4504 __SUP_COUTV__(newVersion);
4506 memberMapAref[bkey.first] = newVersion;
4515 if(!skippingContextPair)
4517 __SUP_COUT__ <<
"New context member map complete." << __E__;
4518 __SUP_COUTV__(StringMacros::mapToString(memberMapAContext));
4521 TableGroupKey newKeyContext = cfgMgr->saveNewTableGroup(
4524 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.toString() +
4525 ") and " + groupBNameContext +
" (" + groupBKeyContext.toString() +
").");
4528 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
4529 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.toString());
4531 if(!skippingConfigPair)
4533 __SUP_COUT__ <<
"New table member map complete." << __E__;
4534 __SUP_COUTV__(StringMacros::mapToString(memberMapAConfig));
4537 TableGroupKey newKeyConfig = cfgMgr->saveNewTableGroup(
4540 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.toString() +
4541 ") and " + groupBNameConfig +
" (" + groupBKeyConfig.toString() +
").");
4544 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
4545 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.toString());
4550 std::string mergeReportBasePath = std::string(__ENV__(
"USER_DATA"));
4551 std::string mergeReportPath =
"/ServiceData/";
4553 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4554 mergeReportPath +=
"ConfigurationGUI_mergeReports/";
4556 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4559 "merge_" + std::to_string(time(0)) +
"_" + std::to_string(clock()) +
".txt";
4560 __SUP_COUTV__(mergeReportPath);
4562 FILE* fp = fopen((mergeReportBasePath + mergeReportPath).c_str(),
"w");
4565 fprintf(fp,
"%s", mergeReport.str().c_str());
4567 xmlOut.addTextElementToData(
"MergeReportFile",
4568 "/$USER_DATA/" + mergeReportPath);
4571 xmlOut.addTextElementToData(
"MergeReportFile",
"FILE FAILURE");
4575 catch(std::runtime_error& e)
4577 __SUP_SS__ <<
"Error merging context group pair " << groupANameContext <<
" ("
4578 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4579 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4580 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4581 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
"': \n\n"
4582 << e.what() << __E__;
4583 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4584 xmlOut.addTextElementToData(
"Error", ss.str());
4588 __SUP_SS__ <<
"Unknown error merging context group pair " << groupANameContext <<
" ("
4589 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4590 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4591 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4592 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
".' \n\n";
4597 catch(
const std::exception& e)
4599 ss <<
"Exception message: " << e.what();
4604 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4605 xmlOut.addTextElementToData(
"Error", ss.str());
4610 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(
4611 HttpXmlDocument& xmlOut,
4612 ConfigurationManagerRW* cfgMgr,
4613 const std::string& groupName,
4614 const TableGroupKey& groupKey,
4615 const std::string& modifiedTables,
4616 const std::string& author,
4617 const std::string& planName,
4618 const std::string& commandString)
4621 __COUT__ <<
"handleSavePlanCommandSequenceXML " << planName << __E__;
4624 setupActiveTablesXML(xmlOut,
4634 TableEditStruct planTable(IterateTable::PLAN_TABLE,
4636 TableEditStruct targetTable(IterateTable::TARGET_TABLE,
4642 std::map<std::string , TableEditStruct> commandTableToEditMap;
4643 for(
const auto& commandPair : IterateTable::commandToTableMap_)
4644 if(commandPair.second !=
"")
4645 commandTableToEditMap.emplace(std::pair<std::string, TableEditStruct>(
4646 commandPair.second, TableEditStruct(commandPair.second, cfgMgr)));
4662 std::string groupName = planName +
"-Plan";
4663 __SUP_COUT__ <<
"Handling commands for group " << groupName << __E__;
4665 unsigned int groupIdCol =
4666 planTable.tableView_->findCol(IterateTable::planTableCols_.GroupID_);
4667 unsigned int cmdTypeCol =
4668 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandType_);
4670 unsigned int targetGroupIdCol =
4671 targetTable.tableView_->findCol(IterateTable::targetCols_.GroupID_);
4672 unsigned int targetTableCol =
4673 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLink_);
4674 unsigned int targetUIDCol =
4675 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLinkUID_);
4677 std::string groupLinkIndex =
4678 planTable.tableView_->getColumnInfo(groupIdCol).getChildLinkIndex();
4679 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << __E__;
4681 std::pair<
unsigned int ,
unsigned int > commandUidLink;
4684 planTable.tableView_->getChildLink(
4685 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandLink_),
4690 unsigned int cmdRow, cmdCol;
4691 std::string targetGroupName;
4695 std::string targetUID, cmdType;
4697 for(
unsigned int row = 0; row < planTable.tableView_->getNumberOfRows();
4700 targetUID = planTable.tableView_
4701 ->getDataView()[row][planTable.tableView_->getColUID()];
4702 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
4705 if(planTable.tableView_->isEntryInGroup(row, groupLinkIndex, groupName))
4707 __SUP_COUT__ <<
"Removing." << __E__;
4711 cmdType = planTable.tableView_->getDataView()[row][cmdTypeCol];
4712 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(cmdType);
4713 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4714 cmdTypeTableIt->second !=
4717 TableEditStruct& cmdTypeTableEdit =
4718 commandTableToEditMap.at(cmdTypeTableIt->second);
4719 cmdRow = cmdTypeTableEdit.tableView_->findRow(
4720 cmdTypeTableEdit.tableView_->getColUID(),
4721 planTable.tableView_
4722 ->getDataView()[row][commandUidLink.second]);
4729 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4730 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
4731 targetGroupName = cmdTypeTableEdit.tableView_
4732 ->getDataView()[cmdRow][cmdCol];
4734 for(
unsigned int trow = 0;
4735 trow < targetTable.tableView_->getNumberOfRows();
4739 if(targetTable.tableView_->isEntryInGroup(
4741 cmdTypeTableEdit.tableView_->getColumnInfo(cmdCol)
4742 .getChildLinkIndex(),
4745 __SUP_COUT__ <<
"Removing target." << __E__;
4747 if(targetTable.tableView_->removeRowFromGroup(
4758 __SUP_COUT__ <<
"No targets." << __E__;
4763 cmdTypeTableEdit.tableView_->deleteRow(cmdRow);
4765 cmdTypeTableEdit.modified_ =
true;
4769 if(planTable.tableView_->removeRowFromGroup(
4770 row, groupIdCol, groupName,
true ))
4779 std::vector<IterateTable::Command> commands;
4784 std::istringstream f(commandString);
4785 std::string commandSubString, paramSubString, paramValue;
4787 while(getline(f, commandSubString,
';'))
4789 __SUP_COUTT__ <<
"commandSubString " << commandSubString << __E__;
4790 std::istringstream g(commandSubString);
4793 while(getline(g, paramSubString,
','))
4795 __SUP_COUTT__ <<
"paramSubString " << paramSubString << __E__;
4798 if(paramSubString !=
"type")
4800 __SUP_SS__ <<
"Invalid command sequence" << __E__;
4804 commands.push_back(IterateTable::Command());
4806 getline(g, paramValue,
',');
4808 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4809 commands.back().type_ = paramValue;
4813 getline(g, paramValue,
',');
4815 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4817 commands.back().params_.emplace(
4818 std::pair<std::string ,
4821 StringMacros::decodeURIComponent(paramValue)));
4830 __SUP_COUT__ <<
"commands size " << commands.size() << __E__;
4837 unsigned int row, tgtRow;
4838 unsigned int targetIndex;
4839 std::string targetStr, cmdUID;
4841 for(
auto& command : commands)
4843 __SUP_COUT__ <<
"command " << command.type_ << __E__;
4844 __SUP_COUT__ <<
"table " << IterateTable::commandToTableMap_.at(command.type_)
4848 row = planTable.tableView_->addRow(
4849 author,
true ,
"planCommand");
4850 planTable.tableView_->addRowToGroup(row, groupIdCol, groupName);
4853 planTable.tableView_->setURIEncodedValue(command.type_, row, cmdTypeCol);
4856 planTable.tableView_->setValueAsString(
4857 "1", row, planTable.tableView_->getColStatus());
4860 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(command.type_);
4861 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4862 cmdTypeTableIt->second !=
4865 TableEditStruct& cmdTypeTableEdit =
4866 commandTableToEditMap.at(cmdTypeTableIt->second);
4867 __SUP_COUT__ <<
"table " << cmdTypeTableEdit.tableName_ << __E__;
4872 cmdRow = cmdTypeTableEdit.tableView_->addRow(
4873 author,
true , command.type_ +
"_COMMAND_");
4879 for(
auto& param : command.params_)
4881 __SUP_COUT__ <<
"\t param " << param.first <<
" : " << param.second
4884 if(param.first == IterateTable::targetParams_.Tables_)
4886 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
4887 std::istringstream f(param.second);
4890 while(getline(f, targetStr,
'='))
4892 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
4893 if(!command.targets_.size() ||
4894 command.targets_.back().table_ !=
"")
4896 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
4899 command.addTarget();
4900 command.targets_.back().table_ = targetStr;
4903 command.targets_[targetIndex++].table_ = targetStr;
4909 if(param.first == IterateTable::targetParams_.UIDs_)
4911 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
4912 std::istringstream f(param.second);
4915 while(getline(f, targetStr,
'='))
4917 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
4918 if(!command.targets_.size() ||
4919 command.targets_.back().UID_ !=
"")
4921 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
4924 command.addTarget();
4925 command.targets_.back().UID_ = targetStr;
4928 command.targets_[targetIndex++].UID_ = targetStr;
4933 cmdCol = cmdTypeTableEdit.tableView_->findCol(param.first);
4935 __SUP_COUT__ <<
"param col " << cmdCol << __E__;
4937 cmdTypeTableEdit.tableView_->setURIEncodedValue(
4938 param.second, cmdRow, cmdCol);
4942 cmdTypeTableEdit.tableView_
4943 ->getDataView()[cmdRow][cmdTypeTableEdit.tableView_->getColUID()];
4945 if(command.targets_.size())
4949 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
4952 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4953 IterateTable::commandTargetCols_.TargetsLink_);
4954 cmdTypeTableEdit.tableView_->setValueAsString(
4955 IterateTable::TARGET_TABLE, cmdRow, cmdCol);
4957 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4958 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
4959 cmdTypeTableEdit.tableView_->setValueAsString(
4960 cmdUID +
"_Targets", cmdRow, cmdCol);
4964 for(
const auto& target : command.targets_)
4966 __SUP_COUT__ << target.table_ <<
" " << target.UID_ << __E__;
4969 tgtRow = targetTable.tableView_->addRow(
4970 author,
true ,
"commandTarget");
4971 targetTable.tableView_->addRowToGroup(
4972 tgtRow, targetGroupIdCol, cmdUID +
"_Targets");
4975 targetTable.tableView_->setValueAsString(
4976 target.table_, tgtRow, targetTableCol);
4979 targetTable.tableView_->setValueAsString(
4980 target.UID_, tgtRow, targetUIDCol);
4985 planTable.tableView_->setValueAsString(
4986 cmdTypeTableEdit.tableName_, row, commandUidLink.first);
4987 planTable.tableView_->setValueAsString(
4988 cmdUID, row, commandUidLink.second);
4990 __SUP_COUT__ <<
"linked to uid = " << cmdUID << __E__;
4992 cmdTypeTableEdit.modified_ =
true;
5000 planTable.tableView_->print();
5001 planTable.tableView_->init();
5003 __SUP_COUT__ <<
"requestType tables:" << __E__;
5005 for(
auto& modifiedConfig : commandTableToEditMap)
5007 __SUP_COUTV__(modifiedConfig.second.modified_);
5008 modifiedConfig.second.tableView_->print();
5009 modifiedConfig.second.tableView_->init();
5012 targetTable.tableView_->print();
5013 targetTable.tableView_->init();
5018 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly "
5024 if(planTable.createdTemporaryVersion_)
5026 __SUP_COUT__ <<
"Erasing temporary version " << planTable.tableName_ <<
"-v"
5027 << planTable.temporaryVersion_ << __E__;
5029 cfgMgr->eraseTemporaryVersion(planTable.tableName_,
5030 planTable.temporaryVersion_);
5033 if(targetTable.createdTemporaryVersion_)
5035 __SUP_COUT__ <<
"Erasing temporary version " << targetTable.tableName_ <<
"-v"
5036 << targetTable.temporaryVersion_ << __E__;
5038 cfgMgr->eraseTemporaryVersion(targetTable.tableName_,
5039 targetTable.temporaryVersion_);
5042 for(
auto& modifiedConfig : commandTableToEditMap)
5044 if(modifiedConfig.second
5045 .createdTemporaryVersion_)
5047 __SUP_COUT__ <<
"Erasing temporary version "
5048 << modifiedConfig.second.tableName_ <<
"-v"
5049 << modifiedConfig.second.temporaryVersion_ << __E__;
5051 cfgMgr->eraseTemporaryVersion(modifiedConfig.second.tableName_,
5052 modifiedConfig.second.temporaryVersion_);
5063 TableVersion finalVersion = ConfigurationSupervisorBase::saveModifiedVersionXML(
5066 planTable.tableName_,
5067 planTable.originalVersion_,
5070 planTable.temporaryVersion_,
5073 __SUP_COUT__ <<
"Final plan version is " << planTable.tableName_ <<
"-v"
5074 << finalVersion << __E__;
5076 finalVersion = ConfigurationSupervisorBase::saveModifiedVersionXML(
5079 targetTable.tableName_,
5080 targetTable.originalVersion_,
5083 targetTable.temporaryVersion_,
5086 __SUP_COUT__ <<
"Final target version is " << targetTable.tableName_ <<
"-v"
5087 << finalVersion << __E__;
5089 for(
auto& modifiedConfig : commandTableToEditMap)
5091 if(!modifiedConfig.second.modified_)
5093 if(modifiedConfig.second
5094 .createdTemporaryVersion_)
5096 __SUP_COUT__ <<
"Erasing unmodified temporary version "
5097 << modifiedConfig.second.tableName_ <<
"-v"
5098 << modifiedConfig.second.temporaryVersion_ << __E__;
5100 cfgMgr->eraseTemporaryVersion(modifiedConfig.second.tableName_,
5101 modifiedConfig.second.temporaryVersion_);
5106 finalVersion = ConfigurationSupervisorBase::saveModifiedVersionXML(
5109 modifiedConfig.second.tableName_,
5110 modifiedConfig.second.originalVersion_,
5112 modifiedConfig.second.table_,
5113 modifiedConfig.second.temporaryVersion_,
5116 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.tableName_ <<
"-v"
5117 << finalVersion << __E__;
5120 handleFillModifiedTablesXML(xmlOut, cfgMgr);
5122 catch(std::runtime_error& e)
5124 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << __E__;
5125 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5126 xmlOut.addTextElementToData(
"Error", ss.str());
5130 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << __E__;
5135 catch(
const std::exception& e)
5137 ss <<
"Exception message: " << e.what();
5142 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5143 xmlOut.addTextElementToData(
"Error", ss.str());
5156 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(HttpXmlDocument& xmlOut,
5157 ConfigurationManagerRW* cfgMgr,
5158 const std::string& tableName,
5159 TableVersion version,
5160 const std::string& type,
5161 const std::string& uid,
5162 const std::string& colName,
5163 const std::string& newValue,
5164 const std::string& author)
5167 __SUP_COUT__ <<
"Editing table " << tableName <<
"(" << version <<
") uid=" << uid
5168 <<
" type=" << type << __E__;
5175 TableBase* table = cfgMgr->getTableByName(tableName);
5178 table->setActiveView(version);
5182 if(version.isTemporaryVersion())
5185 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
5186 << version << __E__;
5187 cfgMgr->getVersionedTableByName(tableName, version);
5190 __SUP_COUT__ <<
"Active version is " << table->getViewVersion() << __E__;
5191 __SUP_COUTTV__(table->getView().getComment());
5193 if(version != table->getViewVersion())
5195 __SUP_SS__ <<
"Target table version (" << version
5196 <<
") is not the currently active version (" << table->getViewVersion()
5197 <<
"). Try refreshing the tree." << __E__;
5201 unsigned int col = -1;
5202 if(type ==
"uid" || type ==
"delete-uid" || type ==
"tree-copy")
5203 col = table->getView().getColUID();
5204 else if(type ==
"node-comment")
5205 col = table->getView().findCol(TableViewColumnInfo::COL_NAME_COMMENT);
5206 else if(type ==
"link-UID" || type ==
"link-GroupID" || type ==
"value" ||
5207 type ==
"value-groupid" || type ==
"value-bool" || type ==
"value-bitmap")
5208 col = table->getView().findCol(colName);
5209 else if(type ==
"table" || type ==
"link-comment" || type ==
"table-newGroupRow" ||
5210 type ==
"table-newUIDRow" || type ==
"table-newRow")
5214 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << __E__;
5219 if(type ==
"table" || type ==
"link-comment")
5222 if(table->getView().isURIEncodedCommentTheSame(newValue))
5224 __SUP_SS__ <<
"Comment '" << newValue
5225 <<
"' is the same as the current comment. No need to save change."
5241 TableVersion temporaryVersion = table->createTemporaryView(version);
5243 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5245 TableView* cfgView = table->getTemporaryView(temporaryVersion);
5248 __SUP_COUTTV__(table->getView().getComment());
5254 if(type ==
"table" || type ==
"link-comment")
5257 cfgView->setURIEncodedComment(newValue);
5259 else if(type ==
"table-newRow" || type ==
"table-newUIDRow")
5262 unsigned int row = cfgView->addRow(
5263 author,
true , newValue );
5268 col = cfgView->getColStatus();
5269 cfgView->setValueAsString(
"1", row, col);
5276 cfgView->setURIEncodedValue(newValue, row, cfgView->getColUID());
5278 else if(type ==
"table-newGroupRow")
5281 unsigned int csvIndex = newValue.find(
',');
5283 std::string linkIndex = newValue.substr(0, csvIndex);
5284 std::string groupId = newValue.substr(csvIndex + 1);
5287 csvIndex = groupId.find(
',');
5288 std::string newRowUID = groupId.substr(csvIndex + 1);
5289 groupId = groupId.substr(0, csvIndex);
5291 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," << groupId <<
"," << newRowUID
5295 unsigned int row = cfgView->addRow(author,
5303 cfgView->setURIEncodedValue(newRowUID, row, cfgView->getColUID());
5306 col = cfgView->getLinkGroupIDColumn(linkIndex);
5309 cfgView->setURIEncodedValue(groupId, row, col);
5314 col = cfgView->getColStatus();
5315 cfgView->setValueAsString(
"1", row, col);
5321 else if(type ==
"delete-uid")
5324 unsigned int row = cfgView->findRow(col, uid);
5325 cfgView->deleteRow(row);
5327 else if(type ==
"tree-copy")
5330 __COUTV__(newValue);
5331 std::vector<std::string> paramArray =
5332 StringMacros::getVectorFromString(newValue);
5333 __COUTV__(StringMacros::vectorToString(paramArray));
5335 if(paramArray.size() != 2)
5337 __SS__ <<
"Illegal parameters for tree copy request: must be number of "
5338 "copy instances & depth of copy."
5343 unsigned int row = cfgView->findRow(col, uid);
5346 unsigned int numberOfInstances = atoi(paramArray[0].c_str());
5347 unsigned int depth = atoi(paramArray[1].c_str());
5349 __COUTV__(numberOfInstances);
5350 if(numberOfInstances > 1000)
5352 __SS__ <<
"Illegal parameters - the maximum number of copy instances is "
5353 "1000. Number of instances provided was "
5354 << numberOfInstances << __E__;
5358 std::map<std::string , TableVersion >
5359 modifiedTablesMap = cfgMgr->getActiveVersions();
5361 ConfigurationSupervisorBase::recursiveCopyTreeUIDNode(xmlOut,
5370 else if(type ==
"uid" || type ==
"value" || type ==
"value-groupid" ||
5371 type ==
"value-bool" || type ==
"value-bitmap" || type ==
"node-comment")
5373 unsigned int row = cfgView->findRow(cfgView->getColUID(), uid);
5374 if(!cfgView->setURIEncodedValue(newValue, row, col, author))
5377 __SUP_SS__ <<
"Value '" << newValue
5378 <<
"' is the same as the current value. No need to save "
5379 "change to tree node."
5384 else if(type ==
"link-UID" || type ==
"link-GroupID")
5387 std::pair<
unsigned int ,
unsigned int > linkPair;
5388 if(!cfgView->getChildLink(col, isGroup, linkPair))
5391 __SUP_SS__ <<
"Col '" << colName <<
"' is not a link column." << __E__;
5395 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," << linkPair.second
5398 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
5400 __SUP_COUT__ <<
"linkIndex " << linkIndex << __E__;
5403 unsigned int csvIndexStart = 0, csvIndex = newValue.find(
',');
5405 std::string newTable = newValue.substr(csvIndexStart, csvIndex);
5406 csvIndexStart = csvIndex + 1;
5407 csvIndex = newValue.find(
',', csvIndexStart);
5408 std::string newLinkId = newValue.substr(
5413 __SUP_COUT__ <<
"newValue " << newTable <<
"," << newLinkId << __E__;
5416 unsigned int row = cfgView->findRow(cfgView->getColUID(), uid);
5417 bool changed =
false;
5418 bool needSecondaryChange = (type ==
"link-GroupID");
5420 if(!cfgView->setURIEncodedValue(newTable, row, linkPair.first, author))
5423 __SUP_COUT__ <<
"Value '" << newTable
5424 <<
"' is the same as the current value." << __E__;
5432 std::string originalValue = cfgView->getValueAsString(row, linkPair.second);
5433 if(!cfgView->setURIEncodedValue(newLinkId, row, linkPair.second, author))
5436 __SUP_COUT__ <<
"Value '" << newLinkId
5437 <<
"' is the same as the current value." << __E__;
5442 needSecondaryChange =
5448 if(needSecondaryChange)
5450 bool secondaryChanged =
false;
5451 bool defaultIsInGroup =
5457 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table."
5459 table->eraseView(temporaryVersion);
5467 ConfigurationSupervisorBase::saveModifiedVersionXML(
5480 catch(std::runtime_error&
5483 __SUP_COUT__ <<
"Caught error while editing main table. Erasing "
5484 "temporary version."
5486 table->eraseView(temporaryVersion);
5490 xmlOut.addTextElementToData(
5492 "Error saving primary tree node! " + std::string(e.what()));
5502 __SUP_COUTV__(newValue);
5503 csvIndexStart = csvIndex + 1;
5504 csvIndex = newValue.find(
',', csvIndexStart);
5505 version = TableVersion(newValue.substr(
5506 csvIndexStart, csvIndex - csvIndexStart));
5509 if(newTable == TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5517 table = cfgMgr->getTableByName(newTable);
5520 table->setActiveView(version);
5524 if(version.isTemporaryVersion())
5527 __SUP_COUT__ <<
"Failed to find stored version, so attempting to "
5529 << newTable <<
" v" << version << __E__;
5530 cfgMgr->getVersionedTableByName(newTable, version);
5533 __SUP_COUT__ << newTable <<
" active version is "
5534 << table->getViewVersion() << __E__;
5536 if(version != table->getViewVersion())
5539 if(version.isMockupVersion())
5540 ss <<
"Target table '" << newTable
5541 <<
"' is likely not a member of the current table group "
5542 <<
"since the mock-up version was not successfully loaded. "
5547 "To add a table to a group, click the group name to go to "
5549 "group view, then click 'Add/Remove/Modify Member Tables.' "
5551 "can then add or remove tables and save the new group." +
5553 "OR!!! Click the following button to add the table '" +
5555 "' to the currently active Configuration Group: " +
5556 "<input type='button' style='color:black !important;' " +
5557 "title='Click to add table to the active Configuration "
5559 "onclick='addTableToConfigurationGroup(\"" + newTable +
5560 "\"); Debug.closeErrorPop();event.stopPropagation();' "
5561 "value='Add Table'>" +
5565 ss <<
"Target table version (" << version
5566 <<
") is not the currently active version ("
5567 << table->getViewVersion() <<
"). Try refreshing the tree."
5573 temporaryVersion = table->createTemporaryView(version);
5575 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5577 cfgView = table->getTemporaryView(temporaryVersion);
5581 if(type ==
"link-UID")
5590 col = cfgView->getColUID();
5591 __SUP_COUT__ <<
"target col " << col << __E__;
5593 unsigned int row = -1;
5596 row = cfgView->findRow(col, newLinkId);
5601 if(row == (
unsigned int)-1)
5603 __SUP_COUT__ <<
"New link UID '" << newLinkId
5604 <<
"' was not found, so attempting to change UID of "
5606 << originalValue <<
"'" << __E__;
5609 row = cfgView->findRow(col, originalValue);
5610 if(cfgView->setURIEncodedValue(newLinkId, row, col, author))
5612 secondaryChanged =
true;
5613 __SUP_COUT__ <<
"Original target record '"
5614 << originalValue <<
"' was changed to '"
5615 << newLinkId <<
"'" << __E__;
5620 __SUP_COUT__ <<
"Original target record '" << originalValue
5621 <<
"' not found." << __E__;
5625 else if(type ==
"link-GroupID")
5631 col = cfgView->getLinkGroupIDColumn(linkIndex);
5633 __SUP_COUT__ <<
"target col " << col << __E__;
5636 std::vector<std::string> memberUIDs;
5639 csvIndexStart = csvIndex + 1;
5640 csvIndex = newValue.find(
',', csvIndexStart);
5641 memberUIDs.push_back(
5642 newValue.substr(csvIndexStart, csvIndex - csvIndexStart));
5643 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << __E__;
5645 (
unsigned int)std::string::npos);
5655 std::string targetUID;
5656 bool shouldBeInGroup;
5659 for(
unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
5661 targetUID = cfgView->getDataView()[row][cfgView->getColUID()];
5662 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
5664 shouldBeInGroup =
false;
5665 for(
unsigned int i = 0; i < memberUIDs.size(); ++i)
5666 if(targetUID == memberUIDs[i])
5669 shouldBeInGroup =
true;
5673 isInGroup = cfgView->isEntryInGroup(row, linkIndex, newLinkId);
5676 if(shouldBeInGroup && !isInGroup)
5678 __SUP_COUT__ <<
"Changed to YES: " << row << __E__;
5679 secondaryChanged =
true;
5681 cfgView->addRowToGroup(row, col, newLinkId);
5684 else if(!shouldBeInGroup && isInGroup)
5686 __SUP_COUT__ <<
"Changed to NO: " << row << __E__;
5687 secondaryChanged =
true;
5689 cfgView->removeRowFromGroup(row, col, newLinkId);
5691 else if(targetUID ==
5693 ->getDefaultRowValues()[cfgView->getColUID()] &&
5697 defaultIsInGroup =
true;
5703 if(!secondaryChanged)
5706 <<
"No changes to secondary view. Erasing temporary table."
5708 table->eraseView(temporaryVersion);
5716 ConfigurationSupervisorBase::saveModifiedVersionXML(
5729 catch(std::runtime_error&
5732 __SUP_COUT__ <<
"Caught error while editing secondary table. "
5733 "Erasing temporary version."
5735 table->eraseView(temporaryVersion);
5736 secondaryChanged =
false;
5739 xmlOut.addTextElementToData(
5741 "Error saving secondary tree node! " + std::string(e.what()));
5749 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
5751 __SUP_SS__ <<
"Link to table '" << newTable <<
"', linkID '"
5753 <<
"', and selected group members are the same as the "
5755 <<
"No need to save changes to tree." << __E__;
5761 else if(0 && !changed)
5766 __SUP_SS__ <<
"Link to table '" << newTable <<
"' and linkID '"
5768 <<
"' are the same as the current values. No need to save "
5769 "change to tree node."
5779 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
5780 table->eraseView(temporaryVersion);
5784 ConfigurationSupervisorBase::saveModifiedVersionXML(
5794 catch(std::runtime_error& e)
5796 __SUP_SS__ <<
"Error saving tree node! " << e.what() << __E__;
5797 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5798 xmlOut.addTextElementToData(
"Error", ss.str());
5802 __SUP_SS__ <<
"Unknown Error saving tree node! " << __E__;
5807 catch(
const std::exception& e)
5809 ss <<
"Exception message: " << e.what();
5814 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5815 xmlOut.addTextElementToData(
"Error", ss.str());
5859 void ConfigurationGUISupervisor::handleGetTableXML(HttpXmlDocument& xmlOut,
5860 ConfigurationManagerRW* cfgMgr,
5861 const std::string& tableName,
5862 TableVersion version,
5863 bool allowIllegalColumns ,
5867 char tmpIntStr[100];
5868 xercesc::DOMElement *parentEl, *subparentEl;
5870 std::string accumulatedErrors =
"";
5872 if(allowIllegalColumns)
5873 xmlOut.addTextElementToData(
"allowIllegalColumns",
"1");
5875 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo(
5876 allowIllegalColumns ,
5877 allowIllegalColumns ? &accumulatedErrors : 0,
5880 TableBase* table = cfgMgr->getTableByName(tableName);
5886 xmlOut.addTextElementToData(
"ExistingTableNames",
5887 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
5888 for(
auto& configPair : allTableInfo)
5890 xmlOut.addTextElementToData(
"ExistingTableNames", configPair.first);
5891 if(configPair.first == tableName &&
5892 configPair.second.versions_.find(version) ==
5893 configPair.second.versions_.end())
5895 __SUP_COUT__ <<
"Version not found, so using mockup." << __E__;
5896 version = TableVersion();
5901 xmlOut.addTextElementToData(
"TableName", tableName);
5902 xmlOut.addTextElementToData(
"TableDescription",
5903 table->getTableDescription());
5911 std::map<std::string , TableVersion >>
5916 versionAliases = cfgMgr->getVersionAliases();
5917 for(
const auto& aliases : versionAliases)
5918 for(
const auto& alias : aliases.second)
5919 __SUP_COUTT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first
5920 <<
" ==> " << alias.second << __E__;
5922 catch(
const std::runtime_error& e)
5924 __SUP_COUT__ <<
"Could not get backbone information for version aliases: "
5925 << e.what() << __E__;
5928 auto tableIterator = versionAliases.find(tableName);
5930 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
5931 for(
const TableVersion& v : allTableInfo.at(tableName).versions_)
5934 xmlOut.addTextElementToParent(
"Version", v.toString(), parentEl);
5936 if(tableIterator != versionAliases.end())
5939 for(
const auto& aliasPair : tableIterator->second)
5941 if(v == aliasPair.second)
5943 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> "
5944 << aliasPair.first << __E__;
5945 xmlOut.addTextElementToParent(
5946 "VersionAlias", aliasPair.first, subparentEl);
5956 TableView* tableViewPtr;
5957 if(version.isInvalid())
5959 tableViewPtr = table->getMockupViewP();
5967 std::string localAccumulatedErrors =
"";
5970 ->getVersionedTableByName(tableName,
5972 allowIllegalColumns ,
5973 &localAccumulatedErrors,
5979 xmlOut.addTextElementToData(
"TableRawData",
5980 tableViewPtr->getSourceRawData());
5982 const std::set<std::string>& srcColNames =
5983 tableViewPtr->getSourceColumnNames();
5984 for(
auto& srcColName : srcColNames)
5985 xmlOut.addTextElementToData(
"ColumnHeader", srcColName);
5987 if(!version.isTemporaryVersion())
5992 tableViewPtr = cfgMgr
5993 ->getVersionedTableByName(
5996 allowIllegalColumns ,
5997 &localAccumulatedErrors,
6003 if(localAccumulatedErrors !=
"")
6004 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
6006 catch(std::runtime_error& e)
6008 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << version
6009 <<
"... defaulting to mock-up! " << __E__;
6010 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
6012 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6013 version = TableVersion();
6014 tableViewPtr = table->getMockupViewP();
6016 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6020 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << version
6021 <<
"... defaulting to mock-up! "
6022 <<
"(You may want to try again to see what was partially loaded "
6023 "into cache before failure. "
6024 <<
"If you think, the failure is due to a column name change, "
6025 <<
"you can also try to Copy the failing view to the new column "
6027 <<
"'Copy and Move' functionality.)" << __E__;
6032 catch(
const std::exception& e)
6034 ss <<
"Exception message: " << e.what();
6040 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6041 version = TableVersion();
6042 tableViewPtr = table->getMockupViewP();
6044 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6047 xmlOut.addTextElementToData(
"TableVersion", version.toString());
6053 xercesc::DOMElement* choicesParentEl;
6054 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
6056 std::vector<TableViewColumnInfo> colInfo = tableViewPtr->getColumnsInfo();
6058 for(
int i = 0; i < (int)colInfo.size(); ++i)
6060 xmlOut.addTextElementToParent(
"ColumnHeader", colInfo[i].getName(), parentEl);
6061 xmlOut.addTextElementToParent(
"ColumnType", colInfo[i].getType(), parentEl);
6062 xmlOut.addTextElementToParent(
6063 "ColumnDataType", colInfo[i].getDataType(), parentEl);
6067 xmlOut.addTextElementToParent(
6068 "ColumnDefaultValue", colInfo[i].getDefaultValue(), parentEl);
6070 choicesParentEl = xmlOut.addTextElementToParent(
"ColumnChoices",
"", parentEl);
6072 if(colInfo[i].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
6073 colInfo[i].getType() == TableViewColumnInfo::TYPE_BITMAP_DATA ||
6074 colInfo[i].isChildLink())
6076 for(
auto& choice : colInfo[i].getDataChoices())
6077 xmlOut.addTextElementToParent(
"ColumnChoice", choice, choicesParentEl);
6080 xmlOut.addTextElementToParent(
6081 "ColumnMinValue", colInfo[i].getMinValue(), parentEl);
6082 xmlOut.addTextElementToParent(
6083 "ColumnMaxValue", colInfo[i].getMaxValue(), parentEl);
6089 if(version.isInvalid())
6090 tableViewPtr->init();
6092 catch(std::runtime_error& e)
6095 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
6102 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
6104 for(
int r = 0; r < (int)tableViewPtr->getNumberOfRows(); ++r)
6106 sprintf(tmpIntStr,
"%d", r);
6107 xercesc::DOMElement* tmpParentEl =
6108 xmlOut.addTextElementToParent(
"Row", tmpIntStr, parentEl);
6110 for(
int c = 0; c < (int)tableViewPtr->getNumberOfColumns(); ++c)
6112 if(colInfo[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
6114 std::string timeAsString;
6115 tableViewPtr->getValue(timeAsString, r, c);
6116 xmlOut.addTextElementToParent(
"Entry", timeAsString, tmpParentEl);
6119 xmlOut.addTextElementToParent(
6120 "Entry", tableViewPtr->getDataView()[r][c], tmpParentEl);
6125 xmlOut.addTextElementToData(
"TableComment", tableViewPtr->getComment());
6126 xmlOut.addTextElementToData(
"TableAuthor", tableViewPtr->getAuthor());
6127 xmlOut.addTextElementToData(
"TableCreationTime",
6128 std::to_string(tableViewPtr->getCreationTime()));
6129 xmlOut.addTextElementToData(
"TableLastAccessTime",
6130 std::to_string(tableViewPtr->getLastAccessTime()));
6135 std::vector<std::string> defaultRowValues =
6136 table->getMockupViewP()->getDefaultRowValues();
6138 for(
unsigned int c = 0; c < defaultRowValues.size() - 2; ++c)
6140 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
6143 const std::set<std::string> srcColNames = tableViewPtr->getSourceColumnNames();
6145 if(accumulatedErrors !=
"")
6147 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so "
6148 "perhaps you can ignore this, ") +
6149 "but please note the following warnings:\n" + accumulatedErrors)
6151 __SUP_COUT_ERR__ << ss.str();
6152 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6154 else if(!version.isTemporaryVersion() &&
6156 (srcColNames.size() != tableViewPtr->getNumberOfColumns() ||
6157 tableViewPtr->getSourceColumnMismatch() !=
6160 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " << tableName
6161 <<
":v" << version <<
". Please see the details below:\n\n"
6162 << tableViewPtr->getMismatchColumnInfo();
6164 __SUP_COUT__ <<
"\n" << ss.str();
6165 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6169 catch(std::runtime_error& e)
6171 __SUP_SS__ <<
"Error getting table view!\n\n " << e.what() << __E__;
6172 __SUP_COUT_ERR__ << ss.str();
6173 xmlOut.addTextElementToData(
"Error", ss.str());
6177 __SUP_SS__ <<
"Error getting table view!\n\n " << __E__;
6182 catch(
const std::exception& e)
6184 ss <<
"Exception message: " << e.what();
6189 __SUP_COUT_ERR__ << ss.str();
6190 xmlOut.addTextElementToData(
"Error", ss.str());
6200 ConfigurationManagerRW* ConfigurationGUISupervisor::refreshUserSession(
6201 std::string username,
bool refresh)
6203 uint64_t sessionIndex =
6206 std::stringstream ssMapKey;
6207 ssMapKey << username <<
":" << sessionIndex;
6208 std::string mapKey = ssMapKey.str();
6209 __SUP_COUTT__ <<
"Using Config Session " << mapKey
6210 <<
" ... Total Session Count: " << userConfigurationManagers_.size()
6213 time_t now = time(0);
6216 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
6218 __SUP_COUT__ <<
"Creating new Configuration Manager. time=" << time(0) <<
" "
6219 << clock() << __E__;
6220 userConfigurationManagers_[mapKey] =
new ConfigurationManagerRW(username);
6225 userConfigurationManagers_[mapKey]->getAllTableInfo(
6233 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
6235 __SUP_SS__ <<
"Fatal error managing userLastUseTime_! Check the logs for "
6236 "Configuration Interface failure."
6238 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6241 else if(refresh || (now - userLastUseTime_[mapKey]) >
6242 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
6244 __SUP_COUT__ <<
"Refreshing all table info." << __E__;
6245 userConfigurationManagers_[mapKey]->getAllTableInfo(
6253 __SUP_COUTT__ <<
"Configuration Manager ready. time=" << time(0) <<
" " << clock()
6254 <<
" runTimeSeconds()="
6255 << userConfigurationManagers_[mapKey]->runTimeSeconds() << __E__;
6258 userLastUseTime_[mapKey] = now;
6261 for(std::map<std::string, time_t>::iterator it = userLastUseTime_.begin();
6262 it != userLastUseTime_.end();
6264 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
6266 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second
6268 delete userConfigurationManagers_[it->first];
6269 if(!(userConfigurationManagers_.erase(it->first)))
6271 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!"
6273 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6276 userLastUseTime_.erase(it);
6278 it = userLastUseTime_.begin();
6281 return userConfigurationManagers_[mapKey];
6289 void ConfigurationGUISupervisor::handleDeleteTableInfoXML(HttpXmlDocument& xmlOut,
6290 ConfigurationManagerRW* cfgMgr,
6291 std::string& tableName)
6293 if(0 == rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
6294 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
6295 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
6296 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6300 __SUP_COUT_ERR__ << (
"Error renaming file to " +
6301 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6304 xmlOut.addTextElementToData(
6306 (
"Error renaming Table Info File to " +
6307 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused")));
6312 cfgMgr->getAllTableInfo(
true );
6322 void ConfigurationGUISupervisor::handleSaveTableInfoXML(
6323 HttpXmlDocument& xmlOut,
6324 ConfigurationManagerRW* cfgMgr,
6325 std::string& tableName,
6326 const std::string& data,
6327 const std::string& tableDescription,
6328 const std::string& columnChoicesCSV,
6329 bool allowOverwrite)
6333 std::string capsName;
6336 capsName = TableBase::convertToCaps(tableName,
true);
6338 catch(std::runtime_error& e)
6340 xmlOut.addTextElementToData(
"Error", e.what());
6346 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"r");
6350 xmlOut.addTextElementToData(
"TableName", tableName);
6351 xmlOut.addTextElementToData(
"OverwriteError",
"1");
6352 xmlOut.addTextElementToData(
6354 "File already exists! ('" +
6355 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT) +
"')");
6360 __SUP_COUT__ <<
"capsName=" << capsName << __E__;
6361 __SUP_COUT__ <<
"tableName=" << tableName << __E__;
6362 __SUP_COUT__ <<
"tableDescription=" << tableDescription << __E__;
6363 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << __E__;
6366 std::stringstream outss;
6368 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
6369 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
6370 "xsi:noNamespaceSchemaLocation=\"TableInfo.xsd\">\n";
6371 outss <<
"\t\t<TABLE Name=\"" << tableName <<
"\">\n";
6372 outss <<
"\t\t\t<VIEW Name=\"" << capsName
6373 <<
"\" Type=\"File,Database,DatabaseTest\" Description=\"" << tableDescription
6379 std::istringstream columnChoicesISS(columnChoicesCSV);
6380 std::string columnChoicesString;
6381 std::string columnDefaultValue, columnMinValue, columnMaxValue;
6382 std::vector<std::string> columnParameters;
6383 std::vector<std::string> columnData =
6384 StringMacros::getVectorFromString(data, {
';'} );
6386 for(
unsigned int c = 0; c < columnData.size() - 1; ++c)
6389 StringMacros::getVectorFromString(columnData[c], {
','} );
6390 __COUT__ <<
"Column #" << c <<
": "
6391 << StringMacros::vectorToString(columnParameters) << __E__;
6392 for(
unsigned int p = 0; p < columnParameters.size(); ++p)
6394 __COUT__ <<
"\t Parameter #" << p <<
": " << columnParameters[p] << __E__;
6396 __COUT__ <<
"\t creating the new xml" << __E__;
6398 std::string& columnType = columnParameters[0];
6399 std::string& columnDataType = columnParameters[2];
6401 outss <<
"\t\t\t\t<COLUMN Type=\"";
6402 outss << columnType;
6403 outss <<
"\" \t Name=\"";
6404 outss << columnParameters[1];
6405 outss <<
"\" \t StorageName=\"";
6408 outss << TableBase::convertToCaps(columnParameters[1]);
6410 catch(std::runtime_error& e)
6412 xmlOut.addTextElementToData(
"Error",
6413 std::string(
"For column name '") +
6414 columnParameters[1] +
"' - " + e.what());
6417 outss <<
"\" \t DataType=\"";
6418 outss << columnDataType;
6420 columnDefaultValue = StringMacros::decodeURIComponent(columnParameters[3]);
6422 if(columnDefaultValue !=
6423 TableViewColumnInfo::getDefaultDefaultValue(columnType, columnDataType))
6425 __SUP_COUT__ <<
"FOUND user spec'd default value '" << columnDefaultValue
6427 outss <<
"\" \t DefaultValue=\"";
6428 outss << columnParameters[3];
6430 getline(columnChoicesISS, columnChoicesString,
';');
6431 outss <<
"\" \t DataChoices=\"";
6432 outss << columnChoicesString;
6434 if(columnParameters.size() > 4 &&
6435 columnDataType == TableViewColumnInfo::DATATYPE_NUMBER)
6437 columnMinValue = StringMacros::decodeURIComponent(columnParameters[4]);
6438 if(columnMinValue !=
"")
6440 if(columnMinValue !=
6441 TableViewColumnInfo::getMinDefaultValue(columnDataType))
6443 __SUP_COUT__ <<
"FOUND user spec'd min value '" << columnParameters[4]
6445 if(!StringMacros::isNumber(
6446 StringMacros::convertEnvironmentVariables(columnMinValue)))
6448 __SS__ <<
"Inavlid user spec'd min value '" << columnParameters[4]
6449 <<
"' which evaluates to '" << columnMinValue
6450 <<
"' and is not a valid number. The minimum value must "
6451 "be a number (environment variables and math "
6452 "operations are allowed)."
6456 outss <<
"\" \t MinValue=\"" << columnParameters[4];
6460 columnMaxValue = StringMacros::decodeURIComponent(columnParameters[5]);
6461 if(columnMaxValue !=
"")
6463 if(columnMaxValue !=
6464 TableViewColumnInfo::getMaxDefaultValue(columnDataType))
6466 __SUP_COUT__ <<
"FOUND user spec'd max value = " << columnMaxValue
6468 if(!StringMacros::isNumber(
6469 StringMacros::convertEnvironmentVariables(columnMaxValue)))
6471 __SS__ <<
"Inavlid user spec'd max value '" << columnParameters[5]
6472 <<
"' which evaluates to '" << columnMaxValue
6473 <<
"' and is not a valid number. The maximum value must "
6474 "be a number (environment variables and math "
6475 "operations are allowed)."
6479 outss <<
"\" \t MaxValue=\"" << columnParameters[5];
6486 outss <<
"\t\t\t</VIEW>\n";
6487 outss <<
"\t\t</TABLE>\n";
6488 outss <<
"\t</ROOT>\n";
6490 __SUP_COUT__ << outss.str() << __E__;
6492 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"w");
6495 xmlOut.addTextElementToData(
"Error",
6496 "Failed to open destination Table Info file:" +
6497 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT));
6501 fprintf(fp,
"%s", outss.str().c_str());
6506 std::string accumulatedErrors =
"";
6507 cfgMgr->getAllTableInfo(
true , &accumulatedErrors, tableName);
6510 if(accumulatedErrors !=
"")
6512 __SUP_SS__ << (
"The new version of the '" + tableName +
6513 "' table column info was saved, however errors were detected "
6514 "reading back the table '" +
6515 tableName +
"' after the save attempt:\n\n" + accumulatedErrors)
6518 __SUP_COUT_ERR__ << ss.str() << __E__;
6519 xmlOut.addTextElementToData(
"Error", ss.str());
6525 handleGetTableXML(xmlOut, cfgMgr, tableName, TableVersion());
6528 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
6531 __SUP_COUT_INFO__ <<
"Looking for errors in all table column info..." << __E__;
6532 for(
const auto& cfgInfo : allTableInfo)
6536 cfgMgr->getTableByName(cfgInfo.first)->getMockupViewP()->init();
6538 catch(std::runtime_error& e)
6540 __SUP_COUT_WARN__ <<
"\n\n##############################################\n"
6541 <<
"Error identified in column info of table '"
6542 << cfgInfo.first <<
"':\n\n"
6543 << e.what() <<
"\n\n"
6557 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(
6558 HttpXmlDocument& xmlOut,
6559 ConfigurationManagerRW* cfgMgr,
6560 const std::string& groupAliasCSV,
6561 const std::string& groupNameCSV,
6562 const std::string& groupKeyCSV,
6563 const std::string& author)
6566 cfgMgr->loadConfigurationBackbone();
6567 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6569 const std::string groupAliasesTableName =
6570 ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
6571 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
6573 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!"
6575 xmlOut.addTextElementToData(
"Error", ss.str());
6580 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6581 for(
auto& memberName : backboneMembers)
6583 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6584 <<
"\"]=" << activeVersions[memberName] << __E__;
6586 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6587 xmlOut.addTextElementToData(
"oldBackboneVersion",
6588 activeVersions[memberName].toString());
6595 TableBase* table = cfgMgr->getTableByName(groupAliasesTableName);
6596 TableVersion originalVersion = activeVersions[groupAliasesTableName];
6597 TableVersion temporaryVersion = table->createTemporaryView(originalVersion);
6599 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6600 bool isDifferent =
false;
6604 TableView* configView = table->getTemporaryView(temporaryVersion);
6606 unsigned int col = configView->findCol(
"GroupKeyAlias");
6607 unsigned int ccol = configView->findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6608 unsigned int ncol = configView->findCol(
"GroupName");
6609 unsigned int kcol = configView->findCol(
"GroupKey");
6612 std::vector<std::string> groupAliases =
6613 StringMacros::getVectorFromString(groupAliasCSV);
6614 std::vector<std::string> groupNames =
6615 StringMacros::getVectorFromString(groupNameCSV);
6616 std::vector<std::string> groupKeys =
6617 StringMacros::getVectorFromString(groupKeyCSV);
6618 __SUP_COUTV__(StringMacros::vectorToString(groupAliases));
6619 __SUP_COUTV__(StringMacros::vectorToString(groupNames));
6620 __SUP_COUTV__(StringMacros::vectorToString(groupKeys));
6623 for(
const auto& groupAlias : groupAliases)
6625 if(groupAlias ==
"" || groupNames[i] ==
"" || groupKeys[i] ==
"")
6628 __SUP_COUT_WARN__ <<
"Empty alias parameter found [" << i <<
"] = {"
6629 << groupAlias <<
", " << groupNames[i] <<
"("
6630 << groupKeys[i] <<
")}" << __E__;
6635 bool localIsDifferent =
false;
6636 const std::string& groupName = groupNames[i];
6637 const TableGroupKey groupKey(groupKeys[i]);
6640 unsigned int row = -1;
6644 row = configView->findRow(col, groupAlias);
6650 if(row == (
unsigned int)-1)
6652 localIsDifferent =
true;
6653 row = configView->addRow();
6656 configView->setValue(
6657 "This Group Alias was automatically setup by the server.", row, ccol);
6658 configView->setValue(groupAlias, row, col);
6661 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6663 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs "
6664 << configView->getDataView()[row][ncol] << __E__;
6665 if(groupName != configView->getDataView()[row][ncol])
6667 configView->setValue(groupName, row, ncol);
6668 localIsDifferent =
true;
6671 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs "
6672 << configView->getDataView()[row][kcol] << __E__;
6673 if(groupKey.toString() != configView->getDataView()[row][kcol])
6675 configView->setValue(groupKey.toString(), row, kcol);
6676 localIsDifferent =
true;
6679 if(localIsDifferent)
6681 configView->setValue(
6684 configView->findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
6685 configView->setValue(
6688 configView->findCol(TableViewColumnInfo::COL_NAME_CREATION));
6695 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << __E__;
6698 table->eraseView(temporaryVersion);
6702 TableVersion newAssignedVersion;
6705 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6709 newAssignedVersion = ConfigurationSupervisorBase::saveModifiedVersionXML(
6712 table->getTableName(),
6723 <<
"\t\t**************************** Using the existing table version"
6727 table->eraseView(temporaryVersion);
6728 newAssignedVersion = activeVersions[groupAliasesTableName];
6730 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
6731 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
6734 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6736 catch(std::runtime_error& e)
6738 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << e.what() << __E__;
6739 __SUP_COUT_ERR__ << ss.str();
6740 xmlOut.addTextElementToData(
"Error", ss.str());
6744 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << __E__;
6749 catch(
const std::exception& e)
6751 ss <<
"Exception message: " << e.what();
6756 __SUP_COUT_ERR__ << ss.str();
6757 xmlOut.addTextElementToData(
"Error", ss.str());
6768 void ConfigurationGUISupervisor::handleSetTableAliasInBackboneXML(
6769 HttpXmlDocument& xmlOut,
6770 ConfigurationManagerRW* cfgMgr,
6771 const std::string& tableAlias,
6772 const std::string& tableName,
6773 TableVersion version,
6774 const std::string& author)
6777 cfgMgr->loadConfigurationBackbone();
6778 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6780 const std::string versionAliasesTableName =
6781 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6782 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6784 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6786 xmlOut.addTextElementToData(
"Error", ss.str());
6791 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6792 for(
auto& memberName : backboneMembers)
6794 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6795 <<
"\"]=" << activeVersions[memberName] << __E__;
6797 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6798 xmlOut.addTextElementToData(
"oldBackboneVersion",
6799 activeVersions[memberName].toString());
6806 TableBase* table = cfgMgr->getTableByName(versionAliasesTableName);
6807 TableVersion originalVersion = activeVersions[versionAliasesTableName];
6808 TableVersion temporaryVersion = table->createTemporaryView(originalVersion);
6810 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6812 bool isDifferent =
false;
6816 TableView* configView = table->getTemporaryView(temporaryVersion);
6819 unsigned int col2 = configView->findCol(
"VersionAlias");
6820 unsigned int col3 = configView->findCol(
"TableName");
6824 unsigned int row = -1;
6829 unsigned int tmpRow = -1;
6832 tmpRow = configView->findRow(col3, tableName, tmpRow + 1);
6833 }
while(configView->getDataView()[tmpRow][col2] != tableAlias);
6840 if(row == (
unsigned int)-1)
6843 row = configView->addRow();
6846 col = configView->findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6847 configView->setValue(
6848 std::string(
"Entry was added by server in ") +
6849 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
6853 col = configView->findCol(
"VersionAliasUID");
6854 configView->setValue(
6855 tableName.substr(0, tableName.rfind(
"Table")) + tableAlias, row, col);
6857 configView->setValue(tableAlias, row, col2);
6858 configView->setValue(tableName, row, col3);
6861 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6863 col = configView->findCol(
"Version");
6864 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs "
6865 << configView->getDataView()[row][col] << __E__;
6866 if(version.toString() != configView->getDataView()[row][col])
6868 configView->setValue(version.toString(), row, col);
6874 configView->setValue(
6875 author, row, configView->findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
6876 configView->setValue(
6879 configView->findCol(TableViewColumnInfo::COL_NAME_CREATION));
6884 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << __E__;
6887 table->eraseView(temporaryVersion);
6891 TableVersion newAssignedVersion;
6894 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6897 newAssignedVersion = ConfigurationSupervisorBase::saveModifiedVersionXML(
6900 table->getTableName(),
6910 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
6914 table->eraseView(temporaryVersion);
6915 newAssignedVersion = activeVersions[versionAliasesTableName];
6917 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
6918 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
6921 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6923 catch(std::runtime_error& e)
6925 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
6926 __SUP_COUT_ERR__ << ss.str();
6927 xmlOut.addTextElementToData(
"Error", ss.str());
6931 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
6936 catch(
const std::exception& e)
6938 ss <<
"Exception message: " << e.what();
6943 __SUP_COUT_ERR__ << ss.str();
6944 xmlOut.addTextElementToData(
"Error", ss.str());
6953 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(
6954 HttpXmlDocument& xmlOut,
6955 ConfigurationManagerRW* cfgMgr,
6956 const std::string& versionAlias,
6957 const std::string& groupName,
6958 TableGroupKey groupKey,
6959 const std::string& author)
6962 cfgMgr->loadConfigurationBackbone();
6963 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
6965 const std::string versionAliasesTableName =
6966 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6967 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6969 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6971 xmlOut.addTextElementToData(
"Error", ss.str());
6976 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6977 for(
auto& memberName : backboneMembers)
6979 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6980 <<
"\"]=" << activeVersions[memberName] << __E__;
6982 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6983 xmlOut.addTextElementToData(
"oldBackboneVersion",
6984 activeVersions[memberName].toString());
6991 TableBase* table = cfgMgr->getTableByName(versionAliasesTableName);
6992 TableVersion temporaryVersion =
6993 table->createTemporaryView(activeVersions[versionAliasesTableName]);
6995 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6997 TableView* configView = table->getTemporaryView(temporaryVersion);
7000 bool isDifferent =
false;
7003 std::map<std::string , TableVersion > memberMap;
7006 cfgMgr->loadTableGroup(groupName,
7019 xmlOut.addTextElementToData(
7021 "Table group \"" + TableGroupKey::getFullGroupString(groupName, groupKey) +
7022 "\" can not be retrieved!");
7027 unsigned int col2 = configView->findCol(
"VersionAlias");
7028 unsigned int col3 = configView->findCol(
"TableName");
7030 for(
auto& memberPair : memberMap)
7032 bool thisMemberIsDifferent =
false;
7033 unsigned int row = -1;
7035 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
"_v"
7036 << memberPair.second <<
" to " << versionAlias << __E__;
7042 unsigned int tmpRow = -1;
7045 tmpRow = configView->findRow(col3, memberPair.first, tmpRow + 1);
7046 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
7053 if(row == (
unsigned int)-1)
7055 thisMemberIsDifferent =
true;
7056 row = configView->addRow();
7059 col = configView->findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7060 configView->setValue(
7061 std::string(
"Entry was added by server in ") +
7062 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7066 col = configView->getColUID();
7067 configView->setValue(
7068 memberPair.first.substr(0, memberPair.first.rfind(
"Table")) +
7073 configView->setValue(versionAlias, row, col2);
7074 configView->setValue(memberPair.first, row, col3);
7077 col = configView->findCol(
"Version");
7079 if(memberPair.second.toString() != configView->getDataView()[row][col])
7081 configView->setValue(memberPair.second.toString(), row, col);
7082 thisMemberIsDifferent =
true;
7085 if(thisMemberIsDifferent)
7087 configView->setValue(
7088 author, row, configView->findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7089 configView->setValue(
7092 configView->findCol(TableViewColumnInfo::COL_NAME_CREATION));
7095 if(thisMemberIsDifferent)
7101 TableVersion newAssignedVersion;
7104 __SUP_COUT__ <<
"\t\t**************************** Save v" << temporaryVersion
7105 <<
" as new table version" << __E__;
7107 newAssignedVersion =
7108 cfgMgr->saveNewTable(versionAliasesTableName, temporaryVersion);
7112 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7116 table->eraseView(temporaryVersion);
7117 newAssignedVersion = activeVersions[versionAliasesTableName];
7120 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7121 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.toString());
7122 __SUP_COUT__ <<
"\t\t Resulting Version: " << newAssignedVersion << __E__;
7124 catch(std::runtime_error& e)
7126 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7127 __SUP_COUT_ERR__ << ss.str();
7128 xmlOut.addTextElementToData(
"Error", ss.str());
7132 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7137 catch(
const std::exception& e)
7139 ss <<
"Exception message: " << e.what();
7144 __SUP_COUT_ERR__ << ss.str();
7145 xmlOut.addTextElementToData(
"Error", ss.str());
7159 void ConfigurationGUISupervisor::handleGroupAliasesXML(HttpXmlDocument& xmlOut,
7160 ConfigurationManagerRW* cfgMgr)
7162 cfgMgr->loadConfigurationBackbone();
7163 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
7165 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
7166 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
7168 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! "
7169 << groupAliasesTableName
7170 <<
" is a required member of the Backbone table group."
7171 <<
"\n\nLikely you need to activate a valid Backbone table group."
7173 __SUP_COUT__ << ss.str();
7178 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName
7179 <<
"\"]=" << activeVersions[groupAliasesTableName] << __E__;
7180 xmlOut.addTextElementToData(
"GroupAliasesTableName", groupAliasesTableName);
7181 xmlOut.addTextElementToData(
"GroupAliasesTableVersion",
7182 activeVersions[groupAliasesTableName].toString());
7184 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7185 cfgMgr->getNode(groupAliasesTableName).getChildren();
7187 const int numOfThreads = ConfigurationManager::PROCESSOR_COUNT / 2;
7188 __SUP_COUT__ <<
" PROCESSOR_COUNT " << ConfigurationManager::PROCESSOR_COUNT
7189 <<
" ==> " << numOfThreads <<
" threads for alias group loads." << __E__;
7191 if(numOfThreads < 2)
7193 std::string groupName, groupKey, groupComment, groupAuthor, groupCreateTime,
7195 for(
auto& aliasNodePair : aliasNodePairs)
7197 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7198 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7200 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7201 xmlOut.addTextElementToData(
"GroupName", groupName);
7202 xmlOut.addTextElementToData(
"GroupKey", groupKey);
7203 xmlOut.addTextElementToData(
7205 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7206 .getValueAsString());
7210 ConfigurationManager::UNKNOWN_INFO;
7211 groupType = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7214 cfgMgr->loadTableGroup(groupName,
7215 TableGroupKey(groupKey),
7228 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7229 << groupKey <<
")' to extract group comment and type."
7232 xmlOut.addTextElementToData(
"GroupComment", groupComment);
7233 xmlOut.addTextElementToData(
"GroupType", groupType);
7238 int threadsLaunched = 0;
7239 int foundThreadIndex = 0;
7240 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
7241 for(
int i = 0; i < numOfThreads; ++i)
7242 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
7244 std::vector<std::shared_ptr<ots::GroupInfo>> sharedGroupInfoPtrs;
7245 std::string groupName, groupKey;
7247 for(
auto& aliasNodePair : aliasNodePairs)
7250 sharedGroupInfoPtrs.push_back(std::make_shared<ots::GroupInfo>());
7252 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7253 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7255 if(threadsLaunched >= numOfThreads)
7258 foundThreadIndex = -1;
7259 while(foundThreadIndex == -1)
7261 for(
int i = 0; i < numOfThreads; ++i)
7262 if(*(threadDone[i]))
7264 foundThreadIndex = i;
7267 if(foundThreadIndex == -1)
7269 __SUP_COUTT__ <<
"Waiting for available thread..." << __E__;
7273 threadsLaunched = numOfThreads - 1;
7275 __SUP_COUTT__ <<
"Starting load group thread... " << groupName <<
"("
7276 << groupKey <<
")" << __E__;
7277 *(threadDone[foundThreadIndex]) =
false;
7280 [](ConfigurationManagerRW* theCfgMgr,
7281 std::string theGroupName,
7282 ots::TableGroupKey theGroupKey,
7283 std::shared_ptr<ots::GroupInfo> theGroupInfo,
7284 std::shared_ptr<std::atomic<bool>> theThreadDone) {
7285 ConfigurationManagerRW::loadTableGroupThread(theCfgMgr,
7293 TableGroupKey(groupKey),
7294 sharedGroupInfoPtrs.back(),
7295 threadDone[foundThreadIndex])
7306 foundThreadIndex = -1;
7307 for(
int i = 0; i < numOfThreads; ++i)
7308 if(!*(threadDone[i]))
7310 foundThreadIndex = i;
7313 if(foundThreadIndex != -1)
7315 __SUP_COUTT__ <<
"Waiting for thread to finish... " << foundThreadIndex
7319 }
while(foundThreadIndex != -1);
7323 for(
auto& aliasNodePair : aliasNodePairs)
7325 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7326 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7327 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7328 xmlOut.addTextElementToData(
"GroupName", groupName);
7329 xmlOut.addTextElementToData(
"GroupKey", groupKey);
7330 xmlOut.addTextElementToData(
7332 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7333 .getValueAsString());
7335 xmlOut.addTextElementToData(
"GroupComment",
7336 sharedGroupInfoPtrs[i]->latestKeyGroupComment_);
7337 xmlOut.addTextElementToData(
"GroupAuthor",
7338 sharedGroupInfoPtrs[i]->latestKeyGroupAuthor_);
7339 xmlOut.addTextElementToData(
7340 "GroupCreationTime", sharedGroupInfoPtrs[i]->latestKeyGroupCreationTime_);
7341 xmlOut.addTextElementToData(
7342 "GroupType", sharedGroupInfoPtrs[i]->latestKeyGroupTypeString_);
7361 void ConfigurationGUISupervisor::handleVersionAliasesXML(HttpXmlDocument& xmlOut,
7362 ConfigurationManagerRW* cfgMgr)
7364 cfgMgr->loadConfigurationBackbone();
7365 std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
7367 std::string versionAliasesTableName =
7368 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7369 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7371 __SUP_SS__ <<
"Active version of VersionAliases missing!"
7372 <<
"Make sure you have a valid active Backbone Group." << __E__;
7373 xmlOut.addTextElementToData(
"Error", ss.str());
7376 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName
7377 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
7378 xmlOut.addTextElementToData(
"VersionAliasesVersion",
7379 activeVersions[versionAliasesTableName].toString());
7381 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7382 cfgMgr->getNode(versionAliasesTableName).getChildren();
7384 for(
auto& aliasNodePair : aliasNodePairs)
7388 xmlOut.addTextElementToData(
7390 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
7391 xmlOut.addTextElementToData(
7392 "TableName", aliasNodePair.second.getNode(
"TableName").getValueAsString());
7393 xmlOut.addTextElementToData(
7394 "Version", aliasNodePair.second.getNode(
"Version").getValueAsString());
7395 xmlOut.addTextElementToData(
7397 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7398 .getValueAsString());
7408 void ConfigurationGUISupervisor::handleGetTableGroupTypeXML(
7409 HttpXmlDocument& xmlOut, ConfigurationManagerRW* cfgMgr,
const std::string& tableList)
7411 std::map<std::string , TableVersion > memberMap;
7412 std::string name, versionStr;
7413 auto c = tableList.find(
',', 0);
7416 while(c < tableList.length())
7419 name = tableList.substr(i, c - i);
7421 c = tableList.find(
',', i);
7422 if(c == std::string::npos)
7424 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
7425 __SUP_COUT_ERR__ <<
"\n" << ss.str();
7426 xmlOut.addTextElementToData(
"Error", ss.str());
7430 versionStr = tableList.substr(i, c - i);
7432 c = tableList.find(
',', i);
7434 memberMap[name] = TableVersion(versionStr);
7437 std::string groupTypeString =
"";
7442 groupTypeString = cfgMgr->getTypeNameOfGroup(memberMap);
7443 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7445 catch(std::runtime_error& e)
7447 __SUP_SS__ <<
"Table group has invalid type! " << e.what() << __E__;
7448 __SUP_COUT__ <<
"\n" << ss.str();
7449 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7450 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7454 __SUP_SS__ <<
"Table group has invalid type! " << __E__;
7459 catch(
const std::exception& e)
7461 ss <<
"Exception message: " << e.what();
7466 __SUP_COUT__ <<
"\n" << ss.str();
7467 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7468 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7488 void ConfigurationGUISupervisor::handleTableGroupsXML(HttpXmlDocument& xmlOut,
7489 ConfigurationManagerRW* cfgMgr,
7492 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7498 if(!cfgMgr->getAllGroupInfo().size() ||
7499 cfgMgr->getAllGroupInfo().begin()->second.latestKeyGroupTypeString_ ==
"" ||
7500 cfgMgr->getAllGroupInfo().begin()->second.latestKeyGroupTypeString_ ==
7501 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)
7503 __SUP_COUT__ <<
"Group Info cache appears empty. Attempting to regenerate."
7505 cfgMgr->getAllTableInfo(
true ,
7513 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
7515 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7517 TableGroupKey groupKey;
7518 std::string groupName;
7519 std::string groupString, groupTypeString, groupComment, groupCreationTime,
7521 for(
auto& groupInfo : allGroupInfo)
7523 groupName = groupInfo.first;
7524 if(groupInfo.second.keys_.size() == 0)
7526 __SUP_COUT__ <<
"Group name '" << groupName
7527 <<
"' found, but no keys so ignoring." << __E__;
7531 groupKey = *(groupInfo.second.keys_.rbegin());
7533 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7534 xmlOut.dataSs_ <<
"<TableGroupKey value='" << groupKey <<
"'/>" << __E__;
7537 xmlOut.dataSs_ <<
"<TableGroupType value='"
7538 << groupInfo.second.latestKeyGroupTypeString_ <<
"'/>" << __E__;
7539 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7540 << StringMacros::escapeString(
7541 groupInfo.second.latestKeyGroupComment_,
7544 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7545 << groupInfo.second.latestKeyGroupAuthor_ <<
"'/>" << __E__;
7546 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7547 << groupInfo.second.latestKeyGroupCreationTime_ <<
"'/>" << __E__;
7565 xmlOut.dataSs_ <<
"<TableGroupMembers value=''>" << __E__;
7567 for(
auto& memberPair : groupInfo.second.latestKeyMemberMap_)
7569 xmlOut.dataSs_ <<
"\t<MemberName value='" << memberPair.first <<
"'/>"
7571 xmlOut.dataSs_ <<
"\t<MemberVersion value='" << memberPair.second <<
"'/>"
7578 xmlOut.dataSs_ <<
"</TableGroupMembers>" << __E__;
7583 for(
auto& keyInSet : groupInfo.second.keys_)
7585 if(keyInSet == groupKey)
7588 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7589 xmlOut.dataSs_ <<
"<TableGroupKey value='" << keyInSet <<
"'/>" << __E__;
7594 bool loadingHistoricalInfo =
false;
7595 if(loadingHistoricalInfo)
7600 cfgMgr->loadTableGroup(groupName,
7614 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7615 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7617 <<
")' to extract group comment and type." << __E__;
7620 xmlOut.dataSs_ <<
"<TableGroupType value='" << groupTypeString <<
"'/>"
7622 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7623 << StringMacros::escapeString(groupComment,
7626 xmlOut.dataSs_ <<
"<TableGroupAuthor value='" << groupAuthor <<
"'/>"
7628 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='" << groupCreationTime
7638 xmlOut.dataSs_ <<
"<TableGroupType value='"
7639 << groupInfo.second.latestKeyGroupTypeString_ <<
"'/>"
7641 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7644 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7647 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7664 xmlOut.dataSs_ <<
"<TableGroupMembers/>" << __E__;
7669 __SUP_COUTT__ << groupName <<
" runtime=" << cfgMgr->runTimeSeconds() << __E__;
7671 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7686 void ConfigurationGUISupervisor::handleTablesXML(HttpXmlDocument& xmlOut,
7687 ConfigurationManagerRW* cfgMgr)
7689 if(cfgMgr->getAllGroupInfo().size() == 0 || cfgMgr->getActiveVersions().size() == 0)
7691 __SUP_COUT__ <<
"Table Info cache appears empty. Attempting to regenerate."
7693 cfgMgr->getAllTableInfo(
true ,
7701 xercesc::DOMElement* parentEl;
7702 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->getAllTableInfo();
7705 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
7706 for(
const auto& tablePair : allTableInfo)
7707 orderedTableSet.emplace(tablePair.first);
7711 __SUP_COUT__ <<
"# of tables found: " << allTableInfo.size() << __E__;
7713 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
7714 cfgMgr->getVersionAliases();
7716 __SUP_COUT__ <<
"# of tables w/aliases: " << versionAliases.size() << __E__;
7718 for(
const auto& orderedTableName : orderedTableSet)
7721 std::map<std::string, TableInfo>::const_iterator it =
7722 allTableInfo.find(orderedTableName);
7723 if(it == allTableInfo.end())
7725 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
7734 xmlOut.addTextElementToData(
"TableName", it->first);
7735 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
7738 if(versionAliases.find(it->first) != versionAliases.end())
7739 for(
auto& aliasVersion : versionAliases[it->first])
7740 if(it->second.versions_.find(aliasVersion.second) !=
7741 it->second.versions_.end())
7745 xmlOut.addTextElementToParent(
7747 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
7765 for(
auto& version : it->second.versions_)
7766 if(!version.isScratchVersion())
7767 xmlOut.addTextElementToParent(
"Version", version.toString(), parentEl);
7781 void ConfigurationGUISupervisor::handleGetArtdaqNodeRecordsXML(
7782 HttpXmlDocument& xmlOut,
7783 ConfigurationManagerRW* cfgMgr,
7784 const std::string& modifiedTables)
7786 __COUT__ <<
"Retrieving artdaq nodes..." << __E__;
7789 setupActiveTablesXML(
7790 xmlOut, cfgMgr,
"", TableGroupKey(-1), modifiedTables,
false );
7792 std::map<std::string ,
7793 std::map<std::string , std::vector<std::string >>>
7794 nodeTypeToObjectMap;
7795 std::map<std::string , std::string >
7798 std::vector<std::string > artdaqSupervisorInfo;
7800 std::string artdaqSupervisorName;
7801 const ARTDAQTableBase::ARTDAQInfo& info = ARTDAQTableBase::getARTDAQSystem(
7802 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap, artdaqSupervisorInfo);
7804 if(artdaqSupervisorInfo.size() != 4 )
7806 __SUP_COUT__ <<
"No artdaq supervisor found." << __E__;
7810 __SUP_COUT__ <<
"========== "
7811 <<
"Found " << info.subsystems.size() <<
" subsystems." << __E__;
7813 unsigned int paramIndex = 0;
7815 auto parentEl = xmlOut.addTextElementToData(
"artdaqSupervisor",
7816 artdaqSupervisorInfo[paramIndex++]);
7818 std::string typeString =
"artdaqSupervisor";
7820 xmlOut.addTextElementToParent(
7821 typeString +
"-status", artdaqSupervisorInfo[paramIndex++], parentEl);
7822 xmlOut.addTextElementToParent(
7823 typeString +
"-contextAddress", artdaqSupervisorInfo[paramIndex++], parentEl);
7824 xmlOut.addTextElementToParent(
7825 typeString +
"-contextPort", artdaqSupervisorInfo[paramIndex++], parentEl);
7827 for(
auto& subsystem : info.subsystems)
7829 typeString =
"subsystem";
7831 __SUP_COUT__ <<
"\t\t"
7832 <<
"Found " << typeString <<
" " << subsystem.first <<
" \t := '"
7833 << subsystem.second.label <<
"'" << __E__;
7835 xmlOut.addTextElementToParent(typeString, subsystem.second.label, parentEl);
7836 xmlOut.addTextElementToParent(
7837 typeString +
"-id", std::to_string(subsystem.first), parentEl);
7839 xmlOut.addTextElementToParent(typeString +
"-sourcesCount",
7840 std::to_string(subsystem.second.sources.size()),
7844 xmlOut.addTextElementToParent(typeString +
"-destination",
7845 std::to_string(subsystem.second.destination),
7850 __SUP_COUT__ <<
"========== "
7851 <<
"Found " << nodeTypeToObjectMap.size() <<
" process types." << __E__;
7853 for(
auto& nameTypePair : nodeTypeToObjectMap)
7855 typeString = nameTypePair.first;
7857 __SUP_COUT__ <<
"\t"
7858 <<
"Found " << nameTypePair.second.size() <<
" " << typeString
7861 for(
auto& artdaqNode : nameTypePair.second)
7863 __SUP_COUT__ <<
"\t\t"
7864 <<
"Found '" << artdaqNode.first <<
"' " << typeString << __E__;
7865 __SUP_COUTV__(StringMacros::vectorToString(artdaqNode.second));
7867 if(artdaqNode.second.size() < 2)
7869 __SUP_SS__ <<
"Impossible parameter size for node '" << artdaqNode.first
7870 <<
"' " << typeString <<
" - please notify admins!" << __E__;
7875 xmlOut.addTextElementToParent(typeString, artdaqNode.first, parentEl);
7878 if(artdaqNode.second.size() > paramIndex)
7879 xmlOut.addTextElementToParent(
7880 typeString +
"-multinode", artdaqNode.second[paramIndex++], nodeEl);
7881 if(artdaqNode.second.size() > paramIndex)
7882 xmlOut.addTextElementToParent(typeString +
"-nodefixedwidth",
7883 artdaqNode.second[paramIndex++],
7885 if(artdaqNode.second.size() > paramIndex)
7886 xmlOut.addTextElementToParent(
7887 typeString +
"-hostarray", artdaqNode.second[paramIndex++], nodeEl);
7888 if(artdaqNode.second.size() > paramIndex)
7889 xmlOut.addTextElementToParent(typeString +
"-hostfixedwidth",
7890 artdaqNode.second[paramIndex++],
7894 xmlOut.addTextElementToParent(
7895 typeString +
"-status", artdaqNode.second[paramIndex++], parentEl);
7896 xmlOut.addTextElementToParent(
7897 typeString +
"-hostname", artdaqNode.second[paramIndex++], parentEl);
7898 xmlOut.addTextElementToParent(
7899 typeString +
"-subsystem", artdaqNode.second[paramIndex], parentEl);
7903 __SUP_COUT__ <<
"Done retrieving artdaq nodes." << __E__;
7914 void ConfigurationGUISupervisor::handleSaveArtdaqNodeRecordsXML(
7915 const std::string& nodeString,
7916 const std::string& subsystemString,
7917 HttpXmlDocument& xmlOut,
7918 ConfigurationManagerRW* cfgMgr,
7919 const std::string& modifiedTables)
7921 __SUP_COUT__ <<
"Saving artdaq nodes..." << __E__;
7924 setupActiveTablesXML(
7925 xmlOut, cfgMgr,
"", TableGroupKey(-1), modifiedTables,
false );
7928 std::map<std::string ,
7929 std::map<std::string , std::vector<std::string >>>
7930 nodeTypeToObjectMap;
7936 std::map<std::string , std::string >
7937 nodeTypeToStringMap;
7938 StringMacros::getMapFromString(nodeString, nodeTypeToStringMap, {
'|'}, {
':'});
7940 __SUP_COUTV__(StringMacros::mapToString(nodeTypeToStringMap));
7942 for(
auto& typePair : nodeTypeToStringMap)
7944 if(typePair.first ==
"")
7947 __SUP_COUTV__(StringMacros::decodeURIComponent(typePair.first));
7949 nodeTypeToObjectMap.emplace(
7950 std::make_pair(StringMacros::decodeURIComponent(typePair.first),
7951 std::map<std::string ,
7952 std::vector<std::string /*property*/>>()));
7954 std::map<std::string , std::string >
7955 nodeRecordToStringMap;
7957 StringMacros::getMapFromString(
7958 typePair.second, nodeRecordToStringMap, {
';'}, {
'='});
7960 __SUP_COUTV__(StringMacros::mapToString(nodeRecordToStringMap));
7962 for(
auto& nodePair : nodeRecordToStringMap)
7964 if(nodePair.first ==
"")
7967 __SUP_COUTV__(StringMacros::decodeURIComponent(nodePair.first));
7969 std::vector<std::string > nodePropertyVector;
7971 StringMacros::getVectorFromString(
7972 nodePair.second, nodePropertyVector, {
','});
7974 __SUP_COUTV__(StringMacros::vectorToString(nodePropertyVector));
7977 for(
unsigned int i = 0; i < nodePropertyVector.size(); ++i)
7980 StringMacros::decodeURIComponent(nodePropertyVector[i]));
7982 nodePropertyVector[i] =
7983 StringMacros::decodeURIComponent(nodePropertyVector[i]);
7986 nodeTypeToObjectMap[typePair.first].emplace(
7987 std::make_pair(StringMacros::decodeURIComponent(nodePair.first),
7988 nodePropertyVector));
7994 std::map<std::string , std::string >
8001 std::map<std::string , std::string >
8002 tmpSubsystemObjectMap;
8003 StringMacros::getMapFromString(
8004 subsystemString, tmpSubsystemObjectMap, {
';'}, {
':'});
8006 __SUP_COUTV__(StringMacros::mapToString(tmpSubsystemObjectMap));
8009 for(
auto& subsystemPair : tmpSubsystemObjectMap)
8011 __SUP_COUTV__(StringMacros::decodeURIComponent(subsystemPair.first));
8012 __SUP_COUTV__(StringMacros::decodeURIComponent(subsystemPair.second));
8014 subsystemObjectMap.emplace(
8015 std::make_pair(StringMacros::decodeURIComponent(subsystemPair.first),
8016 StringMacros::decodeURIComponent(subsystemPair.second)));
8020 ARTDAQTableBase::setAndActivateARTDAQSystem(
8021 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap);
8023 __SUP_COUT__ <<
"Done saving artdaq nodes." << __E__;
8033 void ConfigurationGUISupervisor::handleLoadArtdaqNodeLayoutXML(
8034 HttpXmlDocument& xmlOut,
8035 ConfigurationManager*
8037 const std::string& contextGroupName ,
8038 const TableGroupKey& contextGroupKey )
const
8040 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.isInvalid());
8042 const std::string& finalContextGroupName =
8044 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8046 const TableGroupKey& finalContextGroupKey =
8048 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8051 std::stringstream layoutPath;
8052 layoutPath << ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName <<
"_"
8053 << finalContextGroupKey <<
".dat";
8054 __SUP_COUTV__(layoutPath.str());
8056 FILE* fp = fopen(layoutPath.str().c_str(),
"r");
8059 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8060 << finalContextGroupKey <<
")'" << __E__;
8068 const size_t maxLineSz = 1000;
8069 char line[maxLineSz];
8070 if(!fgets(line, maxLineSz, fp))
8079 unsigned int rows, cols;
8081 sscanf(line,
"%u %u", &rows, &cols);
8083 __COUT__ <<
"Grid rows,cols = " << rows <<
"," << cols << __E__;
8085 xmlOut.addTextElementToData(
"grid-rows", std::to_string(rows));
8086 xmlOut.addTextElementToData(
"grid-cols", std::to_string(cols));
8089 char name[maxLineSz];
8090 char type[maxLineSz];
8092 while(fgets(line, maxLineSz, fp))
8095 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
8097 xmlOut.addTextElementToData(
"node-type", type);
8098 xmlOut.addTextElementToData(
"node-name", name);
8099 xmlOut.addTextElementToData(
"node-x", std::to_string(x));
8100 xmlOut.addTextElementToData(
"node-y", std::to_string(y));
8114 void ConfigurationGUISupervisor::handleSaveArtdaqNodeLayoutXML(
8116 ConfigurationManagerRW* cfgMgr,
8117 const std::string& layoutString,
8118 const std::string& contextGroupName,
8119 const TableGroupKey& contextGroupKey)
8121 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.isInvalid());
8123 const std::string& finalContextGroupName =
8125 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8127 const TableGroupKey& finalContextGroupKey =
8129 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8132 __SUP_COUTV__(layoutString);
8134 std::stringstream layoutPath;
8135 layoutPath << ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName <<
"_"
8136 << finalContextGroupKey <<
".dat";
8137 __SUP_COUTV__(layoutPath.str());
8139 std::vector<std::string> fields = StringMacros::getVectorFromString(layoutString);
8140 __SUP_COUTV__(StringMacros::vectorToString(fields));
8142 if(fields.size() < 2 || (fields.size() - 2) % 4 != 0)
8144 __SUP_SS__ <<
"Invalid layout string fields size of " << fields.size() << __E__;
8148 FILE* fp = fopen(layoutPath.str().c_str(),
"w");
8151 __SUP_SS__ <<
"Could not open layout file for writing for '"
8152 << finalContextGroupName <<
"(" << finalContextGroupKey <<
")'"
8160 fprintf(fp,
"%s %s\n", fields[0].c_str(), fields[1].c_str());
8163 for(
unsigned int i = 2; i < fields.size(); i += 4)
8166 fields[i + 0].c_str(),
8167 fields[i + 1].c_str(),
8168 fields[i + 2].c_str(),
8169 fields[i + 3].c_str());
8177 void ConfigurationGUISupervisor::handleOtherSubsystemActiveGroups(
8178 HttpXmlDocument& xmlOut,
8179 ConfigurationManagerRW* cfgMgr,
8181 std::string targetSubsystem )
8186 ConfigurationTree node =
8187 cfgMgr->getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8188 auto children = node.getChildren();
8190 for(
auto subsystem : children)
8192 __SUP_COUTV__(subsystem.first);
8194 StringMacros::vectorToString(subsystem.second.getChildrenNames()));
8196 std::string userPath =
8197 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8198 __SUP_COUTV__(userPath);
8201 catch(
const std::runtime_error& e)
8203 __SUP_COUT__ <<
"Ignoring errors in handling other subsystem active groups "
8204 "(assuming the subsystem information map is not setup in "
8205 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8206 <<
") -- here is the error: \n"
8207 << e.what() << __E__;
8213 ConfigurationTree node =
8214 cfgMgr->getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8215 auto children = node.getChildren();
8216 for(
auto subsystem : children)
8218 if(targetSubsystem !=
"" && targetSubsystem != subsystem.first)
8221 xercesc::DOMElement* parent =
8222 xmlOut.addTextElementToData(
"SubsystemName", subsystem.first);
8227 std::string filename, userDataPath;
8228 std::string username, hostname;
8230 std::map<std::string ,
8231 std::pair<std::string , TableGroupKey>>
8232 retMap = cfgMgr->getOtherSubsystemActiveTableGroups(
8233 subsystem.first, &userDataPath, &hostname, &username);
8235 for(
const auto& retPair : retMap)
8237 xmlOut.addTextElementToParent(
"CurrentlyActive" + retPair.first +
"GroupName",
8238 retPair.second.first,
8240 xmlOut.addTextElementToParent(
"CurrentlyActive" + retPair.first +
"GroupKey",
8241 retPair.second.second.toString(),
8245 std::vector<std::string> filenameTypes = {
"Configured",
8249 "ActivatedBackbone",
8250 "ActivatedIterator"};
8252 std::vector<std::string> filenames = {
8253 FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE,
8254 FSM_LAST_STARTED_GROUP_ALIAS_FILE,
8255 ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE,
8256 ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE,
8257 ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE,
8258 ConfigurationManager::LAST_ACTIVATED_ITERATOR_GROUP_FILE};
8260 std::string userPath =
8261 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8262 auto splitPath = StringMacros::getVectorFromString(userPath, {
':'});
8263 std::string cmdResult;
8264 for(
unsigned int i = 0; i < filenames.size(); ++i)
8266 filename = userDataPath +
"/ServiceData/RunControlData/" + filenames[i];
8267 __SUP_COUTV__(filename);
8269 std::string tmpSubsystemFilename =
8270 ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" + filenames[i] +
8271 "." + subsystem.first;
8272 __SUP_COUTV__(tmpSubsystemFilename);
8274 if(splitPath.size() == 2)
8277 cmdResult = StringMacros::exec(
8278 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + username +
8279 "@" + hostname +
":" + filename +
" " + tmpSubsystemFilename +
8280 " 2>&1; cat " + tmpSubsystemFilename +
" 2>&1")
8283 cmdResult = StringMacros::exec(
8284 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + hostname +
8285 ":" + filename +
" " + tmpSubsystemFilename +
" 2>&1; cat " +
8286 tmpSubsystemFilename +
" 2>&1")
8289 else if(splitPath.size() == 1)
8291 cmdResult = StringMacros::exec((
"rm " + tmpSubsystemFilename +
8292 " 2>/dev/null; cp " + filename +
" " +
8293 tmpSubsystemFilename +
" 2>&1; cat " +
8294 tmpSubsystemFilename +
" 2>&1")
8298 __SUP_COUTV__(cmdResult);
8299 std::string timeString;
8300 std::pair<std::string , TableGroupKey> theGroup =
8301 ConfigurationManager::loadGroupNameAndKey(
8302 filenames[i] +
"." + subsystem.first, timeString);
8305 xmlOut.addTextElementToParent(
8306 "Last" + filenameTypes[i] +
"GroupName", theGroup.first, parent);
8307 xmlOut.addTextElementToParent(
"Last" + filenameTypes[i] +
"GroupKey",
8308 theGroup.second.toString(),
8310 xmlOut.addTextElementToParent(
8311 "Last" + filenameTypes[i] +
"GroupTime", timeString, parent);
8316 catch(
const std::runtime_error& e)
8319 <<
"An error occurred handling subsystem active groups (Please check the "
8320 "subsystem user data path information map setup in the Context group table "
8321 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8322 <<
") -- here is the error: \n"
8323 << e.what() << __E__;
8329 void ConfigurationGUISupervisor::handleGroupDiff(
8330 HttpXmlDocument& xmlOut,
8331 ConfigurationManagerRW* cfgMgr,
8332 const std::string& groupName,
8333 const TableGroupKey& groupKey,
8334 const TableGroupKey& diffKey ,
8335 const std::string& diffGroupNameInput )
8341 std::string diffGroupName;
8343 if(diffKey.isInvalid())
8344 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8345 <<
") with the active group." << __E__;
8348 if(diffGroupNameInput ==
"")
8349 diffGroupName = groupName;
8351 diffGroupName = diffGroupNameInput;
8353 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8354 <<
") with group " << diffGroupName <<
"(" << diffKey <<
")"
8360 std::map<std::string , TableVersion > memberMap, diffMemberMap;
8361 std::string groupType, accumulateErrors;
8362 std::stringstream diffReport;
8363 bool noDifference =
true;
8365 cfgMgr->loadTableGroup(
8376 (diffKey.isInvalid()
8380 __SUP_COUTV__(StringMacros::mapToString(memberMap));
8382 std::map<std::string , std::pair<std::string, TableGroupKey>>
8384 if(diffKey.isInvalid())
8386 activeGroups = cfgMgr->getActiveTableGroups();
8388 __SUP_COUTV__(StringMacros::mapToString(activeGroups));
8389 __SUP_COUTV__(groupType);
8391 if(activeGroups.find(groupType) == activeGroups.end() ||
8392 activeGroups.at(groupType).first ==
"" ||
8393 activeGroups.at(groupType).second.isInvalid())
8395 __SUP_SS__ <<
"Could not find an active group of type '" << groupType
8396 <<
".' Please check the expected active configuration groups "
8397 "for errors (going to 'System View' of the Config App may "
8403 __SUP_COUT__ <<
"active " << groupType <<
" group is "
8404 << activeGroups.at(groupType).first <<
"("
8405 << activeGroups.at(groupType).second <<
")" << __E__;
8407 diffReport <<
"This difference report is between " << groupType
8408 <<
" group <b>'" << groupName <<
"(" << groupKey <<
")'</b>"
8409 <<
" and active group <b>'" << activeGroups.at(groupType).first
8410 <<
"(" << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8412 cfgMgr->loadTableGroup(activeGroups.at(groupType).first,
8413 activeGroups.at(groupType).second,
8423 diffReport <<
"\n\n"
8424 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8425 << memberMap.size() <<
" member tables</b>, and "
8426 <<
"'" << activeGroups.at(groupType).first <<
"("
8427 << activeGroups.at(groupType).second <<
")' has <b>"
8428 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8432 diffReport <<
"This difference report is between group <b>'" << groupName
8433 <<
"(" << groupKey <<
")'</b>"
8434 <<
" and group <b>'" << diffGroupName <<
"(" << diffKey
8435 <<
")'</b>." << __E__;
8437 cfgMgr->loadTableGroup(diffGroupName,
8448 diffReport <<
"\n\n"
8449 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8450 << memberMap.size() <<
" member tables</b>, and "
8451 <<
"'" << diffGroupName <<
"(" << diffKey <<
")' has <b>"
8452 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8455 __SUP_COUTV__(StringMacros::mapToString(diffMemberMap));
8457 diffReport <<
"<INDENT><ol>";
8459 unsigned int tableDifferences = 0;
8461 for(
auto& member : memberMap)
8463 if(diffMemberMap.find(member.first) == diffMemberMap.end())
8465 diffReport <<
"\n\n<li>"
8466 <<
"Table <b>" << member.first <<
"-v" << member.second
8467 <<
"</b> not found in active group."
8468 <<
"</li>" << __E__;
8469 noDifference =
false;
8474 __SUP_COUTT__ <<
"Comparing " << member.first <<
"-v" << member.second
8475 <<
" ... " << member.first <<
"-v"
8476 << diffMemberMap.at(member.first) << __E__;
8478 if(member.second == diffMemberMap.at(member.first))
8481 diffReport <<
"\n\n<li>"
8482 <<
"Table <b>" << member.first <<
" v" << member.second
8483 <<
"</b> in " << groupName <<
"(" << groupKey <<
")' ...vs... "
8484 <<
" <b>v" << diffMemberMap.at(member.first) <<
"</b> in "
8485 << diffGroupName <<
"(" << diffKey <<
")':" << __E__;
8487 TableBase* table = cfgMgr->getTableByName(member.first);
8489 diffReport <<
"<ul>";
8490 std::map<std::string , std::vector<std::string >>
8492 if(!table->diffTwoVersions(member.second,
8493 diffMemberMap.at(member.first),
8498 noDifference =
false;
8501 xmlOut.addTextElementToData(
"TableWithDiff", member.first);
8502 for(
auto& modifiedRecord : modifiedRecords)
8504 auto recordParentEl = xmlOut.addTextElementToParent(
8505 "RecordWithDiff", modifiedRecord.first, parentEl);
8506 for(
auto& modifiedColumn : modifiedRecord.second)
8507 xmlOut.addTextElementToParent(
8508 "ColNameWithDiff", modifiedColumn, recordParentEl);
8511 diffReport <<
"</ul></li>";
8515 for(
auto& diffMember : diffMemberMap)
8517 if(memberMap.find(diffMember.first) == memberMap.end())
8519 if(diffKey.isInvalid())
8520 diffReport <<
"\n\n<li>"
8521 <<
"Active Group Table <b>" << diffMember.first <<
"-v"
8522 << diffMember.second <<
"</b> not found in '" << groupName
8523 <<
"(" << groupKey <<
")'."
8524 <<
"</li>" << __E__;
8526 diffReport <<
"\n\n<li>" << diffGroupName <<
"(" << diffKey
8527 <<
") Table <b>" << diffMember.first <<
"-v"
8528 << diffMember.second <<
"</b> not found in '" << groupName
8529 <<
"(" << groupKey <<
")'."
8530 <<
"</li>" << __E__;
8532 noDifference =
false;
8537 diffReport <<
"\n</ol></INDENT>";
8539 if(diffKey.isInvalid())
8542 diffReport <<
"\n\nNo difference found between "
8543 <<
"<b>'" << groupName <<
"(" << groupKey
8544 <<
")'</b> and active group "
8545 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8546 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8548 diffReport <<
"\n\n<b>" << tableDifferences
8549 <<
"</b> member table differences identified between "
8550 <<
"<b>'" << groupName <<
"(" << groupKey
8551 <<
")'</b> and active group "
8552 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8553 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8558 diffReport <<
"\n\nNo difference found between "
8559 <<
"<b>'" << groupName <<
"(" << groupKey
8560 <<
")'</b> and group "
8561 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8564 diffReport <<
"\n\n<b>" << tableDifferences
8565 <<
"</b> member table differences identified between "
8566 <<
"<b>'" << groupName <<
"(" << groupKey
8567 <<
")'</b> and group "
8568 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8572 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
8573 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
8575 catch(
const std::runtime_error& e)
8577 __SUP_COUT_ERR__ <<
"Caught error while differencing group " << groupName <<
"("
8578 << groupKey <<
") with group " << diffGroupName <<
"(" << diffKey
8579 <<
")" << __E__ << e.what() << __E__;
8586 void ConfigurationGUISupervisor::handleTableDiff(HttpXmlDocument& xmlOut,
8587 ConfigurationManagerRW* cfgMgr,
8588 const std::string& tableName,
8589 const TableVersion& vA,
8590 const TableVersion& vB)
8592 __SUP_COUT__ <<
"Differencing tableName " << tableName <<
" v" << vA <<
" with v"
8596 TableBase* table = cfgMgr->getTableByName(tableName);
8602 std::string localAccumulatedErrors =
"";
8603 cfgMgr->getVersionedTableByName(tableName,
8606 &localAccumulatedErrors,
8609 if(localAccumulatedErrors !=
"")
8610 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8612 catch(std::runtime_error& e)
8614 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vA;
8615 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8616 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8618 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8622 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vA << __E__;
8627 catch(
const std::exception& e)
8629 ss <<
"Exception message: " << e.what();
8635 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8636 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8642 std::string localAccumulatedErrors =
"";
8643 cfgMgr->getVersionedTableByName(tableName,
8646 &localAccumulatedErrors,
8649 if(localAccumulatedErrors !=
"")
8650 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8652 catch(std::runtime_error& e)
8654 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vB;
8655 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8656 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8658 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8662 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vB << __E__;
8667 catch(
const std::exception& e)
8669 ss <<
"Exception message: " << e.what();
8675 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8676 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8679 bool noDifference =
true;
8680 std::stringstream diffReport;
8682 diffReport <<
"This difference report is between table " << tableName <<
" v" << vA
8683 <<
" and v" << vB <<
"</b>." << __E__;
8685 diffReport <<
"<INDENT>";
8686 diffReport <<
"<ul>";
8687 std::map<std::string , std::vector<std::string >>
8689 if(!table->diffTwoVersions(vA, vB, &diffReport))
8690 noDifference =
false;
8691 diffReport <<
"</ul></INDENT>";
8693 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
8694 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
8700 void ConfigurationGUISupervisor::testXDAQContext()
8709 __SUP_COUT__ <<
"Attempting test activation of the context group." << __E__;
8710 ConfigurationManager cfgMgr;
8712 catch(
const std::runtime_error& e)
8715 <<
"The test activation of the context group failed. Ignoring error: \n"
8716 << e.what() << __E__;
8720 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring."
virtual void forceSupervisorPropertyValues(void) override
override to force supervisor property values (and ignore user settings)
virtual void setSupervisorPropertyDefaults(void) override
ConfigurationGUISupervisor(xdaq::ApplicationStub *s)
static xdaq::Application * instantiate(xdaq::ApplicationStub *s)