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")
43 __SUP_COUT__ <<
"Constructor started." << __E__;
48 mkdir(((std::string)ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH).c_str(), 0755);
51 __SUP_COUT__ <<
"Constructor complete." << __E__;
55 ConfigurationGUISupervisor::~ConfigurationGUISupervisor(
void) { destroy(); }
58 void ConfigurationGUISupervisor::init(
void)
60 __SUP_COUT__ <<
"Initializing..." << __E__;
64 __SUP_COUT__ <<
"Activating saved context, which may prepare for normal mode..."
69 __SUP_COUT__ <<
"Done with test context." << __E__;
73 __COUT_WARN__ <<
"Failed test context group activation. otsdaq, in Normal mode, "
74 "will not launch when this test fails. "
75 <<
"Check the active context group from within Wizard Mode."
80 refreshUserSession(
"" , 1);
86 void ConfigurationGUISupervisor::destroy(
void)
88 __SUP_COUT__ <<
"Destructing..." << __E__;
91 for(std::map<std::string, ConfigurationManagerRW*>::iterator it =
92 userConfigurationManagers_.begin();
93 it != userConfigurationManagers_.end();
99 userConfigurationManagers_.clear();
101 if(ConfigurationInterface::getInstance() !=
nullptr)
102 delete ConfigurationInterface::getInstance();
107 void ConfigurationGUISupervisor::defaultPage(xgi::Input* in, xgi::Output* out)
109 cgicc::Cgicc cgiIn(in);
110 std::string configWindowName =
112 if(configWindowName ==
"tableEditor")
113 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
114 "src='/WebPath/html/ConfigurationTableEditor.html?urn="
115 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
116 if(configWindowName ==
"iterate")
117 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
118 "src='/WebPath/html/Iterate.html?urn="
119 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
121 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
122 "src='/WebPath/html/ConfigurationGUI.html?urn="
123 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
131 CorePropertySupervisorBase::setSupervisorProperty(
132 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
133 "*=10 | deleteTreeNodeRecords=255 | saveTableInfo=255 | "
134 "deleteTableInfo=255");
136 CorePropertySupervisorBase::setSupervisorProperty(
137 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
141 CorePropertySupervisorBase::setSupervisorProperty(
142 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
"get*");
150 CorePropertySupervisorBase::addSupervisorProperty(
151 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
152 "getActiveTableGroups");
155 CorePropertySupervisorBase::setSupervisorProperty(
156 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
161 void ConfigurationGUISupervisor::request(
const std::string& requestType,
164 const WebUsers::RequestUserInfo& userInfo)
169 __COUTTV__(requestType);
239 refreshUserSession(userInfo.username_, (refresh ==
"1"));
240 __COUTTV__(userInfo.username_);
246 const std::set<TableGroupKey>& sortedKeys = groupInfo.getKeys();
247 __COUTTV__(sortedKeys.size());
250 if(requestType ==
"saveTableInfo")
252 std::string tableName =
254 std::string columnCSV =
256 std::string allowOverwrite =
258 std::string tableDescription =
260 std::string columnChoicesCSV =
263 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
264 __SUP_COUT__ <<
"columnCSV: " << columnCSV << __E__;
265 __SUP_COUT__ <<
"tableDescription: " << tableDescription << __E__;
266 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << __E__;
267 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << __E__;
269 if(!allSupervisorInfo_.isWizardMode())
271 __SUP_SS__ <<
"Improper permissions for saving table info." << __E__;
272 xmlOut.addTextElementToData(
"Error", ss.str());
275 handleSaveTableInfoXML(xmlOut,
281 allowOverwrite ==
"1");
283 else if(requestType ==
"deleteTableInfo")
285 std::string tableName =
287 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
288 handleDeleteTableInfoXML(xmlOut, cfgMgr, tableName);
290 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
291 requestType ==
"flattenToSystemAliases")
294 __SUP_COUT_WARN__ << requestType <<
" command received! " << __E__;
295 __COUT_WARN__ << requestType <<
" command received! " << __E__;
298 __SUP_COUT_INFO__ <<
"Launching " << requestType <<
"... " << __E__;
300 __SUP_COUT__ <<
"Extracting target context hostnames... " << __E__;
301 std::vector<std::string> hostnames;
304 if(requestType ==
"flattenToSystemAliases" &&
305 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
307 hostnames.push_back(__ENV__(
"OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER"));
308 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
319 auto contexts = contextTable->getContexts();
321 for(
const auto& context : contexts)
328 for(i = 0; i < context.address_.size(); ++i)
329 if(context.address_[i] ==
'/')
331 hostnames.push_back(context.address_.substr(j));
332 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
337 __SUP_SS__ <<
"The Configuration Manager could not be initialized to "
344 catch(
const std::exception& e)
346 ss <<
"Exception message: " << e.what();
352 __SUP_COUT_ERR__ <<
"\n" << ss.str();
357 if(hostnames.size() == 0)
359 __SUP_SS__ <<
"No hostnames found to launch command '" + requestType +
360 "'... Is there a valid Context group activated?"
362 __SUP_COUT_ERR__ <<
"\n" << ss.str();
364 xmlOut.addTextElementToData(
"Error", ss.str());
367 for(
const auto& hostname : hostnames)
369 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
370 "/StartOTS_action_" + hostname +
".cmd");
371 FILE* fp = fopen(fn.c_str(),
"w");
374 if(requestType ==
"gatewayLaunchOTS")
375 fprintf(fp,
"LAUNCH_OTS");
376 else if(requestType ==
"gatewayLaunchWiz")
377 fprintf(fp,
"LAUNCH_WIZ");
378 else if(requestType ==
"flattenToSystemAliases")
380 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
388 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << __E__;
391 else if(requestType ==
"versionTracking" || requestType ==
"getVersionTracking")
394 if(requestType ==
"getVersionTracking")
398 __SUP_COUT__ <<
"type: " << type << __E__;
401 xmlOut.addTextElementToData(
402 "versionTrackingStatus",
403 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
404 else if(type ==
"ON")
406 ConfigurationInterface::setVersionTrackingEnabled(
true);
407 xmlOut.addTextElementToData(
408 "versionTrackingStatus",
409 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
411 else if(type ==
"OFF")
413 ConfigurationInterface::setVersionTrackingEnabled(
false);
414 xmlOut.addTextElementToData(
415 "versionTrackingStatus",
416 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
419 else if(requestType ==
"getColumnTypes")
422 std::vector<std::string> allTypes = TableViewColumnInfo::getAllTypesForGUI();
423 std::vector<std::string> allDataTypes =
424 TableViewColumnInfo::getAllDataTypesForGUI();
425 std::map<std::pair<std::string, std::string>, std::string> allDefaults =
428 for(
const auto& type : allTypes)
429 xmlOut.addTextElementToData(
"columnTypeForGUI", type);
430 for(
const auto& dataType : allDataTypes)
431 xmlOut.addTextElementToData(
"columnDataTypeForGUI", dataType);
433 for(
const auto& colDefault : allDefaults)
435 xmlOut.addTextElementToData(
"columnDefaultDataType", colDefault.first.first);
436 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
437 colDefault.first.second);
438 xmlOut.addTextElementToData(
"columnDefaultValue", colDefault.second);
442 else if(requestType ==
"getGroupAliases")
447 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
449 __SUP_COUT__ <<
"reloadActive: " << reloadActive << __E__;
457 catch(std::runtime_error& e)
459 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what()))
461 __SUP_COUT_ERR__ <<
"\n" << ss.str();
462 xmlOut.addTextElementToData(
"Error", ss.str());
466 __SUP_SS__ << (
"Error loading active groups!\n\n") << __E__;
471 catch(
const std::exception& e)
473 ss <<
"Exception message: " << e.what();
478 __SUP_COUT_ERR__ <<
"\n" << ss.str();
479 xmlOut.addTextElementToData(
"Error", ss.str());
483 handleGroupAliasesXML(xmlOut, cfgMgr);
485 else if(requestType ==
"setGroupAliasInActiveBackbone")
487 std::string groupAliasCSV =
489 std::string groupNameCSV =
491 std::string groupKeyCSV =
494 __SUP_COUTV__(groupAliasCSV);
495 __SUP_COUTV__(groupNameCSV);
496 __SUP_COUTV__(groupKeyCSV);
498 handleSetGroupAliasInBackboneXML(
499 xmlOut, cfgMgr, groupAliasCSV, groupNameCSV, groupKeyCSV, userInfo.username_);
501 else if(requestType ==
"setTableAliasInActiveBackbone")
503 std::string tableAlias =
505 std::string tableName =
509 __SUP_COUT__ <<
"tableAlias: " << tableAlias << __E__;
510 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
511 __SUP_COUT__ <<
"version: " << version << __E__;
513 handleSetTableAliasInBackboneXML(xmlOut,
520 else if(requestType ==
"setAliasOfGroupMembers")
522 std::string versionAlias =
524 std::string groupName =
528 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
529 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
530 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
532 handleAliasGroupMembersInBackboneXML(xmlOut,
539 else if(requestType ==
"getVersionAliases")
541 handleVersionAliasesXML(xmlOut, cfgMgr);
543 else if(requestType ==
"getTableGroups")
545 bool doNotReturnMembers =
546 CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1
550 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << __E__;
551 handleTableGroupsXML(xmlOut, cfgMgr, !doNotReturnMembers);
553 else if(requestType ==
"getTableGroupType")
555 std::string tableList =
557 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
559 handleGetTableGroupTypeXML(xmlOut, cfgMgr, tableList);
561 else if(requestType ==
"getTables")
563 handleTablesXML(xmlOut, cfgMgr);
565 else if(requestType ==
"getContextMemberNames")
567 std::set<std::string> members = cfgMgr->getFixedContextMemberNames();
569 for(
auto& member : members)
570 xmlOut.addTextElementToData(
"ContextMember", member);
572 else if(requestType ==
"getBackboneMemberNames")
574 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
576 for(
auto& member : members)
577 xmlOut.addTextElementToData(
"BackboneMember", member);
579 else if(requestType ==
"getIterateMemberNames")
581 std::set<std::string> members = cfgMgr->getIterateMemberNames();
583 for(
auto& member : members)
584 xmlOut.addTextElementToData(
"IterateMember", member);
586 else if(requestType ==
"getSpecificTableGroup")
588 std::string groupName =
592 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
593 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
598 else if(requestType ==
"saveNewTableGroup")
600 std::string groupName =
602 bool ignoreWarnings =
603 CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
604 bool allowDuplicates =
605 CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
606 bool lookForEquivalent =
607 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
608 std::string tableList =
610 std::string comment =
613 __SUP_COUT__ <<
"saveNewTableGroup: " << groupName << __E__;
614 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
615 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
616 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << __E__;
617 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
618 __SUP_COUT__ <<
"comment: " << comment << __E__;
629 else if(requestType ==
"getSpecificTable")
631 std::string tableName =
634 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
635 int chunkSize = CgiDataUtilities::getDataAsInt(cgiIn,
"chunkSize");
638 std::string allowIllegalColumns =
640 __SUP_COUT__ <<
"allowIllegalColumns: " << (allowIllegalColumns ==
"1") << __E__;
643 __SUP_COUT__ <<
"rawData: " << (rawData ==
"1") << __E__;
645 __SUP_COUT__ <<
"getSpecificTable: " << tableName <<
" versionStr: " << versionStr
646 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset
650 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
652 if(allTableInfo.find(tableName) != allTableInfo.end())
654 if(versionStr ==
"" &&
655 allTableInfo.at(tableName).versions_.size())
658 auto it = allTableInfo.at(tableName).versions_.rbegin();
659 if(it->isScratchVersion())
663 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
666 std::map<std::string ,
670 std::string versionAlias;
671 versionAlias = versionStr.substr(
672 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
683 if(versionAliases.find(tableName) != versionAliases.end() &&
684 versionAliases[tableName].find(versionAlias) !=
685 versionAliases[tableName].end())
687 version = versionAliases[tableName][versionAlias];
688 __SUP_COUT__ <<
"version alias translated to: " << version << __E__;
693 << versionStr.substr(
694 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
695 <<
"'was not found in active version aliases!" << __E__;
698 version = atoi(versionStr.c_str());
701 __SUP_COUT__ <<
"version: " << version << __E__;
703 handleGetTableXML(xmlOut,
707 (allowIllegalColumns ==
"1"),
710 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
712 else if(requestType ==
"saveSpecificTable")
714 std::string tableName =
716 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
717 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
718 bool sourceTableAsIs =
719 CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
720 bool lookForEquivalent =
721 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
722 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
723 std::string comment =
730 __SUP_COUT__ <<
"tableName: " << tableName <<
" version: " << version
731 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset
733 __SUP_COUT__ <<
"comment: " << comment << __E__;
734 __SUP_COUT__ <<
"data: " << data << __E__;
735 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << __E__;
736 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
750 else if(requestType ==
"clearTableTemporaryVersions")
752 std::string tableName =
754 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
760 catch(std::runtime_error& e)
762 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
763 xmlOut.addTextElementToData(
764 "Error",
"Error clearing temporary views!\n " + std::string(e.what()));
768 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
769 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
772 else if(requestType ==
"clearTableCachedVersions")
774 std::string tableName =
776 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
787 catch(std::runtime_error& e)
789 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
790 xmlOut.addTextElementToData(
791 "Error",
"Error clearing cached views!\n " + std::string(e.what()));
795 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
796 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
799 else if(requestType ==
"getGroupHistory")
806 __SUP_COUTV__(groupAction);
807 __SUP_COUTV__(groupType);
809 std::vector<std::map<std::string ,
812 groupAction, groupType,
true );
814 for(
const auto& group : groups)
816 auto parentEl = xmlOut.addTextElementToData(
817 "GroupHistoryEntry",
"");
818 for(
const auto& field : group)
822 else if(requestType ==
"getTreeView")
829 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
830 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
834 __SUP_COUTT__ <<
"tableGroup: " << tableGroup << __E__;
835 __SUP_COUTT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
836 __SUP_COUTT__ <<
"startPath: " << startPath << __E__;
837 __SUP_COUTT__ <<
"depth: " << depth << __E__;
838 __SUP_COUTT__ <<
"hideStatusFalse: " << hideStatusFalse << __E__;
839 __SUP_COUTT__ <<
"modifiedTables: " << modifiedTables << __E__;
840 __SUP_COUTT__ <<
"filterList: " << filterList << __E__;
842 handleFillTreeViewXML(xmlOut,
854 else if(requestType ==
"getTreeNodeCommonFields")
862 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
864 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
865 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
866 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
867 __SUP_COUT__ <<
"depth: " << depth << __E__;
870 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
871 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
872 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
874 handleFillTreeNodeCommonFieldsXML(xmlOut,
884 else if(requestType ==
"getUniqueFieldValuesForRecords")
893 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
894 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
895 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
896 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
897 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
898 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
900 handleFillUniqueFieldValuesForRecordsXML(xmlOut,
909 else if(requestType ==
"getTreeNodeFieldValues")
918 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
919 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
920 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
921 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
922 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
923 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
925 handleFillGetTreeNodeFieldValuesXML(xmlOut,
934 else if(requestType ==
"setTreeNodeFieldValues")
944 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
945 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
946 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
947 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
948 __SUP_COUT__ <<
"valueList: " << valueList << __E__;
949 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
950 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
952 handleFillSetTreeNodeFieldValuesXML(xmlOut,
963 else if(requestType ==
"addTreeNodeRecords")
971 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
972 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
973 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
974 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
975 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
977 handleFillCreateTreeNodeRecordsXML(xmlOut,
986 else if(requestType ==
"deleteTreeNodeRecords")
994 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
995 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
996 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
997 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
998 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1000 handleFillDeleteTreeNodeRecordsXML(xmlOut,
1008 else if(requestType ==
"renameTreeNodeRecords")
1017 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1018 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1019 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1020 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1021 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1022 __SUP_COUTV__(newRecordList);
1024 handleFillRenameTreeNodeRecordsXML(xmlOut,
1033 else if(requestType ==
"copyTreeNodeRecords")
1040 unsigned int numberOfCopies =
1041 CgiDataUtilities::getDataAsInt(cgiIn,
"numberOfCopies");
1045 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1046 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1047 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1048 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1049 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1050 __SUP_COUTV__(numberOfCopies);
1052 handleFillCopyTreeNodeRecordsXML(xmlOut,
1061 else if(requestType ==
"getTableStructureStatusAsJSON")
1068 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1069 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1070 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1071 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1074 setupActiveTablesXML(xmlOut,
1083 xmlOut.addTextElementToData(
1084 "StructureStatusAsJSON",
1087 catch(
const std::runtime_error& e)
1089 __SUP_SS__ <<
"The table plugin feature getStructureStatusAsJSON(), does not "
1090 "seem to be supported for the table '"
1092 <<
".' Make sure you have the expected table plugin in your path, "
1093 "or contact system admins."
1095 ss <<
"Here is the error: " << e.what() << __E__;
1099 else if(requestType ==
"getArtdaqNodes")
1103 __SUP_COUTV__(modifiedTables);
1105 handleGetArtdaqNodeRecordsXML(xmlOut, cfgMgr, modifiedTables);
1107 else if(requestType ==
"saveArtdaqNodes")
1111 std::string subsystemString =
1114 __SUP_COUTV__(modifiedTables);
1115 __SUP_COUTV__(nodeString);
1116 __SUP_COUTV__(subsystemString);
1118 handleSaveArtdaqNodeRecordsXML(
1119 nodeString, subsystemString, xmlOut, cfgMgr, modifiedTables);
1121 else if(requestType ==
"getArtdaqNodeLayout")
1123 std::string contextGroupName =
1127 __SUP_COUTV__(contextGroupName);
1128 __SUP_COUTV__(contextGroupKey);
1130 handleLoadArtdaqNodeLayoutXML(
1131 xmlOut, cfgMgr, contextGroupName,
TableGroupKey(contextGroupKey));
1133 else if(requestType ==
"saveArtdaqNodeLayout")
1136 std::string contextGroupName =
1140 __SUP_COUTV__(layout);
1141 __SUP_COUTV__(contextGroupName);
1142 __SUP_COUTV__(contextGroupKey);
1144 handleSaveArtdaqNodeLayoutXML(
1145 xmlOut, cfgMgr, layout, contextGroupName,
TableGroupKey(contextGroupKey));
1147 else if(requestType ==
"checkAffectedActiveGroups")
1152 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1153 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
1154 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
1156 handleGetAffectedGroupsXML(
1157 xmlOut, cfgMgr, groupName,
TableGroupKey(groupKey), modifiedTables);
1159 else if(requestType ==
"saveTreeNodeEdit")
1163 std::string targetTableVersion =
1169 __SUP_COUT__ <<
"editNodeType: " << editNodeType << __E__;
1170 __SUP_COUT__ <<
"targetTable: " << targetTable << __E__;
1171 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << __E__;
1172 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
1173 __SUP_COUT__ <<
"targetColumn: " << targetColumn << __E__;
1174 __SUP_COUT__ <<
"newValue: " << newValue << __E__;
1176 handleSaveTreeNodeEditXML(xmlOut,
1184 userInfo.username_);
1186 else if(requestType ==
"getLinkToChoices")
1189 std::string linkToTableVersion =
1196 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << __E__;
1197 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << __E__;
1198 __SUP_COUT__ <<
"linkIdType: " << linkIdType << __E__;
1199 __SUP_COUT__ <<
"linkIndex: " << linkIndex << __E__;
1200 __SUP_COUT__ <<
"linkInitId: " << linkInitId << __E__;
1202 handleGetLinkToChoicesXML(xmlOut,
1210 else if(requestType ==
"activateTableGroup")
1214 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
1216 __SUP_COUT__ <<
"Activating group: " << groupName <<
"(" << groupKey <<
")"
1218 __SUP_COUTV__(ignoreWarnings);
1221 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
1222 xmlOut.addTextElementToData(
"AttemptedGroupActivationName", groupName);
1223 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey", groupKey);
1227 std::string accumulatedErrors, groupTypeString;
1235 groupName,
TableGroupKey(groupKey), &accumulatedErrors, &groupTypeString);
1237 if(accumulatedErrors !=
"")
1241 __SS__ <<
"Throwing exception on accumulated errors: "
1242 << accumulatedErrors << __E__;
1246 __COUT_WARN__ <<
"Ignoring warnings so ignoring this error:"
1247 << accumulatedErrors << __E__;
1248 __COUT_WARN__ <<
"Done ignoring the above error(s)." << __E__;
1250 xmlOut.addTextElementToData(
"AttemptedGroupActivationType", groupTypeString);
1252 catch(std::runtime_error& e)
1257 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1258 xmlOut.addTextElementToData(
1260 "Error activating table group '" + groupName +
"(" + groupKey +
")" +
1261 ".' Please see details below:\n\n" + std::string(e.what()));
1262 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1263 <<
" (" << groupKey <<
")" << __E__;
1272 catch(cet::exception& e)
1278 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1279 xmlOut.addTextElementToData(
"Error",
1280 "Error activating table group '" + groupName +
1281 "(" + groupKey +
")" +
"!'\n\n" +
1282 std::string(e.what()));
1283 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1284 <<
" (" << groupKey <<
")" << __E__;
1295 __SUP_COUT__ <<
"Unknown error detected!" << __E__;
1307 else if(requestType ==
"getActiveTableGroups")
1309 else if(requestType ==
"copyViewToCurrentColumns")
1311 std::string tableName =
1315 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1316 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << __E__;
1317 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << __E__;
1323 newTemporaryVersion =
1326 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << __E__;
1328 catch(std::runtime_error& e)
1330 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1331 xmlOut.addTextElementToData(
"Error",
1332 "Error copying view from '" + tableName +
"_v" +
1333 sourceVersion +
"'! " +
1334 std::string(e.what()));
1338 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1339 xmlOut.addTextElementToData(
1341 "Error copying view from '" + tableName +
"_v" + sourceVersion +
"'! ");
1344 handleGetTableXML(xmlOut, cfgMgr, tableName, newTemporaryVersion);
1346 else if(requestType ==
"getLastTableGroups")
1349 std::map<std::string ,
1350 std::tuple<std::string ,
1355 theRemoteWebUsers_.getLastTableGroups(theGroups);
1357 for(
const auto& theGroup : theGroups)
1359 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupName",
1360 std::get<0>(theGroup.second));
1361 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupKey",
1362 std::get<1>(theGroup.second).toString());
1363 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupTime",
1364 std::get<2>(theGroup.second));
1397 handleOtherSubsystemActiveGroups(xmlOut, cfgMgr,
false );
1399 else if(requestType ==
"getSubsytemTableGroups")
1401 std::string subsystem =
1403 __SUP_COUTV__(subsystem);
1404 handleOtherSubsystemActiveGroups(
1405 xmlOut, cfgMgr,
true , subsystem);
1407 else if(requestType ==
"diffWithActiveGroup")
1409 std::string groupName =
1412 __SUP_COUTV__(groupName);
1413 __SUP_COUTV__(groupKey);
1418 else if(requestType ==
"diffWithGroupKey")
1420 std::string groupName =
1424 std::string diffGroupName =
1426 __SUP_COUTV__(groupName);
1427 __SUP_COUTV__(groupKey);
1428 __SUP_COUTV__(diffKey);
1429 __SUP_COUTV__(diffGroupName);
1431 handleGroupDiff(xmlOut,
1438 else if(requestType ==
"diffTableVersions")
1440 std::string tableName =
1444 __SUP_COUTV__(tableName);
1449 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
1452 if(allTableInfo.find(tableName) != allTableInfo.end())
1454 if(vA.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1457 std::map<std::string ,
1461 std::string versionAlias;
1463 vA.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1465 if(versionAliases.find(tableName) != versionAliases.end() &&
1466 versionAliases[tableName].find(versionAlias) !=
1467 versionAliases[tableName].end())
1469 versionA = versionAliases[tableName][versionAlias];
1470 __SUP_COUT__ <<
"version alias translated to: " << versionA << __E__;
1473 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1474 <<
"'was not found in active version aliases!"
1478 versionA = atoi(vA.c_str());
1480 if(vB.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1483 std::map<std::string ,
1487 std::string versionAlias;
1489 vB.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1491 if(versionAliases.find(tableName) != versionAliases.end() &&
1492 versionAliases[tableName].find(versionAlias) !=
1493 versionAliases[tableName].end())
1495 versionB = versionAliases[tableName][versionAlias];
1496 __SUP_COUT__ <<
"version alias translated to: " << versionB << __E__;
1499 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1500 <<
"'was not found in active version aliases!"
1504 versionB = atoi(vB.c_str());
1508 versionA = atoi(vA.c_str());
1509 versionB = atoi(vB.c_str());
1512 __SUP_COUTV__(versionA);
1513 __SUP_COUTV__(versionB);
1515 handleTableDiff(xmlOut, cfgMgr, tableName, versionA, versionB);
1517 else if(requestType ==
"savePlanCommandSequence")
1520 std::string commands =
1526 __SUP_COUTV__(modifiedTables);
1527 __SUP_COUTV__(planName);
1528 __SUP_COUTV__(commands);
1529 __SUP_COUTV__(groupName);
1530 __SUP_COUTV__(groupKey);
1532 handleSavePlanCommandSequenceXML(xmlOut,
1541 else if(requestType ==
"mergeGroups")
1543 std::string groupANameContext =
1545 std::string groupAKeyContext =
1547 std::string groupBNameContext =
1549 std::string groupBKeyContext =
1551 std::string groupANameConfig =
1554 std::string groupBNameConfig =
1559 __SUP_COUTV__(groupANameContext);
1560 __SUP_COUTV__(groupAKeyContext);
1561 __SUP_COUTV__(groupBNameContext);
1562 __SUP_COUTV__(groupBKeyContext);
1563 __SUP_COUTV__(groupANameConfig);
1564 __SUP_COUTV__(groupAKeyConfig);
1565 __SUP_COUTV__(groupBNameConfig);
1566 __SUP_COUTV__(groupBKeyConfig);
1567 __SUP_COUTV__(mergeApproach);
1569 handleMergeGroupsXML(xmlOut,
1584 __SUP_SS__ <<
"requestType Request, " << requestType
1585 <<
", not recognized by the Configuration GUI Supervisor (was it "
1586 "intended for another Supervisor?)."
1588 __SUP_COUT__ <<
"\n" << ss.str();
1589 xmlOut.addTextElementToData(
"Error", ss.str());
1592 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1595 xmlOut, cfgMgr, userInfo.username_);
1596 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1599 catch(
const std::runtime_error& e)
1601 __SS__ <<
"A fatal error occurred while handling the request '" << requestType
1602 <<
".' Error: " << e.what() << __E__;
1603 __COUT_ERR__ <<
"\n" << ss.str();
1604 xmlOut.addTextElementToData(
"Error", ss.str());
1609 xmlOut.addTextElementToData(
1611 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1615 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1620 __SS__ <<
"An unknown fatal error occurred while handling the request '"
1621 << requestType <<
".'" << __E__;
1626 catch(
const std::exception& e)
1628 ss <<
"Exception message: " << e.what();
1633 __COUT_ERR__ <<
"\n" << ss.str();
1634 xmlOut.addTextElementToData(
"Error", ss.str());
1639 xmlOut.addTextElementToData(
1641 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1645 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1665 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(
1668 const std::string& rootGroupName,
1670 const std::string& modifiedTables)
1673 __SUP_COUT__ <<
"rootGroupName " << rootGroupName <<
"(" << rootGroupKey
1674 <<
"). modifiedTables = " << modifiedTables << __E__;
1676 std::map<std::string, std::pair<std::string, TableGroupKey>> consideredGroups =
1681 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT].second.isInvalid())
1683 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
1684 if(cfgMgr->getFailedTableGroups().find(
1685 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT) !=
1686 cfgMgr->getFailedTableGroups().end())
1688 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1689 cfgMgr->getFailedTableGroups().at(
1690 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT);
1692 else if(cfgMgr->getFailedTableGroups().find(
1693 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1694 cfgMgr->getFailedTableGroups().end())
1696 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1697 cfgMgr->getFailedTableGroups().at(
1698 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1701 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION]
1702 .second.isInvalid())
1704 __SUP_COUT__ <<
"Finding a table group to consider..." << __E__;
1705 if(cfgMgr->getFailedTableGroups().find(
1706 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION) !=
1707 cfgMgr->getFailedTableGroups().end())
1709 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1710 cfgMgr->getFailedTableGroups().at(
1711 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION);
1713 else if(cfgMgr->getFailedTableGroups().find(
1714 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1715 cfgMgr->getFailedTableGroups().end())
1717 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1718 cfgMgr->getFailedTableGroups().at(
1719 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1728 std::map<std::string ,
TableVersion > rootGroupMemberMap;
1733 &rootGroupMemberMap,
1743 consideredGroups[groupType] =
1744 std::pair<std::string, TableGroupKey>(rootGroupName, rootGroupKey);
1746 catch(
const std::runtime_error& e)
1749 if(rootGroupName.size())
1751 __SUP_SS__ <<
"Failed to determine type of table group for " << rootGroupName
1752 <<
"(" << rootGroupKey <<
")! " << e.what() << __E__;
1753 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1758 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1759 "name - assuming this was intentional."
1765 if(rootGroupName.size())
1767 __SUP_COUT_ERR__ <<
"Failed to determine type of table group for "
1768 << rootGroupName <<
"(" << rootGroupKey <<
")!" << __E__;
1773 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1774 "name - assuming this was intentional."
1778 std::map<std::string ,
1781 std::map<std::string ,
1783 modifiedTablesMapIt;
1785 std::istringstream f(modifiedTables);
1786 std::string table, version;
1787 while(getline(f, table,
','))
1789 getline(f, version,
',');
1790 modifiedTablesMap.insert(
1793 std::pair<bool /*foundAffectedGroup*/, TableVersion /*version*/>>(
1797 __SUP_COUT__ << modifiedTables << __E__;
1798 for(
auto& pair : modifiedTablesMap)
1799 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second.second
1804 xercesc::DOMElement* parentEl =
nullptr;
1805 std::string groupComment;
1806 std::vector<std::string> orderedGroupTypes(
1807 {ConfigurationManager::GROUP_TYPE_NAME_CONTEXT,
1808 ConfigurationManager::GROUP_TYPE_NAME_BACKBONE,
1809 ConfigurationManager::GROUP_TYPE_NAME_ITERATE,
1810 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION});
1811 for(
auto groupType : orderedGroupTypes)
1813 if(consideredGroups.find(groupType) == consideredGroups.end())
1816 const std::pair<std::string, TableGroupKey>& group = consideredGroups[groupType];
1818 if(group.second.isInvalid())
1821 __SUP_COUT__ <<
"Considering " << groupType <<
" group " << group.first <<
" ("
1822 << group.second <<
")" << __E__;
1840 __SUP_COUT__ <<
"groupComment = " << groupComment << __E__;
1842 for(
auto& table : memberMap)
1844 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
1847 table.second != (*modifiedTablesMapIt).second.second)
1849 __SUP_COUT__ <<
"Affected by " << (*modifiedTablesMapIt).first <<
":"
1850 << (*modifiedTablesMapIt).second.second << __E__;
1852 memberMap[table.first] = (*modifiedTablesMapIt).second.second;
1853 (*modifiedTablesMapIt).second.first =
true;
1857 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1861 if(groupType == ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
1863 __SUP_COUT__ <<
"Considering mockup tables for Configuration Group..."
1865 for(
auto& table : modifiedTablesMap)
1867 if(table.second.first)
1870 if(table.second.second.isMockupVersion() &&
1871 memberMap.find(table.first) == memberMap.end())
1873 __SUP_COUT__ <<
"Found mockup table '" << table.first
1874 <<
"' for Configuration Group." << __E__;
1875 memberMap[table.first] = table.second.second;
1878 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1882 "AddMemberVersion", table.second.second.toString(), parentEl);
1889 __SUP_COUTV__(affected);
1893 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1898 for(
auto& table : memberMap)
1902 "MemberVersion", table.second.toString(), parentEl);
1907 catch(std::runtime_error& e)
1909 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1910 xmlOut.addTextElementToData(
1911 "Error",
"Error getting affected groups! " + std::string(e.what()));
1915 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1916 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
1927 void ConfigurationGUISupervisor::setupActiveTablesXML(
1930 const std::string& groupName,
1932 const std::string& modifiedTables,
1934 bool doGetGroupInfo,
1935 std::map<std::string /*name*/, TableVersion /*version*/>* returnMemberMap,
1936 bool outputActiveTables,
1937 std::string* accumulatedErrors)
1940 xmlOut.addTextElementToData(
"tableGroup", groupName);
1941 xmlOut.addTextElementToData(
"tableGroupKey", groupKey.
toString());
1943 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
1951 __SUP_COUT__ <<
"Refreshing all table info, ignoring warnings..." << __E__;
1952 std::string accumulatedWarnings =
"";
1954 &accumulatedWarnings,
1968 __SUP_COUT__ <<
"Restoring active table group tables..." << __E__;
1970 for(
const auto& activeGroup : activeGroups)
1972 if(activeGroup.second.first == groupName &&
1973 activeGroup.second.second == groupKey)
1975 __SUP_COUTT__ <<
"Skipping target active group." << __E__;
1978 __SUP_COUTT__ <<
"Loading " << activeGroup.first <<
" "
1979 << activeGroup.second.first <<
"(" << activeGroup.second.second
1984 activeGroup.second.second,
1990 __SUP_COUT__ <<
"Ignoring errors while setting up active tables for "
1991 << activeGroup.second.first <<
"("
1992 << activeGroup.second.second <<
")..." << __E__;
1998 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
2000 std::map<std::string ,
TableVersion > modifiedTablesMap;
2002 modifiedTablesMapIt;
2004 if(usingActiveGroups)
2007 __SUP_COUT__ <<
"Using active groups." << __E__;
2011 __SUP_COUT__ <<
"Loading group '" << groupName <<
"(" << groupKey <<
")'"
2014 std::string groupComment, groupAuthor, tableGroupCreationTime, groupType;
2023 doGetGroupInfo ? &groupComment : 0,
2024 doGetGroupInfo ? &groupAuthor : 0,
2025 doGetGroupInfo ? &tableGroupCreationTime : 0,
2027 doGetGroupInfo ? &groupType : 0);
2031 xmlOut.addTextElementToData(
"tableGroupComment", groupComment);
2032 xmlOut.addTextElementToData(
"tableGroupAuthor", groupAuthor);
2033 xmlOut.addTextElementToData(
"tableGroupCreationTime", tableGroupCreationTime);
2034 xmlOut.addTextElementToData(
"tableGroupType", groupType);
2037 if(accumulatedErrors && *accumulatedErrors !=
"")
2038 __SUP_COUTV__(*accumulatedErrors);
2044 std::istringstream f(modifiedTables);
2045 std::string table, version;
2046 while(getline(f, table,
','))
2048 getline(f, version,
',');
2049 modifiedTablesMap.insert(
2050 std::pair<std::string /*name*/, TableVersion /*version*/>(
2054 for(
auto& pair : modifiedTablesMap)
2055 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
2060 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2061 xmlOut.addTextElementToData(
"DefaultNoLink",
2062 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
2065 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
2066 for(
const auto& tablePair : allActivePairs)
2067 orderedTableSet.emplace(tablePair.first);
2069 std::map<std::string, TableInfo>::const_iterator tableInfoIt;
2070 for(
auto& orderedTableName : orderedTableSet)
2072 tableInfoIt = allTableInfo.find(orderedTableName);
2073 if(tableInfoIt == allTableInfo.end())
2075 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
2080 if(outputActiveTables)
2081 xmlOut.addTextElementToData(
"ActiveTableName", orderedTableName);
2085 if((modifiedTablesMapIt = modifiedTablesMap.find(orderedTableName)) !=
2086 modifiedTablesMap.end())
2088 __SUP_COUT__ <<
"Found modified table " << (*modifiedTablesMapIt).first
2089 <<
": trying... " << (*modifiedTablesMapIt).second << __E__;
2093 tableInfoIt->second.tablePtr_->setActiveView(
2094 (*modifiedTablesMapIt).second);
2098 __SUP_SS__ <<
"Modified table version v" << (*modifiedTablesMapIt).second
2099 <<
" failed. Reverting to v"
2100 << tableInfoIt->second.tablePtr_->getView().getVersion() <<
"."
2102 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << __E__;
2103 xmlOut.addTextElementToData(
2105 "Error setting up active tables!\n\n" + std::string(ss.str()));
2109 if(outputActiveTables)
2111 xmlOut.addTextElementToData(
2112 "ActiveTableVersion",
2113 tableInfoIt->second.tablePtr_->getView().getVersion().toString());
2114 xmlOut.addTextElementToData(
2115 "ActiveTableComment",
2116 tableInfoIt->second.tablePtr_->getView().getAuthor() +
": " +
2117 tableInfoIt->second.tablePtr_->getView().getComment());
2125 catch(std::runtime_error& e)
2127 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what()))
2129 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2130 xmlOut.addTextElementToData(
"Error", ss.str());
2135 __SUP_SS__ << (
"Error setting up active tables!\n\n") << __E__;
2140 catch(
const std::exception& e)
2142 ss <<
"Exception message: " << e.what();
2147 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2148 xmlOut.addTextElementToData(
"Error", ss.str());
2167 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(
2170 const std::string& groupName,
2172 const std::string& startPath,
2173 const std::string& modifiedTables,
2174 const std::string& recordList,
2175 const std::string& author)
2178 setupActiveTablesXML(xmlOut,
2203 bool firstSave =
true;
2210 std::istringstream f(recordList);
2211 std::string recordUID;
2213 while(getline(f, recordUID,
','))
2217 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2222 .isTemporaryVersion())
2224 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2232 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2236 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2242 backupView.copy(table->getView(), temporaryVersion, author);
2251 unsigned int row = table->getViewP()->addRow(
2258 unsigned int col = table->getViewP()->getColStatus();
2259 table->getViewP()->setURIEncodedValue(
"1", row, col);
2266 table->getViewP()->setURIEncodedValue(
2267 recordUID, row, table->getViewP()->getColUID());
2275 table->getViewP()->init();
2279 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
2280 __SUP_COUT__ <<
"Before:" << __E__;
2281 table->getViewP()->
print();
2282 table->getViewP()->copy(backupView, temporaryVersion, author);
2283 __SUP_COUT__ <<
"After:" << __E__;
2284 table->getViewP()->
print();
2290 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2292 catch(std::runtime_error& e)
2294 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what()))
2296 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2297 xmlOut.addTextElementToData(
"Error", ss.str());
2301 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << __E__;
2306 catch(
const std::exception& e)
2308 ss <<
"Exception message: " << e.what();
2313 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2314 xmlOut.addTextElementToData(
"Error", ss.str());
2321 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(
2326 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
2327 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2328 for(
auto& activePair : allActivePairs)
2330 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
2331 xmlOut.addTextElementToData(
"NewActiveTableVersion",
2332 allTableInfo.at(activePair.first)
2333 .tablePtr_->getView()
2336 xmlOut.addTextElementToData(
2337 "NewActiveTableComment",
2338 allTableInfo.at(activePair.first).tablePtr_->getView().getAuthor() +
": " +
2339 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
2342 catch(std::runtime_error& e)
2344 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
2345 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2346 xmlOut.addTextElementToData(
"Error", ss.str());
2350 __SUP_SS__ << (
"Error!\n\n") << __E__;
2355 catch(
const std::exception& e)
2357 ss <<
"Exception message: " << e.what();
2362 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2363 xmlOut.addTextElementToData(
"Error", ss.str());
2381 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(
2384 const std::string& groupName,
2386 const std::string& startPath,
2387 const std::string& modifiedTables,
2388 const std::string& recordList)
2391 setupActiveTablesXML(xmlOut,
2416 bool firstSave =
true;
2420 std::istringstream f(recordList);
2421 std::string recordUID;
2424 while(getline(f, recordUID,
','))
2428 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2433 .isTemporaryVersion())
2435 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2443 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2447 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2458 table->getViewP()->findRow(table->getViewP()->getColUID(), recordUID);
2459 table->getViewP()->deleteRow(row);
2464 table->getViewP()->init();
2466 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2468 catch(std::runtime_error& e)
2470 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << __E__;
2471 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2472 xmlOut.addTextElementToData(
"Error", ss.str());
2476 __SUP_SS__ << (
"Error removing record(s)!\n\n") << __E__;
2481 catch(
const std::exception& e)
2483 ss <<
"Exception message: " << e.what();
2488 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2489 xmlOut.addTextElementToData(
"Error", ss.str());
2509 void ConfigurationGUISupervisor::handleFillRenameTreeNodeRecordsXML(
2512 const std::string& groupName,
2514 const std::string& startPath,
2515 const std::string& modifiedTables,
2516 const std::string& recordList,
2517 const std::string& newRecordList)
2520 setupActiveTablesXML(xmlOut,
2546 std::vector<std::string> recordArray =
2548 std::vector<std::string> newRecordArray =
2554 if(recordArray.size() == 0 || recordArray.size() != newRecordArray.size())
2557 <<
"Invalid record size vs new record name size, they must be the same: "
2558 << recordArray.size() <<
" vs " << newRecordArray.size() << __E__;
2564 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2566 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2574 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2577 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2584 for(
unsigned int i = 0; i < recordArray.size(); ++i)
2586 row = table->getViewP()->findRow(
2587 table->getViewP()->getColUID(),
2590 table->getViewP()->setValueAsString(
2591 newRecordArray[i], row, table->getViewP()->getColUID());
2594 table->getViewP()->init();
2596 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2598 catch(std::runtime_error& e)
2600 __SUP_SS__ << (
"Error renaming record(s)!\n\n" + std::string(e.what())) << __E__;
2601 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2602 xmlOut.addTextElementToData(
"Error", ss.str());
2606 __SUP_SS__ << (
"Error renaming record(s)!\n\n") << __E__;
2611 catch(
const std::exception& e)
2613 ss <<
"Exception message: " << e.what();
2618 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2619 xmlOut.addTextElementToData(
"Error", ss.str());
2640 void ConfigurationGUISupervisor::handleFillCopyTreeNodeRecordsXML(
2643 const std::string& groupName,
2645 const std::string& startPath,
2646 const std::string& modifiedTables,
2647 const std::string& recordList,
2648 unsigned int numberOfCopies )
2654 setupActiveTablesXML(xmlOut,
2680 std::vector<std::string> recordArray =
2686 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2688 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2696 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2699 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2706 for(
const auto& recordUID : recordArray)
2708 row = table->getViewP()->findRow(table->getViewP()->getColUID(),
2710 for(
unsigned int i = 0; i < numberOfCopies; ++i)
2711 table->getViewP()->copyRows(
2721 table->getViewP()->init();
2723 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2725 catch(std::runtime_error& e)
2727 __SUP_SS__ << (
"Error copying record(s)!\n\n" + std::string(e.what())) << __E__;
2728 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2729 xmlOut.addTextElementToData(
"Error", ss.str());
2733 __SUP_SS__ << (
"Error copying record(s)!\n\n") << __E__;
2738 catch(
const std::exception& e)
2740 ss <<
"Exception message: " << e.what();
2745 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2746 xmlOut.addTextElementToData(
"Error", ss.str());
2767 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(
2770 const std::string& groupName,
2772 const std::string& startPath,
2773 const std::string& modifiedTables,
2774 const std::string& recordList,
2775 const std::string& fieldList,
2776 const std::string& valueList,
2777 const std::string& author)
2780 setupActiveTablesXML(xmlOut,
2795 std::vector<std::string > fieldPaths;
2798 std::istringstream f(fieldList);
2799 std::string fieldPath;
2800 while(getline(f, fieldPath,
','))
2804 __SUP_COUT__ << fieldList << __E__;
2805 for(
const auto& field : fieldPaths)
2806 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2809 std::vector<std::string > fieldValues;
2812 std::istringstream f(valueList);
2813 std::string fieldValue;
2814 while(getline(f, fieldValue,
','))
2816 fieldValues.push_back(fieldValue);
2821 if(valueList.size() && valueList[valueList.size() - 1] ==
',')
2822 fieldValues.push_back(
"");
2824 __SUP_COUT__ << valueList << __E__;
2825 for(
const auto& value : fieldValues)
2826 __SUP_COUT__ <<
"fieldValue " << value << __E__;
2829 if(fieldPaths.size() != fieldValues.size())
2832 __THROW__(ss.str() +
"Mismatch in fields and values array size!");
2839 std::istringstream f(recordList);
2840 std::string recordUID;
2843 while(getline(f, recordUID,
','))
2848 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2851 for(i = 0; i < fieldPaths.size(); ++i)
2853 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << __E__;
2854 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << __E__;
2859 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
2900 if(!(temporaryVersion = table->getViewP()->getVersion())
2901 .isTemporaryVersion())
2911 __SUP_COUT__ <<
"Created temporary version "
2916 __SUP_COUT__ <<
"Using temporary version " << table->
getTableName()
2917 <<
"-v" << temporaryVersion << __E__;
2921 table->getViewP()->setURIEncodedValue(fieldValues[i],
2932 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2934 catch(std::runtime_error& e)
2936 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what()))
2938 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2939 xmlOut.addTextElementToData(
"Error", ss.str());
2943 __SUP_SS__ << (
"Error setting field values!\n\n") << __E__;
2948 catch(
const std::exception& e)
2950 ss <<
"Exception message: " << e.what();
2955 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2956 xmlOut.addTextElementToData(
"Error", ss.str());
2975 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(
2978 const std::string& groupName,
2980 const std::string& startPath,
2981 const std::string& modifiedTables,
2982 const std::string& recordList,
2983 const std::string& fieldList)
2986 setupActiveTablesXML(
2987 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
2994 std::vector<std::string > fieldPaths;
2997 std::istringstream f(fieldList);
2998 std::string fieldPath;
2999 while(getline(f, fieldPath,
','))
3003 __SUP_COUT__ << fieldList << __E__;
3008 std::istringstream f(recordList);
3009 std::string recordUID;
3010 while(getline(f, recordUID,
','))
3014 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
3016 xercesc::DOMElement* parentEl =
3017 xmlOut.addTextElementToData(
"fieldValues", recordUID);
3020 for(
const auto& fieldPath : fieldPaths)
3026 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPath);
3038 catch(std::runtime_error& e)
3040 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what()))
3042 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3043 xmlOut.addTextElementToData(
"Error", ss.str());
3047 __SUP_SS__ << (
"Error getting field values!\n\n") << __E__;
3052 catch(
const std::exception& e)
3054 ss <<
"Exception message: " << e.what();
3059 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3060 xmlOut.addTextElementToData(
"Error", ss.str());
3083 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(
3086 const std::string& groupName,
3088 const std::string& startPath,
3090 const std::string& modifiedTables,
3091 const std::string& recordList,
3092 const std::string& fieldList)
3095 setupActiveTablesXML(
3096 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3100 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
3104 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
3105 __SUP_COUT__ << ss.str();
3114 std::vector<ConfigurationTree::RecordField> retFieldList;
3120 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3126 std::vector<std::string > fieldAcceptList, fieldRejectList;
3131 std::istringstream f(fieldList);
3132 std::string fieldPath, decodedFieldPath;
3133 while(getline(f, fieldPath,
','))
3137 if(decodedFieldPath[0] ==
'!')
3138 fieldRejectList.push_back(decodedFieldPath.substr(1));
3140 fieldAcceptList.push_back(decodedFieldPath);
3142 __SUP_COUT__ << fieldList << __E__;
3143 for(
auto& field : fieldAcceptList)
3144 __SUP_COUT__ <<
"fieldAcceptList " << field << __E__;
3145 for(
auto& field : fieldRejectList)
3146 __SUP_COUT__ <<
"fieldRejectList " << field << __E__;
3150 std::vector<std::string > records;
3151 if(recordList ==
"*")
3155 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3156 for(
auto& record : records)
3157 __SUP_COUT__ <<
"recordList " << record << __E__;
3159 else if(recordList !=
"")
3163 std::istringstream f(recordList);
3164 std::string recordStr;
3165 while(getline(f, recordStr,
','))
3169 __SUP_COUT__ << recordList << __E__;
3170 for(
auto& record : records)
3171 __SUP_COUT__ <<
"recordList " << record << __E__;
3177 records, fieldAcceptList, fieldRejectList, depth);
3181 xercesc::DOMElement* parentTypeEl;
3182 for(
const auto& fieldInfo : retFieldList)
3185 "FieldTableName", fieldInfo.tableName_, parentEl);
3187 "FieldColumnName", fieldInfo.columnName_, parentEl);
3189 "FieldRelativePath", fieldInfo.relativePath_, parentEl);
3191 "FieldColumnType", fieldInfo.columnInfo_->getType(), parentEl);
3193 "FieldColumnDataType", fieldInfo.columnInfo_->getDataType(), parentEl);
3195 fieldInfo.columnInfo_->getDefaultValue(),
3202 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
3204 "FieldColumnDataChoice",
3205 fieldInfo.columnInfo_->getDefaultValue(),
3207 for(
const auto& dataChoice : dataChoices)
3209 "FieldColumnDataChoice", dataChoice, parentTypeEl);
3212 catch(std::runtime_error& e)
3214 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
3216 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3217 xmlOut.addTextElementToData(
"Error", ss.str());
3221 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
3226 catch(
const std::exception& e)
3228 ss <<
"Exception message: " << e.what();
3233 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3234 xmlOut.addTextElementToData(
"Error", ss.str());
3266 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(
3269 const std::string& groupName,
3271 const std::string& startPath,
3272 const std::string& modifiedTables,
3273 const std::string& recordList,
3274 const std::string& fieldList)
3277 setupActiveTablesXML(
3278 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3284 if(startPath ==
"/")
3290 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3291 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3296 std::vector<std::string > records;
3297 if(recordList ==
"*")
3301 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3302 for(
auto& record : records)
3303 __SUP_COUT__ <<
"recordList " << record << __E__;
3305 else if(recordList !=
"")
3309 std::istringstream f(recordList);
3310 std::string recordStr;
3311 while(getline(f, recordStr,
','))
3315 __SUP_COUT__ << recordList << __E__;
3316 for(
auto& record : records)
3317 __SUP_COUT__ <<
"recordList " << record << __E__;
3322 std::vector<std::string > fieldsToGet;
3327 if(fieldList ==
"AUTO")
3332 __SUP_COUT__ <<
"Getting AUTO filter fields!" << __E__;
3334 std::vector<ConfigurationTree::RecordField> retFieldList;
3335 std::vector<std::string > fieldAcceptList,
3337 fieldRejectList.push_back(
"*" + TableViewColumnInfo::COL_NAME_COMMENT);
3339 records, fieldAcceptList, fieldRejectList, 5,
true );
3341 for(
const auto& retField : retFieldList)
3342 fieldsToGet.push_back(retField.relativePath_ + retField.columnName_);
3346 std::istringstream f(fieldList);
3347 std::string fieldPath;
3348 while(getline(f, fieldPath,
','))
3352 __SUP_COUTV__(fieldList);
3361 std::string fieldGroupIDChildLinkIndex;
3362 for(
auto& field : fieldsToGet)
3364 __SUP_COUTV__(field);
3366 xercesc::DOMElement* parentEl =
3367 xmlOut.addTextElementToData(
"field", field);
3373 std::set<std::string > uniqueValues =
3375 records, field, &fieldGroupIDChildLinkIndex);
3377 if(fieldGroupIDChildLinkIndex !=
"")
3379 "childLinkIndex", fieldGroupIDChildLinkIndex, parentEl);
3381 for(
auto& uniqueValue : uniqueValues)
3383 __SUP_COUT__ <<
"uniqueValue " << uniqueValue << __E__;
3390 catch(std::runtime_error& e)
3392 __SUP_SS__ <<
"Error getting unique field values from path '" << startPath
3393 <<
"' and field list '" << fieldList <<
"!'\n\n"
3394 << e.what() << __E__;
3395 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3396 xmlOut.addTextElementToData(
"Error", ss.str());
3400 __SUP_SS__ <<
"Error getting unique field values from path '" << startPath
3401 <<
"' and field list '" << fieldList <<
"!'\n\n"
3407 catch(
const std::exception& e)
3409 ss <<
"Exception message: " << e.what();
3414 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3415 xmlOut.addTextElementToData(
"Error", ss.str());
3439 void ConfigurationGUISupervisor::handleFillTreeViewXML(
3442 const std::string& groupName,
3444 const std::string& startPath,
3446 bool hideStatusFalse,
3447 const std::string& modifiedTables,
3448 const std::string& filterList,
3449 const std::string& diffGroupName ,
3452 __SUP_COUTT__ <<
"get Tree View: " << groupName <<
"(" << groupKey <<
")" << __E__;
3484 bool doDiff = (diffGroupName !=
"" && !diffGroupKey.
isInvalid());
3489 std::string diffAccumulateErrors;
3497 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3514 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3517 __SUP_COUTT__ <<
"Diff Group tables loaded." << __E__;
3519 *cfgMgr, diffMemberMap, diffGroupName, diffGroupKey);
3520 __SUP_COUTT__ <<
"Diff Group tables copied to local diff config manager."
3524 for(
auto& memberPair : diffMemberMap)
3526 ->setActiveView(memberPair.second);
3528 for(
const auto& lastGroupLoaded : cfgMgr->getLastTableGroups())
3529 __SUP_COUT__ <<
"cfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3530 << lastGroupLoaded.second.first.first <<
"("
3531 << lastGroupLoaded.second.first.second <<
")";
3533 for(
const auto& lastGroupLoaded : diffCfgMgr->getLastTableGroups())
3534 __SUP_COUT__ <<
"diffCfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3535 << lastGroupLoaded.second.first.first <<
"("
3536 << lastGroupLoaded.second.first.second <<
")";
3539 if(diffCfgMgr->getLastTableGroups().size() == 1)
3541 __SUP_COUT__ <<
"Type already loaded to diff = "
3542 << diffCfgMgr->getLastTableGroups().begin()->first << __E__;
3545 auto groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3546 if(diffCfgMgr->getLastTableGroups().begin()->first ==
3547 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT)
3548 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION;
3549 else if(diffCfgMgr->getLastTableGroups().begin()->first ==
3550 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
3551 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3554 <<
"Loading " << groupTypeToLoad
3555 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first <<
"("
3556 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second
3561 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second,
3562 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first,
3563 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second);
3566 for(
auto& memberPair :
3567 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second)
3569 ->setActiveView(memberPair.second);
3577 __SUP_COUTT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3580 __SUP_COUTT__ <<
"diffCfgMgr " << activeTable.first <<
"-v"
3581 << activeTable.second << __E__;
3583 __SUP_COUTT__ <<
"Diff Group tables are setup: " << diffAccumulateErrors << __E__;
3588 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
3591 std::string accumulatedErrors =
"";
3592 setupActiveTablesXML(
3605 if(memberMap.size() > ConfigurationManager::getFixedContextMemberNames().size() +
3607 && startPath ==
"/")
3609 __COUTT__ <<
"Checking for orphaned tables..." << __E__;
3612 std::set<std::string > linkingTables;
3617 __COUTS__(30) <<
"Table " << tableInfo.first << __E__;
3618 if(!tableInfo.second.tablePtr_->isActive())
3621 __COUTS__(30) <<
"Table active " << tableInfo.first << __E__;
3623 const TableView& view = tableInfo.second.tablePtr_->getView();
3625 bool addedThisTable =
false;
3626 for(
unsigned int col = 0; col < view.getNumberOfColumns(); ++col)
3628 if(!view.getColumnInfo(col).isChildLink())
3631 __COUTS__(30) <<
"Table " << tableInfo.first
3632 <<
" col: " << view.getColumnInfo(col).getName() << __E__;
3634 for(
unsigned int r = 0; r < view.getNumberOfRows(); ++r)
3636 if(view.getDataView()[r][col] ==
"" ||
3637 view.getDataView()[r][col] ==
3638 TableViewColumnInfo::DATATYPE_STRING_DEFAULT)
3643 linkingTables.emplace(tableInfo.first);
3644 addedThisTable =
true;
3646 linkingTables.emplace(
3647 view.getDataView()[r][col]);
3653 std::string missingTables =
"";
3654 for(
const auto& member : memberMap)
3657 if(linkingTables.find(member.first) != linkingTables.end())
3660 if(missingTables.size())
3661 missingTables +=
", ";
3662 missingTables += member.first;
3665 if(missingTables.size())
3667 __COUTV__(missingTables);
3668 std::stringstream ss;
3669 ss <<
"The following member tables of table group '" << groupName <<
"("
3671 <<
")' were identified as possibly orphaned (i.e. no active tables link "
3672 "to these tables, and these tables have no links to other tables):\n\n"
3673 << missingTables <<
".\n"
3675 xmlOut.addTextElementToData(
"NoTreeLinkWarning", ss.str());
3679 if(accumulatedErrors !=
"")
3681 xmlOut.addTextElementToData(
"Warning", accumulatedErrors);
3683 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors
3686 __SUP_COUT__ <<
"Active table versions: "
3691 __SUP_COUTT__ <<
"Active tables are setup. No issues found." << __E__;
3692 __SUP_COUTT__ <<
"Active table versions: "
3698 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
3703 std::vector<std::pair<std::string, ConfigurationTree>> rootMap;
3704 std::map<std::string, ConfigurationTree> diffRootMap;
3706 if(startPath ==
"/")
3710 std::string accumulateTreeErrs;
3712 if(usingActiveGroups)
3713 rootMap = cfgMgr->
getChildren(0, &accumulateTreeErrs);
3715 rootMap = cfgMgr->
getChildren(&memberMap, &accumulateTreeErrs);
3720 diffCfgMgr->
getChildrenMap(&diffMemberMap, &diffAccumulateErrors);
3721 __SUP_COUTV__(diffRootMap.size());
3722 for(
auto& diffChild : diffRootMap)
3723 __SUP_COUTV__(diffChild.first);
3726 __SUP_COUTV__(accumulateTreeErrs);
3728 if(accumulateTreeErrs !=
"")
3729 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
3734 cfgMgr->
getNode(startPath,
true );
3737 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
3742 std::map<std::string , std::string > filterMap;
3746 std::set<char>({
';'}) ,
3747 std::set<char>({
'='}) );
3761 __SUP_COUTT__ <<
"Diff Group disconnected node." << __E__;
3766 catch(
const std::runtime_error& e)
3769 __SUP_COUTT__ <<
"Diff Group node does not exist." << __E__;
3776 for(
auto& treePair : rootMap)
3778 treePair.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
3782 __SUP_COUTT__ <<
"Diff Tree recursive handling." << __E__;
3785 std::set<std::string > rootMapToSearch;
3786 for(
const auto& rootMember : rootMap)
3787 rootMapToSearch.emplace(rootMember.first);
3789 std::stringstream rootSs;
3790 for(
const auto& rootMember : rootMap)
3791 rootSs <<
", " << rootMember.first;
3794 std::stringstream diffRootSs;
3795 for(
const auto& diffMember : diffRootMap)
3797 diffRootSs <<
", " << diffMember.first <<
":"
3798 << diffMember.second.getNodeType();
3799 if(rootMapToSearch.find(diffMember.first) ==
3803 std::stringstream missingSs;
3804 missingSs << diffMember.first <<
3806 " <<< Only in " << diffGroupName <<
"(" << diffGroupKey
3809 "diffNodeMissing", missingSs.str(), parentEl);
3812 if(diffMember.second.getNodeType() ==
"UIDLinkNode")
3823 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3824 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3826 __SUP_COUTT__ <<
"\t\t" << diffMember.second.getValueName() <<
": "
3827 << diffMember.second.getValueAsString() << __E__;
3829 __SUP_COUTT__ << diffMember.second.nodeDump();
3833 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3834 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3837 for(
auto& treePair : rootMap)
3839 if(diffRootMap.find(treePair.first) == diffRootMap.end())
3841 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3854 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3856 recursiveTreeToXML(treePair.second,
3861 diffRootMap.at(treePair.first));
3866 catch(std::runtime_error& e)
3868 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << __E__;
3869 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3870 xmlOut.addTextElementToData(
"Error", ss.str());
3874 __SUP_SS__ <<
"Error detected generating XML tree!" << __E__;
3879 catch(
const std::exception& e)
3881 ss <<
"Exception message: " << e.what();
3886 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3887 xmlOut.addTextElementToData(
"Error", ss.str());
3897 void ConfigurationGUISupervisor::recursiveTreeToXML(
3901 xercesc::DOMElement* parentEl,
3902 bool hideStatusFalse,
3903 std::optional<std::reference_wrapper<const ConfigurationTree>> diffTree)
3913 if(diffTree.has_value() &&
3914 t.
getValueName() != TableViewColumnInfo::COL_NAME_COMMENT &&
3915 t.
getValueName() != TableViewColumnInfo::COL_NAME_AUTHOR &&
3916 t.
getValueName() != TableViewColumnInfo::COL_NAME_CREATION)
3918 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
3920 if(diffTree->get().isValueNode())
3922 __COUTS__(30) <<
"\t" << diffTree->get().getValueAsString() <<
" ? "
3924 __COUTS__(30) <<
"\t" << diffTree->get().getTableName() <<
"-v"
3925 << diffTree->get().getTableVersion() <<
" ? "
3930 std::stringstream missingSs;
3931 auto diffGroupPair =
3932 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3933 diffTree->get().getTableName());
3934 missingSs <<
"<<< '" << diffTree->get().getValueAsString() <<
"' in "
3935 << diffGroupPair.first <<
"(" << diffGroupPair.second
3942 std::stringstream missingSs;
3944 auto diffGroupPair =
3945 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3947 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
3948 << diffGroupPair.second <<
") >>>";
3962 if(t.
getValueType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
3963 t.
getValueType() == TableViewColumnInfo::TYPE_BITMAP_DATA)
3968 for(
const auto& choice : choices)
3985 if(diffTree.has_value())
3987 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType()
3994 std::stringstream missingSs;
3996 auto diffGroupPair =
3997 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3999 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
4000 << diffGroupPair.second <<
") >>>";
4005 __COUTS__(30) <<
"\t\t diff isDisconnected "
4006 << diffTree->get().isDisconnected() << __E__;
4008 std::stringstream missingSs;
4010 auto diffGroupPair =
4011 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4013 missingSs <<
"<<< Link is "
4014 << (diffTree->get().isDisconnected() ?
"DISCONNECTED"
4016 <<
" in " << diffGroupPair.first <<
"("
4017 << diffGroupPair.second <<
") >>>";
4024 std::stringstream missingSs;
4026 auto diffGroupPair =
4027 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4029 missingSs <<
"<<< Link is "
4030 << (diffTree->get().isUIDLinkNode() ?
"a UID Link"
4032 <<
" in " << diffGroupPair.first <<
"("
4033 << diffGroupPair.second <<
") >>>";
4038 diffTree->get().getValueAsString())
4041 std::stringstream missingSs;
4043 auto diffGroupPair =
4044 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4046 missingSs <<
"<<< Link to '" << diffTree->get().getValueAsString()
4047 <<
"' in " << diffGroupPair.first <<
"("
4048 << diffGroupPair.second <<
") >>>";
4054 std::stringstream missingSs;
4057 auto dtchildren = diffTree->get().getChildrenMap();
4058 missingSs <<
"<<< Group link";
4059 if(tchildren.size() != dtchildren.size())
4060 missingSs <<
" has " << tchildren.size() <<
" vs "
4061 << dtchildren.size() <<
" children..";
4062 for(
auto& tchild : tchildren)
4063 if(dtchildren.find(tchild.first) == dtchildren.end())
4064 missingSs <<
" '" << tchild.first <<
"' missing..";
4065 for(
auto& dtchild : dtchildren)
4066 if(tchildren.find(dtchild.first) == tchildren.end())
4067 missingSs <<
" '" << dtchild.first <<
"' present...";
4070 if(missingSs.str().length() > std::string(
"<<< Group link").length())
4072 auto diffGroupPair =
4074 .getConfigurationManager()
4075 ->getGroupOfLoadedTable(diffTree->get().getTableName());
4076 missingSs <<
" in " << diffGroupPair.first <<
"("
4077 << diffGroupPair.second <<
") >>>";
4079 "nodeDiff", missingSs.str(), parentEl);
4107 xercesc::DOMElement* choicesParentEl =
4113 __COUTS__(30) <<
"choices.size() " << choices.size() << __E__;
4115 for(
const auto& choice : choices)
4137 xercesc::DOMElement* choicesParentEl =
4141 for(
const auto& choice : choices)
4148 bool returnNode =
true;
4161 if(diffTree.has_value())
4164 <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
4173 auto diffGroupPair =
4175 .getConfigurationManager()
4177 missingSs <<
"<<< Not in " << diffGroupPair.first <<
"("
4178 << diffGroupPair.second <<
") >>>";
4180 "nodeDiff", missingSs.str(), parentEl);
4214 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(
4217 const std::string& linkToTableName,
4219 const std::string& linkIdType,
4220 const std::string& linkIndex,
4221 const std::string& linkInitId)
4234 const std::string& tableName = linkToTableName;
4239 table->setActiveView(version);
4243 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
4244 << version << __E__;
4250 __SUP_SS__ <<
"Target table version (" << version
4251 <<
") is not the currently active version (" << table->
getViewVersion()
4252 <<
". Try refreshing the tree." << __E__;
4253 __SUP_COUT_WARN__ << ss.str();
4257 __SUP_COUT__ <<
"Active version is " << table->
getViewVersion() << __E__;
4259 if(linkIdType ==
"UID")
4262 unsigned int col = table->getView().getColUID();
4263 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4264 xmlOut.addTextElementToData(
"linkToChoice",
4265 table->getView().getDataView()[row][col]);
4267 else if(linkIdType ==
"GroupID")
4273 __SUP_COUTV__(linkIndex);
4274 __SUP_COUTV__(linkInitId);
4276 std::set<std::string> setOfGroupIDs =
4277 table->getView().getSetOfGroupIDs(linkIndex);
4282 bool foundInitId =
false;
4283 for(
const auto& groupID : setOfGroupIDs)
4285 if(!foundInitId && linkInitId == groupID)
4288 xmlOut.addTextElementToData(
"linkToChoice", groupID);
4292 xmlOut.addTextElementToData(
"linkToChoice", linkInitId);
4295 unsigned int col = table->getView().getColUID();
4296 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4298 xmlOut.addTextElementToData(
"groupChoice",
4299 table->getView().getDataView()[row][col]);
4300 if(table->getView().isEntryInGroup(row, linkIndex, linkInitId))
4301 xmlOut.addTextElementToData(
"groupMember",
4302 table->getView().getDataView()[row][col]);
4307 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType <<
".'" << __E__;
4311 catch(std::runtime_error& e)
4313 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << __E__;
4314 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4315 xmlOut.addTextElementToData(
"Error", ss.str());
4319 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << __E__;
4324 catch(
const std::exception& e)
4326 ss <<
"Exception message: " << e.what();
4331 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4332 xmlOut.addTextElementToData(
"Error", ss.str());
4337 void ConfigurationGUISupervisor::handleMergeGroupsXML(
4340 const std::string& groupANameContext,
4342 const std::string& groupBNameContext,
4344 const std::string& groupANameConfig,
4346 const std::string& groupBNameConfig,
4348 const std::string& author,
4349 const std::string& mergeApproach)
4352 __SUP_COUT__ <<
"Merging context group pair " << groupANameContext <<
" ("
4353 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4354 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4355 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4356 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4372 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" ||
4373 mergeApproach ==
"Skip"))
4375 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
4379 std::map<std::string ,
TableVersion > memberMapAContext,
4380 memberMapBContext, memberMapAConfig, memberMapBConfig;
4383 bool skippingContextPair =
false;
4384 bool skippingConfigPair =
false;
4385 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
4386 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
4388 skippingContextPair =
true;
4389 __SUP_COUTV__(skippingContextPair);
4391 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
4392 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
4394 skippingConfigPair =
true;
4395 __SUP_COUTV__(skippingConfigPair);
4399 if(!skippingContextPair)
4432 if(!skippingConfigPair)
4469 std::map<std::pair<std::string , std::string >,
4473 std::pair<std::string ,
4474 std::pair<std::string , std::string >>,
4476 groupidConversionMap;
4478 std::stringstream mergeReport;
4479 mergeReport <<
"======================================" << __E__;
4481 mergeReport <<
"Merging context group pair " << groupANameContext <<
" ("
4482 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4483 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4484 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4485 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4486 mergeReport <<
"======================================" << __E__;
4490 for(
unsigned int i = 0; i < 2; ++i)
4492 if(i == 0 && mergeApproach !=
"Rename")
4496 for(
unsigned int j = 0; j < 2; ++j)
4498 if(j == 0 && skippingContextPair)
4500 __COUT__ <<
"Skipping context pair..." << __E__;
4503 else if(j == 1 && skippingConfigPair)
4505 __COUT__ <<
"Skipping table pair..." << __E__;
4510 j == 0 ? memberMapAContext : memberMapAConfig;
4513 j == 0 ? memberMapBContext : memberMapBConfig;
4516 __COUT__ <<
"Context pair..." << __E__;
4518 __COUT__ <<
"Table pair..." << __E__;
4520 __COUT__ <<
"Starting member map B scan." << __E__;
4521 for(
const auto& bkey : memberMapBref)
4523 __SUP_COUTV__(bkey.first);
4525 if(memberMapAref.find(bkey.first) == memberMapAref.end())
4527 mergeReport <<
"\n'" << mergeApproach <<
"'-Missing table '"
4528 << bkey.first <<
"' A=v" << -1 <<
", adding B=v"
4529 << bkey.second << __E__;
4532 memberMapAref[bkey.first] = bkey.second;
4534 else if(memberMapAref[bkey.first] != bkey.second)
4537 __SUP_COUTV__(memberMapAref[bkey.first]);
4538 __SUP_COUTV__(bkey.second);
4543 __SUP_COUT__ <<
"Got table." << __E__;
4547 ->getVersionedTableByName(bkey.first,
4548 memberMapAref[bkey.first])
4556 groupidConversionMap,
4560 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME
4566 __SUP_COUTV__(newVersion);
4584 catch(std::runtime_error& e)
4587 <<
"There was an error saving the '"
4589 <<
"' merge result to a persistent table version. "
4590 <<
"Perhaps you can modify this table in one of the "
4591 "groups to resolve this issue, and then re-merge."
4592 << __E__ << e.what();
4596 __SUP_COUTV__(newVersion);
4598 memberMapAref[bkey.first] = newVersion;
4607 if(!skippingContextPair)
4609 __SUP_COUT__ <<
"New context member map complete." << __E__;
4616 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.
toString() +
4617 ") and " + groupBNameContext +
" (" + groupBKeyContext.
toString() +
").");
4620 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
4621 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.
toString());
4623 if(!skippingConfigPair)
4625 __SUP_COUT__ <<
"New table member map complete." << __E__;
4632 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.
toString() +
4633 ") and " + groupBNameConfig +
" (" + groupBKeyConfig.
toString() +
").");
4636 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
4637 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.
toString());
4642 std::string mergeReportBasePath = std::string(__ENV__(
"USER_DATA"));
4643 std::string mergeReportPath =
"/ServiceData/";
4645 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4646 mergeReportPath +=
"ConfigurationGUI_mergeReports/";
4648 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4651 "merge_" + std::to_string(time(0)) +
"_" + std::to_string(clock()) +
".txt";
4652 __SUP_COUTV__(mergeReportPath);
4654 FILE* fp = fopen((mergeReportBasePath + mergeReportPath).c_str(),
"w");
4657 fprintf(fp,
"%s", mergeReport.str().c_str());
4659 xmlOut.addTextElementToData(
"MergeReportFile",
4660 "/$USER_DATA/" + mergeReportPath);
4663 xmlOut.addTextElementToData(
"MergeReportFile",
"FILE FAILURE");
4667 catch(std::runtime_error& e)
4669 __SUP_SS__ <<
"Error merging context group pair " << groupANameContext <<
" ("
4670 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4671 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4672 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4673 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
"': \n\n"
4674 << e.what() << __E__;
4675 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4676 xmlOut.addTextElementToData(
"Error", ss.str());
4680 __SUP_SS__ <<
"Unknown error merging context group pair " << groupANameContext <<
" ("
4681 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4682 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4683 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4684 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
".' \n\n";
4689 catch(
const std::exception& e)
4691 ss <<
"Exception message: " << e.what();
4696 __SUP_COUT_ERR__ <<
"\n" << ss.
str() << __E__;
4697 xmlOut.addTextElementToData(
"Error", ss.str());
4702 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(
4705 const std::string& groupName,
4707 const std::string& modifiedTables,
4708 const std::string& author,
4709 const std::string& planName,
4710 const std::string& commandString)
4713 __COUT__ <<
"handleSavePlanCommandSequenceXML " << planName << __E__;
4716 setupActiveTablesXML(xmlOut,
4735 for(
const auto& commandPair : IterateTable::commandToTableMap_)
4736 if(commandPair.second !=
"")
4737 commandTableToEditMap.emplace(std::pair<std::string, TableEditStruct>(
4754 std::string groupName = planName +
"-Plan";
4755 __SUP_COUT__ <<
"Handling commands for group " << groupName << __E__;
4757 unsigned int groupIdCol =
4758 planTable.tableView_->findCol(IterateTable::planTableCols_.GroupID_);
4759 unsigned int cmdTypeCol =
4760 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandType_);
4762 unsigned int targetGroupIdCol =
4763 targetTable.tableView_->findCol(IterateTable::targetCols_.GroupID_);
4764 unsigned int targetTableCol =
4765 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLink_);
4766 unsigned int targetUIDCol =
4767 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLinkUID_);
4769 std::string groupLinkIndex =
4770 planTable.tableView_->getColumnInfo(groupIdCol).getChildLinkIndex();
4771 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << __E__;
4773 std::pair<
unsigned int ,
unsigned int > commandUidLink;
4776 planTable.tableView_->getChildLink(
4777 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandLink_),
4782 unsigned int cmdRow, cmdCol;
4783 std::string targetGroupName;
4787 std::string targetUID, cmdType;
4789 for(
unsigned int row = 0; row < planTable.tableView_->getNumberOfRows();
4792 targetUID = planTable.tableView_
4793 ->getDataView()[row][planTable.tableView_->getColUID()];
4794 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
4797 if(planTable.tableView_->isEntryInGroup(row, groupLinkIndex, groupName))
4799 __SUP_COUT__ <<
"Removing." << __E__;
4803 cmdType = planTable.tableView_->getDataView()[row][cmdTypeCol];
4804 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(cmdType);
4805 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4806 cmdTypeTableIt->second !=
4810 commandTableToEditMap.at(cmdTypeTableIt->second);
4811 cmdRow = cmdTypeTableEdit.tableView_->findRow(
4812 cmdTypeTableEdit.tableView_->getColUID(),
4813 planTable.tableView_
4814 ->getDataView()[row][commandUidLink.second]);
4821 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4822 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
4823 targetGroupName = cmdTypeTableEdit.tableView_
4824 ->getDataView()[cmdRow][cmdCol];
4826 for(
unsigned int trow = 0;
4827 trow < targetTable.tableView_->getNumberOfRows();
4831 if(targetTable.tableView_->isEntryInGroup(
4833 cmdTypeTableEdit.tableView_->getColumnInfo(cmdCol)
4834 .getChildLinkIndex(),
4837 __SUP_COUT__ <<
"Removing target." << __E__;
4839 if(targetTable.tableView_->removeRowFromGroup(
4850 __SUP_COUT__ <<
"No targets." << __E__;
4855 cmdTypeTableEdit.tableView_->deleteRow(cmdRow);
4861 if(planTable.tableView_->removeRowFromGroup(
4862 row, groupIdCol, groupName,
true ))
4871 std::vector<IterateTable::Command> commands;
4876 std::istringstream f(commandString);
4877 std::string commandSubString, paramSubString, paramValue;
4879 while(getline(f, commandSubString,
';'))
4881 __SUP_COUTT__ <<
"commandSubString " << commandSubString << __E__;
4882 std::istringstream g(commandSubString);
4885 while(getline(g, paramSubString,
','))
4887 __SUP_COUTT__ <<
"paramSubString " << paramSubString << __E__;
4890 if(paramSubString !=
"type")
4892 __SUP_SS__ <<
"Invalid command sequence" << __E__;
4896 commands.push_back(IterateTable::Command());
4898 getline(g, paramValue,
',');
4900 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4901 commands.back().type_ = paramValue;
4905 getline(g, paramValue,
',');
4907 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4909 commands.back().params_.emplace(
4910 std::pair<std::string ,
4922 __SUP_COUT__ <<
"commands size " << commands.size() << __E__;
4929 unsigned int row, tgtRow;
4930 unsigned int targetIndex;
4931 std::string targetStr, cmdUID;
4933 for(
auto& command : commands)
4935 __SUP_COUT__ <<
"command " << command.type_ << __E__;
4936 __SUP_COUT__ <<
"table " << IterateTable::commandToTableMap_.at(command.type_)
4940 row = planTable.tableView_->addRow(
4941 author,
true ,
"planCommand");
4942 planTable.tableView_->addRowToGroup(row, groupIdCol, groupName);
4945 planTable.tableView_->setURIEncodedValue(command.type_, row, cmdTypeCol);
4948 planTable.tableView_->setValueAsString(
4949 "1", row, planTable.tableView_->getColStatus());
4952 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(command.type_);
4953 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4954 cmdTypeTableIt->second !=
4958 commandTableToEditMap.at(cmdTypeTableIt->second);
4959 __SUP_COUT__ <<
"table " << cmdTypeTableEdit.tableName_ << __E__;
4964 cmdRow = cmdTypeTableEdit.tableView_->addRow(
4965 author,
true , command.type_ +
"_COMMAND_");
4971 for(
auto& param : command.params_)
4973 __SUP_COUT__ <<
"\t param " << param.first <<
" : " << param.second
4976 if(param.first == IterateTable::targetParams_.Tables_)
4978 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
4979 std::istringstream f(param.second);
4982 while(getline(f, targetStr,
'='))
4984 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
4985 if(!command.targets_.size() ||
4986 command.targets_.back().table_ !=
"")
4988 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
4991 command.addTarget();
4992 command.targets_.back().table_ = targetStr;
4995 command.targets_[targetIndex++].table_ = targetStr;
5001 if(param.first == IterateTable::targetParams_.UIDs_)
5003 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
5004 std::istringstream f(param.second);
5007 while(getline(f, targetStr,
'='))
5009 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
5010 if(!command.targets_.size() ||
5011 command.targets_.back().UID_ !=
"")
5013 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
5016 command.addTarget();
5017 command.targets_.back().UID_ = targetStr;
5020 command.targets_[targetIndex++].UID_ = targetStr;
5025 cmdCol = cmdTypeTableEdit.tableView_->findCol(param.first);
5027 __SUP_COUT__ <<
"param col " << cmdCol << __E__;
5029 cmdTypeTableEdit.tableView_->setURIEncodedValue(
5030 param.second, cmdRow, cmdCol);
5034 cmdTypeTableEdit.tableView_
5035 ->getDataView()[cmdRow][cmdTypeTableEdit.tableView_->getColUID()];
5037 if(command.targets_.size())
5041 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
5044 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5045 IterateTable::commandTargetCols_.TargetsLink_);
5046 cmdTypeTableEdit.tableView_->setValueAsString(
5047 IterateTable::TARGET_TABLE, cmdRow, cmdCol);
5049 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5050 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
5051 cmdTypeTableEdit.tableView_->setValueAsString(
5052 cmdUID +
"_Targets", cmdRow, cmdCol);
5056 for(
const auto& target : command.targets_)
5058 __SUP_COUT__ << target.
table_ <<
" " << target.UID_ << __E__;
5061 tgtRow = targetTable.tableView_->addRow(
5062 author,
true ,
"commandTarget");
5063 targetTable.tableView_->addRowToGroup(
5064 tgtRow, targetGroupIdCol, cmdUID +
"_Targets");
5067 targetTable.tableView_->setValueAsString(
5068 target.table_, tgtRow, targetTableCol);
5071 targetTable.tableView_->setValueAsString(
5072 target.UID_, tgtRow, targetUIDCol);
5077 planTable.tableView_->setValueAsString(
5078 cmdTypeTableEdit.tableName_, row, commandUidLink.first);
5079 planTable.tableView_->setValueAsString(
5080 cmdUID, row, commandUidLink.second);
5082 __SUP_COUT__ <<
"linked to uid = " << cmdUID << __E__;
5092 planTable.tableView_->print();
5093 planTable.tableView_->init();
5095 __SUP_COUT__ <<
"requestType tables:" << __E__;
5097 for(
auto& modifiedConfig : commandTableToEditMap)
5099 __SUP_COUTV__(modifiedConfig.second.modified_);
5100 modifiedConfig.second.tableView_->print();
5101 modifiedConfig.second.tableView_->init();
5104 targetTable.tableView_->print();
5105 targetTable.tableView_->init();
5110 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly "
5116 if(planTable.createdTemporaryVersion_)
5118 __SUP_COUT__ <<
"Erasing temporary version " << planTable.tableName_ <<
"-v"
5119 << planTable.temporaryVersion_ << __E__;
5122 planTable.temporaryVersion_);
5125 if(targetTable.createdTemporaryVersion_)
5127 __SUP_COUT__ <<
"Erasing temporary version " << targetTable.tableName_ <<
"-v"
5128 << targetTable.temporaryVersion_ << __E__;
5131 targetTable.temporaryVersion_);
5134 for(
auto& modifiedConfig : commandTableToEditMap)
5136 if(modifiedConfig.second
5137 .createdTemporaryVersion_)
5139 __SUP_COUT__ <<
"Erasing temporary version "
5140 << modifiedConfig.second.tableName_ <<
"-v"
5141 << modifiedConfig.second.temporaryVersion_ << __E__;
5144 modifiedConfig.second.temporaryVersion_);
5158 planTable.tableName_,
5159 planTable.originalVersion_,
5162 planTable.temporaryVersion_,
5165 __SUP_COUT__ <<
"Final plan version is " << planTable.tableName_ <<
"-v"
5166 << finalVersion << __E__;
5171 targetTable.tableName_,
5172 targetTable.originalVersion_,
5175 targetTable.temporaryVersion_,
5178 __SUP_COUT__ <<
"Final target version is " << targetTable.tableName_ <<
"-v"
5179 << finalVersion << __E__;
5181 for(
auto& modifiedConfig : commandTableToEditMap)
5183 if(!modifiedConfig.second.modified_)
5185 if(modifiedConfig.second
5186 .createdTemporaryVersion_)
5188 __SUP_COUT__ <<
"Erasing unmodified temporary version "
5189 << modifiedConfig.second.tableName_ <<
"-v"
5190 << modifiedConfig.second.temporaryVersion_ << __E__;
5193 modifiedConfig.second.temporaryVersion_);
5201 modifiedConfig.second.tableName_,
5202 modifiedConfig.second.originalVersion_,
5204 modifiedConfig.second.table_,
5205 modifiedConfig.second.temporaryVersion_,
5208 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.tableName_ <<
"-v"
5209 << finalVersion << __E__;
5212 handleFillModifiedTablesXML(xmlOut, cfgMgr);
5214 catch(std::runtime_error& e)
5216 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << __E__;
5217 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5218 xmlOut.addTextElementToData(
"Error", ss.str());
5222 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << __E__;
5227 catch(
const std::exception& e)
5229 ss <<
"Exception message: " << e.what();
5234 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5235 xmlOut.addTextElementToData(
"Error", ss.str());
5248 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(
HttpXmlDocument& xmlOut,
5250 const std::string& tableName,
5252 const std::string& type,
5253 const std::string& uid,
5254 const std::string& colName,
5255 const std::string& newValue,
5256 const std::string& author)
5259 __SUP_COUT__ <<
"Editing table " << tableName <<
"(" << version <<
") uid=" << uid
5260 <<
" type=" << type << __E__;
5270 table->setActiveView(version);
5277 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
5278 << version << __E__;
5282 __SUP_COUT__ <<
"Active version is " << table->
getViewVersion() << __E__;
5283 __SUP_COUTTV__(table->getView().getComment());
5287 __SUP_SS__ <<
"Target table version (" << version
5288 <<
") is not the currently active version (" << table->
getViewVersion()
5289 <<
"). Try refreshing the tree." << __E__;
5293 unsigned int col = -1;
5294 if(type ==
"uid" || type ==
"delete-uid" || type ==
"tree-copy")
5295 col = table->getView().getColUID();
5296 else if(type ==
"node-comment")
5297 col = table->getView().findCol(TableViewColumnInfo::COL_NAME_COMMENT);
5298 else if(type ==
"link-UID" || type ==
"link-GroupID" || type ==
"value" ||
5299 type ==
"value-groupid" || type ==
"value-bool" || type ==
"value-bitmap")
5300 col = table->getView().findCol(colName);
5301 else if(type ==
"table" || type ==
"link-comment" || type ==
"table-newGroupRow" ||
5302 type ==
"table-newUIDRow" || type ==
"table-newRow")
5306 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << __E__;
5311 if(type ==
"table" || type ==
"link-comment")
5314 if(table->getView().isURIEncodedCommentTheSame(newValue))
5317 <<
"' is the same as the current comment. No need to save change."
5335 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5340 __SUP_COUTTV__(table->getView().getComment());
5346 if(type ==
"table" || type ==
"link-comment")
5351 else if(type ==
"table-newRow" || type ==
"table-newUIDRow")
5354 unsigned int row = cfgView->
addRow(
5355 author,
true , newValue );
5370 else if(type ==
"table-newGroupRow")
5373 unsigned int csvIndex = newValue.find(
',');
5375 std::string linkIndex = newValue.substr(0, csvIndex);
5376 std::string groupId = newValue.substr(csvIndex + 1);
5379 csvIndex = groupId.find(
',');
5380 std::string newRowUID = groupId.substr(csvIndex + 1);
5381 groupId = groupId.substr(0, csvIndex);
5383 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," << groupId <<
"," << newRowUID
5387 unsigned int row = cfgView->
addRow(author,
5413 else if(type ==
"delete-uid")
5416 unsigned int row = cfgView->
findRow(col, uid);
5419 else if(type ==
"tree-copy")
5422 __COUTV__(newValue);
5423 std::vector<std::string> paramArray =
5427 if(paramArray.size() != 2)
5429 __SS__ <<
"Illegal parameters for tree copy request: must be number of "
5430 "copy instances & depth of copy."
5435 unsigned int row = cfgView->
findRow(col, uid);
5438 unsigned int numberOfInstances = atoi(paramArray[0].c_str());
5439 unsigned int depth = atoi(paramArray[1].c_str());
5441 __COUTV__(numberOfInstances);
5442 if(numberOfInstances > 1000)
5444 __SS__ <<
"Illegal parameters - the maximum number of copy instances is "
5445 "1000. Number of instances provided was "
5446 << numberOfInstances << __E__;
5453 ConfigurationSupervisorBase::recursiveCopyTreeUIDNode(xmlOut,
5462 else if(type ==
"uid" || type ==
"value" || type ==
"value-groupid" ||
5463 type ==
"value-bool" || type ==
"value-bitmap" || type ==
"node-comment")
5469 __SUP_SS__ <<
"Value '" << newValue
5470 <<
"' is the same as the current value. No need to save "
5471 "change to tree node."
5476 else if(type ==
"link-UID" || type ==
"link-GroupID")
5479 std::pair<
unsigned int ,
unsigned int > linkPair;
5483 __SUP_SS__ <<
"Col '" << colName <<
"' is not a link column." << __E__;
5487 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," << linkPair.second
5490 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
5492 __SUP_COUT__ <<
"linkIndex " << linkIndex << __E__;
5495 unsigned int csvIndexStart = 0, csvIndex = newValue.find(
',');
5497 std::string newTable = newValue.substr(csvIndexStart, csvIndex);
5498 csvIndexStart = csvIndex + 1;
5499 csvIndex = newValue.find(
',', csvIndexStart);
5500 std::string newLinkId = newValue.substr(
5505 __SUP_COUT__ <<
"newValue " << newTable <<
"," << newLinkId << __E__;
5509 bool changed =
false;
5510 bool needSecondaryChange = (type ==
"link-GroupID");
5515 __SUP_COUT__ <<
"Value '" << newTable
5516 <<
"' is the same as the current value." << __E__;
5524 std::string originalValue = cfgView->
getValueAsString(row, linkPair.second);
5528 __SUP_COUT__ <<
"Value '" << newLinkId
5529 <<
"' is the same as the current value." << __E__;
5534 needSecondaryChange =
5540 if(needSecondaryChange)
5542 bool secondaryChanged =
false;
5543 bool defaultIsInGroup =
5549 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table."
5551 table->eraseView(temporaryVersion);
5572 catch(std::runtime_error&
5575 __SUP_COUT__ <<
"Caught error while editing main table. Erasing "
5576 "temporary version."
5578 table->eraseView(temporaryVersion);
5582 xmlOut.addTextElementToData(
5584 "Error saving primary tree node! " + std::string(e.what()));
5594 __SUP_COUTV__(newValue);
5595 csvIndexStart = csvIndex + 1;
5596 csvIndex = newValue.find(
',', csvIndexStart);
5598 csvIndexStart, csvIndex - csvIndexStart));
5601 if(newTable == TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5612 table->setActiveView(version);
5619 __SUP_COUT__ <<
"Failed to find stored version, so attempting to "
5621 << newTable <<
" v" << version << __E__;
5625 __SUP_COUT__ << newTable <<
" active version is "
5632 ss <<
"Target table '" << newTable
5633 <<
"' is likely not a member of the current table group "
5634 <<
"since the mock-up version was not successfully loaded. "
5639 "To add a table to a group, click the group name to go to "
5641 "group view, then click 'Add/Remove/Modify Member Tables.' "
5643 "can then add or remove tables and save the new group." +
5645 "OR!!! Click the following button to add the table '" +
5647 "' to the currently active Configuration Group: " +
5648 "<input type='button' style='color:black !important;' " +
5649 "title='Click to add table to the active Configuration "
5651 "onclick='addTableToConfigurationGroup(\"" + newTable +
5652 "\"); Debug.closeErrorPop();event.stopPropagation();' "
5653 "value='Add Table'>" +
5657 ss <<
"Target table version (" << version
5658 <<
") is not the currently active version ("
5667 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5673 if(type ==
"link-UID")
5683 __SUP_COUT__ <<
"target col " << col << __E__;
5685 unsigned int row = -1;
5688 row = cfgView->
findRow(col, newLinkId);
5693 if(row == (
unsigned int)-1)
5695 __SUP_COUT__ <<
"New link UID '" << newLinkId
5696 <<
"' was not found, so attempting to change UID of "
5698 << originalValue <<
"'" << __E__;
5701 row = cfgView->
findRow(col, originalValue);
5704 secondaryChanged =
true;
5705 __SUP_COUT__ <<
"Original target record '"
5706 << originalValue <<
"' was changed to '"
5707 << newLinkId <<
"'" << __E__;
5712 __SUP_COUT__ <<
"Original target record '" << originalValue
5713 <<
"' not found." << __E__;
5717 else if(type ==
"link-GroupID")
5725 __SUP_COUT__ <<
"target col " << col << __E__;
5728 std::vector<std::string> memberUIDs;
5731 csvIndexStart = csvIndex + 1;
5732 csvIndex = newValue.find(
',', csvIndexStart);
5733 memberUIDs.push_back(
5734 newValue.substr(csvIndexStart, csvIndex - csvIndexStart));
5735 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << __E__;
5737 (
unsigned int)std::string::npos);
5747 std::string targetUID;
5748 bool shouldBeInGroup;
5751 for(
unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
5753 targetUID = cfgView->getDataView()[row][cfgView->
getColUID()];
5754 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
5756 shouldBeInGroup =
false;
5757 for(
unsigned int i = 0; i < memberUIDs.size(); ++i)
5758 if(targetUID == memberUIDs[i])
5761 shouldBeInGroup =
true;
5768 if(shouldBeInGroup && !isInGroup)
5770 __SUP_COUT__ <<
"Changed to YES: " << row << __E__;
5771 secondaryChanged =
true;
5776 else if(!shouldBeInGroup && isInGroup)
5778 __SUP_COUT__ <<
"Changed to NO: " << row << __E__;
5779 secondaryChanged =
true;
5783 else if(targetUID ==
5785 ->getDefaultRowValues()[cfgView->
getColUID()] &&
5789 defaultIsInGroup =
true;
5795 if(!secondaryChanged)
5798 <<
"No changes to secondary view. Erasing temporary table."
5800 table->eraseView(temporaryVersion);
5821 catch(std::runtime_error&
5824 __SUP_COUT__ <<
"Caught error while editing secondary table. "
5825 "Erasing temporary version."
5827 table->eraseView(temporaryVersion);
5828 secondaryChanged =
false;
5831 xmlOut.addTextElementToData(
5833 "Error saving secondary tree node! " + std::string(e.what()));
5841 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
5843 __SUP_SS__ <<
"Link to table '" << newTable <<
"', linkID '"
5845 <<
"', and selected group members are the same as the "
5847 <<
"No need to save changes to tree." << __E__;
5853 else if(0 && !changed)
5858 __SUP_SS__ <<
"Link to table '" << newTable <<
"' and linkID '"
5860 <<
"' are the same as the current values. No need to save "
5861 "change to tree node."
5871 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
5872 table->eraseView(temporaryVersion);
5886 catch(std::runtime_error& e)
5888 __SUP_SS__ <<
"Error saving tree node! " << e.what() << __E__;
5889 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5890 xmlOut.addTextElementToData(
"Error", ss.str());
5894 __SUP_SS__ <<
"Unknown Error saving tree node! " << __E__;
5899 catch(
const std::exception& e)
5901 ss <<
"Exception message: " << e.what();
5906 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5907 xmlOut.addTextElementToData(
"Error", ss.str());
5951 void ConfigurationGUISupervisor::handleGetTableXML(
HttpXmlDocument& xmlOut,
5953 const std::string& tableName,
5955 bool allowIllegalColumns ,
5959 char tmpIntStr[100];
5960 xercesc::DOMElement *parentEl, *subparentEl;
5962 std::string accumulatedErrors =
"";
5964 if(allowIllegalColumns)
5965 xmlOut.addTextElementToData(
"allowIllegalColumns",
"1");
5967 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo(
5968 allowIllegalColumns ,
5969 allowIllegalColumns ? &accumulatedErrors : 0,
5978 xmlOut.addTextElementToData(
"ExistingTableNames",
5979 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
5980 for(
auto& configPair : allTableInfo)
5982 xmlOut.addTextElementToData(
"ExistingTableNames", configPair.first);
5983 if(configPair.first == tableName &&
5984 configPair.second.versions_.find(version) ==
5985 configPair.second.versions_.end())
5987 __SUP_COUT__ <<
"Version not found, so using mockup." << __E__;
5993 xmlOut.addTextElementToData(
"TableName", tableName);
5994 xmlOut.addTextElementToData(
"TableDescription",
5995 table->getTableDescription());
6009 for(
const auto& aliases : versionAliases)
6010 for(
const auto& alias : aliases.second)
6011 __SUP_COUTT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first
6012 <<
" ==> " << alias.second << __E__;
6014 catch(
const std::runtime_error& e)
6016 __SUP_COUT__ <<
"Could not get backbone information for version aliases: "
6017 << e.what() << __E__;
6020 auto tableIterator = versionAliases.find(tableName);
6022 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
6025 for(
const TableVersion& v : allTableInfo.at(tableName).versions_)
6031 std::vector<std::string> aliases;
6032 if(tableIterator != versionAliases.end())
6035 for(
const auto& aliasPair : tableIterator->second)
6037 if(v == aliasPair.second)
6039 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> "
6040 << aliasPair.first << __E__;
6041 aliases.push_back(aliasPair.first);
6049 __SUP_COUT__ <<
"Handling version w/aliases" << __E__;
6052 TableVersion::INVALID)
6057 else if(hi.
version() + 1 == v.version())
6064 if(lo.
version() != TableVersion::INVALID)
6074 if(versionAliases.size())
6078 for(
const auto& alias : aliases)
6080 hi = lo = TableVersion::INVALID;
6085 if(lo.
version() != TableVersion::INVALID)
6101 tableViewPtr = table->getMockupViewP();
6109 std::string localAccumulatedErrors =
"";
6114 allowIllegalColumns ,
6115 &localAccumulatedErrors,
6121 xmlOut.addTextElementToData(
"TableRawData",
6122 tableViewPtr->getSourceRawData());
6124 const std::set<std::string>& srcColNames =
6125 tableViewPtr->getSourceColumnNames();
6126 for(
auto& srcColName : srcColNames)
6127 xmlOut.addTextElementToData(
"ColumnHeader", srcColName);
6134 tableViewPtr = cfgMgr
6138 allowIllegalColumns ,
6139 &localAccumulatedErrors,
6145 if(localAccumulatedErrors !=
"")
6146 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
6148 catch(std::runtime_error& e)
6150 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << version
6151 <<
"... defaulting to mock-up! " << __E__;
6152 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
6154 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6156 tableViewPtr = table->getMockupViewP();
6158 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6162 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << version
6163 <<
"... defaulting to mock-up! "
6164 <<
"(You may want to try again to see what was partially loaded "
6165 "into cache before failure. "
6166 <<
"If you think, the failure is due to a column name change, "
6167 <<
"you can also try to Copy the failing view to the new column "
6169 <<
"'Copy and Move' functionality.)" << __E__;
6174 catch(
const std::exception& e)
6176 ss <<
"Exception message: " << e.what();
6182 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6184 tableViewPtr = table->getMockupViewP();
6186 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6189 xmlOut.addTextElementToData(
"TableVersion", version.
toString());
6195 xercesc::DOMElement* choicesParentEl;
6196 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
6198 std::vector<TableViewColumnInfo> colInfo = tableViewPtr->getColumnsInfo();
6200 for(
int i = 0; i < (int)colInfo.size(); ++i)
6205 "ColumnDataType", colInfo[i].getDataType(), parentEl);
6210 "ColumnDefaultValue", colInfo[i].getDefaultValue(), parentEl);
6214 if(colInfo[i].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
6215 colInfo[i].getType() == TableViewColumnInfo::TYPE_BITMAP_DATA ||
6216 colInfo[i].isChildLink())
6218 for(
auto& choice : colInfo[i].getDataChoices())
6223 "ColumnMinValue", colInfo[i].getMinValue(), parentEl);
6225 "ColumnMaxValue", colInfo[i].getMaxValue(), parentEl);
6232 tableViewPtr->
init();
6234 catch(std::runtime_error& e)
6237 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
6244 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
6246 for(
int r = 0; r < (int)tableViewPtr->getNumberOfRows(); ++r)
6248 sprintf(tmpIntStr,
"%d", r);
6249 xercesc::DOMElement* tmpParentEl =
6252 for(
int c = 0; c < (int)tableViewPtr->getNumberOfColumns(); ++c)
6254 if(colInfo[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
6256 std::string timeAsString;
6257 tableViewPtr->
getValue(timeAsString, r, c);
6262 "Entry", tableViewPtr->getDataView()[r][c], tmpParentEl);
6267 xmlOut.addTextElementToData(
"TableComment", tableViewPtr->getComment());
6268 xmlOut.addTextElementToData(
"TableAuthor", tableViewPtr->getAuthor());
6269 xmlOut.addTextElementToData(
"TableCreationTime",
6270 std::to_string(tableViewPtr->getCreationTime()));
6271 xmlOut.addTextElementToData(
"TableLastAccessTime",
6272 std::to_string(tableViewPtr->getLastAccessTime()));
6277 std::vector<std::string> defaultRowValues =
6278 table->getMockupViewP()->getDefaultRowValues();
6280 for(
unsigned int c = 0; c < defaultRowValues.size() - 2; ++c)
6282 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
6285 const std::set<std::string> srcColNames = tableViewPtr->getSourceColumnNames();
6287 if(accumulatedErrors !=
"")
6289 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so "
6290 "perhaps you can ignore this, ") +
6291 "but please note the following warnings:\n" + accumulatedErrors)
6293 __SUP_COUT_ERR__ << ss.str();
6294 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6298 (srcColNames.size() != tableViewPtr->getNumberOfColumns() ||
6299 tableViewPtr->getSourceColumnMismatch() !=
6302 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " << tableName
6303 <<
":v" << version <<
". Please see the details below:\n\n"
6304 << tableViewPtr->getMismatchColumnInfo();
6306 __SUP_COUT__ <<
"\n" << ss.str();
6307 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6311 catch(std::runtime_error& e)
6313 __SUP_SS__ <<
"Error getting table view!\n\n " << e.what() << __E__;
6314 __SUP_COUT_ERR__ << ss.str();
6315 xmlOut.addTextElementToData(
"Error", ss.str());
6319 __SUP_SS__ <<
"Error getting table view!\n\n " << __E__;
6324 catch(
const std::exception& e)
6326 ss <<
"Exception message: " << e.what();
6331 __SUP_COUT_ERR__ << ss.str();
6332 xmlOut.addTextElementToData(
"Error", ss.str());
6343 std::string username,
bool refresh)
6345 uint64_t sessionIndex =
6348 std::stringstream ssMapKey;
6349 ssMapKey << username <<
":" << sessionIndex;
6350 std::string mapKey = ssMapKey.str();
6351 __SUP_COUTT__ <<
"Using Config Session " << mapKey
6352 <<
" ... Total Session Count: " << userConfigurationManagers_.size()
6353 <<
" refresh=" << refresh << __E__;
6355 time_t now = time(0);
6361 for(
auto& pair : userConfigurationManagers_)
6362 __SUP_COUTTV__(pair.first);
6365 const std::string preLoadCfgMgrName =
":0";
6366 if(userConfigurationManagers_.size() == 1 &&
6367 userConfigurationManagers_.find(preLoadCfgMgrName) !=
6368 userConfigurationManagers_.end())
6370 __SUP_COUT__ <<
"Using pre-loaded Configuration Manager. time=" << time(0) <<
" "
6371 << clock() <<
" Setting author from "
6372 << userConfigurationManagers_.at(preLoadCfgMgrName)->getUsername()
6373 <<
" to " << username << __E__;
6374 userConfigurationManagers_[mapKey] =
6375 userConfigurationManagers_.at(preLoadCfgMgrName);
6376 userLastUseTime_[mapKey] = userLastUseTime_.at(preLoadCfgMgrName);
6378 userConfigurationManagers_.at(mapKey)->setUsername(username);
6381 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
6383 __SUP_COUT__ <<
"Creating new Configuration Manager. time=" << time(0) <<
" "
6384 << clock() << __E__;
6390 userConfigurationManagers_[mapKey]->getAllTableInfo(
6398 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
6400 __SUP_SS__ <<
"Fatal error managing userLastUseTime_! Check the logs for "
6401 "Configuration Interface failure."
6403 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6408 (now - userLastUseTime_[mapKey]) >
6409 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
6411 __SUP_COUT__ <<
"Refreshing all table info." << __E__;
6412 userConfigurationManagers_[mapKey]->getAllTableInfo(
6420 __SUP_COUTT__ <<
"Configuration Manager for author="
6421 << userConfigurationManagers_[mapKey]->getUsername()
6422 <<
" ready. time=" << time(0) <<
" " << clock() <<
" runTimeSeconds()="
6423 << userConfigurationManagers_[mapKey]->runTimeSeconds() << __E__;
6426 userLastUseTime_[mapKey] = now;
6429 for(std::map<std::string, time_t>::iterator it = userLastUseTime_.begin();
6430 it != userLastUseTime_.end();
6432 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
6434 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second
6436 delete userConfigurationManagers_[it->first];
6437 if(!(userConfigurationManagers_.erase(it->first)))
6439 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!"
6441 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6444 userLastUseTime_.erase(it);
6451 return userConfigurationManagers_[mapKey];
6459 void ConfigurationGUISupervisor::handleDeleteTableInfoXML(
HttpXmlDocument& xmlOut,
6461 std::string& tableName)
6463 if(0 == rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
6464 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
6465 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
6466 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6470 __SUP_COUT_ERR__ << (
"Error renaming file to " +
6471 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6474 xmlOut.addTextElementToData(
6476 (
"Error renaming Table Info File to " +
6477 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused")));
6492 void ConfigurationGUISupervisor::handleSaveTableInfoXML(
6495 std::string& tableName,
6496 const std::string& data,
6497 const std::string& tableDescription,
6498 const std::string& columnChoicesCSV,
6499 bool allowOverwrite)
6503 std::string capsName;
6508 catch(std::runtime_error& e)
6510 xmlOut.addTextElementToData(
"Error", e.what());
6516 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"r");
6520 xmlOut.addTextElementToData(
"TableName", tableName);
6521 xmlOut.addTextElementToData(
"OverwriteError",
"1");
6522 xmlOut.addTextElementToData(
6524 "File already exists! ('" +
6525 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT) +
"')");
6530 __SUP_COUT__ <<
"capsName=" << capsName << __E__;
6531 __SUP_COUT__ <<
"tableName=" << tableName << __E__;
6532 __SUP_COUT__ <<
"tableDescription=" << tableDescription << __E__;
6533 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << __E__;
6536 std::stringstream outss;
6538 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
6539 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
6540 "xsi:noNamespaceSchemaLocation=\"TableInfo.xsd\">\n";
6541 outss <<
"\t\t<TABLE Name=\"" << tableName <<
"\">\n";
6542 outss <<
"\t\t\t<VIEW Name=\"" << capsName
6543 <<
"\" Type=\"File,Database,DatabaseTest\" Description=\"" << tableDescription
6549 std::istringstream columnChoicesISS(columnChoicesCSV);
6550 std::string columnChoicesString;
6551 std::string columnDefaultValue, columnMinValue, columnMaxValue;
6552 std::vector<std::string> columnParameters;
6553 std::vector<std::string> columnData =
6556 for(
unsigned int c = 0; c < columnData.size() - 1; ++c)
6560 __COUT__ <<
"Column #" << c <<
": "
6562 for(
unsigned int p = 0; p < columnParameters.size(); ++p)
6564 __COUT__ <<
"\t Parameter #" << p <<
": " << columnParameters[p] << __E__;
6566 __COUT__ <<
"\t creating the new xml" << __E__;
6568 std::string& columnType = columnParameters[0];
6569 std::string& columnName = columnParameters[1];
6570 std::string& columnDataType = columnParameters[2];
6571 const std::string columnStorageName =
6574 outss <<
"\t\t\t\t<COLUMN Type=\"";
6575 outss << columnType;
6576 outss <<
"\" \t Name=\"";
6577 outss << columnName;
6578 outss <<
"\" \t StorageName=\"";
6581 outss << columnStorageName;
6583 catch(std::runtime_error& e)
6585 xmlOut.addTextElementToData(
6587 std::string(
"For column name '") + columnName +
"' - " + e.what());
6590 outss <<
"\" \t DataType=\"";
6591 outss << columnDataType;
6595 std::string* columnDefaultValuePtr =
nullptr;
6596 if(columnDefaultValue !=
6599 __SUP_COUT__ <<
"FOUND user spec'd default value '" << columnDefaultValue
6601 outss <<
"\" \t DefaultValue=\"";
6602 outss << columnParameters[3];
6603 columnDefaultValuePtr = &columnParameters[3];
6605 getline(columnChoicesISS, columnChoicesString,
';');
6606 outss <<
"\" \t DataChoices=\"";
6607 outss << columnChoicesString;
6609 std::string* columnMinValuePtr =
nullptr;
6610 std::string* columnMaxValuePtr =
nullptr;
6612 if(columnParameters.size() > 4 &&
6616 if(columnMinValue !=
"")
6618 if(columnMinValue !=
6621 __SUP_COUT__ <<
"FOUND user spec'd min value '" << columnParameters[4]
6626 __SS__ <<
"Inavlid user spec'd min value '" << columnParameters[4]
6627 <<
"' which evaluates to '" << columnMinValue
6628 <<
"' and is not a valid number. The minimum value must "
6629 "be a number (environment variables and math "
6630 "operations are allowed)."
6634 outss <<
"\" \t MinValue=\"" << columnParameters[4];
6635 columnMinValuePtr = &columnParameters[4];
6640 if(columnMaxValue !=
"")
6642 if(columnMaxValue !=
6645 __SUP_COUT__ <<
"FOUND user spec'd max value = " << columnMaxValue
6650 __SS__ <<
"Inavlid user spec'd max value '" << columnParameters[5]
6651 <<
"' which evaluates to '" << columnMaxValue
6652 <<
"' and is not a valid number. The maximum value must "
6653 "be a number (environment variables and math "
6654 "operations are allowed)."
6658 outss <<
"\" \t MaxValue=\"" << columnParameters[5];
6659 columnMaxValuePtr = &columnParameters[5];
6671 columnDefaultValuePtr,
6672 columnChoicesString,
6678 catch(
const std::runtime_error& e)
6680 __SS__ <<
"Error identified with Column #" << c <<
": \n" << e.what();
6687 outss <<
"\t\t\t</VIEW>\n";
6688 outss <<
"\t\t</TABLE>\n";
6689 outss <<
"\t</ROOT>\n";
6691 __SUP_COUT__ << outss.str() << __E__;
6693 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"w");
6696 xmlOut.addTextElementToData(
"Error",
6697 "Failed to open destination Table Info file:" +
6698 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT));
6702 fprintf(fp,
"%s", outss.str().c_str());
6705 __SUP_COUT_INFO__ <<
"Finished saving Table Info for '" << tableName
6706 <<
".' Looking for errors in all table column info..." << __E__;
6710 std::string accumulatedErrors =
"";
6714 if(accumulatedErrors !=
"")
6716 __SUP_SS__ << (
"The new version of the '" + tableName +
6717 "' table column info was saved, however errors were detected "
6718 "reading back the table '" +
6719 tableName +
"' after the save attempt:\n\n" + accumulatedErrors)
6722 __SUP_COUT_ERR__ << ss.str() << __E__;
6723 xmlOut.addTextElementToData(
"Error", ss.str());
6729 handleGetTableXML(xmlOut, cfgMgr, tableName,
TableVersion());
6732 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
6735 for(
const auto& cfgInfo : allTableInfo)
6741 catch(std::runtime_error& e)
6743 __SUP_COUT_WARN__ <<
"\n\n##############################################\n"
6744 <<
"Error identified in column info of table '"
6745 << cfgInfo.first <<
"':\n\n"
6746 << e.what() <<
"\n\n"
6760 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(
6763 const std::string& groupAliasCSV,
6764 const std::string& groupNameCSV,
6765 const std::string& groupKeyCSV,
6766 const std::string& author)
6770 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
6772 const std::string groupAliasesTableName =
6773 ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
6774 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
6776 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!"
6778 xmlOut.addTextElementToData(
"Error", ss.str());
6783 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6784 for(
auto& memberName : backboneMembers)
6786 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6787 <<
"\"]=" << activeVersions[memberName] << __E__;
6789 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6790 xmlOut.addTextElementToData(
"oldBackboneVersion",
6791 activeVersions[memberName].toString());
6799 TableVersion originalVersion = activeVersions[groupAliasesTableName];
6802 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6803 bool isDifferent =
false;
6809 unsigned int col = configView->
findCol(
"GroupKeyAlias");
6810 unsigned int ccol = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6811 unsigned int ncol = configView->
findCol(
"GroupName");
6812 unsigned int kcol = configView->
findCol(
"GroupKey");
6815 std::vector<std::string> groupAliases =
6817 std::vector<std::string> groupNames =
6819 std::vector<std::string> groupKeys =
6826 for(
const auto& groupAlias : groupAliases)
6828 if(groupAlias ==
"" || groupNames[i] ==
"" || groupKeys[i] ==
"")
6831 __SUP_COUT_WARN__ <<
"Empty alias parameter found [" << i <<
"] = {"
6832 << groupAlias <<
", " << groupNames[i] <<
"("
6833 << groupKeys[i] <<
")}" << __E__;
6838 bool localIsDifferent =
false;
6839 const std::string& groupName = groupNames[i];
6843 unsigned int row = -1;
6847 row = configView->
findRow(col, groupAlias);
6853 if(row == (
unsigned int)-1)
6855 localIsDifferent =
true;
6856 row = configView->
addRow();
6860 "This Group Alias was automatically setup by the server.", row, ccol);
6861 configView->
setValue(groupAlias, row, col);
6864 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6866 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs "
6867 << configView->getDataView()[row][ncol] << __E__;
6868 if(groupName != configView->getDataView()[row][ncol])
6870 configView->
setValue(groupName, row, ncol);
6871 localIsDifferent =
true;
6874 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs "
6875 << configView->getDataView()[row][kcol] << __E__;
6876 if(groupKey.
toString() != configView->getDataView()[row][kcol])
6879 localIsDifferent =
true;
6882 if(localIsDifferent)
6887 configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
6891 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
6898 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << __E__;
6901 table->eraseView(temporaryVersion);
6908 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6926 <<
"\t\t**************************** Using the existing table version"
6930 table->eraseView(temporaryVersion);
6931 newAssignedVersion = activeVersions[groupAliasesTableName];
6933 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
6934 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
6937 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6939 catch(std::runtime_error& e)
6941 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << e.what() << __E__;
6942 __SUP_COUT_ERR__ << ss.str();
6943 xmlOut.addTextElementToData(
"Error", ss.str());
6947 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << __E__;
6952 catch(
const std::exception& e)
6954 ss <<
"Exception message: " << e.what();
6959 __SUP_COUT_ERR__ << ss.str();
6960 xmlOut.addTextElementToData(
"Error", ss.str());
6971 void ConfigurationGUISupervisor::handleSetTableAliasInBackboneXML(
6974 const std::string& tableAlias,
6975 const std::string& tableName,
6977 const std::string& author)
6981 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
6983 const std::string versionAliasesTableName =
6984 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6985 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6987 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6989 xmlOut.addTextElementToData(
"Error", ss.str());
6994 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6995 for(
auto& memberName : backboneMembers)
6997 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6998 <<
"\"]=" << activeVersions[memberName] << __E__;
7000 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7001 xmlOut.addTextElementToData(
"oldBackboneVersion",
7002 activeVersions[memberName].toString());
7010 TableVersion originalVersion = activeVersions[versionAliasesTableName];
7013 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7015 bool isDifferent =
false;
7022 unsigned int col2 = configView->
findCol(
"VersionAlias");
7023 unsigned int col3 = configView->
findCol(
"TableName");
7027 unsigned int row = -1;
7032 unsigned int tmpRow = -1;
7035 tmpRow = configView->
findRow(col3, tableName, tmpRow + 1);
7036 }
while(configView->getDataView()[tmpRow][col2] != tableAlias);
7043 if(row == (
unsigned int)-1)
7046 row = configView->
addRow();
7049 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7051 std::string(
"Entry was added by server in ") +
7052 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7056 col = configView->
findCol(
"VersionAliasUID");
7058 tableName.substr(0, tableName.rfind(
"Table")) + tableAlias, row, col);
7060 configView->
setValue(tableAlias, row, col2);
7061 configView->
setValue(tableName, row, col3);
7064 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
7066 col = configView->
findCol(
"Version");
7067 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs "
7068 << configView->getDataView()[row][col] << __E__;
7069 if(version.
toString() != configView->getDataView()[row][col])
7078 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7082 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7087 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << __E__;
7090 table->eraseView(temporaryVersion);
7097 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
7113 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7117 table->eraseView(temporaryVersion);
7118 newAssignedVersion = activeVersions[versionAliasesTableName];
7120 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7121 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7124 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
7126 catch(std::runtime_error& e)
7128 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7129 __SUP_COUT_ERR__ << ss.str();
7130 xmlOut.addTextElementToData(
"Error", ss.str());
7134 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7139 catch(
const std::exception& e)
7141 ss <<
"Exception message: " << e.what();
7146 __SUP_COUT_ERR__ << ss.str();
7147 xmlOut.addTextElementToData(
"Error", ss.str());
7156 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(
7159 const std::string& versionAlias,
7160 const std::string& groupName,
7162 const std::string& author)
7166 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7168 const std::string versionAliasesTableName =
7169 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7170 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7172 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
7174 xmlOut.addTextElementToData(
"Error", ss.str());
7179 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
7180 for(
auto& memberName : backboneMembers)
7182 __SUP_COUT__ <<
"activeVersions[\"" << memberName
7183 <<
"\"]=" << activeVersions[memberName] << __E__;
7185 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7186 xmlOut.addTextElementToData(
"oldBackboneVersion",
7187 activeVersions[memberName].toString());
7198 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7203 bool isDifferent =
false;
7222 xmlOut.addTextElementToData(
7225 "\" can not be retrieved!");
7230 unsigned int col2 = configView->
findCol(
"VersionAlias");
7231 unsigned int col3 = configView->
findCol(
"TableName");
7233 for(
auto& memberPair : memberMap)
7235 bool thisMemberIsDifferent =
false;
7236 unsigned int row = -1;
7238 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
"_v"
7239 << memberPair.second <<
" to " << versionAlias << __E__;
7245 unsigned int tmpRow = -1;
7248 tmpRow = configView->
findRow(col3, memberPair.first, tmpRow + 1);
7249 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
7256 if(row == (
unsigned int)-1)
7258 thisMemberIsDifferent =
true;
7259 row = configView->
addRow();
7262 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7264 std::string(
"Entry was added by server in ") +
7265 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7271 memberPair.first.substr(0, memberPair.first.rfind(
"Table")) +
7276 configView->
setValue(versionAlias, row, col2);
7277 configView->
setValue(memberPair.first, row, col3);
7280 col = configView->
findCol(
"Version");
7282 if(memberPair.second.toString() != configView->getDataView()[row][col])
7284 configView->
setValue(memberPair.second.toString(), row, col);
7285 thisMemberIsDifferent =
true;
7288 if(thisMemberIsDifferent)
7291 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7295 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7298 if(thisMemberIsDifferent)
7307 __SUP_COUT__ <<
"\t\t**************************** Save v" << temporaryVersion
7308 <<
" as new table version" << __E__;
7310 newAssignedVersion =
7311 cfgMgr->
saveNewTable(versionAliasesTableName, temporaryVersion);
7315 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7319 table->eraseView(temporaryVersion);
7320 newAssignedVersion = activeVersions[versionAliasesTableName];
7323 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7324 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7325 __SUP_COUT__ <<
"\t\t Resulting Version: " << newAssignedVersion << __E__;
7327 catch(std::runtime_error& e)
7329 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7330 __SUP_COUT_ERR__ << ss.str();
7331 xmlOut.addTextElementToData(
"Error", ss.str());
7335 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7340 catch(
const std::exception& e)
7342 ss <<
"Exception message: " << e.what();
7347 __SUP_COUT_ERR__ << ss.str();
7348 xmlOut.addTextElementToData(
"Error", ss.str());
7362 void ConfigurationGUISupervisor::handleGroupAliasesXML(
HttpXmlDocument& xmlOut,
7366 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7368 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
7369 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
7371 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! "
7372 << groupAliasesTableName
7373 <<
" is a required member of the Backbone table group."
7374 <<
"\n\nLikely you need to activate a valid Backbone table group."
7376 __SUP_COUT__ << ss.str();
7381 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName
7382 <<
"\"]=" << activeVersions[groupAliasesTableName] << __E__;
7383 xmlOut.addTextElementToData(
"GroupAliasesTableName", groupAliasesTableName);
7384 xmlOut.addTextElementToData(
"GroupAliasesTableVersion",
7385 activeVersions[groupAliasesTableName].toString());
7387 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7392 <<
" ==> " << numOfThreads <<
" threads for alias group loads." << __E__;
7394 if(numOfThreads < 2)
7396 std::string groupName, groupKey, groupComment, groupAuthor, groupCreateTime,
7398 for(
auto& aliasNodePair : aliasNodePairs)
7400 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7401 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7403 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7404 xmlOut.addTextElementToData(
"GroupName", groupName);
7405 xmlOut.addTextElementToData(
"GroupKey", groupKey);
7406 xmlOut.addTextElementToData(
7408 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7409 .getValueAsString());
7413 ConfigurationManager::UNKNOWN_INFO;
7414 groupType = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7431 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7432 << groupKey <<
")' to extract group comment and type."
7435 xmlOut.addTextElementToData(
"GroupComment", groupComment);
7436 xmlOut.addTextElementToData(
"GroupType", groupType);
7441 int threadsLaunched = 0;
7442 int foundThreadIndex = 0;
7443 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
7444 for(
int i = 0; i < numOfThreads; ++i)
7445 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
7447 std::vector<std::shared_ptr<ots::GroupInfo>> sharedGroupInfoPtrs;
7448 std::string groupName, groupKey;
7450 for(
auto& aliasNodePair : aliasNodePairs)
7453 sharedGroupInfoPtrs.push_back(std::make_shared<ots::GroupInfo>());
7455 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7456 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7458 if(threadsLaunched >= numOfThreads)
7461 foundThreadIndex = -1;
7462 while(foundThreadIndex == -1)
7464 for(
int i = 0; i < numOfThreads; ++i)
7465 if(*(threadDone[i]))
7467 foundThreadIndex = i;
7470 if(foundThreadIndex == -1)
7472 __SUP_COUTT__ <<
"Waiting for available thread..." << __E__;
7476 threadsLaunched = numOfThreads - 1;
7478 __SUP_COUTT__ <<
"Starting load group thread... " << groupName <<
"("
7479 << groupKey <<
")" << __E__;
7480 *(threadDone[foundThreadIndex]) =
false;
7484 std::string theGroupName,
7486 std::shared_ptr<ots::GroupInfo> theGroupInfo,
7487 std::shared_ptr<std::atomic<bool>> theThreadDone) {
7497 sharedGroupInfoPtrs.back(),
7498 threadDone[foundThreadIndex])
7509 foundThreadIndex = -1;
7510 for(
int i = 0; i < numOfThreads; ++i)
7511 if(!*(threadDone[i]))
7513 foundThreadIndex = i;
7516 if(foundThreadIndex != -1)
7518 __SUP_COUTT__ <<
"Waiting for thread to finish... " << foundThreadIndex
7522 }
while(foundThreadIndex != -1);
7526 for(
auto& aliasNodePair : aliasNodePairs)
7528 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7529 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7531 if(groupKey != sharedGroupInfoPtrs[i]->getLatestKey().toString())
7533 __SUP_SS__ <<
"Error loading group information for the group alias '"
7534 << aliasNodePair.first <<
"' mapping to group '" << groupName
7535 <<
"(" << groupKey <<
")" << __E__;
7539 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7540 xmlOut.addTextElementToData(
"GroupName", groupName);
7541 xmlOut.addTextElementToData(
7542 "GroupKey", sharedGroupInfoPtrs[i]->getLatestKey().toString());
7543 xmlOut.addTextElementToData(
7545 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7546 .getValueAsString());
7548 xmlOut.addTextElementToData(
7549 "GroupComment", sharedGroupInfoPtrs[i]->getLatestKeyGroupComment());
7550 xmlOut.addTextElementToData(
7551 "GroupAuthor", sharedGroupInfoPtrs[i]->getLatestKeyGroupAuthor());
7552 xmlOut.addTextElementToData(
7553 "GroupCreationTime",
7554 sharedGroupInfoPtrs[i]->getLatestKeyGroupCreationTime());
7555 xmlOut.addTextElementToData(
7556 "GroupType", sharedGroupInfoPtrs[i]->getLatestKeyGroupTypeString());
7575 void ConfigurationGUISupervisor::handleVersionAliasesXML(
HttpXmlDocument& xmlOut,
7579 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7581 std::string versionAliasesTableName =
7582 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7583 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7585 __SUP_SS__ <<
"Active version of VersionAliases missing!"
7586 <<
"Make sure you have a valid active Backbone Group." << __E__;
7587 xmlOut.addTextElementToData(
"Error", ss.str());
7590 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName
7591 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
7592 xmlOut.addTextElementToData(
"VersionAliasesVersion",
7593 activeVersions[versionAliasesTableName].toString());
7595 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7598 for(
auto& aliasNodePair : aliasNodePairs)
7602 xmlOut.addTextElementToData(
7604 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
7605 xmlOut.addTextElementToData(
7606 "TableName", aliasNodePair.second.getNode(
"TableName").getValueAsString());
7607 xmlOut.addTextElementToData(
7608 "Version", aliasNodePair.second.getNode(
"Version").getValueAsString());
7609 xmlOut.addTextElementToData(
7611 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7612 .getValueAsString());
7622 void ConfigurationGUISupervisor::handleGetTableGroupTypeXML(
7626 std::string name, versionStr;
7627 auto c = tableList.find(
',', 0);
7630 while(c < tableList.length())
7633 name = tableList.substr(i, c - i);
7635 c = tableList.find(
',', i);
7636 if(c == std::string::npos)
7638 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
7639 __SUP_COUT_ERR__ <<
"\n" << ss.str();
7640 xmlOut.addTextElementToData(
"Error", ss.str());
7644 versionStr = tableList.substr(i, c - i);
7646 c = tableList.find(
',', i);
7651 std::string groupTypeString =
"";
7657 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7659 catch(std::runtime_error& e)
7661 __SUP_SS__ <<
"Table group has invalid type! " << e.what() << __E__;
7662 __SUP_COUT__ <<
"\n" << ss.str();
7663 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7664 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7668 __SUP_SS__ <<
"Table group has invalid type! " << __E__;
7673 catch(
const std::exception& e)
7675 ss <<
"Exception message: " << e.what();
7680 __SUP_COUT__ <<
"\n" << ss.str();
7681 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7682 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7702 void ConfigurationGUISupervisor::handleTableGroupsXML(
HttpXmlDocument& xmlOut,
7706 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7712 if(!cfgMgr->getAllGroupInfo().size() ||
7713 cfgMgr->getAllGroupInfo().begin()->second.getLatestKeyGroupTypeString() ==
"" ||
7714 cfgMgr->getAllGroupInfo().begin()->second.getLatestKeyGroupTypeString() ==
7715 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN ||
7717 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE) !=
7718 TableGroupKey::INVALID &&
7719 cfgMgr->getAllGroupInfo().find(cfgMgr->getActiveGroupName(
7720 ConfigurationManager::GroupType::CONTEXT_TYPE)) !=
7721 cfgMgr->getAllGroupInfo().end() &&
7722 (cfgMgr->getAllGroupInfo()
7723 .at(cfgMgr->getActiveGroupName(
7724 ConfigurationManager::GroupType::CONTEXT_TYPE))
7725 .getLatestKeyGroupTypeString() ==
"" ||
7726 cfgMgr->getAllGroupInfo()
7727 .at(cfgMgr->getActiveGroupName(
7728 ConfigurationManager::GroupType::CONTEXT_TYPE))
7729 .getLatestKeyGroupTypeString() ==
7730 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)) ||
7732 cfgMgr->getActiveGroupKey(
7733 ConfigurationManager::GroupType::CONFIGURATION_TYPE) !=
7734 TableGroupKey::INVALID &&
7735 cfgMgr->getAllGroupInfo().find(cfgMgr->getActiveGroupName(
7736 ConfigurationManager::GroupType::CONFIGURATION_TYPE)) !=
7737 cfgMgr->getAllGroupInfo().end() &&
7738 (cfgMgr->getAllGroupInfo()
7739 .at(cfgMgr->getActiveGroupName(
7740 ConfigurationManager::GroupType::CONFIGURATION_TYPE))
7741 .getLatestKeyGroupTypeString() ==
"" ||
7742 cfgMgr->getAllGroupInfo()
7743 .at(cfgMgr->getActiveGroupName(
7744 ConfigurationManager::GroupType::CONFIGURATION_TYPE))
7745 .getLatestKeyGroupTypeString() ==
7746 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)))
7749 <<
"Group Info cache appears empty or stale. Attempting to regenerate..."
7759 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
7761 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7763 std::string groupName;
7764 std::string groupString, groupTypeString, groupComment, groupCreationTime,
7766 for(
auto& groupInfo : allGroupInfo)
7768 groupName = groupInfo.first;
7773 if(groupInfo.second.getKeys().size() == 0)
7775 __SUP_COUT__ <<
"Group name '" << groupName
7776 <<
"' found, but no keys so ignoring." << __E__;
7780 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7781 xmlOut.dataSs_ <<
"<TableGroupKey value='" << groupInfo.second.getLatestKey()
7785 xmlOut.dataSs_ <<
"<TableGroupType value='"
7786 << groupInfo.second.getLatestKeyGroupTypeString() <<
"'/>"
7788 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7790 groupInfo.second.getLatestKeyGroupComment(),
7793 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7794 << groupInfo.second.getLatestKeyGroupAuthor() <<
"'/>" << __E__;
7795 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7796 << groupInfo.second.getLatestKeyGroupCreationTime() <<
"'/>"
7802 xmlOut.dataSs_ <<
"<TableGroupMembers value=''>" << __E__;
7804 for(
auto& memberPair : groupInfo.second.getLatestKeyMemberMap())
7806 xmlOut.dataSs_ <<
"\t<MemberName value='" << memberPair.first <<
"'/>"
7808 xmlOut.dataSs_ <<
"\t<MemberVersion value='" << memberPair.second <<
"'/>"
7815 xmlOut.dataSs_ <<
"</TableGroupMembers>" << __E__;
7820 for(
auto& keyInSet : groupInfo.second.getKeys())
7822 if(keyInSet == groupInfo.second.getLatestKey())
7825 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7826 xmlOut.dataSs_ <<
"<TableGroupKey value='" << keyInSet <<
"'/>" << __E__;
7831 bool loadingHistoricalInfo =
false;
7832 if(loadingHistoricalInfo)
7851 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7852 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7854 <<
")' to extract group comment and type." << __E__;
7857 xmlOut.dataSs_ <<
"<TableGroupType value='" << groupTypeString <<
"'/>"
7859 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7863 xmlOut.dataSs_ <<
"<TableGroupAuthor value='" << groupAuthor <<
"'/>"
7865 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='" << groupCreationTime
7875 xmlOut.dataSs_ <<
"<TableGroupType value='"
7876 << groupInfo.second.getLatestKeyGroupTypeString() <<
"'/>"
7879 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7882 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7885 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7893 xmlOut.dataSs_ <<
"<TableGroupMembers/>" << __E__;
7898 __SUP_COUTT__ << groupName <<
" runtime=" << cfgMgr->runTimeSeconds() << __E__;
7900 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7915 void ConfigurationGUISupervisor::handleTablesXML(
HttpXmlDocument& xmlOut,
7918 if(cfgMgr->getAllGroupInfo().size() == 0 || cfgMgr->
getActiveVersions().size() == 0)
7920 __SUP_COUT__ <<
"Table Info cache appears empty. Attempting to regenerate."
7930 xercesc::DOMElement* parentEl;
7931 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
7934 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
7935 for(
const auto& tablePair : allTableInfo)
7936 orderedTableSet.emplace(tablePair.first);
7940 __SUP_COUT__ <<
"# of tables found: " << allTableInfo.size() << __E__;
7942 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
7945 __SUP_COUT__ <<
"# of tables w/aliases: " << versionAliases.size() << __E__;
7947 for(
const auto& orderedTableName : orderedTableSet)
7950 std::map<std::string, TableInfo>::const_iterator it =
7951 allTableInfo.find(orderedTableName);
7952 if(it == allTableInfo.end())
7954 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
7963 xmlOut.addTextElementToData(
"TableName", it->first);
7964 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
7967 if(versionAliases.find(it->first) != versionAliases.end())
7968 for(
auto& aliasVersion : versionAliases[it->first])
7969 if(it->second.versions_.find(aliasVersion.second) !=
7970 it->second.versions_
7974 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
7982 auto vSpanToXML = [](
auto const& sortedKeys,
auto& xmlOut,
auto& configEl) {
7984 size_t lo = -1, hi = -1;
7985 for(
auto& keyInOrder : sortedKeys)
7988 if(keyInOrder.isScratchVersion())
7991 if(lo ==
size_t(-1))
7993 hi = lo = keyInOrder.
version();
7996 else if(hi + 1 == keyInOrder.version())
8004 xmlOut.addNumberElementToParent(
"Version", lo, configEl);
8006 xmlOut.addTextElementToParent(
8008 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
8010 hi = lo = keyInOrder.
version();
8013 if(lo !=
size_t(-1))
8016 xmlOut.addNumberElementToParent(
"Version", lo, configEl);
8018 xmlOut.addTextElementToParent(
8020 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
8025 vSpanToXML(it->second.versions_, xmlOut, parentEl);
8038 void ConfigurationGUISupervisor::handleGetArtdaqNodeRecordsXML(
8041 const std::string& modifiedTables)
8043 __COUT__ <<
"Retrieving artdaq nodes..." << __E__;
8046 setupActiveTablesXML(
8047 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
8049 std::map<std::string ,
8050 std::map<std::string , std::vector<std::string >>>
8051 nodeTypeToObjectMap;
8052 std::map<std::string , std::string >
8055 std::vector<std::string > artdaqSupervisorInfo;
8057 std::string artdaqSupervisorName;
8059 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap, artdaqSupervisorInfo);
8061 if(artdaqSupervisorInfo.size() != 4 )
8063 __SUP_COUT__ <<
"No artdaq supervisor found." << __E__;
8067 __SUP_COUT__ <<
"========== "
8068 <<
"Found " << info.subsystems.size() <<
" subsystems." << __E__;
8070 unsigned int paramIndex = 0;
8072 auto parentEl = xmlOut.addTextElementToData(
"artdaqSupervisor",
8073 artdaqSupervisorInfo[paramIndex++]);
8075 std::string typeString =
"artdaqSupervisor";
8078 typeString +
"-status", artdaqSupervisorInfo[paramIndex++], parentEl);
8080 typeString +
"-contextAddress", artdaqSupervisorInfo[paramIndex++], parentEl);
8082 typeString +
"-contextPort", artdaqSupervisorInfo[paramIndex++], parentEl);
8084 for(
auto& subsystem : info.subsystems)
8086 typeString =
"subsystem";
8088 __SUP_COUT__ <<
"\t\t"
8089 <<
"Found " << typeString <<
" " << subsystem.first <<
" \t := '"
8090 << subsystem.second.label <<
"'" << __E__;
8094 typeString +
"-id", std::to_string(subsystem.first), parentEl);
8097 std::to_string(subsystem.second.sources.size()),
8102 std::to_string(subsystem.second.destination),
8107 __SUP_COUT__ <<
"========== "
8108 <<
"Found " << nodeTypeToObjectMap.size() <<
" process types." << __E__;
8110 for(
auto& nameTypePair : nodeTypeToObjectMap)
8112 typeString = nameTypePair.first;
8114 __SUP_COUT__ <<
"\t"
8115 <<
"Found " << nameTypePair.second.size() <<
" " << typeString
8118 for(
auto& artdaqNode : nameTypePair.second)
8120 __SUP_COUT__ <<
"\t\t"
8121 <<
"Found '" << artdaqNode.first <<
"' " << typeString << __E__;
8124 if(artdaqNode.second.size() < 2)
8126 __SUP_SS__ <<
"Impossible parameter size for node '" << artdaqNode.first
8127 <<
"' " << typeString <<
" - please notify admins!" << __E__;
8135 if(artdaqNode.second.size() > paramIndex)
8137 __SUP_COUTT__ <<
"\t\t\t"
8138 <<
"-multinode: " << artdaqNode.second[paramIndex] << __E__;
8140 typeString +
"-multinode", artdaqNode.second[paramIndex++], nodeEl);
8142 if(artdaqNode.second.size() > paramIndex)
8144 __SUP_COUTT__ <<
"\t\t\t"
8145 <<
"-nodefixedwidth: " << artdaqNode.second[paramIndex]
8148 artdaqNode.second[paramIndex++],
8151 if(artdaqNode.second.size() > paramIndex)
8153 __SUP_COUTT__ <<
"\t\t\t"
8154 <<
"-hostarray: " << artdaqNode.second[paramIndex] << __E__;
8156 typeString +
"-hostarray", artdaqNode.second[paramIndex++], nodeEl);
8158 if(artdaqNode.second.size() > paramIndex)
8160 __SUP_COUTT__ <<
"\t\t\t"
8161 <<
"-hostfixedwidth: " << artdaqNode.second[paramIndex]
8164 artdaqNode.second[paramIndex++],
8169 __SUP_COUTT__ <<
"\t\t\t"
8170 <<
"-status: " << artdaqNode.second[paramIndex] << __E__;
8172 typeString +
"-status", artdaqNode.second[paramIndex++], parentEl);
8173 __SUP_COUTT__ <<
"\t\t\t"
8174 <<
"-hostname: " << artdaqNode.second[paramIndex] << __E__;
8176 typeString +
"-hostname", artdaqNode.second[paramIndex++], parentEl);
8177 __SUP_COUTT__ <<
"\t\t\t"
8178 <<
"-subsystem: " << artdaqNode.second[paramIndex] << __E__;
8180 typeString +
"-subsystem", artdaqNode.second[paramIndex], parentEl);
8184 __SUP_COUT__ <<
"Done retrieving artdaq nodes." << __E__;
8195 void ConfigurationGUISupervisor::handleSaveArtdaqNodeRecordsXML(
8196 const std::string& nodeString,
8197 const std::string& subsystemString,
8200 const std::string& modifiedTables)
8202 __SUP_COUT__ <<
"Saving artdaq nodes..." << __E__;
8205 setupActiveTablesXML(
8206 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
8209 std::map<std::string ,
8210 std::map<std::string , std::vector<std::string >>>
8211 nodeTypeToObjectMap;
8217 std::map<std::string , std::string >
8218 nodeTypeToStringMap;
8223 for(
auto& typePair : nodeTypeToStringMap)
8225 if(typePair.first ==
"")
8230 nodeTypeToObjectMap.emplace(
8232 std::map<std::string ,
8233 std::vector<std::string /*property*/>>()));
8235 std::map<std::string , std::string >
8236 nodeRecordToStringMap;
8239 typePair.second, nodeRecordToStringMap, {
';'}, {
'='});
8243 for(
auto& nodePair : nodeRecordToStringMap)
8245 if(nodePair.first ==
"")
8250 std::vector<std::string > nodePropertyVector;
8253 nodePair.second, nodePropertyVector, {
','});
8258 for(
unsigned int i = 0; i < nodePropertyVector.size(); ++i)
8263 nodePropertyVector[i] =
8267 nodeTypeToObjectMap[typePair.first].emplace(
8269 nodePropertyVector));
8275 std::map<std::string , std::string >
8282 std::map<std::string , std::string >
8283 tmpSubsystemObjectMap;
8285 subsystemString, tmpSubsystemObjectMap, {
';'}, {
':'});
8290 for(
auto& subsystemPair : tmpSubsystemObjectMap)
8295 subsystemObjectMap.emplace(
8302 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap);
8304 __SUP_COUT__ <<
"Done saving artdaq nodes." << __E__;
8314 void ConfigurationGUISupervisor::handleLoadArtdaqNodeLayoutXML(
8318 const std::string& contextGroupName ,
8321 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
8324 const std::string& finalContextGroupName =
8326 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8330 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8332 const std::string& finalConfigGroupName =
8333 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8335 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8340 std::stringstream layoutPath;
8341 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8342 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
8343 << finalConfigGroupKey <<
".dat";
8345 fp = fopen(layoutPath.str().c_str(),
"r");
8348 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8349 << finalContextGroupKey <<
") + " << finalConfigGroupName <<
"("
8350 << finalConfigGroupKey <<
")': " << layoutPath.
str() << __E__;
8354 __SUP_COUTV__(layoutPath.str());
8359 std::stringstream layoutPath;
8360 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8361 <<
"_" << finalContextGroupKey <<
".dat";
8362 __SUP_COUTV__(layoutPath.str());
8364 fp = fopen(layoutPath.str().c_str(),
"r");
8367 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8368 << finalContextGroupKey <<
")': " << layoutPath.str() << __E__;
8372 __SUP_COUTV__(layoutPath.str());
8379 const size_t maxLineSz = 1000;
8380 char line[maxLineSz];
8381 if(!fgets(line, maxLineSz, fp))
8390 unsigned int rows, cols;
8392 sscanf(line,
"%u %u", &rows, &cols);
8394 __COUT__ <<
"Grid rows,cols = " << rows <<
"," << cols << __E__;
8396 xmlOut.addTextElementToData(
"grid-rows", std::to_string(rows));
8397 xmlOut.addTextElementToData(
"grid-cols", std::to_string(cols));
8400 char name[maxLineSz];
8401 char type[maxLineSz];
8403 while(fgets(line, maxLineSz, fp))
8406 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
8408 xmlOut.addTextElementToData(
"node-type", type);
8409 xmlOut.addTextElementToData(
"node-name", name);
8410 xmlOut.addTextElementToData(
"node-x", std::to_string(x));
8411 xmlOut.addTextElementToData(
"node-y", std::to_string(y));
8425 void ConfigurationGUISupervisor::handleSaveArtdaqNodeLayoutXML(
8428 const std::string& layoutString,
8429 const std::string& contextGroupName,
8432 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
8434 const std::string& finalContextGroupName =
8436 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8440 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8442 const std::string& finalConfigGroupName =
8443 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8445 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8447 __SUP_COUTV__(layoutString);
8449 std::stringstream layoutPath;
8450 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8451 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
8452 << finalConfigGroupKey <<
".dat";
8453 __SUP_COUTV__(layoutPath.str());
8458 if(fields.size() < 2 || (fields.size() - 2) % 4 != 0)
8460 __SUP_SS__ <<
"Invalid layout string fields size of " << fields.size() << __E__;
8464 FILE* fp = fopen(layoutPath.str().c_str(),
"w");
8467 __SUP_SS__ <<
"Could not open layout file for writing for '"
8468 << finalContextGroupName <<
"(" << finalContextGroupKey <<
") + "
8469 << finalConfigGroupName <<
"(" << finalConfigGroupKey
8470 <<
")': " << layoutPath.
str() << __E__;
8477 fprintf(fp,
"%s %s\n", fields[0].c_str(), fields[1].c_str());
8480 for(
unsigned int i = 2; i < fields.size(); i += 4)
8483 fields[i + 0].c_str(),
8484 fields[i + 1].c_str(),
8485 fields[i + 2].c_str(),
8486 fields[i + 3].c_str());
8494 void ConfigurationGUISupervisor::handleOtherSubsystemActiveGroups(
8498 std::string targetSubsystem )
8504 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8507 for(
auto subsystem : children)
8509 __SUP_COUTV__(subsystem.first);
8513 std::string userPath =
8514 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8515 __SUP_COUTV__(userPath);
8518 catch(
const std::runtime_error& e)
8520 __SUP_COUT__ <<
"Ignoring errors in handling other subsystem active groups "
8521 "(assuming the subsystem information map is not setup in "
8522 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8523 <<
") -- here is the error: \n"
8524 << e.what() << __E__;
8531 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8533 for(
auto subsystem : children)
8535 if(targetSubsystem !=
"" && targetSubsystem != subsystem.first)
8538 xercesc::DOMElement* parent =
8539 xmlOut.addTextElementToData(
"SubsystemName", subsystem.first);
8544 std::string filename, userDataPath;
8545 std::string username, hostname;
8547 std::map<std::string ,
8549 retMap = cfgMgr->getOtherSubsystemActiveTableGroups(
8550 subsystem.first, &userDataPath, &hostname, &username);
8552 for(
const auto& retPair : retMap)
8555 retPair.second.first,
8558 retPair.second.second.toString(),
8562 std::vector<std::string> filenameTypes = {
"Configured",
8566 "ActivatedBackbone",
8567 "ActivatedIterator"};
8569 std::vector<std::string> filenames = {
8570 ConfigurationManager::LAST_CONFIGURED_CONFIG_GROUP_FILE,
8571 ConfigurationManager::LAST_STARTED_CONFIG_GROUP_FILE,
8572 ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE,
8573 ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE,
8574 ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE,
8575 ConfigurationManager::LAST_ACTIVATED_ITERATE_GROUP_FILE};
8577 std::string userPath =
8578 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8580 std::string cmdResult;
8581 for(
unsigned int i = 0; i < filenames.size(); ++i)
8583 filename = userDataPath +
"/ServiceData/RunControlData/" + filenames[i];
8584 __SUP_COUTV__(filename);
8586 std::string tmpSubsystemFilename =
8587 ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" + filenames[i] +
8588 "." + subsystem.first;
8589 __SUP_COUTV__(tmpSubsystemFilename);
8591 if(splitPath.size() == 2)
8595 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + username +
8596 "@" + hostname +
":" + filename +
" " + tmpSubsystemFilename +
8597 " 2>&1; cat " + tmpSubsystemFilename +
" 2>&1")
8601 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + hostname +
8602 ":" + filename +
" " + tmpSubsystemFilename +
" 2>&1; cat " +
8603 tmpSubsystemFilename +
" 2>&1")
8606 else if(splitPath.size() == 1)
8609 " 2>/dev/null; cp " + filename +
" " +
8610 tmpSubsystemFilename +
" 2>&1; cat " +
8611 tmpSubsystemFilename +
" 2>&1")
8615 __SUP_COUTV__(cmdResult);
8616 std::string timeString;
8619 filenames[i] +
"." + subsystem.first, timeString);
8623 "Last" + filenameTypes[i] +
"GroupName", theGroup.first, parent);
8625 theGroup.second.toString(),
8628 "Last" + filenameTypes[i] +
"GroupTime", timeString, parent);
8633 catch(
const std::runtime_error& e)
8636 <<
"An error occurred handling subsystem active groups (Please check the "
8637 "subsystem user data path information map setup in the Context group table "
8638 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8639 <<
") -- here is the error: \n"
8640 << e.what() << __E__;
8646 void ConfigurationGUISupervisor::handleGroupDiff(
8649 const std::string& groupName,
8652 const std::string& diffGroupNameInput )
8658 std::string diffGroupName;
8661 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8662 <<
") with the active group." << __E__;
8665 if(diffGroupNameInput ==
"")
8666 diffGroupName = groupName;
8668 diffGroupName = diffGroupNameInput;
8670 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8671 <<
") with group " << diffGroupName <<
"(" << diffKey <<
")"
8677 std::map<std::string ,
TableVersion > memberMap, diffMemberMap;
8678 std::string groupType, accumulateErrors;
8679 std::stringstream diffReport;
8680 bool noDifference =
true;
8699 std::map<std::string , std::pair<std::string, TableGroupKey>>
8706 __SUP_COUTV__(groupType);
8708 if(activeGroups.find(groupType) == activeGroups.end() ||
8709 activeGroups.at(groupType).first ==
"" ||
8710 activeGroups.at(groupType).second.isInvalid())
8712 __SUP_SS__ <<
"Could not find an active group of type '" << groupType
8713 <<
".' Please check the expected active configuration groups "
8714 "for errors (going to 'System View' of the Config App may "
8720 __SUP_COUT__ <<
"active " << groupType <<
" group is "
8721 << activeGroups.at(groupType).first <<
"("
8722 << activeGroups.at(groupType).second <<
")" << __E__;
8724 diffReport <<
"This difference report is between " << groupType
8725 <<
" group <b>'" << groupName <<
"(" << groupKey <<
")'</b>"
8726 <<
" and active group <b>'" << activeGroups.at(groupType).first
8727 <<
"(" << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8730 activeGroups.at(groupType).second,
8740 diffReport <<
"\n\n"
8741 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8742 << memberMap.size() <<
" member tables</b>, and "
8743 <<
"'" << activeGroups.at(groupType).first <<
"("
8744 << activeGroups.at(groupType).second <<
")' has <b>"
8745 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8749 diffReport <<
"This difference report is between group <b>'" << groupName
8750 <<
"(" << groupKey <<
")'</b>"
8751 <<
" and group <b>'" << diffGroupName <<
"(" << diffKey
8752 <<
")'</b>." << __E__;
8765 diffReport <<
"\n\n"
8766 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8767 << memberMap.size() <<
" member tables</b>, and "
8768 <<
"'" << diffGroupName <<
"(" << diffKey <<
")' has <b>"
8769 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8774 diffReport <<
"<INDENT><ol>";
8776 unsigned int tableDifferences = 0;
8778 for(
auto& member : memberMap)
8780 if(diffMemberMap.find(member.first) == diffMemberMap.end())
8782 diffReport <<
"\n\n<li>"
8783 <<
"Table <b>" << member.first <<
"-v" << member.second
8784 <<
"</b> not found in active group."
8785 <<
"</li>" << __E__;
8786 noDifference =
false;
8791 __SUP_COUTT__ <<
"Comparing " << member.first <<
"-v" << member.second
8792 <<
" ... " << member.first <<
"-v"
8793 << diffMemberMap.at(member.first) << __E__;
8795 if(member.second == diffMemberMap.at(member.first))
8798 diffReport <<
"\n\n<li>"
8799 <<
"Table <b>" << member.first <<
" v" << member.second
8800 <<
"</b> in " << groupName <<
"(" << groupKey <<
")' ...vs... "
8801 <<
" <b>v" << diffMemberMap.at(member.first) <<
"</b> in "
8802 << diffGroupName <<
"(" << diffKey <<
")':" << __E__;
8806 diffReport <<
"<ul>";
8807 std::map<std::string , std::vector<std::string >>
8810 diffMemberMap.at(member.first),
8815 noDifference =
false;
8818 xmlOut.addTextElementToData(
"TableWithDiff", member.first);
8819 for(
auto& modifiedRecord : modifiedRecords)
8822 "RecordWithDiff", modifiedRecord.first, parentEl);
8823 for(
auto& modifiedColumn : modifiedRecord.second)
8825 "ColNameWithDiff", modifiedColumn, recordParentEl);
8828 diffReport <<
"</ul></li>";
8832 for(
auto& diffMember : diffMemberMap)
8834 if(memberMap.find(diffMember.first) == memberMap.end())
8837 diffReport <<
"\n\n<li>"
8838 <<
"Active Group Table <b>" << diffMember.first <<
"-v"
8839 << diffMember.second <<
"</b> not found in '" << groupName
8840 <<
"(" << groupKey <<
")'."
8841 <<
"</li>" << __E__;
8843 diffReport <<
"\n\n<li>" << diffGroupName <<
"(" << diffKey
8844 <<
") Table <b>" << diffMember.first <<
"-v"
8845 << diffMember.second <<
"</b> not found in '" << groupName
8846 <<
"(" << groupKey <<
")'."
8847 <<
"</li>" << __E__;
8849 noDifference =
false;
8854 diffReport <<
"\n</ol></INDENT>";
8859 diffReport <<
"\n\nNo difference found between "
8860 <<
"<b>'" << groupName <<
"(" << groupKey
8861 <<
")'</b> and active group "
8862 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8863 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8865 diffReport <<
"\n\n<b>" << tableDifferences
8866 <<
"</b> member table differences identified between "
8867 <<
"<b>'" << groupName <<
"(" << groupKey
8868 <<
")'</b> and active group "
8869 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8870 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8875 diffReport <<
"\n\nNo difference found between "
8876 <<
"<b>'" << groupName <<
"(" << groupKey
8877 <<
")'</b> and group "
8878 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8881 diffReport <<
"\n\n<b>" << tableDifferences
8882 <<
"</b> member table differences identified between "
8883 <<
"<b>'" << groupName <<
"(" << groupKey
8884 <<
")'</b> and group "
8885 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8889 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
8890 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
8892 catch(
const std::runtime_error& e)
8894 __SUP_COUT_ERR__ <<
"Caught error while differencing group " << groupName <<
"("
8895 << groupKey <<
") with group " << diffGroupName <<
"(" << diffKey
8896 <<
")" << __E__ << e.what() << __E__;
8903 void ConfigurationGUISupervisor::handleTableDiff(
HttpXmlDocument& xmlOut,
8905 const std::string& tableName,
8909 __SUP_COUT__ <<
"Differencing tableName " << tableName <<
" v" << vA <<
" with v"
8919 std::string localAccumulatedErrors =
"";
8923 &localAccumulatedErrors,
8926 if(localAccumulatedErrors !=
"")
8927 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8929 catch(std::runtime_error& e)
8931 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vA;
8932 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8933 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8935 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8939 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vA << __E__;
8944 catch(
const std::exception& e)
8946 ss <<
"Exception message: " << e.what();
8952 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8953 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8959 std::string localAccumulatedErrors =
"";
8963 &localAccumulatedErrors,
8966 if(localAccumulatedErrors !=
"")
8967 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8969 catch(std::runtime_error& e)
8971 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vB;
8972 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8973 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8975 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8979 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vB << __E__;
8984 catch(
const std::exception& e)
8986 ss <<
"Exception message: " << e.what();
8992 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8993 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8996 bool noDifference =
true;
8997 std::stringstream diffReport;
8999 diffReport <<
"This difference report is between table " << tableName <<
" v" << vA
9000 <<
" and v" << vB <<
"</b>." << __E__;
9002 diffReport <<
"<INDENT>";
9003 diffReport <<
"<ul>";
9004 std::map<std::string , std::vector<std::string >>
9007 noDifference =
false;
9008 diffReport <<
"</ul></INDENT>";
9010 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
9011 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
9017 void ConfigurationGUISupervisor::testXDAQContext()
9021 __COUT_INFO__ <<
"Hello0!";
9023 __COUT_INFO__ <<
"Hello1!";
9025 __COUT_INFO__ <<
"Hello2!";
9027 __COUT_INFO__ <<
"Hello3!";
9033 __SUP_COUT_INFO__ <<
"Attempting test activation of the context group." << __E__;
9037 catch(
const std::runtime_error& e)
9040 <<
"The test activation of the context group failed. Ignoring error: \n"
9041 << e.what() << __E__;
9046 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring."
9051 __SUP_COUT_INFO__ <<
"Completed test activation of the context group." << __E__;
static void setAndActivateARTDAQSystem(ConfigurationManagerRW *cfgMgr, const std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, const std::map< std::string, std::string > &subsystemObjectMap)
static const ARTDAQInfo & getARTDAQSystem(ConfigurationManagerRW *cfgMgr, std::map< std::string, std::map< std::string, std::vector< std::string >>> &nodeTypeToObjectMap, std::map< std::string, std::string > &subsystemObjectMap, std::vector< std::string > &artdaqSupervisoInfo)
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
static std::string getData(cgicc::Cgicc &cgi, const std::string &needle)
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)
TableVersion saveNewTable(const std::string &tableName, TableVersion temporaryVersion=TableVersion(), bool makeTemporary=false)
void testXDAQContext(void)
const GroupInfo & getGroupInfo(const std::string &groupName, bool attemptToReloadKeys=false)
void clearAllCachedVersions(void)
const std::map< std::string, TableInfo > & getAllTableInfo(bool refresh=false, std::string *accumulatedWarnings=0, const std::string &errorFilterName="", bool getGroupKeys=false, bool getGroupInfo=false, bool initializeActiveGroups=false)
void loadTableGroup(const std::string &tableGroupName, const TableGroupKey &tableGroupKey, bool doActivate=false, std::map< std::string, TableVersion > *groupMembers=0, ProgressBar *progressBar=0, std::string *accumulateWarnings=0, std::string *groupComment=0, std::string *groupAuthor=0, std::string *groupCreateTime=0, bool doNotLoadMember=false, std::string *groupTypeString=0, std::map< std::string, std::string > *groupAliases=0, ConfigurationManager::LoadGroupType groupTypeToLoad=ConfigurationManager::LoadGroupType::ALL_TYPES, bool ignoreVersionTracking=false)
TableVersion copyViewToCurrentColumns(const std::string &tableName, TableVersion sourceVersion)
TableGroupKey saveNewTableGroup(const std::string &groupName, std::map< std::string, TableVersion > &groupMembers, const std::string &groupComment=TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT, std::map< std::string, std::string > *groupAliases=0)
void activateTableGroup(const std::string &tableGroupName, TableGroupKey tableGroupKey, std::string *accumulatedTreeErrors=0, std::string *groupTypeString=0)
void clearCachedVersions(const std::string &tableName)
const std::string & getUsername(void) const
std::map< std::string, std::map< std::string, TableVersion > > getVersionAliases(void) const
void eraseTemporaryVersion(const std::string &tableName, TableVersion targetVersion=TableVersion())
TableBase * getVersionedTableByName(const std::string &tableName, TableVersion version, bool looseColumnMatching=false, std::string *accumulatedErrors=0, bool getRawData=false)
static void loadTableGroupThread(ConfigurationManagerRW *cfgMgr, std::string groupName, ots::TableGroupKey groupKey, std::shared_ptr< ots::GroupInfo > theGroupInfo, std::shared_ptr< std::atomic< bool >> theThreadDone)
static const unsigned int PROCESSOR_COUNT
void restoreActiveTableGroups(bool throwErrors=false, const std::string &pathToActiveGroupsFile="", ConfigurationManager::LoadGroupType onlyLoadIfBackboneOrContext=ConfigurationManager::LoadGroupType::ALL_TYPES, std::string *accumulatedWarnings=0)
std::map< std::string, std::pair< std::string, TableGroupKey > > getActiveTableGroups(void) const
std::map< std::string, TableVersion > getActiveVersions(void) const
void copyTableGroupFromCache(const ConfigurationManager &cacheConfigMgr, const std::map< std::string, TableVersion > &groupMembers, const std::string &configGroupName="", const TableGroupKey &tableGroupKey=TableGroupKey(TableGroupKey::INVALID), bool doActivate=false, bool ignoreVersionTracking=false)
ConfigurationTree getNode(const std::string &nodeString, bool doNotThrowOnBrokenUIDLinks=false) const
void init(std::string *accumulatedErrors=0, bool initForWriteAccess=false, std::string *accumulatedWarnings=0)
static const std::string & getTypeNameOfGroup(const std::map< std::string, TableVersion > &memberMap)
void destroyTableGroup(const std::string &theGroup="", bool onlyDeactivate=false)
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
static std::vector< std::map< std::string, std::string > > loadGroupHistory(const std::string &groupAction, const std::string &groupType, bool formatTime=false)
TableGroupKey loadConfigurationBackbone(void)
const TableBase * getTableByName(const std::string &configurationName) const
static std::pair< std::string, TableGroupKey > loadGroupNameAndKey(const std::string &fileName, std::string &returnedTimeString)
static void getConfigurationStatusXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &username)
static void handleGetTableGroupXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &groupName, TableGroupKey groupKey, bool ignoreWarnings=false, bool cacheOnly=false)
static TableVersion saveModifiedVersionXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &tableName, TableVersion originalVersion, bool makeTemporary, TableBase *config, TableVersion temporaryModifiedVersion, bool ignoreDuplicates=false, bool lookForEquivalent=false)
static void handleCreateTableXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &tableName, TableVersion version, bool makeTemporary, const std::string &data, const int &dataOffset, const std::string &author, const std::string &comment, bool sourceTableAsIs, bool lookForEquivalent)
static void handleCreateTableGroupXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &groupName, const std::string &configList, bool allowDuplicates=false, bool ignoreWarnings=false, const std::string &groupComment="", bool lookForEquivalent=false)
bool isUIDNode(void) const
const TableVersion & getTableVersion(void) const
bool isDisconnected(void) const
const std::string & getAuthor(void) const
const std::string & getComment(void) const
std::vector< std::string > getChildrenNames(bool byPriority=false, bool onlyStatusTrue=false) const
bool isEnabled(void) const
const std::string & getTableName(void) const
const unsigned int & getFieldRow(void) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool onlyStatusTrue=false) const
const std::string & getValueName(void) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
const std::string & getChildLinkIndex(void) const
const std::string & getDisconnectedTableName(void) const
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool byPriority=false, bool onlyStatusTrue=false) const
std::vector< std::string > getFixedChoices(void) const
bool isLinkNode(void) const
std::vector< ConfigurationTree::RecordField > getCommonFields(const std::vector< std::string > &recordList, const std::vector< std::string > &fieldAcceptList, const std::vector< std::string > &fieldRejectList, unsigned int depth=-1, bool autoSelectFilterFields=false) const
bool isValueNode(void) const
std::set< std::string > getUniqueValuesForField(const std::vector< std::string > &recordList, const std::string &fieldName, std::string *fieldGroupIDChildLinkIndex=0) const
const std::string & getValueType(void) const
bool isGroupLinkNode(void) const
const std::string & getFieldTableName(void) const
const std::string & getDisconnectedLinkID(void) const
const std::string & getParentTableName(void) const
bool isUIDLinkNode(void) const
const unsigned int & getFieldColumn(void) const
const std::string & getTableName(void) const
TableVersion createTemporaryView(TableVersion sourceViewVersion=TableVersion(), TableVersion destTemporaryViewVersion=TableVersion::getNextTemporaryVersion())
bool diffTwoVersions(TableVersion v1, TableVersion v2, std::stringstream *diffReport=0, std::map< std::string, std::vector< std::string >> *v1ModifiedRecords=0) const
TableVersion mergeViews(const TableView &sourceViewA, const TableView &sourceViewB, TableVersion destinationVersion, const std::string &author, const std::string &mergeApproach, std::map< std::pair< std::string, std::string >, std::string > &uidConversionMap, std::map< std::pair< std::string, std::pair< std::string, std::string > >, std::string > &groupidConversionMap, bool fillRecordConversionMaps, bool applyRecordConversionMaps, bool generateUniqueDataColumns=false, std::stringstream *mergeRepoert=nullptr)
static std::string convertToCaps(std::string &str, bool isConfigName=false)
TableView * getTemporaryView(TableVersion temporaryVersion)
const TableVersion & getViewVersion(void) const
void print(std::ostream &out=std::cout) const
std::string toString(void) const
bool isInvalid(void) const
static std::string getFullGroupString(const std::string &groupName, const TableGroupKey &key, const std::string &preKey="_v", const std::string &postKey="")
bool isMockupVersion(void) const
std::string toString(void) const
bool isInvalid(void) const
bool isTemporaryVersion(void) const
unsigned int version(void) const
static const std::string DATATYPE_NUMBER
static std::map< std::pair< std::string, std::string >, std::string > getAllDefaultsForGUI(void)
static const std::string & getDefaultDefaultValue(const std::string &type, const std::string &dataType)
static const std::string & getMaxDefaultValue(const std::string &dataType)
static const std::string & getMinDefaultValue(const std::string &dataType)
unsigned int findRow(unsigned int col, const T &value, unsigned int offsetRow=0, bool doNotThrow=false) const
bool isEntryInGroup(const unsigned int &row, const std::string &childLinkIndex, const std::string &groupNeedle) const
void setValueAsString(const std::string &value, unsigned int row, unsigned int col)
unsigned int getColStatus(void) const
unsigned int getLinkGroupIDColumn(const std::string &childLinkIndex) const
bool removeRowFromGroup(const unsigned int &row, const unsigned int &col, const std::string &groupID, bool deleteRowIfNoGroupLeft=false)
bool getChildLink(const unsigned int &col, bool &isGroup, std::pair< unsigned int, unsigned int > &linkPair) const
void addRowToGroup(const unsigned int &row, const unsigned int &col, const std::string &groupID)
std::string getValueAsString(unsigned int row, unsigned int col, bool convertEnvironmentVariables=true) const
void getValue(T &value, unsigned int row, unsigned int col, bool doConvertEnvironmentVariables=true) const
unsigned int getColUID(void) const
bool setURIEncodedValue(const std::string &value, const unsigned int &row, const unsigned int &col, const std::string &author="")
unsigned int findCol(const std::string &name) const
void setValue(const T &value, unsigned int row, unsigned int col)
void setURIEncodedComment(const std::string &uriComment)
unsigned int addRow(const std::string &author="", unsigned char incrementUniqueData=false, const std::string &baseNameAutoUID="", unsigned int rowToAdd=(unsigned int) -1, std::string childLinkIndex="", std::string groupId="")
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
void INIT_MF(const char *name)
static std::string getTimestampString(const std::string &linuxTimeInSeconds)
static void getVectorFromString(const std::string &inputString, std::vector< std::string > &listToReturn, const std::set< char > &delimiter={',', '|', '&'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'}, std::vector< char > *listOfDelimiters=0, bool decodeURIComponents=false)
static std::string exec(const char *cmd)
static std::string setToString(const std::set< T > &setToReturn, const std::string &delimeter=", ")
static std::string escapeString(std::string inString, bool allowWhiteSpace=false)
static std::string vectorToString(const std::vector< T > &setToReturn, const std::string &delimeter=", ")
static std::string convertEnvironmentVariables(const std::string &data)
static bool isNumber(const std::string &stringToCheck)
static std::string mapToString(const std::map< std::string, T > &mapToReturn, const std::string &primaryDelimeter=", ", const std::string &secondaryDelimeter=": ")
static void getMapFromString(const std::string &inputString, std::map< S, T > &mapToReturn, const std::set< char > &pairPairDelimiter={',', '|', '&'}, const std::set< char > &nameValueDelimiter={'=', ':'}, const std::set< char > &whitespace={' ', '\t', '\n', '\r'})
static std::string decodeURIComponent(const std::string &data)