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);
238 refreshUserSession(userInfo.username_, (refresh ==
"1"));
239 __COUTTV__(userInfo.username_);
245 const std::set<TableGroupKey>& sortedKeys = groupInfo.getKeys();
246 __COUTTV__(sortedKeys.size());
249 if(requestType ==
"saveTableInfo")
251 std::string tableName =
253 std::string columnCSV =
255 std::string allowOverwrite =
257 std::string tableDescription =
259 std::string columnChoicesCSV =
262 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
263 __SUP_COUT__ <<
"columnCSV: " << columnCSV << __E__;
264 __SUP_COUT__ <<
"tableDescription: " << tableDescription << __E__;
265 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << __E__;
266 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << __E__;
268 if(!allSupervisorInfo_.isWizardMode())
270 __SUP_SS__ <<
"Improper permissions for saving table info." << __E__;
271 xmlOut.addTextElementToData(
"Error", ss.str());
274 handleSaveTableInfoXML(xmlOut,
280 allowOverwrite ==
"1");
282 else if(requestType ==
"deleteTableInfo")
284 std::string tableName =
286 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
287 handleDeleteTableInfoXML(xmlOut, cfgMgr, tableName);
289 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
290 requestType ==
"flattenToSystemAliases")
293 __SUP_COUT_WARN__ << requestType <<
" command received! " << __E__;
294 __COUT_WARN__ << requestType <<
" command received! " << __E__;
297 __SUP_COUT_INFO__ <<
"Launching " << requestType <<
"... " << __E__;
299 __SUP_COUT__ <<
"Extracting target context hostnames... " << __E__;
300 std::vector<std::string> hostnames;
303 if(requestType ==
"flattenToSystemAliases" &&
304 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
306 hostnames.push_back(__ENV__(
"OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER"));
307 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
318 auto contexts = contextTable->getContexts();
320 for(
const auto& context : contexts)
327 for(i = 0; i < context.address_.size(); ++i)
328 if(context.address_[i] ==
'/')
330 hostnames.push_back(context.address_.substr(j));
331 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
336 __SUP_SS__ <<
"The Configuration Manager could not be initialized to "
343 catch(
const std::exception& e)
345 ss <<
"Exception message: " << e.what();
351 __SUP_COUT_ERR__ <<
"\n" << ss.str();
356 if(hostnames.size() == 0)
358 __SUP_SS__ <<
"No hostnames found to launch command '" + requestType +
359 "'... Is there a valid Context group activated?"
361 __SUP_COUT_ERR__ <<
"\n" << ss.str();
363 xmlOut.addTextElementToData(
"Error", ss.str());
366 for(
const auto& hostname : hostnames)
368 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
369 "/StartOTS_action_" + hostname +
".cmd");
370 FILE* fp = fopen(fn.c_str(),
"w");
373 if(requestType ==
"gatewayLaunchOTS")
374 fprintf(fp,
"LAUNCH_OTS");
375 else if(requestType ==
"gatewayLaunchWiz")
376 fprintf(fp,
"LAUNCH_WIZ");
377 else if(requestType ==
"flattenToSystemAliases")
379 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
387 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << __E__;
390 else if(requestType ==
"versionTracking" || requestType ==
"getVersionTracking")
393 if(requestType ==
"getVersionTracking")
397 __SUP_COUT__ <<
"type: " << type << __E__;
400 xmlOut.addTextElementToData(
401 "versionTrackingStatus",
402 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
403 else if(type ==
"ON")
405 ConfigurationInterface::setVersionTrackingEnabled(
true);
406 xmlOut.addTextElementToData(
407 "versionTrackingStatus",
408 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
410 else if(type ==
"OFF")
412 ConfigurationInterface::setVersionTrackingEnabled(
false);
413 xmlOut.addTextElementToData(
414 "versionTrackingStatus",
415 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
418 else if(requestType ==
"getColumnTypes")
421 std::vector<std::string> allTypes = TableViewColumnInfo::getAllTypesForGUI();
422 std::vector<std::string> allDataTypes =
423 TableViewColumnInfo::getAllDataTypesForGUI();
424 std::map<std::pair<std::string, std::string>, std::string> allDefaults =
427 for(
const auto& type : allTypes)
428 xmlOut.addTextElementToData(
"columnTypeForGUI", type);
429 for(
const auto& dataType : allDataTypes)
430 xmlOut.addTextElementToData(
"columnDataTypeForGUI", dataType);
432 for(
const auto& colDefault : allDefaults)
434 xmlOut.addTextElementToData(
"columnDefaultDataType", colDefault.first.first);
435 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
436 colDefault.first.second);
437 xmlOut.addTextElementToData(
"columnDefaultValue", colDefault.second);
441 else if(requestType ==
"getGroupAliases")
446 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
448 __SUP_COUT__ <<
"reloadActive: " << reloadActive << __E__;
456 catch(std::runtime_error& e)
458 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what()))
460 __SUP_COUT_ERR__ <<
"\n" << ss.str();
461 xmlOut.addTextElementToData(
"Error", ss.str());
465 __SUP_SS__ << (
"Error loading active groups!\n\n") << __E__;
470 catch(
const std::exception& e)
472 ss <<
"Exception message: " << e.what();
477 __SUP_COUT_ERR__ <<
"\n" << ss.str();
478 xmlOut.addTextElementToData(
"Error", ss.str());
482 handleGroupAliasesXML(xmlOut, cfgMgr);
484 else if(requestType ==
"setGroupAliasInActiveBackbone")
486 std::string groupAliasCSV =
488 std::string groupNameCSV =
490 std::string groupKeyCSV =
493 __SUP_COUTV__(groupAliasCSV);
494 __SUP_COUTV__(groupNameCSV);
495 __SUP_COUTV__(groupKeyCSV);
497 handleSetGroupAliasInBackboneXML(
498 xmlOut, cfgMgr, groupAliasCSV, groupNameCSV, groupKeyCSV, userInfo.username_);
500 else if(requestType ==
"setTableAliasInActiveBackbone")
502 std::string tableAlias =
504 std::string tableName =
508 __SUP_COUT__ <<
"tableAlias: " << tableAlias << __E__;
509 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
510 __SUP_COUT__ <<
"version: " << version << __E__;
512 handleSetTableAliasInBackboneXML(xmlOut,
519 else if(requestType ==
"setAliasOfGroupMembers")
521 std::string versionAlias =
523 std::string groupName =
527 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
528 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
529 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
531 handleAliasGroupMembersInBackboneXML(xmlOut,
538 else if(requestType ==
"getVersionAliases")
540 handleVersionAliasesXML(xmlOut, cfgMgr);
542 else if(requestType ==
"getTableGroups")
544 bool doNotReturnMembers =
545 CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1
549 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << __E__;
550 handleTableGroupsXML(xmlOut, cfgMgr, !doNotReturnMembers);
552 else if(requestType ==
"getTableGroupType")
554 std::string tableList =
556 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
558 handleGetTableGroupTypeXML(xmlOut, cfgMgr, tableList);
560 else if(requestType ==
"getTables")
562 handleTablesXML(xmlOut, cfgMgr);
564 else if(requestType ==
"getContextMemberNames")
566 std::set<std::string> members = cfgMgr->getFixedContextMemberNames();
568 for(
auto& member : members)
569 xmlOut.addTextElementToData(
"ContextMember", member);
571 else if(requestType ==
"getBackboneMemberNames")
573 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
575 for(
auto& member : members)
576 xmlOut.addTextElementToData(
"BackboneMember", member);
578 else if(requestType ==
"getIterateMemberNames")
580 std::set<std::string> members = cfgMgr->getIterateMemberNames();
582 for(
auto& member : members)
583 xmlOut.addTextElementToData(
"IterateMember", member);
585 else if(requestType ==
"getSpecificTableGroup")
587 std::string groupName =
591 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
592 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
597 else if(requestType ==
"saveNewTableGroup")
599 std::string groupName =
601 bool ignoreWarnings =
602 CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
603 bool allowDuplicates =
604 CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
605 bool lookForEquivalent =
606 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
607 std::string tableList =
609 std::string comment =
612 __SUP_COUT__ <<
"saveNewTableGroup: " << groupName << __E__;
613 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
614 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
615 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << __E__;
616 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
617 __SUP_COUT__ <<
"comment: " << comment << __E__;
628 else if(requestType ==
"getSpecificTable")
630 std::string tableName =
633 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
634 int chunkSize = CgiDataUtilities::getDataAsInt(cgiIn,
"chunkSize");
637 std::string allowIllegalColumns =
639 __SUP_COUT__ <<
"allowIllegalColumns: " << (allowIllegalColumns ==
"1") << __E__;
642 __SUP_COUT__ <<
"rawData: " << (rawData ==
"1") << __E__;
644 __SUP_COUT__ <<
"getSpecificTable: " << tableName <<
" versionStr: " << versionStr
645 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset
649 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
651 if(allTableInfo.find(tableName) != allTableInfo.end())
653 if(versionStr ==
"" &&
654 allTableInfo.at(tableName).versions_.size())
657 auto it = allTableInfo.at(tableName).versions_.rbegin();
658 if(it->isScratchVersion())
662 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
665 std::map<std::string ,
669 std::string versionAlias;
670 versionAlias = versionStr.substr(
671 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
682 if(versionAliases.find(tableName) != versionAliases.end() &&
683 versionAliases[tableName].find(versionAlias) !=
684 versionAliases[tableName].end())
686 version = versionAliases[tableName][versionAlias];
687 __SUP_COUT__ <<
"version alias translated to: " << version << __E__;
692 << versionStr.substr(
693 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
694 <<
"'was not found in active version aliases!" << __E__;
697 version = atoi(versionStr.c_str());
700 __SUP_COUT__ <<
"version: " << version << __E__;
702 handleGetTableXML(xmlOut,
706 (allowIllegalColumns ==
"1"),
709 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
711 else if(requestType ==
"saveSpecificTable")
713 std::string tableName =
715 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
716 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
717 bool sourceTableAsIs =
718 CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
719 bool lookForEquivalent =
720 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
721 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
722 std::string comment =
729 __SUP_COUT__ <<
"tableName: " << tableName <<
" version: " << version
730 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset
732 __SUP_COUT__ <<
"comment: " << comment << __E__;
733 __SUP_COUT__ <<
"data: " << data << __E__;
734 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << __E__;
735 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
749 else if(requestType ==
"clearTableTemporaryVersions")
751 std::string tableName =
753 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
759 catch(std::runtime_error& e)
761 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
762 xmlOut.addTextElementToData(
763 "Error",
"Error clearing temporary views!\n " + std::string(e.what()));
767 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
768 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
771 else if(requestType ==
"clearTableCachedVersions")
773 std::string tableName =
775 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
786 catch(std::runtime_error& e)
788 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
789 xmlOut.addTextElementToData(
790 "Error",
"Error clearing cached views!\n " + std::string(e.what()));
794 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
795 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
798 else if(requestType ==
"getTreeView")
805 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
806 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
810 __SUP_COUTT__ <<
"tableGroup: " << tableGroup << __E__;
811 __SUP_COUTT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
812 __SUP_COUTT__ <<
"startPath: " << startPath << __E__;
813 __SUP_COUTT__ <<
"depth: " << depth << __E__;
814 __SUP_COUTT__ <<
"hideStatusFalse: " << hideStatusFalse << __E__;
815 __SUP_COUTT__ <<
"modifiedTables: " << modifiedTables << __E__;
816 __SUP_COUTT__ <<
"filterList: " << filterList << __E__;
818 handleFillTreeViewXML(xmlOut,
830 else if(requestType ==
"getTreeNodeCommonFields")
838 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
840 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
841 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
842 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
843 __SUP_COUT__ <<
"depth: " << depth << __E__;
846 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
847 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
848 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
850 handleFillTreeNodeCommonFieldsXML(xmlOut,
860 else if(requestType ==
"getUniqueFieldValuesForRecords")
869 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
870 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
871 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
872 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
873 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
874 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
876 handleFillUniqueFieldValuesForRecordsXML(xmlOut,
885 else if(requestType ==
"getTreeNodeFieldValues")
894 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
895 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
896 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
897 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
898 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
899 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
901 handleFillGetTreeNodeFieldValuesXML(xmlOut,
910 else if(requestType ==
"setTreeNodeFieldValues")
920 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
921 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
922 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
923 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
924 __SUP_COUT__ <<
"valueList: " << valueList << __E__;
925 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
926 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
928 handleFillSetTreeNodeFieldValuesXML(xmlOut,
939 else if(requestType ==
"addTreeNodeRecords")
947 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
948 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
949 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
950 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
951 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
953 handleFillCreateTreeNodeRecordsXML(xmlOut,
962 else if(requestType ==
"deleteTreeNodeRecords")
970 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
971 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
972 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
973 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
974 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
976 handleFillDeleteTreeNodeRecordsXML(xmlOut,
984 else if(requestType ==
"renameTreeNodeRecords")
993 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
994 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
995 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
996 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
997 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
998 __SUP_COUTV__(newRecordList);
1000 handleFillRenameTreeNodeRecordsXML(xmlOut,
1009 else if(requestType ==
"copyTreeNodeRecords")
1016 unsigned int numberOfCopies =
1017 CgiDataUtilities::getDataAsInt(cgiIn,
"numberOfCopies");
1021 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1022 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1023 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1024 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1025 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1026 __SUP_COUTV__(numberOfCopies);
1028 handleFillCopyTreeNodeRecordsXML(xmlOut,
1037 else if(requestType ==
"getTableStructureStatusAsJSON")
1044 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1045 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1046 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1047 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1050 setupActiveTablesXML(xmlOut,
1059 xmlOut.addTextElementToData(
1060 "StructureStatusAsJSON",
1061 cfgMgr->
getTableByName(tableName)->getStructureStatusAsJSON(cfgMgr));
1063 catch(
const std::runtime_error& e)
1065 __SUP_SS__ <<
"The table plugin feature getStructureStatusAsJSON(), does not "
1066 "seem to be supported for the table '"
1068 <<
".' Make sure you have the expected table plugin in your path, "
1069 "or contact system admins."
1071 ss <<
"Here is the error: " << e.what() << __E__;
1075 else if(requestType ==
"getArtdaqNodes")
1079 __SUP_COUTV__(modifiedTables);
1081 handleGetArtdaqNodeRecordsXML(xmlOut, cfgMgr, modifiedTables);
1083 else if(requestType ==
"saveArtdaqNodes")
1087 std::string subsystemString =
1090 __SUP_COUTV__(modifiedTables);
1091 __SUP_COUTV__(nodeString);
1092 __SUP_COUTV__(subsystemString);
1094 handleSaveArtdaqNodeRecordsXML(
1095 nodeString, subsystemString, xmlOut, cfgMgr, modifiedTables);
1097 else if(requestType ==
"getArtdaqNodeLayout")
1099 std::string contextGroupName =
1103 __SUP_COUTV__(contextGroupName);
1104 __SUP_COUTV__(contextGroupKey);
1106 handleLoadArtdaqNodeLayoutXML(
1107 xmlOut, cfgMgr, contextGroupName,
TableGroupKey(contextGroupKey));
1109 else if(requestType ==
"saveArtdaqNodeLayout")
1112 std::string contextGroupName =
1116 __SUP_COUTV__(layout);
1117 __SUP_COUTV__(contextGroupName);
1118 __SUP_COUTV__(contextGroupKey);
1120 handleSaveArtdaqNodeLayoutXML(
1121 xmlOut, cfgMgr, layout, contextGroupName,
TableGroupKey(contextGroupKey));
1123 else if(requestType ==
"checkAffectedActiveGroups")
1128 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1129 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
1130 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
1132 handleGetAffectedGroupsXML(
1133 xmlOut, cfgMgr, groupName,
TableGroupKey(groupKey), modifiedTables);
1135 else if(requestType ==
"saveTreeNodeEdit")
1139 std::string targetTableVersion =
1145 __SUP_COUT__ <<
"editNodeType: " << editNodeType << __E__;
1146 __SUP_COUT__ <<
"targetTable: " << targetTable << __E__;
1147 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << __E__;
1148 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
1149 __SUP_COUT__ <<
"targetColumn: " << targetColumn << __E__;
1150 __SUP_COUT__ <<
"newValue: " << newValue << __E__;
1152 handleSaveTreeNodeEditXML(xmlOut,
1160 userInfo.username_);
1162 else if(requestType ==
"getLinkToChoices")
1165 std::string linkToTableVersion =
1172 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << __E__;
1173 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << __E__;
1174 __SUP_COUT__ <<
"linkIdType: " << linkIdType << __E__;
1175 __SUP_COUT__ <<
"linkIndex: " << linkIndex << __E__;
1176 __SUP_COUT__ <<
"linkInitId: " << linkInitId << __E__;
1178 handleGetLinkToChoicesXML(xmlOut,
1186 else if(requestType ==
"activateTableGroup")
1190 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
1192 __SUP_COUT__ <<
"Activating group: " << groupName <<
"(" << groupKey <<
")"
1194 __SUP_COUTV__(ignoreWarnings);
1197 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
1198 xmlOut.addTextElementToData(
"AttemptedGroupActivationName", groupName);
1199 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey", groupKey);
1203 std::string accumulatedErrors, groupTypeString;
1211 groupName,
TableGroupKey(groupKey), &accumulatedErrors, &groupTypeString);
1213 if(accumulatedErrors !=
"")
1217 __SS__ <<
"Throwing exception on accumulated errors: "
1218 << accumulatedErrors << __E__;
1222 __COUT_WARN__ <<
"Ignoring warnings so ignoring this error:"
1223 << accumulatedErrors << __E__;
1224 __COUT_WARN__ <<
"Done ignoring the above error(s)." << __E__;
1226 xmlOut.addTextElementToData(
"AttemptedGroupActivationType", groupTypeString);
1228 catch(std::runtime_error& e)
1233 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1234 xmlOut.addTextElementToData(
1236 "Error activating table group '" + groupName +
"(" + groupKey +
")" +
1237 ".' Please see details below:\n\n" + std::string(e.what()));
1238 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1239 <<
" (" << groupKey <<
")" << __E__;
1248 catch(cet::exception& e)
1254 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1255 xmlOut.addTextElementToData(
"Error",
1256 "Error activating table group '" + groupName +
1257 "(" + groupKey +
")" +
"!'\n\n" +
1258 std::string(e.what()));
1259 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1260 <<
" (" << groupKey <<
")" << __E__;
1271 __SUP_COUT__ <<
"Unknown error detected!" << __E__;
1283 else if(requestType ==
"getActiveTableGroups")
1285 else if(requestType ==
"copyViewToCurrentColumns")
1287 std::string tableName =
1291 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1292 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << __E__;
1293 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << __E__;
1299 newTemporaryVersion =
1302 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << __E__;
1304 catch(std::runtime_error& e)
1306 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1307 xmlOut.addTextElementToData(
"Error",
1308 "Error copying view from '" + tableName +
"_v" +
1309 sourceVersion +
"'! " +
1310 std::string(e.what()));
1314 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1315 xmlOut.addTextElementToData(
1317 "Error copying view from '" + tableName +
"_v" + sourceVersion +
"'! ");
1320 handleGetTableXML(xmlOut, cfgMgr, tableName, newTemporaryVersion);
1322 else if(requestType ==
"getLastTableGroups")
1325 std::map<std::string ,
1326 std::tuple<std::string ,
1331 theRemoteWebUsers_.getLastTableGroups(theGroups);
1333 for(
const auto& theGroup : theGroups)
1335 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupName",
1336 std::get<0>(theGroup.second));
1337 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupKey",
1338 std::get<1>(theGroup.second).toString());
1339 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupTime",
1340 std::get<2>(theGroup.second));
1373 handleOtherSubsystemActiveGroups(xmlOut, cfgMgr,
false );
1375 else if(requestType ==
"getSubsytemTableGroups")
1377 std::string subsystem =
1379 __SUP_COUTV__(subsystem);
1380 handleOtherSubsystemActiveGroups(
1381 xmlOut, cfgMgr,
true , subsystem);
1383 else if(requestType ==
"diffWithActiveGroup")
1385 std::string groupName =
1388 __SUP_COUTV__(groupName);
1389 __SUP_COUTV__(groupKey);
1394 else if(requestType ==
"diffWithGroupKey")
1396 std::string groupName =
1400 std::string diffGroupName =
1402 __SUP_COUTV__(groupName);
1403 __SUP_COUTV__(groupKey);
1404 __SUP_COUTV__(diffKey);
1405 __SUP_COUTV__(diffGroupName);
1407 handleGroupDiff(xmlOut,
1414 else if(requestType ==
"diffTableVersions")
1416 std::string tableName =
1420 __SUP_COUTV__(tableName);
1425 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
1428 if(allTableInfo.find(tableName) != allTableInfo.end())
1430 if(vA.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1433 std::map<std::string ,
1437 std::string versionAlias;
1439 vA.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1441 if(versionAliases.find(tableName) != versionAliases.end() &&
1442 versionAliases[tableName].find(versionAlias) !=
1443 versionAliases[tableName].end())
1445 versionA = versionAliases[tableName][versionAlias];
1446 __SUP_COUT__ <<
"version alias translated to: " << versionA << __E__;
1449 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1450 <<
"'was not found in active version aliases!"
1454 versionA = atoi(vA.c_str());
1456 if(vB.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1459 std::map<std::string ,
1463 std::string versionAlias;
1465 vB.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1467 if(versionAliases.find(tableName) != versionAliases.end() &&
1468 versionAliases[tableName].find(versionAlias) !=
1469 versionAliases[tableName].end())
1471 versionB = versionAliases[tableName][versionAlias];
1472 __SUP_COUT__ <<
"version alias translated to: " << versionB << __E__;
1475 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1476 <<
"'was not found in active version aliases!"
1480 versionB = atoi(vB.c_str());
1484 versionA = atoi(vA.c_str());
1485 versionB = atoi(vB.c_str());
1488 __SUP_COUTV__(versionA);
1489 __SUP_COUTV__(versionB);
1491 handleTableDiff(xmlOut, cfgMgr, tableName, versionA, versionB);
1493 else if(requestType ==
"savePlanCommandSequence")
1496 std::string commands =
1502 __SUP_COUTV__(modifiedTables);
1503 __SUP_COUTV__(planName);
1504 __SUP_COUTV__(commands);
1505 __SUP_COUTV__(groupName);
1506 __SUP_COUTV__(groupKey);
1508 handleSavePlanCommandSequenceXML(xmlOut,
1517 else if(requestType ==
"mergeGroups")
1519 std::string groupANameContext =
1521 std::string groupAKeyContext =
1523 std::string groupBNameContext =
1525 std::string groupBKeyContext =
1527 std::string groupANameConfig =
1530 std::string groupBNameConfig =
1535 __SUP_COUTV__(groupANameContext);
1536 __SUP_COUTV__(groupAKeyContext);
1537 __SUP_COUTV__(groupBNameContext);
1538 __SUP_COUTV__(groupBKeyContext);
1539 __SUP_COUTV__(groupANameConfig);
1540 __SUP_COUTV__(groupAKeyConfig);
1541 __SUP_COUTV__(groupBNameConfig);
1542 __SUP_COUTV__(groupBKeyConfig);
1543 __SUP_COUTV__(mergeApproach);
1545 handleMergeGroupsXML(xmlOut,
1560 __SUP_SS__ <<
"requestType Request, " << requestType
1561 <<
", not recognized by the Configuration GUI Supervisor (was it "
1562 "intended for another Supervisor?)."
1564 __SUP_COUT__ <<
"\n" << ss.str();
1565 xmlOut.addTextElementToData(
"Error", ss.str());
1568 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1571 xmlOut, cfgMgr, userInfo.username_);
1572 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1575 catch(
const std::runtime_error& e)
1577 __SS__ <<
"A fatal error occurred while handling the request '" << requestType
1578 <<
".' Error: " << e.what() << __E__;
1579 __COUT_ERR__ <<
"\n" << ss.str();
1580 xmlOut.addTextElementToData(
"Error", ss.str());
1585 xmlOut.addTextElementToData(
1587 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1591 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1596 __SS__ <<
"An unknown fatal error occurred while handling the request '"
1597 << requestType <<
".'" << __E__;
1602 catch(
const std::exception& e)
1604 ss <<
"Exception message: " << e.what();
1609 __COUT_ERR__ <<
"\n" << ss.str();
1610 xmlOut.addTextElementToData(
"Error", ss.str());
1615 xmlOut.addTextElementToData(
1617 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1621 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1641 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(
1644 const std::string& rootGroupName,
1646 const std::string& modifiedTables)
1649 __SUP_COUT__ <<
"rootGroupName " << rootGroupName <<
"(" << rootGroupKey
1650 <<
"). modifiedTables = " << modifiedTables << __E__;
1652 std::map<std::string, std::pair<std::string, TableGroupKey>> consideredGroups =
1657 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT].second.isInvalid())
1659 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
1660 if(cfgMgr->getFailedTableGroups().find(
1661 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT) !=
1662 cfgMgr->getFailedTableGroups().end())
1664 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1665 cfgMgr->getFailedTableGroups().at(
1666 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT);
1668 else if(cfgMgr->getFailedTableGroups().find(
1669 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1670 cfgMgr->getFailedTableGroups().end())
1672 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
1673 cfgMgr->getFailedTableGroups().at(
1674 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1677 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION]
1678 .second.isInvalid())
1680 __SUP_COUT__ <<
"Finding a table group to consider..." << __E__;
1681 if(cfgMgr->getFailedTableGroups().find(
1682 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION) !=
1683 cfgMgr->getFailedTableGroups().end())
1685 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1686 cfgMgr->getFailedTableGroups().at(
1687 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION);
1689 else if(cfgMgr->getFailedTableGroups().find(
1690 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
1691 cfgMgr->getFailedTableGroups().end())
1693 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
1694 cfgMgr->getFailedTableGroups().at(
1695 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
1704 std::map<std::string ,
TableVersion > rootGroupMemberMap;
1709 &rootGroupMemberMap,
1719 consideredGroups[groupType] =
1720 std::pair<std::string, TableGroupKey>(rootGroupName, rootGroupKey);
1722 catch(
const std::runtime_error& e)
1725 if(rootGroupName.size())
1727 __SUP_SS__ <<
"Failed to determine type of table group for " << rootGroupName
1728 <<
"(" << rootGroupKey <<
")! " << e.what() << __E__;
1729 __SUP_COUT_ERR__ <<
"\n" << ss.str();
1734 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1735 "name - assuming this was intentional."
1741 if(rootGroupName.size())
1743 __SUP_COUT_ERR__ <<
"Failed to determine type of table group for "
1744 << rootGroupName <<
"(" << rootGroupKey <<
")!" << __E__;
1749 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
1750 "name - assuming this was intentional."
1754 std::map<std::string ,
1757 std::map<std::string ,
1759 modifiedTablesMapIt;
1761 std::istringstream f(modifiedTables);
1762 std::string table, version;
1763 while(getline(f, table,
','))
1765 getline(f, version,
',');
1766 modifiedTablesMap.insert(
1769 std::pair<bool /*foundAffectedGroup*/, TableVersion /*version*/>>(
1773 __SUP_COUT__ << modifiedTables << __E__;
1774 for(
auto& pair : modifiedTablesMap)
1775 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second.second
1780 xercesc::DOMElement* parentEl =
nullptr;
1781 std::string groupComment;
1782 std::vector<std::string> orderedGroupTypes(
1783 {ConfigurationManager::GROUP_TYPE_NAME_CONTEXT,
1784 ConfigurationManager::GROUP_TYPE_NAME_BACKBONE,
1785 ConfigurationManager::GROUP_TYPE_NAME_ITERATE,
1786 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION});
1787 for(
auto groupType : orderedGroupTypes)
1789 if(consideredGroups.find(groupType) == consideredGroups.end())
1792 const std::pair<std::string, TableGroupKey>& group = consideredGroups[groupType];
1794 if(group.second.isInvalid())
1797 __SUP_COUT__ <<
"Considering " << groupType <<
" group " << group.first <<
" ("
1798 << group.second <<
")" << __E__;
1816 __SUP_COUT__ <<
"groupComment = " << groupComment << __E__;
1818 for(
auto& table : memberMap)
1820 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
1823 table.second != (*modifiedTablesMapIt).second.second)
1825 __SUP_COUT__ <<
"Affected by " << (*modifiedTablesMapIt).first <<
":"
1826 << (*modifiedTablesMapIt).second.second << __E__;
1828 memberMap[table.first] = (*modifiedTablesMapIt).second.second;
1829 (*modifiedTablesMapIt).second.first =
true;
1833 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1837 if(groupType == ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
1839 __SUP_COUT__ <<
"Considering mockup tables for Configuration Group..."
1841 for(
auto& table : modifiedTablesMap)
1843 if(table.second.first)
1846 if(table.second.second.isMockupVersion() &&
1847 memberMap.find(table.first) == memberMap.end())
1849 __SUP_COUT__ <<
"Found mockup table '" << table.first
1850 <<
"' for Configuration Group." << __E__;
1851 memberMap[table.first] = table.second.second;
1854 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1858 "AddMemberVersion", table.second.second.toString(), parentEl);
1865 __SUP_COUTV__(affected);
1869 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
1874 for(
auto& table : memberMap)
1878 "MemberVersion", table.second.toString(), parentEl);
1883 catch(std::runtime_error& e)
1885 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1886 xmlOut.addTextElementToData(
1887 "Error",
"Error getting affected groups! " + std::string(e.what()));
1891 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1892 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
1903 void ConfigurationGUISupervisor::setupActiveTablesXML(
1906 const std::string& groupName,
1908 const std::string& modifiedTables,
1910 bool doGetGroupInfo,
1911 std::map<std::string /*name*/, TableVersion /*version*/>* returnMemberMap,
1912 bool outputActiveTables,
1913 std::string* accumulatedErrors)
1916 xmlOut.addTextElementToData(
"tableGroup", groupName);
1917 xmlOut.addTextElementToData(
"tableGroupKey", groupKey.
toString());
1919 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
1927 __SUP_COUT__ <<
"Refreshing all table info, ignoring warnings..." << __E__;
1928 std::string accumulatedWarnings =
"";
1930 &accumulatedWarnings,
1944 __SUP_COUT__ <<
"Restoring active table group tables..." << __E__;
1946 for(
const auto& activeGroup : activeGroups)
1948 if(activeGroup.second.first == groupName &&
1949 activeGroup.second.second == groupKey)
1951 __SUP_COUTT__ <<
"Skipping target active group." << __E__;
1954 __SUP_COUTT__ <<
"Loading " << activeGroup.first <<
" "
1955 << activeGroup.second.first <<
"(" << activeGroup.second.second
1960 activeGroup.second.second,
1966 __SUP_COUT__ <<
"Ignoring errors while setting up active tables for "
1967 << activeGroup.second.first <<
"("
1968 << activeGroup.second.second <<
")..." << __E__;
1974 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
1976 std::map<std::string ,
TableVersion > modifiedTablesMap;
1978 modifiedTablesMapIt;
1980 if(usingActiveGroups)
1983 __SUP_COUT__ <<
"Using active groups." << __E__;
1987 __SUP_COUT__ <<
"Loading group '" << groupName <<
"(" << groupKey <<
")'"
1990 std::string groupComment, groupAuthor, tableGroupCreationTime, groupType;
1999 doGetGroupInfo ? &groupComment : 0,
2000 doGetGroupInfo ? &groupAuthor : 0,
2001 doGetGroupInfo ? &tableGroupCreationTime : 0,
2003 doGetGroupInfo ? &groupType : 0);
2007 xmlOut.addTextElementToData(
"tableGroupComment", groupComment);
2008 xmlOut.addTextElementToData(
"tableGroupAuthor", groupAuthor);
2009 xmlOut.addTextElementToData(
"tableGroupCreationTime", tableGroupCreationTime);
2010 xmlOut.addTextElementToData(
"tableGroupType", groupType);
2013 if(accumulatedErrors && *accumulatedErrors !=
"")
2014 __SUP_COUTV__(*accumulatedErrors);
2020 std::istringstream f(modifiedTables);
2021 std::string table, version;
2022 while(getline(f, table,
','))
2024 getline(f, version,
',');
2025 modifiedTablesMap.insert(
2026 std::pair<std::string /*name*/, TableVersion /*version*/>(
2030 for(
auto& pair : modifiedTablesMap)
2031 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
2036 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2037 xmlOut.addTextElementToData(
"DefaultNoLink",
2038 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
2041 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
2042 for(
const auto& tablePair : allActivePairs)
2043 orderedTableSet.emplace(tablePair.first);
2045 std::map<std::string, TableInfo>::const_iterator tableInfoIt;
2046 for(
auto& orderedTableName : orderedTableSet)
2048 tableInfoIt = allTableInfo.find(orderedTableName);
2049 if(tableInfoIt == allTableInfo.end())
2051 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
2056 if(outputActiveTables)
2057 xmlOut.addTextElementToData(
"ActiveTableName", orderedTableName);
2061 if((modifiedTablesMapIt = modifiedTablesMap.find(orderedTableName)) !=
2062 modifiedTablesMap.end())
2064 __SUP_COUT__ <<
"Found modified table " << (*modifiedTablesMapIt).first
2065 <<
": trying... " << (*modifiedTablesMapIt).second << __E__;
2069 tableInfoIt->second.tablePtr_->setActiveView(
2070 (*modifiedTablesMapIt).second);
2074 __SUP_SS__ <<
"Modified table version v" << (*modifiedTablesMapIt).second
2075 <<
" failed. Reverting to v"
2076 << tableInfoIt->second.tablePtr_->getView().getVersion() <<
"."
2078 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << __E__;
2079 xmlOut.addTextElementToData(
2081 "Error setting up active tables!\n\n" + std::string(ss.str()));
2085 if(outputActiveTables)
2087 xmlOut.addTextElementToData(
2088 "ActiveTableVersion",
2089 tableInfoIt->second.tablePtr_->getView().getVersion().toString());
2090 xmlOut.addTextElementToData(
2091 "ActiveTableComment",
2092 tableInfoIt->second.tablePtr_->getView().getAuthor() +
": " +
2093 tableInfoIt->second.tablePtr_->getView().getComment());
2101 catch(std::runtime_error& e)
2103 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what()))
2105 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2106 xmlOut.addTextElementToData(
"Error", ss.str());
2111 __SUP_SS__ << (
"Error setting up active tables!\n\n") << __E__;
2116 catch(
const std::exception& e)
2118 ss <<
"Exception message: " << e.what();
2123 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2124 xmlOut.addTextElementToData(
"Error", ss.str());
2143 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(
2146 const std::string& groupName,
2148 const std::string& startPath,
2149 const std::string& modifiedTables,
2150 const std::string& recordList,
2151 const std::string& author)
2154 setupActiveTablesXML(xmlOut,
2179 bool firstSave =
true;
2186 std::istringstream f(recordList);
2187 std::string recordUID;
2189 while(getline(f, recordUID,
','))
2193 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2198 .isTemporaryVersion())
2200 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2208 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2212 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2218 backupView.copy(table->getView(), temporaryVersion, author);
2227 unsigned int row = table->getViewP()->addRow(
2234 unsigned int col = table->getViewP()->getColStatus();
2235 table->getViewP()->setURIEncodedValue(
"1", row, col);
2242 table->getViewP()->setURIEncodedValue(
2243 recordUID, row, table->getViewP()->getColUID());
2251 table->getViewP()->init();
2255 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
2256 __SUP_COUT__ <<
"Before:" << __E__;
2257 table->getViewP()->
print();
2258 table->getViewP()->copy(backupView, temporaryVersion, author);
2259 __SUP_COUT__ <<
"After:" << __E__;
2260 table->getViewP()->
print();
2266 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2268 catch(std::runtime_error& e)
2270 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what()))
2272 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2273 xmlOut.addTextElementToData(
"Error", ss.str());
2277 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << __E__;
2282 catch(
const std::exception& e)
2284 ss <<
"Exception message: " << e.what();
2289 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2290 xmlOut.addTextElementToData(
"Error", ss.str());
2297 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(
2302 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
2303 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2304 for(
auto& activePair : allActivePairs)
2306 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
2307 xmlOut.addTextElementToData(
"NewActiveTableVersion",
2308 allTableInfo.at(activePair.first)
2309 .tablePtr_->getView()
2312 xmlOut.addTextElementToData(
2313 "NewActiveTableComment",
2314 allTableInfo.at(activePair.first).tablePtr_->getView().getAuthor() +
": " +
2315 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
2318 catch(std::runtime_error& e)
2320 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
2321 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2322 xmlOut.addTextElementToData(
"Error", ss.str());
2326 __SUP_SS__ << (
"Error!\n\n") << __E__;
2331 catch(
const std::exception& e)
2333 ss <<
"Exception message: " << e.what();
2338 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2339 xmlOut.addTextElementToData(
"Error", ss.str());
2357 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(
2360 const std::string& groupName,
2362 const std::string& startPath,
2363 const std::string& modifiedTables,
2364 const std::string& recordList)
2367 setupActiveTablesXML(xmlOut,
2392 bool firstSave =
true;
2396 std::istringstream f(recordList);
2397 std::string recordUID;
2400 while(getline(f, recordUID,
','))
2404 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2409 .isTemporaryVersion())
2411 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2419 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2423 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2434 table->getViewP()->findRow(table->getViewP()->getColUID(), recordUID);
2435 table->getViewP()->deleteRow(row);
2440 table->getViewP()->init();
2442 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2444 catch(std::runtime_error& e)
2446 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << __E__;
2447 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2448 xmlOut.addTextElementToData(
"Error", ss.str());
2452 __SUP_SS__ << (
"Error removing record(s)!\n\n") << __E__;
2457 catch(
const std::exception& e)
2459 ss <<
"Exception message: " << e.what();
2464 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2465 xmlOut.addTextElementToData(
"Error", ss.str());
2485 void ConfigurationGUISupervisor::handleFillRenameTreeNodeRecordsXML(
2488 const std::string& groupName,
2490 const std::string& startPath,
2491 const std::string& modifiedTables,
2492 const std::string& recordList,
2493 const std::string& newRecordList)
2496 setupActiveTablesXML(xmlOut,
2522 std::vector<std::string> recordArray =
2524 std::vector<std::string> newRecordArray =
2530 if(recordArray.size() == 0 || recordArray.size() != newRecordArray.size())
2533 <<
"Invalid record size vs new record name size, they must be the same: "
2534 << recordArray.size() <<
" vs " << newRecordArray.size() << __E__;
2540 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2542 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2550 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2553 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2560 for(
unsigned int i = 0; i < recordArray.size(); ++i)
2562 row = table->getViewP()->findRow(
2563 table->getViewP()->getColUID(),
2566 table->getViewP()->setValueAsString(
2567 newRecordArray[i], row, table->getViewP()->getColUID());
2570 table->getViewP()->init();
2572 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2574 catch(std::runtime_error& e)
2576 __SUP_SS__ << (
"Error renaming record(s)!\n\n" + std::string(e.what())) << __E__;
2577 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2578 xmlOut.addTextElementToData(
"Error", ss.str());
2582 __SUP_SS__ << (
"Error renaming record(s)!\n\n") << __E__;
2587 catch(
const std::exception& e)
2589 ss <<
"Exception message: " << e.what();
2594 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2595 xmlOut.addTextElementToData(
"Error", ss.str());
2616 void ConfigurationGUISupervisor::handleFillCopyTreeNodeRecordsXML(
2619 const std::string& groupName,
2621 const std::string& startPath,
2622 const std::string& modifiedTables,
2623 const std::string& recordList,
2624 unsigned int numberOfCopies )
2630 setupActiveTablesXML(xmlOut,
2656 std::vector<std::string> recordArray =
2662 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2664 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2672 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2675 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2682 for(
const auto& recordUID : recordArray)
2684 row = table->getViewP()->findRow(table->getViewP()->getColUID(),
2686 for(
unsigned int i = 0; i < numberOfCopies; ++i)
2687 table->getViewP()->copyRows(
2697 table->getViewP()->init();
2699 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2701 catch(std::runtime_error& e)
2703 __SUP_SS__ << (
"Error copying record(s)!\n\n" + std::string(e.what())) << __E__;
2704 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2705 xmlOut.addTextElementToData(
"Error", ss.str());
2709 __SUP_SS__ << (
"Error copying record(s)!\n\n") << __E__;
2714 catch(
const std::exception& e)
2716 ss <<
"Exception message: " << e.what();
2721 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2722 xmlOut.addTextElementToData(
"Error", ss.str());
2743 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(
2746 const std::string& groupName,
2748 const std::string& startPath,
2749 const std::string& modifiedTables,
2750 const std::string& recordList,
2751 const std::string& fieldList,
2752 const std::string& valueList,
2753 const std::string& author)
2756 setupActiveTablesXML(xmlOut,
2771 std::vector<std::string > fieldPaths;
2774 std::istringstream f(fieldList);
2775 std::string fieldPath;
2776 while(getline(f, fieldPath,
','))
2780 __SUP_COUT__ << fieldList << __E__;
2781 for(
const auto& field : fieldPaths)
2782 __SUP_COUT__ <<
"fieldPath " << field << __E__;
2785 std::vector<std::string > fieldValues;
2788 std::istringstream f(valueList);
2789 std::string fieldValue;
2790 while(getline(f, fieldValue,
','))
2792 fieldValues.push_back(fieldValue);
2797 if(valueList.size() && valueList[valueList.size() - 1] ==
',')
2798 fieldValues.push_back(
"");
2800 __SUP_COUT__ << valueList << __E__;
2801 for(
const auto& value : fieldValues)
2802 __SUP_COUT__ <<
"fieldValue " << value << __E__;
2805 if(fieldPaths.size() != fieldValues.size())
2808 __THROW__(ss.str() +
"Mismatch in fields and values array size!");
2815 std::istringstream f(recordList);
2816 std::string recordUID;
2819 while(getline(f, recordUID,
','))
2824 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2827 for(i = 0; i < fieldPaths.size(); ++i)
2829 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << __E__;
2830 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << __E__;
2835 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
2876 if(!(temporaryVersion = table->getViewP()->getVersion())
2877 .isTemporaryVersion())
2887 __SUP_COUT__ <<
"Created temporary version "
2892 __SUP_COUT__ <<
"Using temporary version " << table->
getTableName()
2893 <<
"-v" << temporaryVersion << __E__;
2897 table->getViewP()->setURIEncodedValue(fieldValues[i],
2908 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2910 catch(std::runtime_error& e)
2912 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what()))
2914 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2915 xmlOut.addTextElementToData(
"Error", ss.str());
2919 __SUP_SS__ << (
"Error setting field values!\n\n") << __E__;
2924 catch(
const std::exception& e)
2926 ss <<
"Exception message: " << e.what();
2931 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2932 xmlOut.addTextElementToData(
"Error", ss.str());
2951 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(
2954 const std::string& groupName,
2956 const std::string& startPath,
2957 const std::string& modifiedTables,
2958 const std::string& recordList,
2959 const std::string& fieldList)
2962 setupActiveTablesXML(
2963 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
2970 std::vector<std::string > fieldPaths;
2973 std::istringstream f(fieldList);
2974 std::string fieldPath;
2975 while(getline(f, fieldPath,
','))
2979 __SUP_COUT__ << fieldList << __E__;
2984 std::istringstream f(recordList);
2985 std::string recordUID;
2986 while(getline(f, recordUID,
','))
2990 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2992 xercesc::DOMElement* parentEl =
2993 xmlOut.addTextElementToData(
"fieldValues", recordUID);
2996 for(
const auto& fieldPath : fieldPaths)
3002 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPath);
3014 catch(std::runtime_error& e)
3016 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what()))
3018 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3019 xmlOut.addTextElementToData(
"Error", ss.str());
3023 __SUP_SS__ << (
"Error getting field values!\n\n") << __E__;
3028 catch(
const std::exception& e)
3030 ss <<
"Exception message: " << e.what();
3035 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3036 xmlOut.addTextElementToData(
"Error", ss.str());
3059 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(
3062 const std::string& groupName,
3064 const std::string& startPath,
3066 const std::string& modifiedTables,
3067 const std::string& recordList,
3068 const std::string& fieldList)
3071 setupActiveTablesXML(
3072 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3076 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
3080 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
3081 __SUP_COUT__ << ss.str();
3090 std::vector<ConfigurationTree::RecordField> retFieldList;
3096 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3102 std::vector<std::string > fieldAcceptList, fieldRejectList;
3107 std::istringstream f(fieldList);
3108 std::string fieldPath, decodedFieldPath;
3109 while(getline(f, fieldPath,
','))
3113 if(decodedFieldPath[0] ==
'!')
3114 fieldRejectList.push_back(decodedFieldPath.substr(1));
3116 fieldAcceptList.push_back(decodedFieldPath);
3118 __SUP_COUT__ << fieldList << __E__;
3119 for(
auto& field : fieldAcceptList)
3120 __SUP_COUT__ <<
"fieldAcceptList " << field << __E__;
3121 for(
auto& field : fieldRejectList)
3122 __SUP_COUT__ <<
"fieldRejectList " << field << __E__;
3126 std::vector<std::string > records;
3127 if(recordList ==
"*")
3131 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3132 for(
auto& record : records)
3133 __SUP_COUT__ <<
"recordList " << record << __E__;
3135 else if(recordList !=
"")
3139 std::istringstream f(recordList);
3140 std::string recordStr;
3141 while(getline(f, recordStr,
','))
3145 __SUP_COUT__ << recordList << __E__;
3146 for(
auto& record : records)
3147 __SUP_COUT__ <<
"recordList " << record << __E__;
3153 records, fieldAcceptList, fieldRejectList, depth);
3157 xercesc::DOMElement* parentTypeEl;
3158 for(
const auto& fieldInfo : retFieldList)
3161 "FieldTableName", fieldInfo.tableName_, parentEl);
3163 "FieldColumnName", fieldInfo.columnName_, parentEl);
3165 "FieldRelativePath", fieldInfo.relativePath_, parentEl);
3167 "FieldColumnType", fieldInfo.columnInfo_->getType(), parentEl);
3169 "FieldColumnDataType", fieldInfo.columnInfo_->getDataType(), parentEl);
3171 fieldInfo.columnInfo_->getDefaultValue(),
3178 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
3180 "FieldColumnDataChoice",
3181 fieldInfo.columnInfo_->getDefaultValue(),
3183 for(
const auto& dataChoice : dataChoices)
3185 "FieldColumnDataChoice", dataChoice, parentTypeEl);
3188 catch(std::runtime_error& e)
3190 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
3192 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3193 xmlOut.addTextElementToData(
"Error", ss.str());
3197 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
3202 catch(
const std::exception& e)
3204 ss <<
"Exception message: " << e.what();
3209 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3210 xmlOut.addTextElementToData(
"Error", ss.str());
3242 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(
3245 const std::string& groupName,
3247 const std::string& startPath,
3248 const std::string& modifiedTables,
3249 const std::string& recordList,
3250 const std::string& fieldList)
3253 setupActiveTablesXML(
3254 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3260 if(startPath ==
"/")
3266 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3267 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3272 std::vector<std::string > records;
3273 if(recordList ==
"*")
3277 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3278 for(
auto& record : records)
3279 __SUP_COUT__ <<
"recordList " << record << __E__;
3281 else if(recordList !=
"")
3285 std::istringstream f(recordList);
3286 std::string recordStr;
3287 while(getline(f, recordStr,
','))
3291 __SUP_COUT__ << recordList << __E__;
3292 for(
auto& record : records)
3293 __SUP_COUT__ <<
"recordList " << record << __E__;
3298 std::vector<std::string > fieldsToGet;
3303 if(fieldList ==
"AUTO")
3308 __SUP_COUT__ <<
"Getting AUTO filter fields!" << __E__;
3310 std::vector<ConfigurationTree::RecordField> retFieldList;
3311 std::vector<std::string > fieldAcceptList,
3313 fieldRejectList.push_back(
"*" + TableViewColumnInfo::COL_NAME_COMMENT);
3315 records, fieldAcceptList, fieldRejectList, 5,
true );
3317 for(
const auto& retField : retFieldList)
3318 fieldsToGet.push_back(retField.relativePath_ + retField.columnName_);
3322 std::istringstream f(fieldList);
3323 std::string fieldPath;
3324 while(getline(f, fieldPath,
','))
3328 __SUP_COUTV__(fieldList);
3337 std::string fieldGroupIDChildLinkIndex;
3338 for(
auto& field : fieldsToGet)
3340 __SUP_COUTV__(field);
3342 xercesc::DOMElement* parentEl =
3343 xmlOut.addTextElementToData(
"field", field);
3349 std::set<std::string > uniqueValues =
3351 records, field, &fieldGroupIDChildLinkIndex);
3353 if(fieldGroupIDChildLinkIndex !=
"")
3355 "childLinkIndex", fieldGroupIDChildLinkIndex, parentEl);
3357 for(
auto& uniqueValue : uniqueValues)
3359 __SUP_COUT__ <<
"uniqueValue " << uniqueValue << __E__;
3366 catch(std::runtime_error& e)
3368 __SUP_SS__ <<
"Error getting unique field values from path '" << startPath
3369 <<
"' and field list '" << fieldList <<
"!'\n\n"
3370 << e.what() << __E__;
3371 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3372 xmlOut.addTextElementToData(
"Error", ss.str());
3376 __SUP_SS__ <<
"Error getting unique field values from path '" << startPath
3377 <<
"' and field list '" << fieldList <<
"!'\n\n"
3383 catch(
const std::exception& e)
3385 ss <<
"Exception message: " << e.what();
3390 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3391 xmlOut.addTextElementToData(
"Error", ss.str());
3415 void ConfigurationGUISupervisor::handleFillTreeViewXML(
3418 const std::string& groupName,
3420 const std::string& startPath,
3422 bool hideStatusFalse,
3423 const std::string& modifiedTables,
3424 const std::string& filterList,
3425 const std::string& diffGroupName ,
3428 __SUP_COUTT__ <<
"get Tree View: " << groupName <<
"(" << groupKey <<
")" << __E__;
3460 bool doDiff = (diffGroupName !=
"" && !diffGroupKey.
isInvalid());
3465 std::string diffAccumulateErrors;
3473 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3490 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3493 __SUP_COUTT__ <<
"Diff Group tables loaded." << __E__;
3495 *cfgMgr, diffMemberMap, diffGroupName, diffGroupKey);
3496 __SUP_COUTT__ <<
"Diff Group tables copied to local diff config manager."
3500 for(
auto& memberPair : diffMemberMap)
3502 ->setActiveView(memberPair.second);
3504 for(
const auto& lastGroupLoaded : cfgMgr->getLastTableGroups())
3505 __SUP_COUT__ <<
"cfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3506 << lastGroupLoaded.second.first.first <<
"("
3507 << lastGroupLoaded.second.first.second <<
")";
3509 for(
const auto& lastGroupLoaded : diffCfgMgr->getLastTableGroups())
3510 __SUP_COUT__ <<
"diffCfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3511 << lastGroupLoaded.second.first.first <<
"("
3512 << lastGroupLoaded.second.first.second <<
")";
3515 if(diffCfgMgr->getLastTableGroups().size() == 1)
3517 __SUP_COUT__ <<
"Type already loaded to diff = "
3518 << diffCfgMgr->getLastTableGroups().begin()->first << __E__;
3521 auto groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3522 if(diffCfgMgr->getLastTableGroups().begin()->first ==
3523 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT)
3524 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION;
3525 else if(diffCfgMgr->getLastTableGroups().begin()->first ==
3526 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
3527 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3530 <<
"Loading " << groupTypeToLoad
3531 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first <<
"("
3532 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second
3537 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second,
3538 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first,
3539 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second);
3542 for(
auto& memberPair :
3543 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second)
3545 ->setActiveView(memberPair.second);
3553 __SUP_COUTT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3556 __SUP_COUTT__ <<
"diffCfgMgr " << activeTable.first <<
"-v"
3557 << activeTable.second << __E__;
3559 __SUP_COUTT__ <<
"Diff Group tables are setup: " << diffAccumulateErrors << __E__;
3564 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
3567 std::string accumulatedErrors =
"";
3568 setupActiveTablesXML(
3581 if(memberMap.size() > ConfigurationManager::getFixedContextMemberNames().size() +
3583 && startPath ==
"/")
3585 __COUTT__ <<
"Checking for orphaned tables..." << __E__;
3588 std::set<std::string > linkingTables;
3593 __COUTS__(30) <<
"Table " << tableInfo.first << __E__;
3594 if(!tableInfo.second.tablePtr_->isActive())
3597 __COUTS__(30) <<
"Table active " << tableInfo.first << __E__;
3599 const TableView& view = tableInfo.second.tablePtr_->getView();
3601 bool addedThisTable =
false;
3602 for(
unsigned int col = 0; col < view.getNumberOfColumns(); ++col)
3604 if(!view.getColumnInfo(col).isChildLink())
3607 __COUTS__(30) <<
"Table " << tableInfo.first
3608 <<
" col: " << view.getColumnInfo(col).getName() << __E__;
3610 for(
unsigned int r = 0; r < view.getNumberOfRows(); ++r)
3612 if(view.getDataView()[r][col] ==
"" ||
3613 view.getDataView()[r][col] ==
3614 TableViewColumnInfo::DATATYPE_STRING_DEFAULT)
3619 linkingTables.emplace(tableInfo.first);
3620 addedThisTable =
true;
3622 linkingTables.emplace(
3623 view.getDataView()[r][col]);
3629 std::string missingTables =
"";
3630 for(
const auto& member : memberMap)
3633 if(linkingTables.find(member.first) != linkingTables.end())
3636 if(missingTables.size())
3637 missingTables +=
", ";
3638 missingTables += member.first;
3641 if(missingTables.size())
3643 __COUTV__(missingTables);
3644 std::stringstream ss;
3645 ss <<
"The following member tables of table group '" << groupName <<
"("
3647 <<
")' were identified as possibly orphaned (i.e. no active tables link "
3648 "to these tables, and these tables have no links to other tables):\n\n"
3649 << missingTables <<
".\n"
3651 xmlOut.addTextElementToData(
"NoTreeLinkWarning", ss.str());
3655 if(accumulatedErrors !=
"")
3657 xmlOut.addTextElementToData(
"Warning", accumulatedErrors);
3659 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors
3662 __SUP_COUT__ <<
"Active table versions: "
3667 __SUP_COUTT__ <<
"Active tables are setup. No issues found." << __E__;
3668 __SUP_COUTT__ <<
"Active table versions: "
3674 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
3679 std::vector<std::pair<std::string, ConfigurationTree>> rootMap;
3680 std::map<std::string, ConfigurationTree> diffRootMap;
3682 if(startPath ==
"/")
3686 std::string accumulateTreeErrs;
3688 if(usingActiveGroups)
3689 rootMap = cfgMgr->
getChildren(0, &accumulateTreeErrs);
3691 rootMap = cfgMgr->
getChildren(&memberMap, &accumulateTreeErrs);
3696 diffCfgMgr->
getChildrenMap(&diffMemberMap, &diffAccumulateErrors);
3697 __SUP_COUTV__(diffRootMap.size());
3698 for(
auto& diffChild : diffRootMap)
3699 __SUP_COUTV__(diffChild.first);
3702 __SUP_COUTV__(accumulateTreeErrs);
3704 if(accumulateTreeErrs !=
"")
3705 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
3710 cfgMgr->
getNode(startPath,
true );
3713 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
3718 std::map<std::string , std::string > filterMap;
3722 std::set<char>({
';'}) ,
3723 std::set<char>({
'='}) );
3737 __SUP_COUTT__ <<
"Diff Group disconnected node." << __E__;
3742 catch(
const std::runtime_error& e)
3745 __SUP_COUTT__ <<
"Diff Group node does not exist." << __E__;
3752 for(
auto& treePair : rootMap)
3754 treePair.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
3758 __SUP_COUTT__ <<
"Diff Tree recursive handling." << __E__;
3761 std::set<std::string > rootMapToSearch;
3762 for(
const auto& rootMember : rootMap)
3763 rootMapToSearch.emplace(rootMember.first);
3765 std::stringstream rootSs;
3766 for(
const auto& rootMember : rootMap)
3767 rootSs <<
", " << rootMember.first;
3770 std::stringstream diffRootSs;
3771 for(
const auto& diffMember : diffRootMap)
3773 diffRootSs <<
", " << diffMember.first <<
":"
3774 << diffMember.second.getNodeType();
3775 if(rootMapToSearch.find(diffMember.first) ==
3779 std::stringstream missingSs;
3780 missingSs << diffMember.first <<
3782 " <<< Only in " << diffGroupName <<
"(" << diffGroupKey
3785 "diffNodeMissing", missingSs.str(), parentEl);
3788 if(diffMember.second.getNodeType() ==
"UIDLinkNode")
3799 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3800 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3802 __SUP_COUTT__ <<
"\t\t" << diffMember.second.getValueName() <<
": "
3803 << diffMember.second.getValueAsString() << __E__;
3805 __SUP_COUTT__ << diffMember.second.nodeDump();
3809 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
3810 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
3813 for(
auto& treePair : rootMap)
3815 if(diffRootMap.find(treePair.first) == diffRootMap.end())
3817 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3830 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
3832 recursiveTreeToXML(treePair.second,
3837 diffRootMap.at(treePair.first));
3842 catch(std::runtime_error& e)
3844 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << __E__;
3845 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3846 xmlOut.addTextElementToData(
"Error", ss.str());
3850 __SUP_SS__ <<
"Error detected generating XML tree!" << __E__;
3855 catch(
const std::exception& e)
3857 ss <<
"Exception message: " << e.what();
3862 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3863 xmlOut.addTextElementToData(
"Error", ss.str());
3873 void ConfigurationGUISupervisor::recursiveTreeToXML(
3877 xercesc::DOMElement* parentEl,
3878 bool hideStatusFalse,
3879 std::optional<std::reference_wrapper<const ConfigurationTree>> diffTree)
3889 if(diffTree.has_value() &&
3890 t.
getValueName() != TableViewColumnInfo::COL_NAME_COMMENT &&
3891 t.
getValueName() != TableViewColumnInfo::COL_NAME_AUTHOR &&
3892 t.
getValueName() != TableViewColumnInfo::COL_NAME_CREATION)
3894 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
3896 if(diffTree->get().isValueNode())
3898 __COUTS__(30) <<
"\t" << diffTree->get().getValueAsString() <<
" ? "
3900 __COUTS__(30) <<
"\t" << diffTree->get().getTableName() <<
"-v"
3901 << diffTree->get().getTableVersion() <<
" ? "
3906 std::stringstream missingSs;
3907 auto diffGroupPair =
3908 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3909 diffTree->get().getTableName());
3910 missingSs <<
"<<< '" << diffTree->get().getValueAsString() <<
"' in "
3911 << diffGroupPair.first <<
"(" << diffGroupPair.second
3918 std::stringstream missingSs;
3920 auto diffGroupPair =
3921 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3923 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
3924 << diffGroupPair.second <<
") >>>";
3938 if(t.
getValueType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
3939 t.
getValueType() == TableViewColumnInfo::TYPE_BITMAP_DATA)
3944 for(
const auto& choice : choices)
3961 if(diffTree.has_value())
3963 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType()
3970 std::stringstream missingSs;
3972 auto diffGroupPair =
3973 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3975 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
3976 << diffGroupPair.second <<
") >>>";
3981 __COUTS__(30) <<
"\t\t diff isDisconnected "
3982 << diffTree->get().isDisconnected() << __E__;
3984 std::stringstream missingSs;
3986 auto diffGroupPair =
3987 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
3989 missingSs <<
"<<< Link is "
3990 << (diffTree->get().isDisconnected() ?
"DISCONNECTED"
3992 <<
" in " << diffGroupPair.first <<
"("
3993 << diffGroupPair.second <<
") >>>";
4000 std::stringstream missingSs;
4002 auto diffGroupPair =
4003 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4005 missingSs <<
"<<< Link is "
4006 << (diffTree->get().isUIDLinkNode() ?
"a UID Link"
4008 <<
" in " << diffGroupPair.first <<
"("
4009 << diffGroupPair.second <<
") >>>";
4014 diffTree->get().getValueAsString())
4017 std::stringstream missingSs;
4019 auto diffGroupPair =
4020 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4022 missingSs <<
"<<< Link to '" << diffTree->get().getValueAsString()
4023 <<
"' in " << diffGroupPair.first <<
"("
4024 << diffGroupPair.second <<
") >>>";
4030 std::stringstream missingSs;
4033 auto dtchildren = diffTree->get().getChildrenMap();
4034 missingSs <<
"<<< Group link";
4035 if(tchildren.size() != dtchildren.size())
4036 missingSs <<
" has " << tchildren.size() <<
" vs "
4037 << dtchildren.size() <<
" children..";
4038 for(
auto& tchild : tchildren)
4039 if(dtchildren.find(tchild.first) == dtchildren.end())
4040 missingSs <<
" '" << tchild.first <<
"' missing..";
4041 for(
auto& dtchild : dtchildren)
4042 if(tchildren.find(dtchild.first) == tchildren.end())
4043 missingSs <<
" '" << dtchild.first <<
"' present...";
4046 if(missingSs.str().length() > std::string(
"<<< Group link").length())
4048 auto diffGroupPair =
4050 .getConfigurationManager()
4051 ->getGroupOfLoadedTable(diffTree->get().getTableName());
4052 missingSs <<
" in " << diffGroupPair.first <<
"("
4053 << diffGroupPair.second <<
") >>>";
4055 "nodeDiff", missingSs.str(), parentEl);
4083 xercesc::DOMElement* choicesParentEl =
4089 __COUTS__(30) <<
"choices.size() " << choices.size() << __E__;
4091 for(
const auto& choice : choices)
4113 xercesc::DOMElement* choicesParentEl =
4117 for(
const auto& choice : choices)
4124 bool returnNode =
true;
4137 if(diffTree.has_value())
4140 <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
4149 auto diffGroupPair =
4151 .getConfigurationManager()
4153 missingSs <<
"<<< Not in " << diffGroupPair.first <<
"("
4154 << diffGroupPair.second <<
") >>>";
4156 "nodeDiff", missingSs.str(), parentEl);
4190 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(
4193 const std::string& linkToTableName,
4195 const std::string& linkIdType,
4196 const std::string& linkIndex,
4197 const std::string& linkInitId)
4210 const std::string& tableName = linkToTableName;
4215 table->setActiveView(version);
4219 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
4220 << version << __E__;
4226 __SUP_SS__ <<
"Target table version (" << version
4227 <<
") is not the currently active version (" << table->
getViewVersion()
4228 <<
". Try refreshing the tree." << __E__;
4229 __SUP_COUT_WARN__ << ss.str();
4233 __SUP_COUT__ <<
"Active version is " << table->
getViewVersion() << __E__;
4235 if(linkIdType ==
"UID")
4238 unsigned int col = table->getView().getColUID();
4239 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4240 xmlOut.addTextElementToData(
"linkToChoice",
4241 table->getView().getDataView()[row][col]);
4243 else if(linkIdType ==
"GroupID")
4249 __SUP_COUTV__(linkIndex);
4250 __SUP_COUTV__(linkInitId);
4252 std::set<std::string> setOfGroupIDs =
4253 table->getView().getSetOfGroupIDs(linkIndex);
4258 bool foundInitId =
false;
4259 for(
const auto& groupID : setOfGroupIDs)
4261 if(!foundInitId && linkInitId == groupID)
4264 xmlOut.addTextElementToData(
"linkToChoice", groupID);
4268 xmlOut.addTextElementToData(
"linkToChoice", linkInitId);
4271 unsigned int col = table->getView().getColUID();
4272 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4274 xmlOut.addTextElementToData(
"groupChoice",
4275 table->getView().getDataView()[row][col]);
4276 if(table->getView().isEntryInGroup(row, linkIndex, linkInitId))
4277 xmlOut.addTextElementToData(
"groupMember",
4278 table->getView().getDataView()[row][col]);
4283 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType <<
".'" << __E__;
4287 catch(std::runtime_error& e)
4289 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << __E__;
4290 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4291 xmlOut.addTextElementToData(
"Error", ss.str());
4295 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << __E__;
4300 catch(
const std::exception& e)
4302 ss <<
"Exception message: " << e.what();
4307 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4308 xmlOut.addTextElementToData(
"Error", ss.str());
4313 void ConfigurationGUISupervisor::handleMergeGroupsXML(
4316 const std::string& groupANameContext,
4318 const std::string& groupBNameContext,
4320 const std::string& groupANameConfig,
4322 const std::string& groupBNameConfig,
4324 const std::string& author,
4325 const std::string& mergeApproach)
4328 __SUP_COUT__ <<
"Merging context group pair " << groupANameContext <<
" ("
4329 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4330 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4331 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4332 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4348 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" ||
4349 mergeApproach ==
"Skip"))
4351 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
4355 std::map<std::string ,
TableVersion > memberMapAContext,
4356 memberMapBContext, memberMapAConfig, memberMapBConfig;
4359 bool skippingContextPair =
false;
4360 bool skippingConfigPair =
false;
4361 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
4362 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
4364 skippingContextPair =
true;
4365 __SUP_COUTV__(skippingContextPair);
4367 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
4368 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
4370 skippingConfigPair =
true;
4371 __SUP_COUTV__(skippingConfigPair);
4375 if(!skippingContextPair)
4408 if(!skippingConfigPair)
4445 std::map<std::pair<std::string , std::string >,
4449 std::pair<std::string ,
4450 std::pair<std::string , std::string >>,
4452 groupidConversionMap;
4454 std::stringstream mergeReport;
4455 mergeReport <<
"======================================" << __E__;
4457 mergeReport <<
"Merging context group pair " << groupANameContext <<
" ("
4458 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4459 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4460 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4461 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4462 mergeReport <<
"======================================" << __E__;
4466 for(
unsigned int i = 0; i < 2; ++i)
4468 if(i == 0 && mergeApproach !=
"Rename")
4472 for(
unsigned int j = 0; j < 2; ++j)
4474 if(j == 0 && skippingContextPair)
4476 __COUT__ <<
"Skipping context pair..." << __E__;
4479 else if(j == 1 && skippingConfigPair)
4481 __COUT__ <<
"Skipping table pair..." << __E__;
4486 j == 0 ? memberMapAContext : memberMapAConfig;
4489 j == 0 ? memberMapBContext : memberMapBConfig;
4492 __COUT__ <<
"Context pair..." << __E__;
4494 __COUT__ <<
"Table pair..." << __E__;
4496 __COUT__ <<
"Starting member map B scan." << __E__;
4497 for(
const auto& bkey : memberMapBref)
4499 __SUP_COUTV__(bkey.first);
4501 if(memberMapAref.find(bkey.first) == memberMapAref.end())
4503 mergeReport <<
"\n'" << mergeApproach <<
"'-Missing table '"
4504 << bkey.first <<
"' A=v" << -1 <<
", adding B=v"
4505 << bkey.second << __E__;
4508 memberMapAref[bkey.first] = bkey.second;
4510 else if(memberMapAref[bkey.first] != bkey.second)
4513 __SUP_COUTV__(memberMapAref[bkey.first]);
4514 __SUP_COUTV__(bkey.second);
4519 __SUP_COUT__ <<
"Got table." << __E__;
4523 ->getVersionedTableByName(bkey.first,
4524 memberMapAref[bkey.first])
4532 groupidConversionMap,
4536 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME
4542 __SUP_COUTV__(newVersion);
4560 catch(std::runtime_error& e)
4563 <<
"There was an error saving the '"
4565 <<
"' merge result to a persistent table version. "
4566 <<
"Perhaps you can modify this table in one of the "
4567 "groups to resolve this issue, and then re-merge."
4568 << __E__ << e.what();
4572 __SUP_COUTV__(newVersion);
4574 memberMapAref[bkey.first] = newVersion;
4583 if(!skippingContextPair)
4585 __SUP_COUT__ <<
"New context member map complete." << __E__;
4592 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.
toString() +
4593 ") and " + groupBNameContext +
" (" + groupBKeyContext.
toString() +
").");
4596 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
4597 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.
toString());
4599 if(!skippingConfigPair)
4601 __SUP_COUT__ <<
"New table member map complete." << __E__;
4608 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.
toString() +
4609 ") and " + groupBNameConfig +
" (" + groupBKeyConfig.
toString() +
").");
4612 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
4613 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.
toString());
4618 std::string mergeReportBasePath = std::string(__ENV__(
"USER_DATA"));
4619 std::string mergeReportPath =
"/ServiceData/";
4621 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4622 mergeReportPath +=
"ConfigurationGUI_mergeReports/";
4624 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
4627 "merge_" + std::to_string(time(0)) +
"_" + std::to_string(clock()) +
".txt";
4628 __SUP_COUTV__(mergeReportPath);
4630 FILE* fp = fopen((mergeReportBasePath + mergeReportPath).c_str(),
"w");
4633 fprintf(fp,
"%s", mergeReport.str().c_str());
4635 xmlOut.addTextElementToData(
"MergeReportFile",
4636 "/$USER_DATA/" + mergeReportPath);
4639 xmlOut.addTextElementToData(
"MergeReportFile",
"FILE FAILURE");
4643 catch(std::runtime_error& e)
4645 __SUP_SS__ <<
"Error merging context group pair " << groupANameContext <<
" ("
4646 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4647 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4648 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4649 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
"': \n\n"
4650 << e.what() << __E__;
4651 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4652 xmlOut.addTextElementToData(
"Error", ss.str());
4656 __SUP_SS__ <<
"Unknown error merging context group pair " << groupANameContext <<
" ("
4657 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4658 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4659 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4660 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
".' \n\n";
4665 catch(
const std::exception& e)
4667 ss <<
"Exception message: " << e.what();
4672 __SUP_COUT_ERR__ <<
"\n" << ss.
str() << __E__;
4673 xmlOut.addTextElementToData(
"Error", ss.str());
4678 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(
4681 const std::string& groupName,
4683 const std::string& modifiedTables,
4684 const std::string& author,
4685 const std::string& planName,
4686 const std::string& commandString)
4689 __COUT__ <<
"handleSavePlanCommandSequenceXML " << planName << __E__;
4692 setupActiveTablesXML(xmlOut,
4711 for(
const auto& commandPair : IterateTable::commandToTableMap_)
4712 if(commandPair.second !=
"")
4713 commandTableToEditMap.emplace(std::pair<std::string, TableEditStruct>(
4730 std::string groupName = planName +
"-Plan";
4731 __SUP_COUT__ <<
"Handling commands for group " << groupName << __E__;
4733 unsigned int groupIdCol =
4734 planTable.tableView_->findCol(IterateTable::planTableCols_.GroupID_);
4735 unsigned int cmdTypeCol =
4736 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandType_);
4738 unsigned int targetGroupIdCol =
4739 targetTable.tableView_->findCol(IterateTable::targetCols_.GroupID_);
4740 unsigned int targetTableCol =
4741 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLink_);
4742 unsigned int targetUIDCol =
4743 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLinkUID_);
4745 std::string groupLinkIndex =
4746 planTable.tableView_->getColumnInfo(groupIdCol).getChildLinkIndex();
4747 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << __E__;
4749 std::pair<
unsigned int ,
unsigned int > commandUidLink;
4752 planTable.tableView_->getChildLink(
4753 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandLink_),
4758 unsigned int cmdRow, cmdCol;
4759 std::string targetGroupName;
4763 std::string targetUID, cmdType;
4765 for(
unsigned int row = 0; row < planTable.tableView_->getNumberOfRows();
4768 targetUID = planTable.tableView_
4769 ->getDataView()[row][planTable.tableView_->getColUID()];
4770 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
4773 if(planTable.tableView_->isEntryInGroup(row, groupLinkIndex, groupName))
4775 __SUP_COUT__ <<
"Removing." << __E__;
4779 cmdType = planTable.tableView_->getDataView()[row][cmdTypeCol];
4780 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(cmdType);
4781 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4782 cmdTypeTableIt->second !=
4786 commandTableToEditMap.at(cmdTypeTableIt->second);
4787 cmdRow = cmdTypeTableEdit.tableView_->findRow(
4788 cmdTypeTableEdit.tableView_->getColUID(),
4789 planTable.tableView_
4790 ->getDataView()[row][commandUidLink.second]);
4797 cmdCol = cmdTypeTableEdit.tableView_->findCol(
4798 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
4799 targetGroupName = cmdTypeTableEdit.tableView_
4800 ->getDataView()[cmdRow][cmdCol];
4802 for(
unsigned int trow = 0;
4803 trow < targetTable.tableView_->getNumberOfRows();
4807 if(targetTable.tableView_->isEntryInGroup(
4809 cmdTypeTableEdit.tableView_->getColumnInfo(cmdCol)
4810 .getChildLinkIndex(),
4813 __SUP_COUT__ <<
"Removing target." << __E__;
4815 if(targetTable.tableView_->removeRowFromGroup(
4826 __SUP_COUT__ <<
"No targets." << __E__;
4831 cmdTypeTableEdit.tableView_->deleteRow(cmdRow);
4837 if(planTable.tableView_->removeRowFromGroup(
4838 row, groupIdCol, groupName,
true ))
4847 std::vector<IterateTable::Command> commands;
4852 std::istringstream f(commandString);
4853 std::string commandSubString, paramSubString, paramValue;
4855 while(getline(f, commandSubString,
';'))
4857 __SUP_COUTT__ <<
"commandSubString " << commandSubString << __E__;
4858 std::istringstream g(commandSubString);
4861 while(getline(g, paramSubString,
','))
4863 __SUP_COUTT__ <<
"paramSubString " << paramSubString << __E__;
4866 if(paramSubString !=
"type")
4868 __SUP_SS__ <<
"Invalid command sequence" << __E__;
4872 commands.push_back(IterateTable::Command());
4874 getline(g, paramValue,
',');
4876 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4877 commands.back().type_ = paramValue;
4881 getline(g, paramValue,
',');
4883 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
4885 commands.back().params_.emplace(
4886 std::pair<std::string ,
4898 __SUP_COUT__ <<
"commands size " << commands.size() << __E__;
4905 unsigned int row, tgtRow;
4906 unsigned int targetIndex;
4907 std::string targetStr, cmdUID;
4909 for(
auto& command : commands)
4911 __SUP_COUT__ <<
"command " << command.type_ << __E__;
4912 __SUP_COUT__ <<
"table " << IterateTable::commandToTableMap_.at(command.type_)
4916 row = planTable.tableView_->addRow(
4917 author,
true ,
"planCommand");
4918 planTable.tableView_->addRowToGroup(row, groupIdCol, groupName);
4921 planTable.tableView_->setURIEncodedValue(command.type_, row, cmdTypeCol);
4924 planTable.tableView_->setValueAsString(
4925 "1", row, planTable.tableView_->getColStatus());
4928 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(command.type_);
4929 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
4930 cmdTypeTableIt->second !=
4934 commandTableToEditMap.at(cmdTypeTableIt->second);
4935 __SUP_COUT__ <<
"table " << cmdTypeTableEdit.tableName_ << __E__;
4940 cmdRow = cmdTypeTableEdit.tableView_->addRow(
4941 author,
true , command.type_ +
"_COMMAND_");
4947 for(
auto& param : command.params_)
4949 __SUP_COUT__ <<
"\t param " << param.first <<
" : " << param.second
4952 if(param.first == IterateTable::targetParams_.Tables_)
4954 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
4955 std::istringstream f(param.second);
4958 while(getline(f, targetStr,
'='))
4960 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
4961 if(!command.targets_.size() ||
4962 command.targets_.back().table_ !=
"")
4964 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
4967 command.addTarget();
4968 command.targets_.back().table_ = targetStr;
4971 command.targets_[targetIndex++].table_ = targetStr;
4977 if(param.first == IterateTable::targetParams_.UIDs_)
4979 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
4980 std::istringstream f(param.second);
4983 while(getline(f, targetStr,
'='))
4985 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
4986 if(!command.targets_.size() ||
4987 command.targets_.back().UID_ !=
"")
4989 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
4992 command.addTarget();
4993 command.targets_.back().UID_ = targetStr;
4996 command.targets_[targetIndex++].UID_ = targetStr;
5001 cmdCol = cmdTypeTableEdit.tableView_->findCol(param.first);
5003 __SUP_COUT__ <<
"param col " << cmdCol << __E__;
5005 cmdTypeTableEdit.tableView_->setURIEncodedValue(
5006 param.second, cmdRow, cmdCol);
5010 cmdTypeTableEdit.tableView_
5011 ->getDataView()[cmdRow][cmdTypeTableEdit.tableView_->getColUID()];
5013 if(command.targets_.size())
5017 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
5020 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5021 IterateTable::commandTargetCols_.TargetsLink_);
5022 cmdTypeTableEdit.tableView_->setValueAsString(
5023 IterateTable::TARGET_TABLE, cmdRow, cmdCol);
5025 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5026 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
5027 cmdTypeTableEdit.tableView_->setValueAsString(
5028 cmdUID +
"_Targets", cmdRow, cmdCol);
5032 for(
const auto& target : command.targets_)
5034 __SUP_COUT__ << target.
table_ <<
" " << target.UID_ << __E__;
5037 tgtRow = targetTable.tableView_->addRow(
5038 author,
true ,
"commandTarget");
5039 targetTable.tableView_->addRowToGroup(
5040 tgtRow, targetGroupIdCol, cmdUID +
"_Targets");
5043 targetTable.tableView_->setValueAsString(
5044 target.table_, tgtRow, targetTableCol);
5047 targetTable.tableView_->setValueAsString(
5048 target.UID_, tgtRow, targetUIDCol);
5053 planTable.tableView_->setValueAsString(
5054 cmdTypeTableEdit.tableName_, row, commandUidLink.first);
5055 planTable.tableView_->setValueAsString(
5056 cmdUID, row, commandUidLink.second);
5058 __SUP_COUT__ <<
"linked to uid = " << cmdUID << __E__;
5068 planTable.tableView_->print();
5069 planTable.tableView_->init();
5071 __SUP_COUT__ <<
"requestType tables:" << __E__;
5073 for(
auto& modifiedConfig : commandTableToEditMap)
5075 __SUP_COUTV__(modifiedConfig.second.modified_);
5076 modifiedConfig.second.tableView_->print();
5077 modifiedConfig.second.tableView_->init();
5080 targetTable.tableView_->print();
5081 targetTable.tableView_->init();
5086 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly "
5092 if(planTable.createdTemporaryVersion_)
5094 __SUP_COUT__ <<
"Erasing temporary version " << planTable.tableName_ <<
"-v"
5095 << planTable.temporaryVersion_ << __E__;
5098 planTable.temporaryVersion_);
5101 if(targetTable.createdTemporaryVersion_)
5103 __SUP_COUT__ <<
"Erasing temporary version " << targetTable.tableName_ <<
"-v"
5104 << targetTable.temporaryVersion_ << __E__;
5107 targetTable.temporaryVersion_);
5110 for(
auto& modifiedConfig : commandTableToEditMap)
5112 if(modifiedConfig.second
5113 .createdTemporaryVersion_)
5115 __SUP_COUT__ <<
"Erasing temporary version "
5116 << modifiedConfig.second.tableName_ <<
"-v"
5117 << modifiedConfig.second.temporaryVersion_ << __E__;
5120 modifiedConfig.second.temporaryVersion_);
5134 planTable.tableName_,
5135 planTable.originalVersion_,
5138 planTable.temporaryVersion_,
5141 __SUP_COUT__ <<
"Final plan version is " << planTable.tableName_ <<
"-v"
5142 << finalVersion << __E__;
5147 targetTable.tableName_,
5148 targetTable.originalVersion_,
5151 targetTable.temporaryVersion_,
5154 __SUP_COUT__ <<
"Final target version is " << targetTable.tableName_ <<
"-v"
5155 << finalVersion << __E__;
5157 for(
auto& modifiedConfig : commandTableToEditMap)
5159 if(!modifiedConfig.second.modified_)
5161 if(modifiedConfig.second
5162 .createdTemporaryVersion_)
5164 __SUP_COUT__ <<
"Erasing unmodified temporary version "
5165 << modifiedConfig.second.tableName_ <<
"-v"
5166 << modifiedConfig.second.temporaryVersion_ << __E__;
5169 modifiedConfig.second.temporaryVersion_);
5177 modifiedConfig.second.tableName_,
5178 modifiedConfig.second.originalVersion_,
5180 modifiedConfig.second.table_,
5181 modifiedConfig.second.temporaryVersion_,
5184 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.tableName_ <<
"-v"
5185 << finalVersion << __E__;
5188 handleFillModifiedTablesXML(xmlOut, cfgMgr);
5190 catch(std::runtime_error& e)
5192 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << __E__;
5193 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5194 xmlOut.addTextElementToData(
"Error", ss.str());
5198 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << __E__;
5203 catch(
const std::exception& e)
5205 ss <<
"Exception message: " << e.what();
5210 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5211 xmlOut.addTextElementToData(
"Error", ss.str());
5224 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(
HttpXmlDocument& xmlOut,
5226 const std::string& tableName,
5228 const std::string& type,
5229 const std::string& uid,
5230 const std::string& colName,
5231 const std::string& newValue,
5232 const std::string& author)
5235 __SUP_COUT__ <<
"Editing table " << tableName <<
"(" << version <<
") uid=" << uid
5236 <<
" type=" << type << __E__;
5246 table->setActiveView(version);
5253 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
5254 << version << __E__;
5258 __SUP_COUT__ <<
"Active version is " << table->
getViewVersion() << __E__;
5259 __SUP_COUTTV__(table->getView().getComment());
5263 __SUP_SS__ <<
"Target table version (" << version
5264 <<
") is not the currently active version (" << table->
getViewVersion()
5265 <<
"). Try refreshing the tree." << __E__;
5269 unsigned int col = -1;
5270 if(type ==
"uid" || type ==
"delete-uid" || type ==
"tree-copy")
5271 col = table->getView().getColUID();
5272 else if(type ==
"node-comment")
5273 col = table->getView().findCol(TableViewColumnInfo::COL_NAME_COMMENT);
5274 else if(type ==
"link-UID" || type ==
"link-GroupID" || type ==
"value" ||
5275 type ==
"value-groupid" || type ==
"value-bool" || type ==
"value-bitmap")
5276 col = table->getView().findCol(colName);
5277 else if(type ==
"table" || type ==
"link-comment" || type ==
"table-newGroupRow" ||
5278 type ==
"table-newUIDRow" || type ==
"table-newRow")
5282 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << __E__;
5287 if(type ==
"table" || type ==
"link-comment")
5290 if(table->getView().isURIEncodedCommentTheSame(newValue))
5293 <<
"' is the same as the current comment. No need to save change."
5311 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5316 __SUP_COUTTV__(table->getView().getComment());
5322 if(type ==
"table" || type ==
"link-comment")
5327 else if(type ==
"table-newRow" || type ==
"table-newUIDRow")
5330 unsigned int row = cfgView->
addRow(
5331 author,
true , newValue );
5346 else if(type ==
"table-newGroupRow")
5349 unsigned int csvIndex = newValue.find(
',');
5351 std::string linkIndex = newValue.substr(0, csvIndex);
5352 std::string groupId = newValue.substr(csvIndex + 1);
5355 csvIndex = groupId.find(
',');
5356 std::string newRowUID = groupId.substr(csvIndex + 1);
5357 groupId = groupId.substr(0, csvIndex);
5359 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," << groupId <<
"," << newRowUID
5363 unsigned int row = cfgView->
addRow(author,
5389 else if(type ==
"delete-uid")
5392 unsigned int row = cfgView->
findRow(col, uid);
5395 else if(type ==
"tree-copy")
5398 __COUTV__(newValue);
5399 std::vector<std::string> paramArray =
5403 if(paramArray.size() != 2)
5405 __SS__ <<
"Illegal parameters for tree copy request: must be number of "
5406 "copy instances & depth of copy."
5411 unsigned int row = cfgView->
findRow(col, uid);
5414 unsigned int numberOfInstances = atoi(paramArray[0].c_str());
5415 unsigned int depth = atoi(paramArray[1].c_str());
5417 __COUTV__(numberOfInstances);
5418 if(numberOfInstances > 1000)
5420 __SS__ <<
"Illegal parameters - the maximum number of copy instances is "
5421 "1000. Number of instances provided was "
5422 << numberOfInstances << __E__;
5429 ConfigurationSupervisorBase::recursiveCopyTreeUIDNode(xmlOut,
5438 else if(type ==
"uid" || type ==
"value" || type ==
"value-groupid" ||
5439 type ==
"value-bool" || type ==
"value-bitmap" || type ==
"node-comment")
5445 __SUP_SS__ <<
"Value '" << newValue
5446 <<
"' is the same as the current value. No need to save "
5447 "change to tree node."
5452 else if(type ==
"link-UID" || type ==
"link-GroupID")
5455 std::pair<
unsigned int ,
unsigned int > linkPair;
5459 __SUP_SS__ <<
"Col '" << colName <<
"' is not a link column." << __E__;
5463 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," << linkPair.second
5466 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
5468 __SUP_COUT__ <<
"linkIndex " << linkIndex << __E__;
5471 unsigned int csvIndexStart = 0, csvIndex = newValue.find(
',');
5473 std::string newTable = newValue.substr(csvIndexStart, csvIndex);
5474 csvIndexStart = csvIndex + 1;
5475 csvIndex = newValue.find(
',', csvIndexStart);
5476 std::string newLinkId = newValue.substr(
5481 __SUP_COUT__ <<
"newValue " << newTable <<
"," << newLinkId << __E__;
5485 bool changed =
false;
5486 bool needSecondaryChange = (type ==
"link-GroupID");
5491 __SUP_COUT__ <<
"Value '" << newTable
5492 <<
"' is the same as the current value." << __E__;
5500 std::string originalValue = cfgView->
getValueAsString(row, linkPair.second);
5504 __SUP_COUT__ <<
"Value '" << newLinkId
5505 <<
"' is the same as the current value." << __E__;
5510 needSecondaryChange =
5516 if(needSecondaryChange)
5518 bool secondaryChanged =
false;
5519 bool defaultIsInGroup =
5525 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table."
5527 table->eraseView(temporaryVersion);
5548 catch(std::runtime_error&
5551 __SUP_COUT__ <<
"Caught error while editing main table. Erasing "
5552 "temporary version."
5554 table->eraseView(temporaryVersion);
5558 xmlOut.addTextElementToData(
5560 "Error saving primary tree node! " + std::string(e.what()));
5570 __SUP_COUTV__(newValue);
5571 csvIndexStart = csvIndex + 1;
5572 csvIndex = newValue.find(
',', csvIndexStart);
5574 csvIndexStart, csvIndex - csvIndexStart));
5577 if(newTable == TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
5588 table->setActiveView(version);
5595 __SUP_COUT__ <<
"Failed to find stored version, so attempting to "
5597 << newTable <<
" v" << version << __E__;
5601 __SUP_COUT__ << newTable <<
" active version is "
5608 ss <<
"Target table '" << newTable
5609 <<
"' is likely not a member of the current table group "
5610 <<
"since the mock-up version was not successfully loaded. "
5615 "To add a table to a group, click the group name to go to "
5617 "group view, then click 'Add/Remove/Modify Member Tables.' "
5619 "can then add or remove tables and save the new group." +
5621 "OR!!! Click the following button to add the table '" +
5623 "' to the currently active Configuration Group: " +
5624 "<input type='button' style='color:black !important;' " +
5625 "title='Click to add table to the active Configuration "
5627 "onclick='addTableToConfigurationGroup(\"" + newTable +
5628 "\"); Debug.closeErrorPop();event.stopPropagation();' "
5629 "value='Add Table'>" +
5633 ss <<
"Target table version (" << version
5634 <<
") is not the currently active version ("
5643 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5649 if(type ==
"link-UID")
5659 __SUP_COUT__ <<
"target col " << col << __E__;
5661 unsigned int row = -1;
5664 row = cfgView->
findRow(col, newLinkId);
5669 if(row == (
unsigned int)-1)
5671 __SUP_COUT__ <<
"New link UID '" << newLinkId
5672 <<
"' was not found, so attempting to change UID of "
5674 << originalValue <<
"'" << __E__;
5677 row = cfgView->
findRow(col, originalValue);
5680 secondaryChanged =
true;
5681 __SUP_COUT__ <<
"Original target record '"
5682 << originalValue <<
"' was changed to '"
5683 << newLinkId <<
"'" << __E__;
5688 __SUP_COUT__ <<
"Original target record '" << originalValue
5689 <<
"' not found." << __E__;
5693 else if(type ==
"link-GroupID")
5701 __SUP_COUT__ <<
"target col " << col << __E__;
5704 std::vector<std::string> memberUIDs;
5707 csvIndexStart = csvIndex + 1;
5708 csvIndex = newValue.find(
',', csvIndexStart);
5709 memberUIDs.push_back(
5710 newValue.substr(csvIndexStart, csvIndex - csvIndexStart));
5711 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << __E__;
5713 (
unsigned int)std::string::npos);
5723 std::string targetUID;
5724 bool shouldBeInGroup;
5727 for(
unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
5729 targetUID = cfgView->getDataView()[row][cfgView->
getColUID()];
5730 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
5732 shouldBeInGroup =
false;
5733 for(
unsigned int i = 0; i < memberUIDs.size(); ++i)
5734 if(targetUID == memberUIDs[i])
5737 shouldBeInGroup =
true;
5744 if(shouldBeInGroup && !isInGroup)
5746 __SUP_COUT__ <<
"Changed to YES: " << row << __E__;
5747 secondaryChanged =
true;
5752 else if(!shouldBeInGroup && isInGroup)
5754 __SUP_COUT__ <<
"Changed to NO: " << row << __E__;
5755 secondaryChanged =
true;
5759 else if(targetUID ==
5761 ->getDefaultRowValues()[cfgView->
getColUID()] &&
5765 defaultIsInGroup =
true;
5771 if(!secondaryChanged)
5774 <<
"No changes to secondary view. Erasing temporary table."
5776 table->eraseView(temporaryVersion);
5797 catch(std::runtime_error&
5800 __SUP_COUT__ <<
"Caught error while editing secondary table. "
5801 "Erasing temporary version."
5803 table->eraseView(temporaryVersion);
5804 secondaryChanged =
false;
5807 xmlOut.addTextElementToData(
5809 "Error saving secondary tree node! " + std::string(e.what()));
5817 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
5819 __SUP_SS__ <<
"Link to table '" << newTable <<
"', linkID '"
5821 <<
"', and selected group members are the same as the "
5823 <<
"No need to save changes to tree." << __E__;
5829 else if(0 && !changed)
5834 __SUP_SS__ <<
"Link to table '" << newTable <<
"' and linkID '"
5836 <<
"' are the same as the current values. No need to save "
5837 "change to tree node."
5847 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
5848 table->eraseView(temporaryVersion);
5862 catch(std::runtime_error& e)
5864 __SUP_SS__ <<
"Error saving tree node! " << e.what() << __E__;
5865 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5866 xmlOut.addTextElementToData(
"Error", ss.str());
5870 __SUP_SS__ <<
"Unknown Error saving tree node! " << __E__;
5875 catch(
const std::exception& e)
5877 ss <<
"Exception message: " << e.what();
5882 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5883 xmlOut.addTextElementToData(
"Error", ss.str());
5927 void ConfigurationGUISupervisor::handleGetTableXML(
HttpXmlDocument& xmlOut,
5929 const std::string& tableName,
5931 bool allowIllegalColumns ,
5935 char tmpIntStr[100];
5936 xercesc::DOMElement *parentEl, *subparentEl;
5938 std::string accumulatedErrors =
"";
5940 if(allowIllegalColumns)
5941 xmlOut.addTextElementToData(
"allowIllegalColumns",
"1");
5943 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo(
5944 allowIllegalColumns ,
5945 allowIllegalColumns ? &accumulatedErrors : 0,
5954 xmlOut.addTextElementToData(
"ExistingTableNames",
5955 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
5956 for(
auto& configPair : allTableInfo)
5958 xmlOut.addTextElementToData(
"ExistingTableNames", configPair.first);
5959 if(configPair.first == tableName &&
5960 configPair.second.versions_.find(version) ==
5961 configPair.second.versions_.end())
5963 __SUP_COUT__ <<
"Version not found, so using mockup." << __E__;
5969 xmlOut.addTextElementToData(
"TableName", tableName);
5970 xmlOut.addTextElementToData(
"TableDescription",
5971 table->getTableDescription());
5985 for(
const auto& aliases : versionAliases)
5986 for(
const auto& alias : aliases.second)
5987 __SUP_COUTT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first
5988 <<
" ==> " << alias.second << __E__;
5990 catch(
const std::runtime_error& e)
5992 __SUP_COUT__ <<
"Could not get backbone information for version aliases: "
5993 << e.what() << __E__;
5996 auto tableIterator = versionAliases.find(tableName);
5998 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
6001 for(
const TableVersion& v : allTableInfo.at(tableName).versions_)
6007 std::vector<std::string> aliases;
6008 if(tableIterator != versionAliases.end())
6011 for(
const auto& aliasPair : tableIterator->second)
6013 if(v == aliasPair.second)
6015 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> "
6016 << aliasPair.first << __E__;
6017 aliases.push_back(aliasPair.first);
6025 __SUP_COUT__ <<
"Handling version w/aliases" << __E__;
6028 TableVersion::INVALID)
6033 else if(hi.
version() + 1 == v.version())
6040 if(lo.
version() != TableVersion::INVALID)
6050 if(versionAliases.size())
6054 for(
const auto& alias : aliases)
6056 hi = lo = TableVersion::INVALID;
6061 if(lo.
version() != TableVersion::INVALID)
6077 tableViewPtr = table->getMockupViewP();
6085 std::string localAccumulatedErrors =
"";
6090 allowIllegalColumns ,
6091 &localAccumulatedErrors,
6097 xmlOut.addTextElementToData(
"TableRawData",
6098 tableViewPtr->getSourceRawData());
6100 const std::set<std::string>& srcColNames =
6101 tableViewPtr->getSourceColumnNames();
6102 for(
auto& srcColName : srcColNames)
6103 xmlOut.addTextElementToData(
"ColumnHeader", srcColName);
6110 tableViewPtr = cfgMgr
6114 allowIllegalColumns ,
6115 &localAccumulatedErrors,
6121 if(localAccumulatedErrors !=
"")
6122 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
6124 catch(std::runtime_error& e)
6126 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << version
6127 <<
"... defaulting to mock-up! " << __E__;
6128 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
6130 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6132 tableViewPtr = table->getMockupViewP();
6134 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6138 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << version
6139 <<
"... defaulting to mock-up! "
6140 <<
"(You may want to try again to see what was partially loaded "
6141 "into cache before failure. "
6142 <<
"If you think, the failure is due to a column name change, "
6143 <<
"you can also try to Copy the failing view to the new column "
6145 <<
"'Copy and Move' functionality.)" << __E__;
6150 catch(
const std::exception& e)
6152 ss <<
"Exception message: " << e.what();
6158 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6160 tableViewPtr = table->getMockupViewP();
6162 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6165 xmlOut.addTextElementToData(
"TableVersion", version.
toString());
6171 xercesc::DOMElement* choicesParentEl;
6172 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
6174 std::vector<TableViewColumnInfo> colInfo = tableViewPtr->getColumnsInfo();
6176 for(
int i = 0; i < (int)colInfo.size(); ++i)
6181 "ColumnDataType", colInfo[i].getDataType(), parentEl);
6186 "ColumnDefaultValue", colInfo[i].getDefaultValue(), parentEl);
6190 if(colInfo[i].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
6191 colInfo[i].getType() == TableViewColumnInfo::TYPE_BITMAP_DATA ||
6192 colInfo[i].isChildLink())
6194 for(
auto& choice : colInfo[i].getDataChoices())
6199 "ColumnMinValue", colInfo[i].getMinValue(), parentEl);
6201 "ColumnMaxValue", colInfo[i].getMaxValue(), parentEl);
6208 tableViewPtr->
init();
6210 catch(std::runtime_error& e)
6213 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
6220 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
6222 for(
int r = 0; r < (int)tableViewPtr->getNumberOfRows(); ++r)
6224 sprintf(tmpIntStr,
"%d", r);
6225 xercesc::DOMElement* tmpParentEl =
6228 for(
int c = 0; c < (int)tableViewPtr->getNumberOfColumns(); ++c)
6230 if(colInfo[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
6232 std::string timeAsString;
6233 tableViewPtr->
getValue(timeAsString, r, c);
6238 "Entry", tableViewPtr->getDataView()[r][c], tmpParentEl);
6243 xmlOut.addTextElementToData(
"TableComment", tableViewPtr->getComment());
6244 xmlOut.addTextElementToData(
"TableAuthor", tableViewPtr->getAuthor());
6245 xmlOut.addTextElementToData(
"TableCreationTime",
6246 std::to_string(tableViewPtr->getCreationTime()));
6247 xmlOut.addTextElementToData(
"TableLastAccessTime",
6248 std::to_string(tableViewPtr->getLastAccessTime()));
6253 std::vector<std::string> defaultRowValues =
6254 table->getMockupViewP()->getDefaultRowValues();
6256 for(
unsigned int c = 0; c < defaultRowValues.size() - 2; ++c)
6258 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
6261 const std::set<std::string> srcColNames = tableViewPtr->getSourceColumnNames();
6263 if(accumulatedErrors !=
"")
6265 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so "
6266 "perhaps you can ignore this, ") +
6267 "but please note the following warnings:\n" + accumulatedErrors)
6269 __SUP_COUT_ERR__ << ss.str();
6270 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6274 (srcColNames.size() != tableViewPtr->getNumberOfColumns() ||
6275 tableViewPtr->getSourceColumnMismatch() !=
6278 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " << tableName
6279 <<
":v" << version <<
". Please see the details below:\n\n"
6280 << tableViewPtr->getMismatchColumnInfo();
6282 __SUP_COUT__ <<
"\n" << ss.str();
6283 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6287 catch(std::runtime_error& e)
6289 __SUP_SS__ <<
"Error getting table view!\n\n " << e.what() << __E__;
6290 __SUP_COUT_ERR__ << ss.str();
6291 xmlOut.addTextElementToData(
"Error", ss.str());
6295 __SUP_SS__ <<
"Error getting table view!\n\n " << __E__;
6300 catch(
const std::exception& e)
6302 ss <<
"Exception message: " << e.what();
6307 __SUP_COUT_ERR__ << ss.str();
6308 xmlOut.addTextElementToData(
"Error", ss.str());
6319 std::string username,
bool refresh)
6321 uint64_t sessionIndex =
6324 std::stringstream ssMapKey;
6325 ssMapKey << username <<
":" << sessionIndex;
6326 std::string mapKey = ssMapKey.str();
6327 __SUP_COUTT__ <<
"Using Config Session " << mapKey
6328 <<
" ... Total Session Count: " << userConfigurationManagers_.size()
6329 <<
" refresh=" << refresh << __E__;
6331 time_t now = time(0);
6337 for(
auto& pair : userConfigurationManagers_)
6338 __SUP_COUTTV__(pair.first);
6341 const std::string preLoadCfgMgrName =
":0";
6342 if(userConfigurationManagers_.size() == 1 &&
6343 userConfigurationManagers_.find(preLoadCfgMgrName) !=
6344 userConfigurationManagers_.end())
6346 __SUP_COUT__ <<
"Using pre-loaded Configuration Manager. time=" << time(0) <<
" "
6347 << clock() <<
" Setting author from "
6348 << userConfigurationManagers_.at(preLoadCfgMgrName)->getUsername()
6349 <<
" to " << username << __E__;
6350 userConfigurationManagers_[mapKey] =
6351 userConfigurationManagers_.at(preLoadCfgMgrName);
6352 userLastUseTime_[mapKey] = userLastUseTime_.at(preLoadCfgMgrName);
6354 userConfigurationManagers_.at(mapKey)->setUsername(username);
6357 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
6359 __SUP_COUT__ <<
"Creating new Configuration Manager. time=" << time(0) <<
" "
6360 << clock() << __E__;
6366 userConfigurationManagers_[mapKey]->getAllTableInfo(
6374 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
6376 __SUP_SS__ <<
"Fatal error managing userLastUseTime_! Check the logs for "
6377 "Configuration Interface failure."
6379 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6384 (now - userLastUseTime_[mapKey]) >
6385 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
6387 __SUP_COUT__ <<
"Refreshing all table info." << __E__;
6388 userConfigurationManagers_[mapKey]->getAllTableInfo(
6396 __SUP_COUTT__ <<
"Configuration Manager for author="
6397 << userConfigurationManagers_[mapKey]->getUsername()
6398 <<
" ready. time=" << time(0) <<
" " << clock() <<
" runTimeSeconds()="
6399 << userConfigurationManagers_[mapKey]->runTimeSeconds() << __E__;
6402 userLastUseTime_[mapKey] = now;
6405 for(std::map<std::string, time_t>::iterator it = userLastUseTime_.begin();
6406 it != userLastUseTime_.end();
6408 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
6410 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second
6412 delete userConfigurationManagers_[it->first];
6413 if(!(userConfigurationManagers_.erase(it->first)))
6415 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!"
6417 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6420 userLastUseTime_.erase(it);
6427 return userConfigurationManagers_[mapKey];
6435 void ConfigurationGUISupervisor::handleDeleteTableInfoXML(
HttpXmlDocument& xmlOut,
6437 std::string& tableName)
6439 if(0 == rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
6440 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
6441 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
6442 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6446 __SUP_COUT_ERR__ << (
"Error renaming file to " +
6447 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
6450 xmlOut.addTextElementToData(
6452 (
"Error renaming Table Info File to " +
6453 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused")));
6468 void ConfigurationGUISupervisor::handleSaveTableInfoXML(
6471 std::string& tableName,
6472 const std::string& data,
6473 const std::string& tableDescription,
6474 const std::string& columnChoicesCSV,
6475 bool allowOverwrite)
6479 std::string capsName;
6484 catch(std::runtime_error& e)
6486 xmlOut.addTextElementToData(
"Error", e.what());
6492 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"r");
6496 xmlOut.addTextElementToData(
"TableName", tableName);
6497 xmlOut.addTextElementToData(
"OverwriteError",
"1");
6498 xmlOut.addTextElementToData(
6500 "File already exists! ('" +
6501 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT) +
"')");
6506 __SUP_COUT__ <<
"capsName=" << capsName << __E__;
6507 __SUP_COUT__ <<
"tableName=" << tableName << __E__;
6508 __SUP_COUT__ <<
"tableDescription=" << tableDescription << __E__;
6509 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << __E__;
6512 std::stringstream outss;
6514 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
6515 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
6516 "xsi:noNamespaceSchemaLocation=\"TableInfo.xsd\">\n";
6517 outss <<
"\t\t<TABLE Name=\"" << tableName <<
"\">\n";
6518 outss <<
"\t\t\t<VIEW Name=\"" << capsName
6519 <<
"\" Type=\"File,Database,DatabaseTest\" Description=\"" << tableDescription
6525 std::istringstream columnChoicesISS(columnChoicesCSV);
6526 std::string columnChoicesString;
6527 std::string columnDefaultValue, columnMinValue, columnMaxValue;
6528 std::vector<std::string> columnParameters;
6529 std::vector<std::string> columnData =
6532 for(
unsigned int c = 0; c < columnData.size() - 1; ++c)
6536 __COUT__ <<
"Column #" << c <<
": "
6538 for(
unsigned int p = 0; p < columnParameters.size(); ++p)
6540 __COUT__ <<
"\t Parameter #" << p <<
": " << columnParameters[p] << __E__;
6542 __COUT__ <<
"\t creating the new xml" << __E__;
6544 std::string& columnType = columnParameters[0];
6545 std::string& columnName = columnParameters[1];
6546 std::string& columnDataType = columnParameters[2];
6547 const std::string columnStorageName =
6550 outss <<
"\t\t\t\t<COLUMN Type=\"";
6551 outss << columnType;
6552 outss <<
"\" \t Name=\"";
6553 outss << columnName;
6554 outss <<
"\" \t StorageName=\"";
6557 outss << columnStorageName;
6559 catch(std::runtime_error& e)
6561 xmlOut.addTextElementToData(
6563 std::string(
"For column name '") + columnName +
"' - " + e.what());
6566 outss <<
"\" \t DataType=\"";
6567 outss << columnDataType;
6571 std::string* columnDefaultValuePtr =
nullptr;
6572 if(columnDefaultValue !=
6575 __SUP_COUT__ <<
"FOUND user spec'd default value '" << columnDefaultValue
6577 outss <<
"\" \t DefaultValue=\"";
6578 outss << columnParameters[3];
6579 columnDefaultValuePtr = &columnParameters[3];
6581 getline(columnChoicesISS, columnChoicesString,
';');
6582 outss <<
"\" \t DataChoices=\"";
6583 outss << columnChoicesString;
6585 std::string* columnMinValuePtr =
nullptr;
6586 std::string* columnMaxValuePtr =
nullptr;
6588 if(columnParameters.size() > 4 &&
6592 if(columnMinValue !=
"")
6594 if(columnMinValue !=
6597 __SUP_COUT__ <<
"FOUND user spec'd min value '" << columnParameters[4]
6602 __SS__ <<
"Inavlid user spec'd min value '" << columnParameters[4]
6603 <<
"' which evaluates to '" << columnMinValue
6604 <<
"' and is not a valid number. The minimum value must "
6605 "be a number (environment variables and math "
6606 "operations are allowed)."
6610 outss <<
"\" \t MinValue=\"" << columnParameters[4];
6611 columnMinValuePtr = &columnParameters[4];
6616 if(columnMaxValue !=
"")
6618 if(columnMaxValue !=
6621 __SUP_COUT__ <<
"FOUND user spec'd max value = " << columnMaxValue
6626 __SS__ <<
"Inavlid user spec'd max value '" << columnParameters[5]
6627 <<
"' which evaluates to '" << columnMaxValue
6628 <<
"' and is not a valid number. The maximum value must "
6629 "be a number (environment variables and math "
6630 "operations are allowed)."
6634 outss <<
"\" \t MaxValue=\"" << columnParameters[5];
6635 columnMaxValuePtr = &columnParameters[5];
6647 columnDefaultValuePtr,
6648 columnChoicesString,
6654 catch(
const std::runtime_error& e)
6656 __SS__ <<
"Error identified with Column #" << c <<
": \n" << e.what();
6663 outss <<
"\t\t\t</VIEW>\n";
6664 outss <<
"\t\t</TABLE>\n";
6665 outss <<
"\t</ROOT>\n";
6667 __SUP_COUT__ << outss.str() << __E__;
6669 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"w");
6672 xmlOut.addTextElementToData(
"Error",
6673 "Failed to open destination Table Info file:" +
6674 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT));
6678 fprintf(fp,
"%s", outss.str().c_str());
6681 __SUP_COUT_INFO__ <<
"Finished saving Table Info for '" << tableName
6682 <<
".' Looking for errors in all table column info..." << __E__;
6686 std::string accumulatedErrors =
"";
6690 if(accumulatedErrors !=
"")
6692 __SUP_SS__ << (
"The new version of the '" + tableName +
6693 "' table column info was saved, however errors were detected "
6694 "reading back the table '" +
6695 tableName +
"' after the save attempt:\n\n" + accumulatedErrors)
6698 __SUP_COUT_ERR__ << ss.str() << __E__;
6699 xmlOut.addTextElementToData(
"Error", ss.str());
6705 handleGetTableXML(xmlOut, cfgMgr, tableName,
TableVersion());
6708 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
6711 for(
const auto& cfgInfo : allTableInfo)
6717 catch(std::runtime_error& e)
6719 __SUP_COUT_WARN__ <<
"\n\n##############################################\n"
6720 <<
"Error identified in column info of table '"
6721 << cfgInfo.first <<
"':\n\n"
6722 << e.what() <<
"\n\n"
6736 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(
6739 const std::string& groupAliasCSV,
6740 const std::string& groupNameCSV,
6741 const std::string& groupKeyCSV,
6742 const std::string& author)
6746 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
6748 const std::string groupAliasesTableName =
6749 ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
6750 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
6752 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!"
6754 xmlOut.addTextElementToData(
"Error", ss.str());
6759 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6760 for(
auto& memberName : backboneMembers)
6762 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6763 <<
"\"]=" << activeVersions[memberName] << __E__;
6765 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6766 xmlOut.addTextElementToData(
"oldBackboneVersion",
6767 activeVersions[memberName].toString());
6775 TableVersion originalVersion = activeVersions[groupAliasesTableName];
6778 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6779 bool isDifferent =
false;
6785 unsigned int col = configView->
findCol(
"GroupKeyAlias");
6786 unsigned int ccol = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
6787 unsigned int ncol = configView->
findCol(
"GroupName");
6788 unsigned int kcol = configView->
findCol(
"GroupKey");
6791 std::vector<std::string> groupAliases =
6793 std::vector<std::string> groupNames =
6795 std::vector<std::string> groupKeys =
6802 for(
const auto& groupAlias : groupAliases)
6804 if(groupAlias ==
"" || groupNames[i] ==
"" || groupKeys[i] ==
"")
6807 __SUP_COUT_WARN__ <<
"Empty alias parameter found [" << i <<
"] = {"
6808 << groupAlias <<
", " << groupNames[i] <<
"("
6809 << groupKeys[i] <<
")}" << __E__;
6814 bool localIsDifferent =
false;
6815 const std::string& groupName = groupNames[i];
6819 unsigned int row = -1;
6823 row = configView->
findRow(col, groupAlias);
6829 if(row == (
unsigned int)-1)
6831 localIsDifferent =
true;
6832 row = configView->
addRow();
6836 "This Group Alias was automatically setup by the server.", row, ccol);
6837 configView->
setValue(groupAlias, row, col);
6840 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
6842 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs "
6843 << configView->getDataView()[row][ncol] << __E__;
6844 if(groupName != configView->getDataView()[row][ncol])
6846 configView->
setValue(groupName, row, ncol);
6847 localIsDifferent =
true;
6850 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs "
6851 << configView->getDataView()[row][kcol] << __E__;
6852 if(groupKey.
toString() != configView->getDataView()[row][kcol])
6855 localIsDifferent =
true;
6858 if(localIsDifferent)
6863 configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
6867 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
6874 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << __E__;
6877 table->eraseView(temporaryVersion);
6884 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
6902 <<
"\t\t**************************** Using the existing table version"
6906 table->eraseView(temporaryVersion);
6907 newAssignedVersion = activeVersions[groupAliasesTableName];
6909 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
6910 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
6913 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
6915 catch(std::runtime_error& e)
6917 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << e.what() << __E__;
6918 __SUP_COUT_ERR__ << ss.str();
6919 xmlOut.addTextElementToData(
"Error", ss.str());
6923 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << __E__;
6928 catch(
const std::exception& e)
6930 ss <<
"Exception message: " << e.what();
6935 __SUP_COUT_ERR__ << ss.str();
6936 xmlOut.addTextElementToData(
"Error", ss.str());
6947 void ConfigurationGUISupervisor::handleSetTableAliasInBackboneXML(
6950 const std::string& tableAlias,
6951 const std::string& tableName,
6953 const std::string& author)
6957 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
6959 const std::string versionAliasesTableName =
6960 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
6961 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
6963 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
6965 xmlOut.addTextElementToData(
"Error", ss.str());
6970 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
6971 for(
auto& memberName : backboneMembers)
6973 __SUP_COUT__ <<
"activeVersions[\"" << memberName
6974 <<
"\"]=" << activeVersions[memberName] << __E__;
6976 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
6977 xmlOut.addTextElementToData(
"oldBackboneVersion",
6978 activeVersions[memberName].toString());
6986 TableVersion originalVersion = activeVersions[versionAliasesTableName];
6989 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
6991 bool isDifferent =
false;
6998 unsigned int col2 = configView->
findCol(
"VersionAlias");
6999 unsigned int col3 = configView->
findCol(
"TableName");
7003 unsigned int row = -1;
7008 unsigned int tmpRow = -1;
7011 tmpRow = configView->
findRow(col3, tableName, tmpRow + 1);
7012 }
while(configView->getDataView()[tmpRow][col2] != tableAlias);
7019 if(row == (
unsigned int)-1)
7022 row = configView->
addRow();
7025 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7027 std::string(
"Entry was added by server in ") +
7028 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7032 col = configView->
findCol(
"VersionAliasUID");
7034 tableName.substr(0, tableName.rfind(
"Table")) + tableAlias, row, col);
7036 configView->
setValue(tableAlias, row, col2);
7037 configView->
setValue(tableName, row, col3);
7040 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
7042 col = configView->
findCol(
"Version");
7043 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs "
7044 << configView->getDataView()[row][col] << __E__;
7045 if(version.
toString() != configView->getDataView()[row][col])
7054 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7058 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7063 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << __E__;
7066 table->eraseView(temporaryVersion);
7073 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
7089 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7093 table->eraseView(temporaryVersion);
7094 newAssignedVersion = activeVersions[versionAliasesTableName];
7096 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7097 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7100 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
7102 catch(std::runtime_error& e)
7104 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7105 __SUP_COUT_ERR__ << ss.str();
7106 xmlOut.addTextElementToData(
"Error", ss.str());
7110 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7115 catch(
const std::exception& e)
7117 ss <<
"Exception message: " << e.what();
7122 __SUP_COUT_ERR__ << ss.str();
7123 xmlOut.addTextElementToData(
"Error", ss.str());
7132 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(
7135 const std::string& versionAlias,
7136 const std::string& groupName,
7138 const std::string& author)
7142 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7144 const std::string versionAliasesTableName =
7145 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7146 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7148 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
7150 xmlOut.addTextElementToData(
"Error", ss.str());
7155 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
7156 for(
auto& memberName : backboneMembers)
7158 __SUP_COUT__ <<
"activeVersions[\"" << memberName
7159 <<
"\"]=" << activeVersions[memberName] << __E__;
7161 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7162 xmlOut.addTextElementToData(
"oldBackboneVersion",
7163 activeVersions[memberName].toString());
7174 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7179 bool isDifferent =
false;
7198 xmlOut.addTextElementToData(
7201 "\" can not be retrieved!");
7206 unsigned int col2 = configView->
findCol(
"VersionAlias");
7207 unsigned int col3 = configView->
findCol(
"TableName");
7209 for(
auto& memberPair : memberMap)
7211 bool thisMemberIsDifferent =
false;
7212 unsigned int row = -1;
7214 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
"_v"
7215 << memberPair.second <<
" to " << versionAlias << __E__;
7221 unsigned int tmpRow = -1;
7224 tmpRow = configView->
findRow(col3, memberPair.first, tmpRow + 1);
7225 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
7232 if(row == (
unsigned int)-1)
7234 thisMemberIsDifferent =
true;
7235 row = configView->
addRow();
7238 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7240 std::string(
"Entry was added by server in ") +
7241 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7247 memberPair.first.substr(0, memberPair.first.rfind(
"Table")) +
7252 configView->
setValue(versionAlias, row, col2);
7253 configView->
setValue(memberPair.first, row, col3);
7256 col = configView->
findCol(
"Version");
7258 if(memberPair.second.toString() != configView->getDataView()[row][col])
7260 configView->
setValue(memberPair.second.toString(), row, col);
7261 thisMemberIsDifferent =
true;
7264 if(thisMemberIsDifferent)
7267 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7271 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7274 if(thisMemberIsDifferent)
7283 __SUP_COUT__ <<
"\t\t**************************** Save v" << temporaryVersion
7284 <<
" as new table version" << __E__;
7286 newAssignedVersion =
7287 cfgMgr->
saveNewTable(versionAliasesTableName, temporaryVersion);
7291 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7295 table->eraseView(temporaryVersion);
7296 newAssignedVersion = activeVersions[versionAliasesTableName];
7299 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7300 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7301 __SUP_COUT__ <<
"\t\t Resulting Version: " << newAssignedVersion << __E__;
7303 catch(std::runtime_error& e)
7305 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7306 __SUP_COUT_ERR__ << ss.str();
7307 xmlOut.addTextElementToData(
"Error", ss.str());
7311 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7316 catch(
const std::exception& e)
7318 ss <<
"Exception message: " << e.what();
7323 __SUP_COUT_ERR__ << ss.str();
7324 xmlOut.addTextElementToData(
"Error", ss.str());
7338 void ConfigurationGUISupervisor::handleGroupAliasesXML(
HttpXmlDocument& xmlOut,
7342 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7344 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
7345 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
7347 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! "
7348 << groupAliasesTableName
7349 <<
" is a required member of the Backbone table group."
7350 <<
"\n\nLikely you need to activate a valid Backbone table group."
7352 __SUP_COUT__ << ss.str();
7357 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName
7358 <<
"\"]=" << activeVersions[groupAliasesTableName] << __E__;
7359 xmlOut.addTextElementToData(
"GroupAliasesTableName", groupAliasesTableName);
7360 xmlOut.addTextElementToData(
"GroupAliasesTableVersion",
7361 activeVersions[groupAliasesTableName].toString());
7363 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7368 <<
" ==> " << numOfThreads <<
" threads for alias group loads." << __E__;
7370 if(numOfThreads < 2)
7372 std::string groupName, groupKey, groupComment, groupAuthor, groupCreateTime,
7374 for(
auto& aliasNodePair : aliasNodePairs)
7376 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7377 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7379 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7380 xmlOut.addTextElementToData(
"GroupName", groupName);
7381 xmlOut.addTextElementToData(
"GroupKey", groupKey);
7382 xmlOut.addTextElementToData(
7384 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7385 .getValueAsString());
7389 ConfigurationManager::UNKNOWN_INFO;
7390 groupType = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7407 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7408 << groupKey <<
")' to extract group comment and type."
7411 xmlOut.addTextElementToData(
"GroupComment", groupComment);
7412 xmlOut.addTextElementToData(
"GroupType", groupType);
7417 int threadsLaunched = 0;
7418 int foundThreadIndex = 0;
7419 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
7420 for(
int i = 0; i < numOfThreads; ++i)
7421 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
7423 std::vector<std::shared_ptr<ots::GroupInfo>> sharedGroupInfoPtrs;
7424 std::string groupName, groupKey;
7426 for(
auto& aliasNodePair : aliasNodePairs)
7429 sharedGroupInfoPtrs.push_back(std::make_shared<ots::GroupInfo>());
7431 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7432 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7434 if(threadsLaunched >= numOfThreads)
7437 foundThreadIndex = -1;
7438 while(foundThreadIndex == -1)
7440 for(
int i = 0; i < numOfThreads; ++i)
7441 if(*(threadDone[i]))
7443 foundThreadIndex = i;
7446 if(foundThreadIndex == -1)
7448 __SUP_COUTT__ <<
"Waiting for available thread..." << __E__;
7452 threadsLaunched = numOfThreads - 1;
7454 __SUP_COUTT__ <<
"Starting load group thread... " << groupName <<
"("
7455 << groupKey <<
")" << __E__;
7456 *(threadDone[foundThreadIndex]) =
false;
7460 std::string theGroupName,
7462 std::shared_ptr<ots::GroupInfo> theGroupInfo,
7463 std::shared_ptr<std::atomic<bool>> theThreadDone) {
7473 sharedGroupInfoPtrs.back(),
7474 threadDone[foundThreadIndex])
7485 foundThreadIndex = -1;
7486 for(
int i = 0; i < numOfThreads; ++i)
7487 if(!*(threadDone[i]))
7489 foundThreadIndex = i;
7492 if(foundThreadIndex != -1)
7494 __SUP_COUTT__ <<
"Waiting for thread to finish... " << foundThreadIndex
7498 }
while(foundThreadIndex != -1);
7502 for(
auto& aliasNodePair : aliasNodePairs)
7504 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
7505 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
7507 if(groupKey != sharedGroupInfoPtrs[i]->getLatestKey().toString())
7509 __SUP_SS__ <<
"Error loading group information for the group alias '"
7510 << aliasNodePair.first <<
"' mapping to group '" << groupName
7511 <<
"(" << groupKey <<
")" << __E__;
7515 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
7516 xmlOut.addTextElementToData(
"GroupName", groupName);
7517 xmlOut.addTextElementToData(
7518 "GroupKey", sharedGroupInfoPtrs[i]->getLatestKey().toString());
7519 xmlOut.addTextElementToData(
7521 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7522 .getValueAsString());
7524 xmlOut.addTextElementToData(
7525 "GroupComment", sharedGroupInfoPtrs[i]->getLatestKeyGroupComment());
7526 xmlOut.addTextElementToData(
7527 "GroupAuthor", sharedGroupInfoPtrs[i]->getLatestKeyGroupAuthor());
7528 xmlOut.addTextElementToData(
7529 "GroupCreationTime",
7530 sharedGroupInfoPtrs[i]->getLatestKeyGroupCreationTime());
7531 xmlOut.addTextElementToData(
7532 "GroupType", sharedGroupInfoPtrs[i]->getLatestKeyGroupTypeString());
7551 void ConfigurationGUISupervisor::handleVersionAliasesXML(
HttpXmlDocument& xmlOut,
7555 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7557 std::string versionAliasesTableName =
7558 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7559 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7561 __SUP_SS__ <<
"Active version of VersionAliases missing!"
7562 <<
"Make sure you have a valid active Backbone Group." << __E__;
7563 xmlOut.addTextElementToData(
"Error", ss.str());
7566 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName
7567 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
7568 xmlOut.addTextElementToData(
"VersionAliasesVersion",
7569 activeVersions[versionAliasesTableName].toString());
7571 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
7574 for(
auto& aliasNodePair : aliasNodePairs)
7578 xmlOut.addTextElementToData(
7580 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
7581 xmlOut.addTextElementToData(
7582 "TableName", aliasNodePair.second.getNode(
"TableName").getValueAsString());
7583 xmlOut.addTextElementToData(
7584 "Version", aliasNodePair.second.getNode(
"Version").getValueAsString());
7585 xmlOut.addTextElementToData(
7587 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
7588 .getValueAsString());
7598 void ConfigurationGUISupervisor::handleGetTableGroupTypeXML(
7602 std::string name, versionStr;
7603 auto c = tableList.find(
',', 0);
7606 while(c < tableList.length())
7609 name = tableList.substr(i, c - i);
7611 c = tableList.find(
',', i);
7612 if(c == std::string::npos)
7614 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
7615 __SUP_COUT_ERR__ <<
"\n" << ss.str();
7616 xmlOut.addTextElementToData(
"Error", ss.str());
7620 versionStr = tableList.substr(i, c - i);
7622 c = tableList.find(
',', i);
7627 std::string groupTypeString =
"";
7633 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7635 catch(std::runtime_error& e)
7637 __SUP_SS__ <<
"Table group has invalid type! " << e.what() << __E__;
7638 __SUP_COUT__ <<
"\n" << ss.str();
7639 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7640 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7644 __SUP_SS__ <<
"Table group has invalid type! " << __E__;
7649 catch(
const std::exception& e)
7651 ss <<
"Exception message: " << e.what();
7656 __SUP_COUT__ <<
"\n" << ss.str();
7657 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7658 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
7678 void ConfigurationGUISupervisor::handleTableGroupsXML(
HttpXmlDocument& xmlOut,
7682 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7688 if(!cfgMgr->getAllGroupInfo().size() ||
7689 cfgMgr->getAllGroupInfo().begin()->second.getLatestKeyGroupTypeString() ==
"" ||
7690 cfgMgr->getAllGroupInfo().begin()->second.getLatestKeyGroupTypeString() ==
7691 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN ||
7693 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE) !=
7694 TableGroupKey::INVALID &&
7695 cfgMgr->getAllGroupInfo().find(cfgMgr->getActiveGroupName(
7696 ConfigurationManager::GroupType::CONTEXT_TYPE)) !=
7697 cfgMgr->getAllGroupInfo().end() &&
7698 (cfgMgr->getAllGroupInfo()
7699 .at(cfgMgr->getActiveGroupName(
7700 ConfigurationManager::GroupType::CONTEXT_TYPE))
7701 .getLatestKeyGroupTypeString() ==
"" ||
7702 cfgMgr->getAllGroupInfo()
7703 .at(cfgMgr->getActiveGroupName(
7704 ConfigurationManager::GroupType::CONTEXT_TYPE))
7705 .getLatestKeyGroupTypeString() ==
7706 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)) ||
7708 cfgMgr->getActiveGroupKey(
7709 ConfigurationManager::GroupType::CONFIGURATION_TYPE) !=
7710 TableGroupKey::INVALID &&
7711 cfgMgr->getAllGroupInfo().find(cfgMgr->getActiveGroupName(
7712 ConfigurationManager::GroupType::CONFIGURATION_TYPE)) !=
7713 cfgMgr->getAllGroupInfo().end() &&
7714 (cfgMgr->getAllGroupInfo()
7715 .at(cfgMgr->getActiveGroupName(
7716 ConfigurationManager::GroupType::CONFIGURATION_TYPE))
7717 .getLatestKeyGroupTypeString() ==
"" ||
7718 cfgMgr->getAllGroupInfo()
7719 .at(cfgMgr->getActiveGroupName(
7720 ConfigurationManager::GroupType::CONFIGURATION_TYPE))
7721 .getLatestKeyGroupTypeString() ==
7722 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)))
7725 <<
"Group Info cache appears empty or stale. Attempting to regenerate..."
7735 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
7737 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7739 std::string groupName;
7740 std::string groupString, groupTypeString, groupComment, groupCreationTime,
7742 for(
auto& groupInfo : allGroupInfo)
7744 groupName = groupInfo.first;
7749 if(groupInfo.second.getKeys().size() == 0)
7751 __SUP_COUT__ <<
"Group name '" << groupName
7752 <<
"' found, but no keys so ignoring." << __E__;
7756 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7757 xmlOut.dataSs_ <<
"<TableGroupKey value='" << groupInfo.second.getLatestKey()
7761 xmlOut.dataSs_ <<
"<TableGroupType value='"
7762 << groupInfo.second.getLatestKeyGroupTypeString() <<
"'/>"
7764 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7766 groupInfo.second.getLatestKeyGroupComment(),
7769 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7770 << groupInfo.second.getLatestKeyGroupAuthor() <<
"'/>" << __E__;
7771 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7772 << groupInfo.second.getLatestKeyGroupCreationTime() <<
"'/>"
7778 xmlOut.dataSs_ <<
"<TableGroupMembers value=''>" << __E__;
7780 for(
auto& memberPair : groupInfo.second.getLatestKeyMemberMap())
7782 xmlOut.dataSs_ <<
"\t<MemberName value='" << memberPair.first <<
"'/>"
7784 xmlOut.dataSs_ <<
"\t<MemberVersion value='" << memberPair.second <<
"'/>"
7791 xmlOut.dataSs_ <<
"</TableGroupMembers>" << __E__;
7796 for(
auto& keyInSet : groupInfo.second.getKeys())
7798 if(keyInSet == groupInfo.second.getLatestKey())
7801 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
7802 xmlOut.dataSs_ <<
"<TableGroupKey value='" << keyInSet <<
"'/>" << __E__;
7807 bool loadingHistoricalInfo =
false;
7808 if(loadingHistoricalInfo)
7827 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
7828 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
7830 <<
")' to extract group comment and type." << __E__;
7833 xmlOut.dataSs_ <<
"<TableGroupType value='" << groupTypeString <<
"'/>"
7835 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7839 xmlOut.dataSs_ <<
"<TableGroupAuthor value='" << groupAuthor <<
"'/>"
7841 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='" << groupCreationTime
7851 xmlOut.dataSs_ <<
"<TableGroupType value='"
7852 << groupInfo.second.getLatestKeyGroupTypeString() <<
"'/>"
7855 xmlOut.dataSs_ <<
"<TableGroupComment value='"
7858 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
7861 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
7869 xmlOut.dataSs_ <<
"<TableGroupMembers/>" << __E__;
7874 __SUP_COUTT__ << groupName <<
" runtime=" << cfgMgr->runTimeSeconds() << __E__;
7876 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
7891 void ConfigurationGUISupervisor::handleTablesXML(
HttpXmlDocument& xmlOut,
7894 if(cfgMgr->getAllGroupInfo().size() == 0 || cfgMgr->
getActiveVersions().size() == 0)
7896 __SUP_COUT__ <<
"Table Info cache appears empty. Attempting to regenerate."
7906 xercesc::DOMElement* parentEl;
7907 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
7910 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
7911 for(
const auto& tablePair : allTableInfo)
7912 orderedTableSet.emplace(tablePair.first);
7916 __SUP_COUT__ <<
"# of tables found: " << allTableInfo.size() << __E__;
7918 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
7921 __SUP_COUT__ <<
"# of tables w/aliases: " << versionAliases.size() << __E__;
7923 for(
const auto& orderedTableName : orderedTableSet)
7926 std::map<std::string, TableInfo>::const_iterator it =
7927 allTableInfo.find(orderedTableName);
7928 if(it == allTableInfo.end())
7930 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
7939 xmlOut.addTextElementToData(
"TableName", it->first);
7940 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
7943 if(versionAliases.find(it->first) != versionAliases.end())
7944 for(
auto& aliasVersion : versionAliases[it->first])
7945 if(it->second.versions_.find(aliasVersion.second) !=
7946 it->second.versions_
7950 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
7958 auto vSpanToXML = [](
auto const& sortedKeys,
auto& xmlOut,
auto& configEl) {
7960 size_t lo = -1, hi = -1;
7961 for(
auto& keyInOrder : sortedKeys)
7964 if(keyInOrder.isScratchVersion())
7967 if(lo ==
size_t(-1))
7969 hi = lo = keyInOrder.
version();
7972 else if(hi + 1 == keyInOrder.version())
7980 xmlOut.addNumberElementToParent(
"Version", lo, configEl);
7982 xmlOut.addTextElementToParent(
7984 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
7986 hi = lo = keyInOrder.
version();
7989 if(lo !=
size_t(-1))
7992 xmlOut.addNumberElementToParent(
"Version", lo, configEl);
7994 xmlOut.addTextElementToParent(
7996 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
8001 vSpanToXML(it->second.versions_, xmlOut, parentEl);
8014 void ConfigurationGUISupervisor::handleGetArtdaqNodeRecordsXML(
8017 const std::string& modifiedTables)
8019 __COUT__ <<
"Retrieving artdaq nodes..." << __E__;
8022 setupActiveTablesXML(
8023 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
8025 std::map<std::string ,
8026 std::map<std::string , std::vector<std::string >>>
8027 nodeTypeToObjectMap;
8028 std::map<std::string , std::string >
8031 std::vector<std::string > artdaqSupervisorInfo;
8033 std::string artdaqSupervisorName;
8035 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap, artdaqSupervisorInfo);
8037 if(artdaqSupervisorInfo.size() != 4 )
8039 __SUP_COUT__ <<
"No artdaq supervisor found." << __E__;
8043 __SUP_COUT__ <<
"========== "
8044 <<
"Found " << info.subsystems.size() <<
" subsystems." << __E__;
8046 unsigned int paramIndex = 0;
8048 auto parentEl = xmlOut.addTextElementToData(
"artdaqSupervisor",
8049 artdaqSupervisorInfo[paramIndex++]);
8051 std::string typeString =
"artdaqSupervisor";
8054 typeString +
"-status", artdaqSupervisorInfo[paramIndex++], parentEl);
8056 typeString +
"-contextAddress", artdaqSupervisorInfo[paramIndex++], parentEl);
8058 typeString +
"-contextPort", artdaqSupervisorInfo[paramIndex++], parentEl);
8060 for(
auto& subsystem : info.subsystems)
8062 typeString =
"subsystem";
8064 __SUP_COUT__ <<
"\t\t"
8065 <<
"Found " << typeString <<
" " << subsystem.first <<
" \t := '"
8066 << subsystem.second.label <<
"'" << __E__;
8070 typeString +
"-id", std::to_string(subsystem.first), parentEl);
8073 std::to_string(subsystem.second.sources.size()),
8078 std::to_string(subsystem.second.destination),
8083 __SUP_COUT__ <<
"========== "
8084 <<
"Found " << nodeTypeToObjectMap.size() <<
" process types." << __E__;
8086 for(
auto& nameTypePair : nodeTypeToObjectMap)
8088 typeString = nameTypePair.first;
8090 __SUP_COUT__ <<
"\t"
8091 <<
"Found " << nameTypePair.second.size() <<
" " << typeString
8094 for(
auto& artdaqNode : nameTypePair.second)
8096 __SUP_COUT__ <<
"\t\t"
8097 <<
"Found '" << artdaqNode.first <<
"' " << typeString << __E__;
8100 if(artdaqNode.second.size() < 2)
8102 __SUP_SS__ <<
"Impossible parameter size for node '" << artdaqNode.first
8103 <<
"' " << typeString <<
" - please notify admins!" << __E__;
8111 if(artdaqNode.second.size() > paramIndex)
8113 __SUP_COUTT__ <<
"\t\t\t"
8114 <<
"-multinode: " << artdaqNode.second[paramIndex] << __E__;
8116 typeString +
"-multinode", artdaqNode.second[paramIndex++], nodeEl);
8118 if(artdaqNode.second.size() > paramIndex)
8120 __SUP_COUTT__ <<
"\t\t\t"
8121 <<
"-nodefixedwidth: " << artdaqNode.second[paramIndex]
8124 artdaqNode.second[paramIndex++],
8127 if(artdaqNode.second.size() > paramIndex)
8129 __SUP_COUTT__ <<
"\t\t\t"
8130 <<
"-hostarray: " << artdaqNode.second[paramIndex] << __E__;
8132 typeString +
"-hostarray", artdaqNode.second[paramIndex++], nodeEl);
8134 if(artdaqNode.second.size() > paramIndex)
8136 __SUP_COUTT__ <<
"\t\t\t"
8137 <<
"-hostfixedwidth: " << artdaqNode.second[paramIndex]
8140 artdaqNode.second[paramIndex++],
8145 __SUP_COUTT__ <<
"\t\t\t"
8146 <<
"-status: " << artdaqNode.second[paramIndex] << __E__;
8148 typeString +
"-status", artdaqNode.second[paramIndex++], parentEl);
8149 __SUP_COUTT__ <<
"\t\t\t"
8150 <<
"-hostname: " << artdaqNode.second[paramIndex] << __E__;
8152 typeString +
"-hostname", artdaqNode.second[paramIndex++], parentEl);
8153 __SUP_COUTT__ <<
"\t\t\t"
8154 <<
"-subsystem: " << artdaqNode.second[paramIndex] << __E__;
8156 typeString +
"-subsystem", artdaqNode.second[paramIndex], parentEl);
8160 __SUP_COUT__ <<
"Done retrieving artdaq nodes." << __E__;
8171 void ConfigurationGUISupervisor::handleSaveArtdaqNodeRecordsXML(
8172 const std::string& nodeString,
8173 const std::string& subsystemString,
8176 const std::string& modifiedTables)
8178 __SUP_COUT__ <<
"Saving artdaq nodes..." << __E__;
8181 setupActiveTablesXML(
8182 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
8185 std::map<std::string ,
8186 std::map<std::string , std::vector<std::string >>>
8187 nodeTypeToObjectMap;
8193 std::map<std::string , std::string >
8194 nodeTypeToStringMap;
8199 for(
auto& typePair : nodeTypeToStringMap)
8201 if(typePair.first ==
"")
8206 nodeTypeToObjectMap.emplace(
8208 std::map<std::string ,
8209 std::vector<std::string /*property*/>>()));
8211 std::map<std::string , std::string >
8212 nodeRecordToStringMap;
8215 typePair.second, nodeRecordToStringMap, {
';'}, {
'='});
8219 for(
auto& nodePair : nodeRecordToStringMap)
8221 if(nodePair.first ==
"")
8226 std::vector<std::string > nodePropertyVector;
8229 nodePair.second, nodePropertyVector, {
','});
8234 for(
unsigned int i = 0; i < nodePropertyVector.size(); ++i)
8239 nodePropertyVector[i] =
8243 nodeTypeToObjectMap[typePair.first].emplace(
8245 nodePropertyVector));
8251 std::map<std::string , std::string >
8258 std::map<std::string , std::string >
8259 tmpSubsystemObjectMap;
8261 subsystemString, tmpSubsystemObjectMap, {
';'}, {
':'});
8266 for(
auto& subsystemPair : tmpSubsystemObjectMap)
8271 subsystemObjectMap.emplace(
8278 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap);
8280 __SUP_COUT__ <<
"Done saving artdaq nodes." << __E__;
8290 void ConfigurationGUISupervisor::handleLoadArtdaqNodeLayoutXML(
8294 const std::string& contextGroupName ,
8297 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
8300 const std::string& finalContextGroupName =
8302 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8306 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8308 const std::string& finalConfigGroupName =
8309 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8311 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8316 std::stringstream layoutPath;
8317 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8318 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
8319 << finalConfigGroupKey <<
".dat";
8321 fp = fopen(layoutPath.str().c_str(),
"r");
8324 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8325 << finalContextGroupKey <<
") + " << finalConfigGroupName <<
"("
8326 << finalConfigGroupKey <<
")': " << layoutPath.
str() << __E__;
8330 __SUP_COUTV__(layoutPath.str());
8335 std::stringstream layoutPath;
8336 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8337 <<
"_" << finalContextGroupKey <<
".dat";
8338 __SUP_COUTV__(layoutPath.str());
8340 fp = fopen(layoutPath.str().c_str(),
"r");
8343 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
8344 << finalContextGroupKey <<
")': " << layoutPath.str() << __E__;
8348 __SUP_COUTV__(layoutPath.str());
8355 const size_t maxLineSz = 1000;
8356 char line[maxLineSz];
8357 if(!fgets(line, maxLineSz, fp))
8366 unsigned int rows, cols;
8368 sscanf(line,
"%u %u", &rows, &cols);
8370 __COUT__ <<
"Grid rows,cols = " << rows <<
"," << cols << __E__;
8372 xmlOut.addTextElementToData(
"grid-rows", std::to_string(rows));
8373 xmlOut.addTextElementToData(
"grid-cols", std::to_string(cols));
8376 char name[maxLineSz];
8377 char type[maxLineSz];
8379 while(fgets(line, maxLineSz, fp))
8382 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
8384 xmlOut.addTextElementToData(
"node-type", type);
8385 xmlOut.addTextElementToData(
"node-name", name);
8386 xmlOut.addTextElementToData(
"node-x", std::to_string(x));
8387 xmlOut.addTextElementToData(
"node-y", std::to_string(y));
8401 void ConfigurationGUISupervisor::handleSaveArtdaqNodeLayoutXML(
8404 const std::string& layoutString,
8405 const std::string& contextGroupName,
8408 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
8410 const std::string& finalContextGroupName =
8412 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
8416 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
8418 const std::string& finalConfigGroupName =
8419 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8421 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
8423 __SUP_COUTV__(layoutString);
8425 std::stringstream layoutPath;
8426 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
8427 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
8428 << finalConfigGroupKey <<
".dat";
8429 __SUP_COUTV__(layoutPath.str());
8434 if(fields.size() < 2 || (fields.size() - 2) % 4 != 0)
8436 __SUP_SS__ <<
"Invalid layout string fields size of " << fields.size() << __E__;
8440 FILE* fp = fopen(layoutPath.str().c_str(),
"w");
8443 __SUP_SS__ <<
"Could not open layout file for writing for '"
8444 << finalContextGroupName <<
"(" << finalContextGroupKey <<
") + "
8445 << finalConfigGroupName <<
"(" << finalConfigGroupKey
8446 <<
")': " << layoutPath.
str() << __E__;
8453 fprintf(fp,
"%s %s\n", fields[0].c_str(), fields[1].c_str());
8456 for(
unsigned int i = 2; i < fields.size(); i += 4)
8459 fields[i + 0].c_str(),
8460 fields[i + 1].c_str(),
8461 fields[i + 2].c_str(),
8462 fields[i + 3].c_str());
8470 void ConfigurationGUISupervisor::handleOtherSubsystemActiveGroups(
8474 std::string targetSubsystem )
8480 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8483 for(
auto subsystem : children)
8485 __SUP_COUTV__(subsystem.first);
8489 std::string userPath =
8490 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8491 __SUP_COUTV__(userPath);
8494 catch(
const std::runtime_error& e)
8496 __SUP_COUT__ <<
"Ignoring errors in handling other subsystem active groups "
8497 "(assuming the subsystem information map is not setup in "
8498 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8499 <<
") -- here is the error: \n"
8500 << e.what() << __E__;
8507 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
8509 for(
auto subsystem : children)
8511 if(targetSubsystem !=
"" && targetSubsystem != subsystem.first)
8514 xercesc::DOMElement* parent =
8515 xmlOut.addTextElementToData(
"SubsystemName", subsystem.first);
8520 std::string filename, userDataPath;
8521 std::string username, hostname;
8523 std::map<std::string ,
8525 retMap = cfgMgr->getOtherSubsystemActiveTableGroups(
8526 subsystem.first, &userDataPath, &hostname, &username);
8528 for(
const auto& retPair : retMap)
8531 retPair.second.first,
8534 retPair.second.second.toString(),
8538 std::vector<std::string> filenameTypes = {
"Configured",
8542 "ActivatedBackbone",
8543 "ActivatedIterator"};
8545 std::vector<std::string> filenames = {
8546 FSM_LAST_CONFIGURED_GROUP_ALIAS_FILE,
8547 FSM_LAST_STARTED_GROUP_ALIAS_FILE,
8548 ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE,
8549 ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE,
8550 ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE,
8551 ConfigurationManager::LAST_ACTIVATED_ITERATOR_GROUP_FILE};
8553 std::string userPath =
8554 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
8556 std::string cmdResult;
8557 for(
unsigned int i = 0; i < filenames.size(); ++i)
8559 filename = userDataPath +
"/ServiceData/RunControlData/" + filenames[i];
8560 __SUP_COUTV__(filename);
8562 std::string tmpSubsystemFilename =
8563 ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" + filenames[i] +
8564 "." + subsystem.first;
8565 __SUP_COUTV__(tmpSubsystemFilename);
8567 if(splitPath.size() == 2)
8571 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + username +
8572 "@" + hostname +
":" + filename +
" " + tmpSubsystemFilename +
8573 " 2>&1; cat " + tmpSubsystemFilename +
" 2>&1")
8577 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + hostname +
8578 ":" + filename +
" " + tmpSubsystemFilename +
" 2>&1; cat " +
8579 tmpSubsystemFilename +
" 2>&1")
8582 else if(splitPath.size() == 1)
8585 " 2>/dev/null; cp " + filename +
" " +
8586 tmpSubsystemFilename +
" 2>&1; cat " +
8587 tmpSubsystemFilename +
" 2>&1")
8591 __SUP_COUTV__(cmdResult);
8592 std::string timeString;
8595 filenames[i] +
"." + subsystem.first, timeString);
8599 "Last" + filenameTypes[i] +
"GroupName", theGroup.first, parent);
8601 theGroup.second.toString(),
8604 "Last" + filenameTypes[i] +
"GroupTime", timeString, parent);
8609 catch(
const std::runtime_error& e)
8612 <<
"An error occurred handling subsystem active groups (Please check the "
8613 "subsystem user data path information map setup in the Context group table "
8614 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
8615 <<
") -- here is the error: \n"
8616 << e.what() << __E__;
8622 void ConfigurationGUISupervisor::handleGroupDiff(
8625 const std::string& groupName,
8628 const std::string& diffGroupNameInput )
8634 std::string diffGroupName;
8637 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8638 <<
") with the active group." << __E__;
8641 if(diffGroupNameInput ==
"")
8642 diffGroupName = groupName;
8644 diffGroupName = diffGroupNameInput;
8646 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
8647 <<
") with group " << diffGroupName <<
"(" << diffKey <<
")"
8653 std::map<std::string ,
TableVersion > memberMap, diffMemberMap;
8654 std::string groupType, accumulateErrors;
8655 std::stringstream diffReport;
8656 bool noDifference =
true;
8675 std::map<std::string , std::pair<std::string, TableGroupKey>>
8682 __SUP_COUTV__(groupType);
8684 if(activeGroups.find(groupType) == activeGroups.end() ||
8685 activeGroups.at(groupType).first ==
"" ||
8686 activeGroups.at(groupType).second.isInvalid())
8688 __SUP_SS__ <<
"Could not find an active group of type '" << groupType
8689 <<
".' Please check the expected active configuration groups "
8690 "for errors (going to 'System View' of the Config App may "
8696 __SUP_COUT__ <<
"active " << groupType <<
" group is "
8697 << activeGroups.at(groupType).first <<
"("
8698 << activeGroups.at(groupType).second <<
")" << __E__;
8700 diffReport <<
"This difference report is between " << groupType
8701 <<
" group <b>'" << groupName <<
"(" << groupKey <<
")'</b>"
8702 <<
" and active group <b>'" << activeGroups.at(groupType).first
8703 <<
"(" << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8706 activeGroups.at(groupType).second,
8716 diffReport <<
"\n\n"
8717 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8718 << memberMap.size() <<
" member tables</b>, and "
8719 <<
"'" << activeGroups.at(groupType).first <<
"("
8720 << activeGroups.at(groupType).second <<
")' has <b>"
8721 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8725 diffReport <<
"This difference report is between group <b>'" << groupName
8726 <<
"(" << groupKey <<
")'</b>"
8727 <<
" and group <b>'" << diffGroupName <<
"(" << diffKey
8728 <<
")'</b>." << __E__;
8741 diffReport <<
"\n\n"
8742 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
8743 << memberMap.size() <<
" member tables</b>, and "
8744 <<
"'" << diffGroupName <<
"(" << diffKey <<
")' has <b>"
8745 << diffMemberMap.size() <<
" member tables</b>." << __E__;
8750 diffReport <<
"<INDENT><ol>";
8752 unsigned int tableDifferences = 0;
8754 for(
auto& member : memberMap)
8756 if(diffMemberMap.find(member.first) == diffMemberMap.end())
8758 diffReport <<
"\n\n<li>"
8759 <<
"Table <b>" << member.first <<
"-v" << member.second
8760 <<
"</b> not found in active group."
8761 <<
"</li>" << __E__;
8762 noDifference =
false;
8767 __SUP_COUTT__ <<
"Comparing " << member.first <<
"-v" << member.second
8768 <<
" ... " << member.first <<
"-v"
8769 << diffMemberMap.at(member.first) << __E__;
8771 if(member.second == diffMemberMap.at(member.first))
8774 diffReport <<
"\n\n<li>"
8775 <<
"Table <b>" << member.first <<
" v" << member.second
8776 <<
"</b> in " << groupName <<
"(" << groupKey <<
")' ...vs... "
8777 <<
" <b>v" << diffMemberMap.at(member.first) <<
"</b> in "
8778 << diffGroupName <<
"(" << diffKey <<
")':" << __E__;
8782 diffReport <<
"<ul>";
8783 std::map<std::string , std::vector<std::string >>
8786 diffMemberMap.at(member.first),
8791 noDifference =
false;
8794 xmlOut.addTextElementToData(
"TableWithDiff", member.first);
8795 for(
auto& modifiedRecord : modifiedRecords)
8798 "RecordWithDiff", modifiedRecord.first, parentEl);
8799 for(
auto& modifiedColumn : modifiedRecord.second)
8801 "ColNameWithDiff", modifiedColumn, recordParentEl);
8804 diffReport <<
"</ul></li>";
8808 for(
auto& diffMember : diffMemberMap)
8810 if(memberMap.find(diffMember.first) == memberMap.end())
8813 diffReport <<
"\n\n<li>"
8814 <<
"Active Group Table <b>" << diffMember.first <<
"-v"
8815 << diffMember.second <<
"</b> not found in '" << groupName
8816 <<
"(" << groupKey <<
")'."
8817 <<
"</li>" << __E__;
8819 diffReport <<
"\n\n<li>" << diffGroupName <<
"(" << diffKey
8820 <<
") Table <b>" << diffMember.first <<
"-v"
8821 << diffMember.second <<
"</b> not found in '" << groupName
8822 <<
"(" << groupKey <<
")'."
8823 <<
"</li>" << __E__;
8825 noDifference =
false;
8830 diffReport <<
"\n</ol></INDENT>";
8835 diffReport <<
"\n\nNo difference found between "
8836 <<
"<b>'" << groupName <<
"(" << groupKey
8837 <<
")'</b> and active group "
8838 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8839 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8841 diffReport <<
"\n\n<b>" << tableDifferences
8842 <<
"</b> member table differences identified between "
8843 <<
"<b>'" << groupName <<
"(" << groupKey
8844 <<
")'</b> and active group "
8845 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
8846 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
8851 diffReport <<
"\n\nNo difference found between "
8852 <<
"<b>'" << groupName <<
"(" << groupKey
8853 <<
")'</b> and group "
8854 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8857 diffReport <<
"\n\n<b>" << tableDifferences
8858 <<
"</b> member table differences identified between "
8859 <<
"<b>'" << groupName <<
"(" << groupKey
8860 <<
")'</b> and group "
8861 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
8865 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
8866 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
8868 catch(
const std::runtime_error& e)
8870 __SUP_COUT_ERR__ <<
"Caught error while differencing group " << groupName <<
"("
8871 << groupKey <<
") with group " << diffGroupName <<
"(" << diffKey
8872 <<
")" << __E__ << e.what() << __E__;
8879 void ConfigurationGUISupervisor::handleTableDiff(
HttpXmlDocument& xmlOut,
8881 const std::string& tableName,
8885 __SUP_COUT__ <<
"Differencing tableName " << tableName <<
" v" << vA <<
" with v"
8895 std::string localAccumulatedErrors =
"";
8899 &localAccumulatedErrors,
8902 if(localAccumulatedErrors !=
"")
8903 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8905 catch(std::runtime_error& e)
8907 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vA;
8908 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8909 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8911 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8915 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vA << __E__;
8920 catch(
const std::exception& e)
8922 ss <<
"Exception message: " << e.what();
8928 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8929 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8935 std::string localAccumulatedErrors =
"";
8939 &localAccumulatedErrors,
8942 if(localAccumulatedErrors !=
"")
8943 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
8945 catch(std::runtime_error& e)
8947 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vB;
8948 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
8949 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8951 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8955 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vB << __E__;
8960 catch(
const std::exception& e)
8962 ss <<
"Exception message: " << e.what();
8968 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8969 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
8972 bool noDifference =
true;
8973 std::stringstream diffReport;
8975 diffReport <<
"This difference report is between table " << tableName <<
" v" << vA
8976 <<
" and v" << vB <<
"</b>." << __E__;
8978 diffReport <<
"<INDENT>";
8979 diffReport <<
"<ul>";
8980 std::map<std::string , std::vector<std::string >>
8983 noDifference =
false;
8984 diffReport <<
"</ul></INDENT>";
8986 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
8987 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
8993 void ConfigurationGUISupervisor::testXDAQContext()
8997 __SUP_COUT_INFO__ <<
"Attempting test activation of the context group." << __E__;
9001 catch(
const std::runtime_error& e)
9004 <<
"The test activation of the context group failed. Ignoring error: \n"
9005 << e.what() << __E__;
9010 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring."
9015 __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)
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
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)