1 #include "otsdaq-utilities/ConfigurationGUI/ConfigurationGUISupervisor.h"
3 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
4 #include "otsdaq/Macros/CoutMacros.h"
5 #include "otsdaq/Macros/StringMacros.h"
6 #include "otsdaq/MessageFacility/MessageFacility.h"
7 #include "otsdaq/TablePlugins/IterateTable.h"
8 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
10 #include <boost/stacktrace.hpp>
12 #include "otsdaq/GatewaySupervisor/GatewaySupervisor.h"
13 #include "otsdaq/TablePlugins/ARTDAQTableBase/ARTDAQTableBase.h"
14 #include "otsdaq/TablePlugins/XDAQContextTable/XDAQContextTable.h"
16 #include <xdaq/NamespaceURI.h>
27 #define __MF_SUBJECT__ "CfgGUI"
29 #define TABLE_INFO_PATH std::string(__ENV__("TABLE_INFO_PATH")) + "/"
30 #define TABLE_INFO_EXT std::string("Info.xml")
46 __SUP_COUT__ <<
"Constructor started." << __E__;
51 mkdir(((std::string)ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH).c_str(), 0755);
54 __SUP_COUT__ <<
"Constructor complete." << __E__;
58 ConfigurationGUISupervisor::~ConfigurationGUISupervisor(
void) { destroy(); }
61 void ConfigurationGUISupervisor::init(
void)
63 __SUP_COUT__ <<
"Initializing..." << __E__;
67 __SUP_COUT__ <<
"Activating saved context, which may prepare for normal mode..."
72 __SUP_COUT__ <<
"Done with test context." << __E__;
76 __COUT_WARN__ <<
"Failed test context group activation. otsdaq, in Normal mode, "
77 "will not launch when this test fails. "
78 <<
"Check the active context group from within Wizard Mode."
83 refreshUserSession(
"" , 1);
86 if(CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
89 <<
"After successful Config GUI init, marking alive for wiz mode!" << __E__;
90 CorePropertySupervisorBase::
96 void ConfigurationGUISupervisor::destroy(
void)
98 __SUP_COUT__ <<
"Destructing..." << __E__;
101 for(std::map<std::string, ConfigurationManagerRW*>::iterator it =
102 userConfigurationManagers_.begin();
103 it != userConfigurationManagers_.end();
109 userConfigurationManagers_.clear();
111 if(ConfigurationInterface::getInstance() !=
nullptr)
112 delete ConfigurationInterface::getInstance();
117 void ConfigurationGUISupervisor::defaultPage(xgi::Input* in, xgi::Output* out)
119 cgicc::Cgicc cgiIn(in);
120 std::string configWindowName =
122 if(configWindowName ==
"tableEditor")
123 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
124 "src='/WebPath/html/ConfigurationTableEditor.html?urn="
125 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
126 if(configWindowName ==
"iterate")
127 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
128 "src='/WebPath/html/Iterate.html?urn="
129 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
131 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
132 "src='/WebPath/html/ConfigurationGUI.html?urn="
133 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
141 CorePropertySupervisorBase::setSupervisorProperty(
142 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
143 "*=10 | deleteTreeNodeRecords=255 | saveTableInfo=255 | "
144 "deleteTableInfo=255");
146 CorePropertySupervisorBase::setSupervisorProperty(
147 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.RequireUserLockRequestTypes,
151 CorePropertySupervisorBase::setSupervisorProperty(
152 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
"get*");
160 CorePropertySupervisorBase::addSupervisorProperty(
161 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
162 "getActiveTableGroups");
165 CorePropertySupervisorBase::setSupervisorProperty(
166 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.CheckUserLockRequestTypes,
171 void ConfigurationGUISupervisor::request(
const std::string& requestType,
174 const WebUsers::RequestUserInfo& userInfo)
179 __COUTTV__(requestType);
252 refreshUserSession(userInfo.username_, (refresh ==
"1"));
253 __COUTTV__(userInfo.username_);
259 const std::set<TableGroupKey>& sortedKeys = groupInfo.getKeys();
260 __COUTTV__(sortedKeys.size());
263 if(requestType ==
"saveTableInfo")
265 std::string tableName =
267 std::string columnCSV =
269 std::string allowOverwrite =
271 std::string tableDescription =
273 std::string columnChoicesCSV =
276 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
277 __SUP_COUT__ <<
"columnCSV: " << columnCSV << __E__;
278 __SUP_COUT__ <<
"tableDescription: " << tableDescription << __E__;
279 __SUP_COUT__ <<
"columnChoicesCSV: " << columnChoicesCSV << __E__;
280 __SUP_COUT__ <<
"allowOverwrite: " << allowOverwrite << __E__;
282 if(!allSupervisorInfo_.isWizardMode())
284 __SUP_SS__ <<
"Improper permissions for saving table info." << __E__;
285 xmlOut.addTextElementToData(
"Error", ss.str());
288 handleSaveTableInfoXML(xmlOut,
294 allowOverwrite ==
"1");
296 else if(requestType ==
"deleteTableInfo")
298 std::string tableName =
300 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
301 handleDeleteTableInfoXML(xmlOut, cfgMgr, tableName);
303 else if(requestType ==
"gatewayLaunchOTS" || requestType ==
"gatewayLaunchWiz" ||
304 requestType ==
"flattenToSystemAliases")
307 __SUP_COUT_WARN__ << requestType <<
" command received! " << __E__;
308 __COUT_WARN__ << requestType <<
" command received! " << __E__;
311 __SUP_COUT_INFO__ <<
"Launching " << requestType <<
"... " << __E__;
313 __SUP_COUT__ <<
"Extracting target context hostnames... " << __E__;
314 std::vector<std::string> hostnames;
317 if(requestType ==
"flattenToSystemAliases" &&
318 CorePropertySupervisorBase::allSupervisorInfo_.isWizardMode())
320 hostnames.push_back(__ENV__(
"OTS_CONFIGURATION_WIZARD_SUPERVISOR_SERVER"));
321 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
332 auto contexts = contextTable->getContexts();
334 for(
const auto& context : contexts)
341 for(i = 0; i < context.address_.size(); ++i)
342 if(context.address_[i] ==
'/')
344 hostnames.push_back(context.address_.substr(j));
345 __SUP_COUT__ <<
"hostname = " << hostnames.back() << __E__;
350 __SUP_SS__ <<
"The Configuration Manager could not be initialized to "
357 catch(
const std::exception& e)
359 ss <<
"Exception message: " << e.what();
365 __SUP_COUT_ERR__ <<
"\n" << ss.str();
370 if(hostnames.size() == 0)
372 __SUP_SS__ <<
"No hostnames found to launch command '" + requestType +
373 "'... Is there a valid Context group activated?"
375 __SUP_COUT_ERR__ <<
"\n" << ss.str();
377 xmlOut.addTextElementToData(
"Error", ss.str());
380 for(
const auto& hostname : hostnames)
382 std::string fn = (std::string(__ENV__(
"SERVICE_DATA_PATH")) +
383 "/StartOTS_action_" + hostname +
".cmd");
384 FILE* fp = fopen(fn.c_str(),
"w");
387 if(requestType ==
"gatewayLaunchOTS")
388 fprintf(fp,
"LAUNCH_OTS");
389 else if(requestType ==
"gatewayLaunchWiz")
390 fprintf(fp,
"LAUNCH_WIZ");
391 else if(requestType ==
"flattenToSystemAliases")
393 fprintf(fp,
"FLATTEN_TO_SYSTEM_ALIASES");
401 __SUP_COUT_ERR__ <<
"Unable to open command file: " << fn << __E__;
404 else if(requestType ==
"versionTracking" || requestType ==
"getVersionTracking")
407 if(requestType ==
"getVersionTracking")
411 __SUP_COUT__ <<
"type: " << type << __E__;
414 xmlOut.addTextElementToData(
415 "versionTrackingStatus",
416 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
417 else if(type ==
"ON")
419 ConfigurationInterface::setVersionTrackingEnabled(
true);
420 xmlOut.addTextElementToData(
421 "versionTrackingStatus",
422 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
424 else if(type ==
"OFF")
426 ConfigurationInterface::setVersionTrackingEnabled(
false);
427 xmlOut.addTextElementToData(
428 "versionTrackingStatus",
429 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
432 else if(requestType ==
"getColumnTypes")
435 std::vector<std::string> allTypes = TableViewColumnInfo::getAllTypesForGUI();
436 std::vector<std::string> allDataTypes =
437 TableViewColumnInfo::getAllDataTypesForGUI();
438 std::map<std::pair<std::string, std::string>, std::string> allDefaults =
441 for(
const auto& type : allTypes)
442 xmlOut.addTextElementToData(
"columnTypeForGUI", type);
443 for(
const auto& dataType : allDataTypes)
444 xmlOut.addTextElementToData(
"columnDataTypeForGUI", dataType);
446 for(
const auto& colDefault : allDefaults)
448 xmlOut.addTextElementToData(
"columnDefaultDataType", colDefault.first.first);
449 xmlOut.addTextElementToData(
"columnDefaultTypeFilter",
450 colDefault.first.second);
451 xmlOut.addTextElementToData(
"columnDefaultValue", colDefault.second);
455 else if(requestType ==
"getGroupAliases")
460 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"reloadActiveGroups");
462 __SUP_COUT__ <<
"reloadActive: " << reloadActive << __E__;
470 catch(std::runtime_error& e)
472 __SUP_SS__ << (
"Error loading active groups!\n\n" + std::string(e.what()))
474 __SUP_COUT_ERR__ <<
"\n" << ss.str();
475 xmlOut.addTextElementToData(
"Error", ss.str());
479 __SUP_SS__ << (
"Error loading active groups!\n\n") << __E__;
484 catch(
const std::exception& e)
486 ss <<
"Exception message: " << e.what();
491 __SUP_COUT_ERR__ <<
"\n" << ss.str();
492 xmlOut.addTextElementToData(
"Error", ss.str());
496 handleGroupAliasesXML(xmlOut, cfgMgr);
498 else if(requestType ==
"setGroupAliasInActiveBackbone")
500 std::string groupAliasCSV =
502 std::string groupNameCSV =
504 std::string groupKeyCSV =
507 __SUP_COUTV__(groupAliasCSV);
508 __SUP_COUTV__(groupNameCSV);
509 __SUP_COUTV__(groupKeyCSV);
511 handleSetGroupAliasInBackboneXML(
512 xmlOut, cfgMgr, groupAliasCSV, groupNameCSV, groupKeyCSV, userInfo.username_);
514 else if(requestType ==
"setTableAliasInActiveBackbone")
516 std::string tableAlias =
518 std::string tableName =
522 __SUP_COUT__ <<
"tableAlias: " << tableAlias << __E__;
523 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
524 __SUP_COUT__ <<
"version: " << version << __E__;
526 handleSetTableAliasInBackboneXML(xmlOut,
533 else if(requestType ==
"setAliasOfGroupMembers")
535 std::string versionAlias =
537 std::string groupName =
541 __SUP_COUT__ <<
"versionAlias: " << versionAlias << __E__;
542 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
543 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
545 handleAliasGroupMembersInBackboneXML(xmlOut,
552 else if(requestType ==
"getVersionAliases")
554 handleVersionAliasesXML(xmlOut, cfgMgr);
556 else if(requestType ==
"getTableGroups")
558 bool doNotReturnMembers =
559 CgiDataUtilities::getDataAsInt(cgiIn,
"doNotReturnMembers") == 1
563 __SUP_COUT__ <<
"doNotReturnMembers: " << doNotReturnMembers << __E__;
564 handleTableGroupsXML(xmlOut, cfgMgr, !doNotReturnMembers);
566 else if(requestType ==
"getTableGroupType")
568 std::string tableList =
570 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
572 handleGetTableGroupTypeXML(xmlOut, cfgMgr, tableList);
574 else if(requestType ==
"getTables")
580 filterMode =
"created";
581 __COUT__ <<
"startTime: " << filterStartTime << __E__;
582 __COUT__ <<
"endTime: " << filterEndTime << __E__;
583 __COUT__ <<
"filterMode: " << filterMode << __E__;
585 handleTablesXML(xmlOut, cfgMgr, filterStartTime, filterEndTime, filterMode);
587 else if(requestType ==
"getContextMemberNames")
589 std::set<std::string> members = cfgMgr->getFixedContextMemberNames();
591 for(
auto& member : members)
592 xmlOut.addTextElementToData(
"ContextMember", member);
594 else if(requestType ==
"getBackboneMemberNames")
596 std::set<std::string> members = cfgMgr->getBackboneMemberNames();
598 for(
auto& member : members)
599 xmlOut.addTextElementToData(
"BackboneMember", member);
601 else if(requestType ==
"getIterateMemberNames")
603 std::set<std::string> members = cfgMgr->getIterateMemberNames();
605 for(
auto& member : members)
606 xmlOut.addTextElementToData(
"IterateMember", member);
608 else if(requestType ==
"getSpecificTableGroup")
610 std::string groupName =
614 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
615 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
620 else if(requestType ==
"saveNewTableGroup")
622 std::string groupName =
624 bool ignoreWarnings =
625 CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
626 bool allowDuplicates =
627 CgiDataUtilities::getDataAsInt(cgiIn,
"allowDuplicates");
628 bool lookForEquivalent =
629 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
630 std::string tableList =
632 std::string comment =
635 __SUP_COUT__ <<
"saveNewTableGroup: " << groupName << __E__;
636 __SUP_COUT__ <<
"tableList: " << tableList << __E__;
637 __SUP_COUT__ <<
"ignoreWarnings: " << ignoreWarnings << __E__;
638 __SUP_COUT__ <<
"allowDuplicates: " << allowDuplicates << __E__;
639 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
640 __SUP_COUT__ <<
"comment: " << comment << __E__;
651 else if(requestType ==
"getSpecificTable")
653 std::string tableName =
656 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
657 int chunkSize = CgiDataUtilities::getDataAsInt(
660 bool descriptionOnly = CgiDataUtilities::getDataAsInt(
661 cgiIn,
"descriptionOnly");
662 bool allowIllegalColumns =
663 CgiDataUtilities::getDataAsInt(cgiIn,
"allowIllegalColumns");
664 bool rawData = CgiDataUtilities::getDataAsInt(cgiIn,
"rawData");
666 __SUP_COUT__ <<
"getSpecificTable: " << tableName <<
" versionStr: " << versionStr
667 <<
" chunkSize: " << chunkSize <<
" dataOffset: " << dataOffset
668 <<
" descriptionOnly: " << descriptionOnly
669 <<
" allowIllegalColumns: " << allowIllegalColumns
670 <<
" rawData: " << rawData << __E__;
673 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
675 if(allTableInfo.find(tableName) != allTableInfo.end())
677 if(versionStr ==
"" &&
678 allTableInfo.at(tableName).versions_.size())
681 auto it = allTableInfo.at(tableName).versions_.rbegin();
682 if(it->isScratchVersion())
686 else if(versionStr.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
689 std::map<std::string ,
693 std::string versionAlias;
694 versionAlias = versionStr.substr(
695 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
706 if(versionAliases.find(tableName) != versionAliases.end() &&
707 versionAliases[tableName].find(versionAlias) !=
708 versionAliases[tableName].end())
710 version = versionAliases[tableName][versionAlias];
711 __SUP_COUT__ <<
"version alias translated to: " << version << __E__;
716 << versionStr.substr(
717 ConfigurationManager::ALIAS_VERSION_PREAMBLE.size())
718 <<
"'was not found in active version aliases!" << __E__;
721 version = atoi(versionStr.c_str());
724 __SUP_COUT__ <<
"version: " << version << __E__;
726 handleGetTableXML(xmlOut,
734 xmlOut.addTextElementToData(
"DefaultRowValue", userInfo.username_);
736 else if(requestType ==
"saveSpecificTable")
738 std::string tableName =
740 int version = CgiDataUtilities::getDataAsInt(cgiIn,
"version");
741 int dataOffset = CgiDataUtilities::getDataAsInt(cgiIn,
"dataOffset");
742 bool sourceTableAsIs =
743 CgiDataUtilities::getDataAsInt(cgiIn,
"sourceTableAsIs");
744 bool lookForEquivalent =
745 CgiDataUtilities::getDataAsInt(cgiIn,
"lookForEquivalent");
746 int temporary = CgiDataUtilities::getDataAsInt(cgiIn,
"temporary");
747 std::string comment =
754 __SUP_COUT__ <<
"tableName: " << tableName <<
" version: " << version
755 <<
" temporary: " << temporary <<
" dataOffset: " << dataOffset
757 __SUP_COUT__ <<
"comment: " << comment << __E__;
758 __SUP_COUT__ <<
"data: " << data << __E__;
759 __SUP_COUT__ <<
"sourceTableAsIs: " << sourceTableAsIs << __E__;
760 __SUP_COUT__ <<
"lookForEquivalent: " << lookForEquivalent << __E__;
774 else if(requestType ==
"clearTableTemporaryVersions")
776 std::string tableName =
778 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
784 catch(std::runtime_error& e)
786 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
787 xmlOut.addTextElementToData(
788 "Error",
"Error clearing temporary views!\n " + std::string(e.what()));
792 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
793 xmlOut.addTextElementToData(
"Error",
"Error clearing temporary views! ");
796 else if(requestType ==
"clearTableCachedVersions")
798 std::string tableName =
800 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
811 catch(std::runtime_error& e)
813 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
814 xmlOut.addTextElementToData(
815 "Error",
"Error clearing cached views!\n " + std::string(e.what()));
819 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
820 xmlOut.addTextElementToData(
"Error",
"Error clearing cached views! ");
823 else if(requestType ==
"getGroupHistory")
830 __SUP_COUTV__(groupAction);
831 __SUP_COUTV__(groupType);
833 std::vector<std::map<std::string ,
836 groupAction, groupType,
true );
838 for(
const auto& group : groups)
840 auto parentEl = xmlOut.addTextElementToData(
841 "GroupHistoryEntry",
"");
842 for(
const auto& field : group)
846 else if(requestType ==
"getTreeView")
853 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
854 bool hideStatusFalse = CgiDataUtilities::getDataAsInt(cgiIn,
"hideStatusFalse");
858 __SUP_COUTT__ <<
"tableGroup: " << tableGroup << __E__;
859 __SUP_COUTT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
860 __SUP_COUTT__ <<
"startPath: " << startPath << __E__;
861 __SUP_COUTT__ <<
"depth: " << depth << __E__;
862 __SUP_COUTT__ <<
"hideStatusFalse: " << hideStatusFalse << __E__;
863 __SUP_COUTT__ <<
"modifiedTables: " << modifiedTables << __E__;
864 __SUP_COUTT__ <<
"filterList: " << filterList << __E__;
866 handleFillTreeViewXML(xmlOut,
878 else if(requestType ==
"getTreeNodeCommonFields")
886 int depth = CgiDataUtilities::getDataAsInt(cgiIn,
"depth");
888 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
889 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
890 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
891 __SUP_COUT__ <<
"depth: " << depth << __E__;
894 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
895 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
896 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
898 handleFillTreeNodeCommonFieldsXML(xmlOut,
908 else if(requestType ==
"getUniqueFieldValuesForRecords")
917 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
918 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
919 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
920 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
921 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
922 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
924 handleFillUniqueFieldValuesForRecordsXML(xmlOut,
933 else if(requestType ==
"getTreeNodeFieldValues")
942 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
943 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
944 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
945 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
946 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
947 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
949 handleFillGetTreeNodeFieldValuesXML(xmlOut,
958 else if(requestType ==
"setTreeNodeFieldValues")
968 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
969 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
970 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
971 __SUP_COUT__ <<
"fieldList: " << fieldList << __E__;
972 __SUP_COUT__ <<
"valueList: " << valueList << __E__;
973 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
974 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
976 handleFillSetTreeNodeFieldValuesXML(xmlOut,
987 else if(requestType ==
"addTreeNodeRecords")
995 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
996 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
997 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
998 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
999 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1001 handleFillCreateTreeNodeRecordsXML(xmlOut,
1008 userInfo.username_);
1010 else if(requestType ==
"deleteTreeNodeRecords")
1018 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1019 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1020 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1021 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1022 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1024 handleFillDeleteTreeNodeRecordsXML(xmlOut,
1032 else if(requestType ==
"renameTreeNodeRecords")
1041 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1042 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1043 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1044 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1045 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1046 __SUP_COUTV__(newRecordList);
1048 handleFillRenameTreeNodeRecordsXML(xmlOut,
1057 else if(requestType ==
"copyTreeNodeRecords")
1064 unsigned int numberOfCopies =
1065 CgiDataUtilities::getDataAsInt(cgiIn,
"numberOfCopies");
1069 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1070 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1071 __SUP_COUT__ <<
"startPath: " << startPath << __E__;
1072 __SUP_COUT__ <<
"recordList: " << recordList << __E__;
1073 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1074 __SUP_COUTV__(numberOfCopies);
1076 handleFillCopyTreeNodeRecordsXML(xmlOut,
1085 else if(requestType ==
"getTableStructureStatusAsJSON")
1092 __SUP_COUT__ <<
"tableGroup: " << tableGroup << __E__;
1093 __SUP_COUT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1094 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1095 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1098 setupActiveTablesXML(xmlOut,
1107 xmlOut.addTextElementToData(
1108 "StructureStatusAsJSON",
1111 catch(
const std::runtime_error& e)
1113 __SUP_SS__ <<
"The table plugin feature getStructureStatusAsJSON(), does not "
1114 "seem to be supported for the table '"
1116 <<
".' Make sure you have the expected table plugin in your path, "
1117 "or contact system admins."
1119 ss <<
"Here is the error: " << e.what() << __E__;
1123 else if(requestType ==
"getArtdaqNodes")
1130 bool suppressMultiNode =
1131 1 == CgiDataUtilities::getDataAsInt(cgiIn,
"suppressMultiNode");
1133 __SUP_COUTV__(modifiedTables);
1134 __SUP_COUTT__ <<
"tableGroup: " << tableGroup << __E__;
1135 __SUP_COUTT__ <<
"tableGroupKey: " << tableGroupKey << __E__;
1136 __SUP_COUTT__ <<
"contextGroup: " << contextGroup << __E__;
1137 __SUP_COUTT__ <<
"contextGroupKey: " << contextGroupKey << __E__;
1138 __SUP_COUTT__ <<
"suppressMultiNode: " << suppressMultiNode << __E__;
1140 handleGetArtdaqNodeRecordsXML(xmlOut,
1149 else if(requestType ==
"saveArtdaqNodes")
1153 std::string subsystemString =
1156 __SUP_COUTV__(modifiedTables);
1157 __SUP_COUTV__(nodeString);
1158 __SUP_COUTV__(subsystemString);
1160 handleSaveArtdaqNodeRecordsXML(
1161 nodeString, subsystemString, xmlOut, cfgMgr, modifiedTables);
1163 else if(requestType ==
"getArtdaqNodeLayout")
1165 std::string contextGroupName =
1169 __SUP_COUTV__(contextGroupName);
1170 __SUP_COUTV__(contextGroupKey);
1172 handleLoadArtdaqNodeLayoutXML(
1173 xmlOut, cfgMgr, contextGroupName,
TableGroupKey(contextGroupKey));
1175 else if(requestType ==
"saveArtdaqNodeLayout")
1178 std::string contextGroupName =
1182 __SUP_COUTV__(layout);
1183 __SUP_COUTV__(contextGroupName);
1184 __SUP_COUTV__(contextGroupKey);
1186 handleSaveArtdaqNodeLayoutXML(
1187 xmlOut, cfgMgr, layout, contextGroupName,
TableGroupKey(contextGroupKey));
1189 else if(requestType ==
"checkAffectedActiveGroups")
1194 __SUP_COUT__ <<
"modifiedTables: " << modifiedTables << __E__;
1195 __SUP_COUT__ <<
"groupName: " << groupName << __E__;
1196 __SUP_COUT__ <<
"groupKey: " << groupKey << __E__;
1198 handleGetAffectedGroupsXML(
1199 xmlOut, cfgMgr, groupName,
TableGroupKey(groupKey), modifiedTables);
1201 else if(requestType ==
"SearchFieldInGroup")
1215 __SUP_COUT__ <<
"searchText: " << searchText << __E__;
1216 __SUP_COUT__ <<
"filterValue: " << filterValue << __E__;
1217 __SUP_COUT__ <<
"groupType: " << groupType << __E__;
1218 __SUP_COUT__ <<
"optionGroups: " << optionGroups << __E__;
1219 __SUP_COUT__ <<
"versionsToCheck: " << versionsToCheck << __E__;
1221 handleSearchFieldInGroupXML(xmlOut,
1224 (filterValue ==
"true"),
1229 else if(requestType ==
"SearchFieldInTableVersions")
1233 std::string searchVersionToCheck =
1242 __SUP_COUT__ <<
"searchText: " << searchText << __E__;
1243 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1244 __SUP_COUT__ <<
"searchVersionToCheck: " << searchVersionToCheck << __E__;
1245 __SUP_COUT__ <<
"activeTablesOnly: " << activeTablesOnly << __E__;
1247 handleSearchFieldInTableXML(xmlOut,
1251 searchVersionToCheck,
1252 (activeTablesOnly ==
"true"));
1254 else if(requestType ==
"saveTreeNodeEdit")
1258 std::string targetTableVersion =
1264 __SUP_COUT__ <<
"editNodeType: " << editNodeType << __E__;
1265 __SUP_COUT__ <<
"targetTable: " << targetTable << __E__;
1266 __SUP_COUT__ <<
"targetTableVersion: " << targetTableVersion << __E__;
1267 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
1268 __SUP_COUT__ <<
"targetColumn: " << targetColumn << __E__;
1269 __SUP_COUT__ <<
"newValue: " << newValue << __E__;
1271 handleSaveTreeNodeEditXML(xmlOut,
1279 userInfo.username_);
1281 else if(requestType ==
"getLinkToChoices")
1284 std::string linkToTableVersion =
1291 __SUP_COUT__ <<
"linkToTableName: " << linkToTableName << __E__;
1292 __SUP_COUT__ <<
"linkToTableVersion: " << linkToTableVersion << __E__;
1293 __SUP_COUT__ <<
"linkIdType: " << linkIdType << __E__;
1294 __SUP_COUT__ <<
"linkIndex: " << linkIndex << __E__;
1295 __SUP_COUT__ <<
"linkInitId: " << linkInitId << __E__;
1297 handleGetLinkToChoicesXML(xmlOut,
1305 else if(requestType ==
"activateTableGroup")
1309 bool ignoreWarnings = CgiDataUtilities::getDataAsInt(cgiIn,
"ignoreWarnings");
1311 __SUP_COUT__ <<
"Activating group: " << groupName <<
"(" << groupKey <<
")"
1313 __SUP_COUTV__(ignoreWarnings);
1316 xmlOut.addTextElementToData(
"AttemptedGroupActivation",
"1");
1317 xmlOut.addTextElementToData(
"AttemptedGroupActivationName", groupName);
1318 xmlOut.addTextElementToData(
"AttemptedGroupActivationKey", groupKey);
1322 std::string accumulatedErrors, groupTypeString;
1330 groupName,
TableGroupKey(groupKey), &accumulatedErrors, &groupTypeString);
1332 if(accumulatedErrors !=
"")
1336 __SS__ <<
"Throwing exception on accumulated errors: "
1337 << accumulatedErrors << __E__;
1341 __COUT_WARN__ <<
"Ignoring warnings so ignoring this error:"
1342 << accumulatedErrors << __E__;
1343 __COUT_WARN__ <<
"Done ignoring the above error(s)." << __E__;
1345 xmlOut.addTextElementToData(
"AttemptedGroupActivationType", groupTypeString);
1347 catch(std::runtime_error& e)
1352 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1353 xmlOut.addTextElementToData(
1355 "Error activating table group '" + groupName +
"(" + groupKey +
")" +
1356 ".' Please see details below:\n\n" + std::string(e.what()));
1357 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1358 <<
" (" << groupKey <<
")" << __E__;
1367 catch(cet::exception& e)
1373 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1374 xmlOut.addTextElementToData(
"Error",
1375 "Error activating table group '" + groupName +
1376 "(" + groupKey +
")" +
"!'\n\n" +
1377 std::string(e.what()));
1378 __SUP_COUT_ERR__ <<
"Errors detected so de-activating group: " << groupName
1379 <<
" (" << groupKey <<
")" << __E__;
1390 __SUP_COUT__ <<
"Unknown error detected!" << __E__;
1402 else if(requestType ==
"getActiveTableGroups")
1404 else if(requestType ==
"copyViewToCurrentColumns")
1406 std::string tableName =
1410 __SUP_COUT__ <<
"tableName: " << tableName << __E__;
1411 __SUP_COUT__ <<
"sourceVersion: " << sourceVersion << __E__;
1412 __SUP_COUT__ <<
"userInfo.username_: " << userInfo.username_ << __E__;
1418 newTemporaryVersion =
1421 __SUP_COUT__ <<
"New temporary version = " << newTemporaryVersion << __E__;
1423 catch(std::runtime_error& e)
1425 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
1426 xmlOut.addTextElementToData(
"Error",
1427 "Error copying view from '" + tableName +
"_v" +
1428 sourceVersion +
"'! " +
1429 std::string(e.what()));
1433 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
1434 xmlOut.addTextElementToData(
1436 "Error copying view from '" + tableName +
"_v" + sourceVersion +
"'! ");
1439 handleGetTableXML(xmlOut, cfgMgr, tableName, newTemporaryVersion);
1441 else if(requestType ==
"getLastTableGroups")
1444 std::map<std::string ,
1445 std::tuple<std::string ,
1450 theRemoteWebUsers_.getLastTableGroups(theGroups);
1452 for(
const auto& theGroup : theGroups)
1454 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupName",
1455 std::get<0>(theGroup.second));
1456 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupKey",
1457 std::get<1>(theGroup.second).toString());
1458 xmlOut.addTextElementToData(
"Last" + theGroup.first +
"GroupTime",
1459 std::get<2>(theGroup.second));
1492 handleOtherSubsystemActiveGroups(xmlOut, cfgMgr,
false );
1494 else if(requestType ==
"getSubsytemTableGroups")
1496 std::string subsystem =
1498 __SUP_COUTV__(subsystem);
1499 handleOtherSubsystemActiveGroups(
1500 xmlOut, cfgMgr,
true , subsystem);
1502 else if(requestType ==
"diffWithActiveGroup")
1504 std::string groupName =
1507 __SUP_COUTV__(groupName);
1508 __SUP_COUTV__(groupKey);
1513 else if(requestType ==
"diffWithGroupKey")
1515 std::string groupName =
1519 std::string diffGroupName =
1521 __SUP_COUTV__(groupName);
1522 __SUP_COUTV__(groupKey);
1523 __SUP_COUTV__(diffKey);
1524 __SUP_COUTV__(diffGroupName);
1526 handleGroupDiff(xmlOut,
1533 else if(requestType ==
"diffTableVersions")
1535 std::string tableName =
1539 __SUP_COUTV__(tableName);
1544 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
1547 if(allTableInfo.find(tableName) != allTableInfo.end())
1549 if(vA.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1552 std::map<std::string ,
1556 std::string versionAlias;
1558 vA.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1560 if(versionAliases.find(tableName) != versionAliases.end() &&
1561 versionAliases[tableName].find(versionAlias) !=
1562 versionAliases[tableName].end())
1564 versionA = versionAliases[tableName][versionAlias];
1565 __SUP_COUT__ <<
"version alias translated to: " << versionA << __E__;
1568 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1569 <<
"'was not found in active version aliases!"
1573 versionA = atoi(vA.c_str());
1575 if(vB.find(ConfigurationManager::ALIAS_VERSION_PREAMBLE) == 0)
1578 std::map<std::string ,
1582 std::string versionAlias;
1584 vB.substr(ConfigurationManager::ALIAS_VERSION_PREAMBLE.size());
1586 if(versionAliases.find(tableName) != versionAliases.end() &&
1587 versionAliases[tableName].find(versionAlias) !=
1588 versionAliases[tableName].end())
1590 versionB = versionAliases[tableName][versionAlias];
1591 __SUP_COUT__ <<
"version alias translated to: " << versionB << __E__;
1594 __SUP_COUT_WARN__ <<
"version alias '" << versionAlias
1595 <<
"'was not found in active version aliases!"
1599 versionB = atoi(vB.c_str());
1603 versionA = atoi(vA.c_str());
1604 versionB = atoi(vB.c_str());
1607 __SUP_COUTV__(versionA);
1608 __SUP_COUTV__(versionB);
1610 handleTableDiff(xmlOut, cfgMgr, tableName, versionA, versionB);
1612 else if(requestType ==
"findGroupsWithTable")
1614 std::string tableName =
1616 std::string tableVersion =
1619 __SUP_COUTV__(tableName);
1620 __SUP_COUTV__(tableVersion);
1622 std::set<std::string> groupsContainingTable =
1623 cfgMgr->getConfigurationInterface()->findGroupsWithTable(
1625 __SUP_COUT__ <<
"Groups containing " << tableName <<
"-v" << tableVersion
1626 <<
" count: " << groupsContainingTable.size() << __E__;
1627 std::string groupsContainingTableString =
1629 __SUP_COUTTV__(groupsContainingTableString);
1631 xmlOut.addNumberElementToData(
"GroupsContainingCount",
1632 groupsContainingTable.size());
1633 xmlOut.addTextElementToData(
"GroupsContainingCSV", groupsContainingTableString);
1636 else if(requestType ==
"savePlanCommandSequence")
1639 std::string commands =
1645 __SUP_COUTV__(modifiedTables);
1646 __SUP_COUTV__(planName);
1647 __SUP_COUTV__(commands);
1648 __SUP_COUTV__(groupName);
1649 __SUP_COUTV__(groupKey);
1651 handleSavePlanCommandSequenceXML(xmlOut,
1660 else if(requestType ==
"mergeGroups")
1662 std::string groupANameContext =
1664 std::string groupAKeyContext =
1666 std::string groupBNameContext =
1668 std::string groupBKeyContext =
1670 std::string groupANameConfig =
1673 std::string groupBNameConfig =
1678 __SUP_COUTV__(groupANameContext);
1679 __SUP_COUTV__(groupAKeyContext);
1680 __SUP_COUTV__(groupBNameContext);
1681 __SUP_COUTV__(groupBKeyContext);
1682 __SUP_COUTV__(groupANameConfig);
1683 __SUP_COUTV__(groupAKeyConfig);
1684 __SUP_COUTV__(groupBNameConfig);
1685 __SUP_COUTV__(groupBKeyConfig);
1686 __SUP_COUTV__(mergeApproach);
1688 handleMergeGroupsXML(xmlOut,
1701 else if(requestType ==
"getArtdaqSystemVariables")
1703 std::string filePath =
1704 std::string(__ENV__(
"USER_DATA")) +
"/ServiceData/ArtdaqSystemVariables.dat";
1705 std::ifstream inFile(filePath);
1706 if(inFile.is_open())
1709 while(std::getline(inFile, line))
1711 size_t eqPos = line.find(
'=');
1712 if(eqPos == std::string::npos)
1714 std::string key = line.substr(0, eqPos);
1715 std::string value = line.substr(eqPos + 1);
1716 xmlOut.addTextElementToData(
"artdaq_" + key, value);
1720 else if(requestType ==
"setArtdaqSystemVariable")
1728 xmlOut.addTextElementToData(
"Error",
"Variable key must not be empty.");
1734 if(!std::isalnum(c) && c !=
'_')
1741 xmlOut.addTextElementToData(
"Error",
1742 "Variable key must contain only alphanumeric "
1743 "characters and underscores.");
1747 std::string filePath = std::string(__ENV__(
"USER_DATA")) +
1748 "/ServiceData/ArtdaqSystemVariables.dat";
1749 std::map<std::string, std::string> vars;
1751 std::ifstream inFile(filePath);
1752 if(inFile.is_open())
1755 while(std::getline(inFile, line))
1757 size_t eqPos = line.find(
'=');
1758 if(eqPos == std::string::npos)
1760 vars[line.substr(0, eqPos)] = line.substr(eqPos + 1);
1767 std::ofstream outFile(filePath);
1768 if(!outFile.is_open())
1770 xmlOut.addTextElementToData(
1771 "Error",
"Failed to open persistence file for writing.");
1775 for(
auto& [k, v] : vars)
1776 outFile << k <<
"=" << v <<
"\n";
1777 __SUP_COUT__ <<
"Set artdaq system variable " << key <<
" = " << value
1779 xmlOut.addTextElementToData(
"Success",
"Variable '" + key +
"' set.");
1784 else if(requestType ==
"getJsonDocuments")
1786 auto* ifc = ConfigurationInterface::getInstance();
1788 std::set<std::string> allTableNames = ifc->getAllTableNames();
1790 for(
const auto& tableName : allTableNames)
1792 if(tableName.find(TableBase::JSON_DOC_PREPEND) != 0)
1795 std::string docName = tableName.substr(TableBase::JSON_DOC_PREPEND.size());
1798 std::set<TableVersion> versions = ifc->getVersions(&tmpTable);
1800 std::string versionList;
1801 for(
const auto& v : versions)
1803 if(!versionList.empty())
1805 versionList += v.toString();
1808 xmlOut.addTextElementToData(
"jsonDoc_name", docName);
1809 xmlOut.addTextElementToData(
"jsonDoc_versions", versionList);
1812 else if(requestType ==
"getJsonDocumentContent")
1817 __SUP_COUTV__(docName);
1818 __SUP_COUTV__(docVersion);
1820 bool valid = !docName.empty();
1821 for(
char c : docName)
1822 if(!std::isalnum(c) && c !=
'_' && c !=
'-')
1829 xmlOut.addTextElementToData(
1831 "Document name must be non-empty and contain only "
1832 "alphanumeric characters, dashes, and underscores.");
1834 else if(docVersion.empty() ||
1835 docVersion.find_first_not_of(
"0123456789") != std::string::npos)
1837 xmlOut.addTextElementToData(
1838 "Error",
"Document version must contain only numeric characters.");
1844 auto* ifc = ConfigurationInterface::getInstance();
1845 std::string json = ifc->loadCustomJSON(docName,
TableVersion(docVersion));
1846 xmlOut.addTextElementToData(
"content", json);
1848 catch(
const std::exception& e)
1850 xmlOut.addTextElementToData(
"Error",
1851 "Failed to load document '" + docName +
"-v" +
1852 docVersion +
"': " + e.what());
1856 else if(requestType ==
"saveJsonDocumentContent")
1863 __SUP_COUTV__(docName);
1864 __SUP_COUTVS__(10, content);
1866 bool valid = !docName.empty();
1867 for(
char c : docName)
1868 if(!std::isalnum(c) && c !=
'_' && c !=
'-')
1875 xmlOut.addTextElementToData(
1877 "Document name must be non-empty and contain only "
1878 "alphanumeric characters, dashes, and underscores.");
1880 else if(content.empty())
1882 xmlOut.addTextElementToData(
"Error",
"Document content must not be empty.");
1888 auto* ifc = ConfigurationInterface::getInstance();
1889 std::pair<std::string, TableVersion> saved =
1890 ifc->saveCustomJSON(content, docName);
1891 __SUP_COUT__ <<
"Saved JSON document '" << docName <<
"' as version "
1892 << saved.second.toString() << __E__;
1893 xmlOut.addTextElementToData(
"newVersion", saved.second.toString());
1894 xmlOut.addTextElementToData(
1895 "Success",
"Saved as version " + saved.second.toString());
1897 catch(
const std::exception& e)
1899 xmlOut.addTextElementToData(
1900 "Error",
"Failed to save document '" + docName +
"': " + e.what());
1904 else if(requestType ==
"getAppUrnByClass")
1908 __SUP_COUTV__(className);
1910 if(className.empty())
1912 xmlOut.addTextElementToData(
"Error",
"className must not be empty.");
1918 std::vector<std::pair<std::string, ConfigurationTree>> appRecords =
1919 cfgMgr->
getNode(ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME)
1923 for(
const auto& appRecord : appRecords)
1925 std::string appClass =
1926 appRecord.second.getNode(
"Class").getValueAsString();
1932 appClass == className ||
1933 (appClass.size() > className.size() &&
1934 appClass.compare(appClass.size() - className.size(),
1937 appClass[appClass.size() - className.size() - 1] ==
':');
1941 std::string appId = appRecord.second.getNode(
"Id").getValueAsString();
1942 xmlOut.addTextElementToData(
"urn", appId);
1948 xmlOut.addTextElementToData(
1950 "No enabled application found for class '" + className +
"'.");
1952 catch(
const std::exception& e)
1954 xmlOut.addTextElementToData(
1956 "Failed to look up application URN for class '" + className +
1963 __SUP_SS__ <<
"requestType Request, " << requestType
1964 <<
", not recognized by the Configuration GUI Supervisor (was it "
1965 "intended for another Supervisor?)."
1967 __SUP_COUT__ <<
"\n" << ss.str();
1968 xmlOut.addTextElementToData(
"Error", ss.str());
1971 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1974 xmlOut, cfgMgr, userInfo.username_);
1975 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
1978 catch(
const std::runtime_error& e)
1980 __SS__ <<
"A fatal error occurred while handling the request '" << requestType
1981 <<
".' Error: " << e.what() << __E__;
1982 __COUT_ERR__ <<
"\n" << ss.str();
1983 xmlOut.addTextElementToData(
"Error", ss.str());
1988 xmlOut.addTextElementToData(
1990 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
1994 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
1999 __SS__ <<
"An unknown fatal error occurred while handling the request '"
2000 << requestType <<
".'" << __E__;
2005 catch(
const std::exception& e)
2007 ss <<
"Exception message: " << e.what();
2012 __COUT_ERR__ <<
"\n" << ss.str();
2013 xmlOut.addTextElementToData(
"Error", ss.str());
2018 xmlOut.addTextElementToData(
2020 ConfigurationInterface::isVersionTrackingEnabled() ?
"ON" :
"OFF");
2024 __COUT_ERR__ <<
"Error getting version tracking status!" << __E__;
2044 void ConfigurationGUISupervisor::handleGetAffectedGroupsXML(
2047 const std::string& rootGroupName,
2049 const std::string& modifiedTables)
2052 __SUP_COUT__ <<
"rootGroupName " << rootGroupName <<
"(" << rootGroupKey
2053 <<
"). modifiedTables = " << modifiedTables << __E__;
2055 std::map<std::string, std::pair<std::string, TableGroupKey>> consideredGroups =
2060 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT].second.isInvalid())
2062 __SUP_COUT__ <<
"Finding a context group to consider..." << __E__;
2063 if(cfgMgr->getFailedTableGroups().find(
2064 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT) !=
2065 cfgMgr->getFailedTableGroups().end())
2067 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
2068 cfgMgr->getFailedTableGroups().at(
2069 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT);
2071 else if(cfgMgr->getFailedTableGroups().find(
2072 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
2073 cfgMgr->getFailedTableGroups().end())
2075 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONTEXT] =
2076 cfgMgr->getFailedTableGroups().at(
2077 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
2080 if(consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION]
2081 .second.isInvalid())
2083 __SUP_COUT__ <<
"Finding a table group to consider..." << __E__;
2084 if(cfgMgr->getFailedTableGroups().find(
2085 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION) !=
2086 cfgMgr->getFailedTableGroups().end())
2088 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
2089 cfgMgr->getFailedTableGroups().at(
2090 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION);
2092 else if(cfgMgr->getFailedTableGroups().find(
2093 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN) !=
2094 cfgMgr->getFailedTableGroups().end())
2096 consideredGroups[ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION] =
2097 cfgMgr->getFailedTableGroups().at(
2098 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN);
2107 std::map<std::string ,
TableVersion > rootGroupMemberMap;
2112 &rootGroupMemberMap,
2122 consideredGroups[groupType] =
2123 std::pair<std::string, TableGroupKey>(rootGroupName, rootGroupKey);
2125 catch(
const std::runtime_error& e)
2128 if(rootGroupName.size())
2130 __SUP_SS__ <<
"Failed to determine type of table group for " << rootGroupName
2131 <<
"(" << rootGroupKey <<
")! " << e.what() << __E__;
2132 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2137 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
2138 "name - assuming this was intentional."
2144 if(rootGroupName.size())
2146 __SUP_COUT_ERR__ <<
"Failed to determine type of table group for "
2147 << rootGroupName <<
"(" << rootGroupKey <<
")!" << __E__;
2152 __SUP_COUT__ <<
"Did not modify considered active groups due to empty root group "
2153 "name - assuming this was intentional."
2157 std::map<std::string ,
2160 std::map<std::string ,
2162 modifiedTablesMapIt;
2164 std::istringstream f(modifiedTables);
2165 std::string table, version;
2166 while(getline(f, table,
','))
2168 getline(f, version,
',');
2169 modifiedTablesMap.insert(
2172 std::pair<bool /*foundAffectedGroup*/, TableVersion /*version*/>>(
2176 __SUP_COUT__ << modifiedTables << __E__;
2177 for(
auto& pair : modifiedTablesMap)
2178 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second.second
2183 xercesc::DOMElement* parentEl =
nullptr;
2184 std::string groupComment;
2185 std::vector<std::string> orderedGroupTypes(
2186 {ConfigurationManager::GROUP_TYPE_NAME_CONTEXT,
2187 ConfigurationManager::GROUP_TYPE_NAME_BACKBONE,
2188 ConfigurationManager::GROUP_TYPE_NAME_ITERATE,
2189 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION});
2190 for(
auto groupType : orderedGroupTypes)
2192 if(consideredGroups.find(groupType) == consideredGroups.end())
2195 const std::pair<std::string, TableGroupKey>& group = consideredGroups[groupType];
2197 if(group.second.isInvalid())
2200 __SUP_COUT__ <<
"Considering " << groupType <<
" group " << group.first <<
" ("
2201 << group.second <<
")" << __E__;
2219 __SUP_COUT__ <<
"groupComment = " << groupComment << __E__;
2221 for(
auto& table : memberMap)
2223 if((modifiedTablesMapIt = modifiedTablesMap.find(table.first)) !=
2226 table.second != (*modifiedTablesMapIt).second.second)
2228 __SUP_COUT__ <<
"Affected by " << (*modifiedTablesMapIt).first <<
":"
2229 << (*modifiedTablesMapIt).second.second << __E__;
2231 memberMap[table.first] = (*modifiedTablesMapIt).second.second;
2232 (*modifiedTablesMapIt).second.first =
true;
2236 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
2240 if(groupType == ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
2242 __SUP_COUT__ <<
"Considering mockup tables for Configuration Group..."
2244 for(
auto& table : modifiedTablesMap)
2246 if(table.second.first)
2249 if(table.second.second.isMockupVersion() &&
2250 memberMap.find(table.first) == memberMap.end())
2252 __SUP_COUT__ <<
"Found mockup table '" << table.first
2253 <<
"' for Configuration Group." << __E__;
2254 memberMap[table.first] = table.second.second;
2257 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
2261 "AddMemberVersion", table.second.second.toString(), parentEl);
2268 __SUP_COUTV__(affected);
2272 parentEl = xmlOut.addTextElementToData(
"AffectedActiveGroup",
"");
2277 for(
auto& table : memberMap)
2281 "MemberVersion", table.second.toString(), parentEl);
2286 catch(std::runtime_error& e)
2288 __SUP_COUT__ <<
"Error detected!\n\n " << e.what() << __E__;
2289 xmlOut.addTextElementToData(
2290 "Error",
"Error getting affected groups! " + std::string(e.what()));
2294 __SUP_COUT__ <<
"Error detected!\n\n " << __E__;
2295 xmlOut.addTextElementToData(
"Error",
"Error getting affected groups! ");
2306 void ConfigurationGUISupervisor::setupActiveTablesXML(
2309 const std::string& groupName,
2311 const std::string& modifiedTables,
2313 bool doGetGroupInfo,
2314 std::map<std::string /*name*/, TableVersion /*version*/>* returnMemberMap,
2315 bool outputActiveTables,
2316 std::string* accumulatedErrors)
2319 xmlOut.addTextElementToData(
"tableGroup", groupName);
2320 xmlOut.addTextElementToData(
"tableGroupKey", groupKey.
toString());
2322 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
2330 __SUP_COUT__ <<
"Refreshing all table info, ignoring warnings..." << __E__;
2331 std::string accumulatedWarnings =
"";
2333 &accumulatedWarnings,
2347 __SUP_COUT__ <<
"Restoring active table group tables..." << __E__;
2349 for(
const auto& activeGroup : activeGroups)
2351 if(activeGroup.second.first == groupName &&
2352 activeGroup.second.second == groupKey)
2354 __SUP_COUTT__ <<
"Skipping target active group." << __E__;
2357 __SUP_COUTT__ <<
"Loading " << activeGroup.first <<
" "
2358 << activeGroup.second.first <<
"(" << activeGroup.second.second
2363 activeGroup.second.second,
2369 __SUP_COUT__ <<
"Ignoring errors while setting up active tables for "
2370 << activeGroup.second.first <<
"("
2371 << activeGroup.second.second <<
")..." << __E__;
2377 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
2379 std::map<std::string ,
TableVersion > modifiedTablesMap;
2381 modifiedTablesMapIt;
2383 if(usingActiveGroups)
2386 __SUP_COUT__ <<
"Using active groups." << __E__;
2390 __SUP_COUT__ <<
"Loading group '" << groupName <<
"(" << groupKey <<
")'"
2393 std::string groupComment, groupAuthor, tableGroupCreationTime, groupType;
2402 doGetGroupInfo ? &groupComment : 0,
2403 doGetGroupInfo ? &groupAuthor : 0,
2404 doGetGroupInfo ? &tableGroupCreationTime : 0,
2406 doGetGroupInfo ? &groupType : 0);
2410 xmlOut.addTextElementToData(
"tableGroupComment", groupComment);
2411 xmlOut.addTextElementToData(
"tableGroupAuthor", groupAuthor);
2412 xmlOut.addTextElementToData(
"tableGroupCreationTime", tableGroupCreationTime);
2413 xmlOut.addTextElementToData(
"tableGroupType", groupType);
2416 if(accumulatedErrors && *accumulatedErrors !=
"")
2417 __SUP_COUTV__(*accumulatedErrors);
2423 std::istringstream f(modifiedTables);
2424 std::string table, version;
2425 while(getline(f, table,
','))
2427 getline(f, version,
',');
2428 modifiedTablesMap.insert(
2429 std::pair<std::string /*name*/, TableVersion /*version*/>(
2433 for(
auto& pair : modifiedTablesMap)
2434 __SUP_COUT__ <<
"modified table " << pair.first <<
":" << pair.second
2439 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2440 xmlOut.addTextElementToData(
"DefaultNoLink",
2441 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
2444 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
2445 for(
const auto& tablePair : allActivePairs)
2446 orderedTableSet.emplace(tablePair.first);
2448 std::map<std::string, TableInfo>::const_iterator tableInfoIt;
2449 for(
auto& orderedTableName : orderedTableSet)
2451 tableInfoIt = allTableInfo.find(orderedTableName);
2452 if(tableInfoIt == allTableInfo.end())
2454 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
2459 if(outputActiveTables)
2460 xmlOut.addTextElementToData(
"ActiveTableName", orderedTableName);
2464 if((modifiedTablesMapIt = modifiedTablesMap.find(orderedTableName)) !=
2465 modifiedTablesMap.end())
2467 __SUP_COUT__ <<
"Found modified table " << (*modifiedTablesMapIt).first
2468 <<
": trying... " << (*modifiedTablesMapIt).second << __E__;
2472 tableInfoIt->second.tablePtr_->setActiveView(
2473 (*modifiedTablesMapIt).second);
2477 __SUP_SS__ <<
"Modified table version v" << (*modifiedTablesMapIt).second
2478 <<
" failed. Reverting to v"
2479 << tableInfoIt->second.tablePtr_->getView().getVersion() <<
"."
2481 __SUP_COUT_WARN__ <<
"Warning detected!\n\n " << ss.str() << __E__;
2482 xmlOut.addTextElementToData(
2484 "Error setting up active tables!\n\n" + std::string(ss.str()));
2488 if(outputActiveTables)
2490 xmlOut.addTextElementToData(
2491 "ActiveTableVersion",
2492 tableInfoIt->second.tablePtr_->getView().getVersion().toString());
2493 xmlOut.addTextElementToData(
2494 "ActiveTableComment",
2495 tableInfoIt->second.tablePtr_->getView().getAuthor() +
": " +
2496 tableInfoIt->second.tablePtr_->getView().getComment());
2504 catch(std::runtime_error& e)
2506 __SUP_SS__ << (
"Error setting up active tables!\n\n" + std::string(e.what()))
2508 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2509 xmlOut.addTextElementToData(
"Error", ss.str());
2514 __SUP_SS__ << (
"Error setting up active tables!\n\n") << __E__;
2519 catch(
const std::exception& e)
2521 ss <<
"Exception message: " << e.what();
2526 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2527 xmlOut.addTextElementToData(
"Error", ss.str());
2546 void ConfigurationGUISupervisor::handleFillCreateTreeNodeRecordsXML(
2549 const std::string& groupName,
2551 const std::string& startPath,
2552 const std::string& modifiedTables,
2553 const std::string& recordList,
2554 const std::string& author)
2557 setupActiveTablesXML(xmlOut,
2572 __SUP_COUT__ << table->getTableName() << __E__;
2582 bool firstSave =
true;
2589 std::istringstream f(recordList);
2590 std::string recordUID;
2592 while(getline(f, recordUID,
','))
2596 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2601 .isTemporaryVersion())
2603 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2605 temporaryVersion = table->createTemporaryView(temporaryVersion);
2611 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2615 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2621 backupView.copy(table->getView(), temporaryVersion, author);
2630 unsigned int row = table->getViewP()->addRow(
2637 unsigned int col = table->getViewP()->getColStatus();
2638 table->getViewP()->setURIEncodedValue(
"1", row, col);
2645 table->getViewP()->setURIEncodedValue(
2646 recordUID, row, table->getViewP()->getColUID());
2654 table->getViewP()->init();
2658 __SUP_COUT_INFO__ <<
"Reverting to original view." << __E__;
2659 __SUP_COUT__ <<
"Before:" << __E__;
2660 table->getViewP()->print();
2661 table->getViewP()->copy(backupView, temporaryVersion, author);
2662 __SUP_COUT__ <<
"After:" << __E__;
2663 table->getViewP()->print();
2669 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2671 catch(std::runtime_error& e)
2673 __SUP_SS__ << (
"Error creating new record(s)!\n\n" + std::string(e.what()))
2675 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2676 xmlOut.addTextElementToData(
"Error", ss.str());
2680 __SUP_SS__ << (
"Error creating new record(s)!\n\n") << __E__;
2685 catch(
const std::exception& e)
2687 ss <<
"Exception message: " << e.what();
2692 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2693 xmlOut.addTextElementToData(
"Error", ss.str());
2700 void ConfigurationGUISupervisor::handleFillModifiedTablesXML(
2705 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
2706 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
2707 for(
auto& activePair : allActivePairs)
2709 xmlOut.addTextElementToData(
"NewActiveTableName", activePair.first);
2710 xmlOut.addTextElementToData(
"NewActiveTableVersion",
2711 allTableInfo.at(activePair.first)
2712 .tablePtr_->getView()
2715 xmlOut.addTextElementToData(
2716 "NewActiveTableComment",
2717 allTableInfo.at(activePair.first).tablePtr_->getView().getAuthor() +
": " +
2718 allTableInfo.at(activePair.first).tablePtr_->getView().getComment());
2721 catch(std::runtime_error& e)
2723 __SUP_SS__ << (
"Error!\n\n" + std::string(e.what())) << __E__;
2724 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2725 xmlOut.addTextElementToData(
"Error", ss.str());
2729 __SUP_SS__ << (
"Error!\n\n") << __E__;
2734 catch(
const std::exception& e)
2736 ss <<
"Exception message: " << e.what();
2741 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2742 xmlOut.addTextElementToData(
"Error", ss.str());
2760 void ConfigurationGUISupervisor::handleFillDeleteTreeNodeRecordsXML(
2763 const std::string& groupName,
2765 const std::string& startPath,
2766 const std::string& modifiedTables,
2767 const std::string& recordList)
2770 setupActiveTablesXML(xmlOut,
2785 __SUP_COUT__ << table->getTableName() << __E__;
2795 bool firstSave =
true;
2799 std::istringstream f(recordList);
2800 std::string recordUID;
2803 while(getline(f, recordUID,
','))
2807 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
2812 .isTemporaryVersion())
2814 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2816 temporaryVersion = table->createTemporaryView(temporaryVersion);
2822 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion
2826 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion
2837 table->getViewP()->findRow(table->getViewP()->getColUID(), recordUID);
2838 table->getViewP()->deleteRow(row);
2843 table->getViewP()->init();
2845 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2847 catch(std::runtime_error& e)
2849 __SUP_SS__ << (
"Error removing record(s)!\n\n" + std::string(e.what())) << __E__;
2850 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2851 xmlOut.addTextElementToData(
"Error", ss.str());
2855 __SUP_SS__ << (
"Error removing record(s)!\n\n") << __E__;
2860 catch(
const std::exception& e)
2862 ss <<
"Exception message: " << e.what();
2867 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2868 xmlOut.addTextElementToData(
"Error", ss.str());
2888 void ConfigurationGUISupervisor::handleFillRenameTreeNodeRecordsXML(
2891 const std::string& groupName,
2893 const std::string& startPath,
2894 const std::string& modifiedTables,
2895 const std::string& recordList,
2896 const std::string& newRecordList)
2899 setupActiveTablesXML(xmlOut,
2914 __SUP_COUT__ << table->getTableName() << __E__;
2925 std::vector<std::string> recordArray =
2927 std::vector<std::string> newRecordArray =
2933 if(recordArray.size() == 0 || recordArray.size() != newRecordArray.size())
2936 <<
"Invalid record size vs new record name size, they must be the same: "
2937 << recordArray.size() <<
" vs " << newRecordArray.size() << __E__;
2943 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
2945 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
2947 temporaryVersion = table->createTemporaryView(temporaryVersion);
2953 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
2956 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
2963 for(
unsigned int i = 0; i < recordArray.size(); ++i)
2965 row = table->getViewP()->findRow(
2966 table->getViewP()->getColUID(),
2969 table->getViewP()->setValueAsString(
2970 newRecordArray[i], row, table->getViewP()->getColUID());
2973 table->getViewP()->init();
2975 handleFillModifiedTablesXML(xmlOut, cfgMgr);
2977 catch(std::runtime_error& e)
2979 __SUP_SS__ << (
"Error renaming record(s)!\n\n" + std::string(e.what())) << __E__;
2980 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2981 xmlOut.addTextElementToData(
"Error", ss.str());
2985 __SUP_SS__ << (
"Error renaming record(s)!\n\n") << __E__;
2990 catch(
const std::exception& e)
2992 ss <<
"Exception message: " << e.what();
2997 __SUP_COUT_ERR__ <<
"\n" << ss.str();
2998 xmlOut.addTextElementToData(
"Error", ss.str());
3019 void ConfigurationGUISupervisor::handleFillCopyTreeNodeRecordsXML(
3022 const std::string& groupName,
3024 const std::string& startPath,
3025 const std::string& modifiedTables,
3026 const std::string& recordList,
3027 unsigned int numberOfCopies )
3033 setupActiveTablesXML(xmlOut,
3048 __SUP_COUT__ << table->getTableName() << __E__;
3059 std::vector<std::string> recordArray =
3065 if(!(temporaryVersion = targetNode.
getTableVersion()).isTemporaryVersion())
3067 __SUP_COUT__ <<
"Start version " << temporaryVersion << __E__;
3069 temporaryVersion = table->createTemporaryView(temporaryVersion);
3075 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
3078 __SUP_COUT__ <<
"Using temporary version " << temporaryVersion << __E__;
3085 for(
const auto& recordUID : recordArray)
3087 row = table->getViewP()->findRow(table->getViewP()->getColUID(),
3089 for(
unsigned int i = 0; i < numberOfCopies; ++i)
3090 table->getViewP()->copyRows(
3100 table->getViewP()->init();
3102 handleFillModifiedTablesXML(xmlOut, cfgMgr);
3104 catch(std::runtime_error& e)
3106 __SUP_SS__ << (
"Error copying record(s)!\n\n" + std::string(e.what())) << __E__;
3107 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3108 xmlOut.addTextElementToData(
"Error", ss.str());
3112 __SUP_SS__ << (
"Error copying record(s)!\n\n") << __E__;
3117 catch(
const std::exception& e)
3119 ss <<
"Exception message: " << e.what();
3124 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3125 xmlOut.addTextElementToData(
"Error", ss.str());
3146 void ConfigurationGUISupervisor::handleFillSetTreeNodeFieldValuesXML(
3149 const std::string& groupName,
3151 const std::string& startPath,
3152 const std::string& modifiedTables,
3153 const std::string& recordList,
3154 const std::string& fieldList,
3155 const std::string& valueList,
3156 const std::string& author)
3159 setupActiveTablesXML(xmlOut,
3174 std::vector<std::string > fieldPaths;
3177 std::istringstream f(fieldList);
3178 std::string fieldPath;
3179 while(getline(f, fieldPath,
','))
3183 __SUP_COUT__ << fieldList << __E__;
3184 for(
const auto& field : fieldPaths)
3185 __SUP_COUT__ <<
"fieldPath " << field << __E__;
3188 std::vector<std::string > fieldValues;
3191 std::istringstream f(valueList);
3192 std::string fieldValue;
3193 while(getline(f, fieldValue,
','))
3195 fieldValues.push_back(fieldValue);
3200 if(valueList.size() && valueList[valueList.size() - 1] ==
',')
3201 fieldValues.push_back(
"");
3203 __SUP_COUT__ << valueList << __E__;
3204 for(
const auto& value : fieldValues)
3205 __SUP_COUT__ <<
"fieldValue " << value << __E__;
3208 if(fieldPaths.size() != fieldValues.size())
3211 __THROW__(ss.str() +
"Mismatch in fields and values array size!");
3218 std::istringstream f(recordList);
3219 std::string recordUID;
3222 while(getline(f, recordUID,
','))
3227 xmlOut.addTextElementToData(
"fieldValues", recordUID);
3230 for(i = 0; i < fieldPaths.size(); ++i)
3232 __SUP_COUT__ <<
"fieldPath " << fieldPaths[i] << __E__;
3233 __SUP_COUT__ <<
"fieldValue " << fieldValues[i] << __E__;
3238 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPaths[i],
3279 if(!(temporaryVersion = table->getViewP()->getVersion())
3280 .isTemporaryVersion())
3284 table->createTemporaryView(table->getViewP()->getVersion());
3290 __SUP_COUT__ <<
"Created temporary version "
3291 << table->getTableName() <<
"-v" << temporaryVersion
3295 __SUP_COUT__ <<
"Using temporary version " << table->getTableName()
3296 <<
"-v" << temporaryVersion << __E__;
3300 table->getViewP()->setURIEncodedValue(fieldValues[i],
3311 handleFillModifiedTablesXML(xmlOut, cfgMgr);
3313 catch(std::runtime_error& e)
3315 __SUP_SS__ << (
"Error setting field values!\n\n" + std::string(e.what()))
3317 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3318 xmlOut.addTextElementToData(
"Error", ss.str());
3322 __SUP_SS__ << (
"Error setting field values!\n\n") << __E__;
3327 catch(
const std::exception& e)
3329 ss <<
"Exception message: " << e.what();
3334 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3335 xmlOut.addTextElementToData(
"Error", ss.str());
3354 void ConfigurationGUISupervisor::handleFillGetTreeNodeFieldValuesXML(
3357 const std::string& groupName,
3359 const std::string& startPath,
3360 const std::string& modifiedTables,
3361 const std::string& recordList,
3362 const std::string& fieldList)
3365 setupActiveTablesXML(
3366 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3373 std::vector<std::string > fieldPaths;
3376 std::istringstream f(fieldList);
3377 std::string fieldPath;
3378 while(getline(f, fieldPath,
','))
3382 __SUP_COUT__ << fieldList << __E__;
3387 std::istringstream f(recordList);
3388 std::string recordUID;
3389 while(getline(f, recordUID,
','))
3393 __SUP_COUT__ <<
"recordUID " << recordUID << __E__;
3395 xercesc::DOMElement* parentEl =
3396 xmlOut.addTextElementToData(
"fieldValues", recordUID);
3399 for(
const auto& fieldPath : fieldPaths)
3405 cfgMgr->
getNode(startPath +
"/" + recordUID +
"/" + fieldPath);
3417 catch(std::runtime_error& e)
3419 __SUP_SS__ << (
"Error getting field values!\n\n" + std::string(e.what()))
3421 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3422 xmlOut.addTextElementToData(
"Error", ss.str());
3426 __SUP_SS__ << (
"Error getting field values!\n\n") << __E__;
3431 catch(
const std::exception& e)
3433 ss <<
"Exception message: " << e.what();
3438 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3439 xmlOut.addTextElementToData(
"Error", ss.str());
3462 void ConfigurationGUISupervisor::handleFillTreeNodeCommonFieldsXML(
3465 const std::string& groupName,
3467 const std::string& startPath,
3469 const std::string& modifiedTables,
3470 const std::string& recordList,
3471 const std::string& fieldList)
3474 setupActiveTablesXML(
3475 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3479 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"fields", startPath);
3483 __SUP_SS__ <<
"Depth of search must be greater than 0." << __E__;
3484 __SUP_COUT__ << ss.str();
3493 std::vector<ConfigurationTree::RecordField> retFieldList;
3499 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3505 std::vector<std::string > fieldAcceptList, fieldRejectList;
3510 std::istringstream f(fieldList);
3511 std::string fieldPath, decodedFieldPath;
3512 while(getline(f, fieldPath,
','))
3516 if(decodedFieldPath[0] ==
'!')
3517 fieldRejectList.push_back(decodedFieldPath.substr(1));
3519 fieldAcceptList.push_back(decodedFieldPath);
3521 __SUP_COUT__ << fieldList << __E__;
3522 for(
auto& field : fieldAcceptList)
3523 __SUP_COUT__ <<
"fieldAcceptList " << field << __E__;
3524 for(
auto& field : fieldRejectList)
3525 __SUP_COUT__ <<
"fieldRejectList " << field << __E__;
3529 std::vector<std::string > records;
3530 if(recordList ==
"*")
3534 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3535 for(
auto& record : records)
3536 __SUP_COUT__ <<
"recordList " << record << __E__;
3538 else if(recordList !=
"")
3542 std::istringstream f(recordList);
3543 std::string recordStr;
3544 while(getline(f, recordStr,
','))
3548 __SUP_COUT__ << recordList << __E__;
3549 for(
auto& record : records)
3550 __SUP_COUT__ <<
"recordList " << record << __E__;
3556 records, fieldAcceptList, fieldRejectList, depth);
3560 xercesc::DOMElement* parentTypeEl;
3561 for(
const auto& fieldInfo : retFieldList)
3564 "FieldTableName", fieldInfo.tableName_, parentEl);
3566 "FieldColumnName", fieldInfo.columnName_, parentEl);
3568 "FieldRelativePath", fieldInfo.relativePath_, parentEl);
3570 "FieldColumnType", fieldInfo.columnInfo_->getType(), parentEl);
3572 "FieldColumnDataType", fieldInfo.columnInfo_->getDataType(), parentEl);
3574 fieldInfo.columnInfo_->getDefaultValue(),
3581 auto dataChoices = fieldInfo.columnInfo_->getDataChoices();
3583 "FieldColumnDataChoice",
3584 fieldInfo.columnInfo_->getDefaultValue(),
3586 for(
const auto& dataChoice : dataChoices)
3588 "FieldColumnDataChoice", dataChoice, parentTypeEl);
3591 catch(std::runtime_error& e)
3593 __SUP_SS__ << (
"Error getting common fields!\n\n" + std::string(e.what()))
3595 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3596 xmlOut.addTextElementToData(
"Error", ss.str());
3600 __SUP_SS__ << (
"Error getting common fields!\n\n") << __E__;
3605 catch(
const std::exception& e)
3607 ss <<
"Exception message: " << e.what();
3612 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3613 xmlOut.addTextElementToData(
"Error", ss.str());
3645 void ConfigurationGUISupervisor::handleFillUniqueFieldValuesForRecordsXML(
3648 const std::string& groupName,
3650 const std::string& startPath,
3651 const std::string& modifiedTables,
3652 const std::string& recordList,
3653 const std::string& fieldList)
3656 setupActiveTablesXML(
3657 xmlOut, cfgMgr, groupName, groupKey, modifiedTables,
false );
3663 if(startPath ==
"/")
3669 __SUP_SS__ <<
"Start path was a disconnected link node!" << __E__;
3670 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3675 std::vector<std::string > records;
3676 if(recordList ==
"*")
3680 __SUP_COUT__ <<
"Translating wildcard..." << __E__;
3681 for(
auto& record : records)
3682 __SUP_COUT__ <<
"recordList " << record << __E__;
3684 else if(recordList !=
"")
3688 std::istringstream f(recordList);
3689 std::string recordStr;
3690 while(getline(f, recordStr,
','))
3694 __SUP_COUT__ << recordList << __E__;
3695 for(
auto& record : records)
3696 __SUP_COUT__ <<
"recordList " << record << __E__;
3701 std::vector<std::string > fieldsToGet;
3706 if(fieldList ==
"AUTO")
3711 __SUP_COUT__ <<
"Getting AUTO filter fields!" << __E__;
3713 std::vector<ConfigurationTree::RecordField> retFieldList;
3714 std::vector<std::string > fieldAcceptList,
3716 fieldRejectList.push_back(
"*" + TableViewColumnInfo::COL_NAME_COMMENT);
3718 records, fieldAcceptList, fieldRejectList, 5,
true );
3720 for(
const auto& retField : retFieldList)
3721 fieldsToGet.push_back(retField.relativePath_ + retField.columnName_);
3725 std::istringstream f(fieldList);
3726 std::string fieldPath;
3727 while(getline(f, fieldPath,
','))
3731 __SUP_COUTV__(fieldList);
3740 std::string fieldGroupIDChildLinkIndex;
3741 for(
auto& field : fieldsToGet)
3743 __SUP_COUTV__(field);
3745 xercesc::DOMElement* parentEl =
3746 xmlOut.addTextElementToData(
"field", field);
3752 std::set<std::string > uniqueValues =
3754 records, field, &fieldGroupIDChildLinkIndex);
3756 if(fieldGroupIDChildLinkIndex !=
"")
3758 "childLinkIndex", fieldGroupIDChildLinkIndex, parentEl);
3760 for(
auto& uniqueValue : uniqueValues)
3762 __SUP_COUT__ <<
"uniqueValue " << uniqueValue << __E__;
3769 catch(std::runtime_error& e)
3771 __SUP_SS__ <<
"Error getting unique field values from path '" << startPath
3772 <<
"' and field list '" << fieldList <<
"!'\n\n"
3773 << e.what() << __E__;
3774 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3775 xmlOut.addTextElementToData(
"Error", ss.str());
3779 __SUP_SS__ <<
"Error getting unique field values from path '" << startPath
3780 <<
"' and field list '" << fieldList <<
"!'\n\n"
3786 catch(
const std::exception& e)
3788 ss <<
"Exception message: " << e.what();
3793 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3794 xmlOut.addTextElementToData(
"Error", ss.str());
3818 void ConfigurationGUISupervisor::handleFillTreeViewXML(
3821 const std::string& groupName,
3823 const std::string& startPath,
3825 bool hideStatusFalse,
3826 const std::string& modifiedTables,
3827 const std::string& filterList,
3828 const std::string& diffGroupName ,
3831 __SUP_COUTT__ <<
"get Tree View: " << groupName <<
"(" << groupKey <<
")" << __E__;
3863 bool doDiff = (diffGroupName !=
"" && !diffGroupKey.
isInvalid());
3868 std::string diffAccumulateErrors;
3876 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3893 __SUP_COUT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3896 __SUP_COUTT__ <<
"Diff Group tables loaded." << __E__;
3898 *cfgMgr, diffMemberMap, diffGroupName, diffGroupKey);
3899 __SUP_COUTT__ <<
"Diff Group tables copied to local diff config manager."
3903 for(
auto& memberPair : diffMemberMap)
3905 ->setActiveView(memberPair.second);
3907 for(
const auto& lastGroupLoaded : cfgMgr->getLastTableGroups())
3908 __SUP_COUT__ <<
"cfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3909 << lastGroupLoaded.second.first.first <<
"("
3910 << lastGroupLoaded.second.first.second <<
")";
3912 for(
const auto& lastGroupLoaded : diffCfgMgr->getLastTableGroups())
3913 __SUP_COUT__ <<
"diffCfgMgr Last loaded " << lastGroupLoaded.first <<
": "
3914 << lastGroupLoaded.second.first.first <<
"("
3915 << lastGroupLoaded.second.first.second <<
")";
3918 if(diffCfgMgr->getLastTableGroups().size() == 1)
3920 __SUP_COUT__ <<
"Type already loaded to diff = "
3921 << diffCfgMgr->getLastTableGroups().begin()->first << __E__;
3924 auto groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3925 if(diffCfgMgr->getLastTableGroups().begin()->first ==
3926 ConfigurationManager::GROUP_TYPE_NAME_CONTEXT)
3927 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION;
3928 else if(diffCfgMgr->getLastTableGroups().begin()->first ==
3929 ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
3930 groupTypeToLoad = ConfigurationManager::GROUP_TYPE_NAME_CONTEXT;
3933 <<
"Loading " << groupTypeToLoad
3934 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first <<
"("
3935 << cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second
3940 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second,
3941 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.first,
3942 cfgMgr->getLastTableGroups().at(groupTypeToLoad).first.second);
3945 for(
auto& memberPair :
3946 cfgMgr->getLastTableGroups().at(groupTypeToLoad).second)
3948 ->setActiveView(memberPair.second);
3956 __SUP_COUTT__ <<
"cfgMgr " << activeTable.first <<
"-v" << activeTable.second
3959 __SUP_COUTT__ <<
"diffCfgMgr " << activeTable.first <<
"-v"
3960 << activeTable.second << __E__;
3962 __SUP_COUTT__ <<
"Diff Group tables are setup: " << diffAccumulateErrors << __E__;
3967 bool usingActiveGroups = (groupName ==
"" || groupKey.
isInvalid());
3970 std::string accumulatedErrors =
"";
3971 setupActiveTablesXML(
3984 if(memberMap.size() > ConfigurationManager::getFixedContextMemberNames().size() +
3986 && startPath ==
"/")
3988 __COUTT__ <<
"Checking for orphaned tables..." << __E__;
3991 std::set<std::string > linkingTables;
3996 __COUTS__(30) <<
"Table " << tableInfo.first << __E__;
3997 if(!tableInfo.second.tablePtr_->isActive())
4000 __COUTS__(30) <<
"Table active " << tableInfo.first << __E__;
4002 const TableView& view = tableInfo.second.tablePtr_->getView();
4004 bool addedThisTable =
false;
4005 for(
unsigned int col = 0; col < view.getNumberOfColumns(); ++col)
4007 if(!view.getColumnInfo(col).isChildLink())
4010 __COUTS__(30) <<
"Table " << tableInfo.first
4011 <<
" col: " << view.getColumnInfo(col).getName() << __E__;
4013 for(
unsigned int r = 0; r < view.getNumberOfRows(); ++r)
4015 if(view.getDataView()[r][col] ==
"" ||
4016 view.getDataView()[r][col] ==
4017 TableViewColumnInfo::DATATYPE_STRING_DEFAULT ||
4018 view.getDataView()[r][col] ==
4019 TableViewColumnInfo::DATATYPE_STRING_ALT_DEFAULT)
4024 linkingTables.emplace(tableInfo.first);
4025 addedThisTable =
true;
4027 linkingTables.emplace(
4028 view.getDataView()[r][col]);
4034 std::string missingTables =
"";
4035 for(
const auto& member : memberMap)
4038 if(linkingTables.find(member.first) != linkingTables.end())
4041 if(missingTables.size())
4042 missingTables +=
", ";
4043 missingTables += member.first;
4046 if(missingTables.size())
4048 __COUTV__(missingTables);
4049 std::stringstream ss;
4050 ss <<
"The following member tables of table group '" << groupName <<
"("
4052 <<
")' were identified as possibly orphaned (i.e. no active tables link "
4053 "to these tables, and these tables have no links to other tables):\n\n"
4054 << missingTables <<
".\n"
4056 xmlOut.addTextElementToData(
"NoTreeLinkWarning", ss.str());
4060 if(accumulatedErrors !=
"")
4062 xmlOut.addTextElementToData(
"Warning", accumulatedErrors);
4064 __SUP_COUT__ <<
"Active tables are setup. Warning string: '" << accumulatedErrors
4067 __SUP_COUT__ <<
"Active table versions: "
4072 __SUP_COUTT__ <<
"Active tables are setup. No issues found." << __E__;
4073 __SUP_COUTT__ <<
"Active table versions: "
4079 xercesc::DOMElement* parentEl = xmlOut.addTextElementToData(
"tree", startPath);
4084 std::vector<std::pair<std::string, ConfigurationTree>> rootMap;
4085 std::map<std::string, ConfigurationTree> diffRootMap;
4087 if(startPath ==
"/")
4091 std::string accumulateTreeErrs;
4093 if(usingActiveGroups)
4094 rootMap = cfgMgr->
getChildren(0, &accumulateTreeErrs);
4096 rootMap = cfgMgr->
getChildren(&memberMap, &accumulateTreeErrs);
4101 diffCfgMgr->
getChildrenMap(&diffMemberMap, &diffAccumulateErrors);
4102 __SUP_COUTV__(diffRootMap.size());
4103 for(
auto& diffChild : diffRootMap)
4104 __SUP_COUTV__(diffChild.first);
4107 __SUP_COUTV__(accumulateTreeErrs);
4109 if(accumulateTreeErrs !=
"")
4110 xmlOut.addTextElementToData(
"TreeErrors", accumulateTreeErrs);
4115 cfgMgr->
getNode(startPath,
true );
4118 xmlOut.addTextElementToData(
"DisconnectedStartNode",
"1");
4123 std::map<std::string , std::string > filterMap;
4127 std::set<char>({
';'}) ,
4128 std::set<char>({
'='}) );
4142 __SUP_COUTT__ <<
"Diff Group disconnected node." << __E__;
4147 catch(
const std::runtime_error& e)
4150 __SUP_COUTT__ <<
"Diff Group node does not exist." << __E__;
4157 for(
auto& treePair : rootMap)
4159 treePair.second, depth - 1, xmlOut, parentEl, hideStatusFalse);
4163 __SUP_COUTT__ <<
"Diff Tree recursive handling." << __E__;
4166 std::set<std::string > rootMapToSearch;
4167 for(
const auto& rootMember : rootMap)
4168 rootMapToSearch.emplace(rootMember.first);
4170 std::stringstream rootSs;
4171 for(
const auto& rootMember : rootMap)
4172 rootSs <<
", " << rootMember.first;
4175 std::stringstream diffRootSs;
4176 for(
const auto& diffMember : diffRootMap)
4178 diffRootSs <<
", " << diffMember.first <<
":"
4179 << diffMember.second.getNodeType();
4180 if(rootMapToSearch.find(diffMember.first) ==
4184 std::stringstream missingSs;
4185 missingSs << diffMember.first <<
4187 " <<< Only in " << diffGroupName <<
"(" << diffGroupKey
4190 "diffNodeMissing", missingSs.str(), parentEl);
4193 if(diffMember.second.getNodeType() ==
"UIDLinkNode")
4204 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
4205 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
4207 __SUP_COUTT__ <<
"\t\t" << diffMember.second.getValueName() <<
": "
4208 << diffMember.second.getValueAsString() << __E__;
4210 __SUP_COUTT__ << diffMember.second.nodeDump();
4214 __SUP_COUTT__ <<
"diff map " << diffRootSs.str() << __E__;
4215 __SUP_COUTT__ <<
"root map " << rootSs.str() << __E__;
4218 for(
auto& treePair : rootMap)
4220 if(diffRootMap.find(treePair.first) == diffRootMap.end())
4222 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
4235 __SUP_COUTT__ <<
"Diff Tree recursive handling... " << treePair.first
4237 recursiveTreeToXML(treePair.second,
4242 diffRootMap.at(treePair.first));
4247 catch(std::runtime_error& e)
4249 __SUP_SS__ <<
"Error detected generating XML tree!\n\n " << e.what() << __E__;
4250 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4251 xmlOut.addTextElementToData(
"Error", ss.str());
4255 __SUP_SS__ <<
"Error detected generating XML tree!" << __E__;
4260 catch(
const std::exception& e)
4262 ss <<
"Exception message: " << e.what();
4267 __SUP_COUT_ERR__ <<
"\n" << ss.str();
4268 xmlOut.addTextElementToData(
"Error", ss.str());
4278 void ConfigurationGUISupervisor::recursiveTreeToXML(
4282 xercesc::DOMElement* parentEl,
4283 bool hideStatusFalse,
4284 std::optional<std::reference_wrapper<const ConfigurationTree>> diffTree)
4294 if(diffTree.has_value() &&
4295 t.
getValueName() != TableViewColumnInfo::COL_NAME_COMMENT &&
4296 t.
getValueName() != TableViewColumnInfo::COL_NAME_AUTHOR &&
4297 t.
getValueName() != TableViewColumnInfo::COL_NAME_CREATION)
4299 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
4301 if(diffTree->get().isValueNode())
4303 __COUTS__(30) <<
"\t" << diffTree->get().getValueAsString() <<
" ? "
4305 __COUTS__(30) <<
"\t" << diffTree->get().getTableName() <<
"-v"
4306 << diffTree->get().getTableVersion() <<
" ? "
4311 std::stringstream missingSs;
4312 auto diffGroupPair =
4313 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4314 diffTree->get().getTableName());
4315 missingSs <<
"<<< '" << diffTree->get().getValueAsString() <<
"' in "
4316 << diffGroupPair.first <<
"(" << diffGroupPair.second
4323 std::stringstream missingSs;
4325 auto diffGroupPair =
4326 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4328 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
4329 << diffGroupPair.second <<
") >>>";
4343 if(t.
getValueType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
4344 t.
getValueType() == TableViewColumnInfo::TYPE_BITMAP_DATA)
4349 for(
const auto& choice : choices)
4366 if(diffTree.has_value())
4368 __COUTS__(30) <<
"\t\t diff type " << diffTree->get().getNodeType()
4375 std::stringstream missingSs;
4377 auto diffGroupPair =
4378 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4380 missingSs <<
"<<< Path not found in " << diffGroupPair.first <<
"("
4381 << diffGroupPair.second <<
") >>>";
4386 __COUTS__(30) <<
"\t\t diff isDisconnected "
4387 << diffTree->get().isDisconnected() << __E__;
4389 std::stringstream missingSs;
4391 auto diffGroupPair =
4392 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4394 missingSs <<
"<<< Link is "
4395 << (diffTree->get().isDisconnected() ?
"DISCONNECTED"
4397 <<
" in " << diffGroupPair.first <<
"("
4398 << diffGroupPair.second <<
") >>>";
4405 std::stringstream missingSs;
4407 auto diffGroupPair =
4408 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4410 missingSs <<
"<<< Link is "
4411 << (diffTree->get().isUIDLinkNode() ?
"a UID Link"
4413 <<
" in " << diffGroupPair.first <<
"("
4414 << diffGroupPair.second <<
") >>>";
4419 diffTree->get().getValueAsString())
4422 std::stringstream missingSs;
4424 auto diffGroupPair =
4425 diffTree->get().getConfigurationManager()->getGroupOfLoadedTable(
4427 missingSs <<
"<<< Link to '" << diffTree->get().getValueAsString()
4428 <<
"' in " << diffGroupPair.first <<
"("
4429 << diffGroupPair.second <<
") >>>";
4435 std::stringstream missingSs;
4438 auto dtchildren = diffTree->get().getChildrenMap();
4439 missingSs <<
"<<< Group link";
4440 if(tchildren.size() != dtchildren.size())
4441 missingSs <<
" has " << tchildren.size() <<
" vs "
4442 << dtchildren.size() <<
" children..";
4443 for(
auto& tchild : tchildren)
4444 if(dtchildren.find(tchild.first) == dtchildren.end())
4445 missingSs <<
" '" << tchild.first <<
"' missing..";
4446 for(
auto& dtchild : dtchildren)
4447 if(tchildren.find(dtchild.first) == tchildren.end())
4448 missingSs <<
" '" << dtchild.first <<
"' present...";
4451 if(missingSs.str().length() > std::string(
"<<< Group link").length())
4453 auto diffGroupPair =
4455 .getConfigurationManager()
4456 ->getGroupOfLoadedTable(diffTree->get().getTableName());
4457 missingSs <<
" in " << diffGroupPair.first <<
"("
4458 << diffGroupPair.second <<
") >>>";
4460 "nodeDiff", missingSs.str(), parentEl);
4488 xercesc::DOMElement* choicesParentEl =
4494 __COUTS__(30) <<
"choices.size() " << choices.size() << __E__;
4496 for(
const auto& choice : choices)
4518 xercesc::DOMElement* choicesParentEl =
4522 for(
const auto& choice : choices)
4529 bool returnNode =
true;
4543 "nodeStatus", t.
isEnabled() ?
"1" :
"0", parentEl);
4546 if(diffTree.has_value())
4549 <<
"\t\t diff type " << diffTree->get().getNodeType() << __E__;
4558 auto diffGroupPair =
4560 .getConfigurationManager()
4562 missingSs <<
"<<< Not in " << diffGroupPair.first <<
"("
4563 << diffGroupPair.second <<
") >>>";
4565 "nodeDiff", missingSs.str(), parentEl);
4599 void ConfigurationGUISupervisor::handleGetLinkToChoicesXML(
4602 const std::string& linkToTableName,
4604 const std::string& linkIdType,
4605 const std::string& linkIndex,
4606 const std::string& linkInitId)
4619 const std::string& tableName = linkToTableName;
4624 table->setActiveView(version);
4628 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
4629 << version << __E__;
4633 if(version != table->getViewVersion())
4635 __SUP_SS__ <<
"Target table version (" << version
4636 <<
") is not the currently active version (" << table->getViewVersion()
4637 <<
". Try refreshing the tree." << __E__;
4638 __SUP_COUT_WARN__ << ss.str();
4642 __SUP_COUT__ <<
"Active version is " << table->getViewVersion() << __E__;
4644 if(linkIdType ==
"UID")
4647 unsigned int col = table->getView().getColUID();
4648 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4649 xmlOut.addTextElementToData(
"linkToChoice",
4650 table->getView().getDataView()[row][col]);
4652 else if(linkIdType ==
"GroupID")
4658 __SUP_COUTV__(linkIndex);
4659 __SUP_COUTV__(linkInitId);
4661 std::set<std::string> setOfGroupIDs =
4662 table->getView().getSetOfGroupIDs(linkIndex);
4667 bool foundInitId =
false;
4668 for(
const auto& groupID : setOfGroupIDs)
4670 if(!foundInitId && linkInitId == groupID)
4673 xmlOut.addTextElementToData(
"linkToChoice", groupID);
4677 xmlOut.addTextElementToData(
"linkToChoice", linkInitId);
4680 unsigned int col = table->getView().getColUID();
4681 for(
unsigned int row = 0; row < table->getView().getNumberOfRows(); ++row)
4683 xmlOut.addTextElementToData(
"groupChoice",
4684 table->getView().getDataView()[row][col]);
4685 if(table->getView().isEntryInGroup(row, linkIndex, linkInitId))
4686 xmlOut.addTextElementToData(
"groupMember",
4687 table->getView().getDataView()[row][col]);
4692 __SUP_SS__ <<
"Unrecognized linkIdType '" << linkIdType <<
".'" << __E__;
4696 catch(std::runtime_error& e)
4698 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << e.what() << __E__;
4699 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4700 xmlOut.addTextElementToData(
"Error", ss.str());
4704 __SUP_SS__ <<
"Error detected saving tree node!\n\n " << __E__;
4709 catch(
const std::exception& e)
4711 ss <<
"Exception message: " << e.what();
4716 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
4717 xmlOut.addTextElementToData(
"Error", ss.str());
4722 void ConfigurationGUISupervisor::handleMergeGroupsXML(
4725 const std::string& groupANameContext,
4727 const std::string& groupBNameContext,
4729 const std::string& groupANameConfig,
4731 const std::string& groupBNameConfig,
4733 const std::string& author,
4734 const std::string& mergeApproach)
4737 __SUP_COUT__ <<
"Merging context group pair " << groupANameContext <<
" ("
4738 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4739 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4740 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4741 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4757 if(!(mergeApproach ==
"Rename" || mergeApproach ==
"Replace" ||
4758 mergeApproach ==
"Skip"))
4760 __SS__ <<
"Error! Invalid merge approach '" << mergeApproach <<
".'" << __E__;
4764 std::map<std::string ,
TableVersion > memberMapAContext,
4765 memberMapBContext, memberMapAConfig, memberMapBConfig;
4768 bool skippingContextPair =
false;
4769 bool skippingConfigPair =
false;
4770 if(groupANameContext.size() == 0 || groupANameContext[0] ==
' ' ||
4771 groupBNameContext.size() == 0 || groupBNameContext[0] ==
' ')
4773 skippingContextPair =
true;
4774 __SUP_COUTV__(skippingContextPair);
4776 if(groupANameConfig.size() == 0 || groupANameConfig[0] ==
' ' ||
4777 groupBNameConfig.size() == 0 || groupBNameConfig[0] ==
' ')
4779 skippingConfigPair =
true;
4780 __SUP_COUTV__(skippingConfigPair);
4784 if(!skippingContextPair)
4817 if(!skippingConfigPair)
4854 std::map<std::pair<std::string , std::string >,
4858 std::pair<std::string ,
4859 std::pair<std::string , std::string >>,
4861 groupidConversionMap;
4863 std::stringstream mergeReport;
4864 mergeReport <<
"======================================" << __E__;
4866 mergeReport <<
"Merging context group pair " << groupANameContext <<
" ("
4867 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
4868 << groupBKeyContext <<
") and table group pair " << groupANameConfig
4869 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
4870 << groupBKeyConfig <<
") with approach '" << mergeApproach << __E__;
4871 mergeReport <<
"======================================" << __E__;
4875 for(
unsigned int i = 0; i < 2; ++i)
4877 if(i == 0 && mergeApproach !=
"Rename")
4881 for(
unsigned int j = 0; j < 2; ++j)
4883 if(j == 0 && skippingContextPair)
4885 __COUT__ <<
"Skipping context pair..." << __E__;
4888 else if(j == 1 && skippingConfigPair)
4890 __COUT__ <<
"Skipping table pair..." << __E__;
4895 j == 0 ? memberMapAContext : memberMapAConfig;
4898 j == 0 ? memberMapBContext : memberMapBConfig;
4901 __COUT__ <<
"Context pair..." << __E__;
4903 __COUT__ <<
"Table pair..." << __E__;
4905 __COUT__ <<
"Starting member map B scan." << __E__;
4906 for(
const auto& bkey : memberMapBref)
4908 __SUP_COUTV__(bkey.first);
4910 if(memberMapAref.find(bkey.first) == memberMapAref.end())
4912 mergeReport <<
"\n'" << mergeApproach <<
"'-Missing table '"
4913 << bkey.first <<
"' A=v" << -1 <<
", adding B=v"
4914 << bkey.second << __E__;
4917 memberMapAref[bkey.first] = bkey.second;
4919 else if(memberMapAref[bkey.first] != bkey.second)
4922 __SUP_COUTV__(memberMapAref[bkey.first]);
4923 __SUP_COUTV__(bkey.second);
4928 __SUP_COUT__ <<
"Got table." << __E__;
4932 ->getVersionedTableByName(bkey.first,
4933 memberMapAref[bkey.first])
4939 mergeApproach ==
"Rename"
4940 ? TableBase::MergeApproach::RENAME
4941 : (mergeApproach ==
"Replace"
4942 ? TableBase::MergeApproach::REPLACE
4943 : TableBase::MergeApproach::SKIP),
4945 groupidConversionMap,
4948 table->getTableName() ==
4949 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME
4955 __SUP_COUTV__(newVersion);
4973 catch(std::runtime_error& e)
4976 <<
"There was an error saving the '"
4977 << table->getTableName()
4978 <<
"' merge result to a persistent table version. "
4979 <<
"Perhaps you can modify this table in one of the "
4980 "groups to resolve this issue, and then re-merge."
4981 << __E__ << e.what();
4985 __SUP_COUTV__(newVersion);
4987 memberMapAref[bkey.first] = newVersion;
4996 if(!skippingContextPair)
4998 __SUP_COUT__ <<
"New context member map complete." << __E__;
5005 "Merger of group " + groupANameContext +
" (" + groupAKeyContext.
toString() +
5006 ") and " + groupBNameContext +
" (" + groupBKeyContext.
toString() +
").");
5009 xmlOut.addTextElementToData(
"ContextGroupName", groupANameContext);
5010 xmlOut.addTextElementToData(
"ContextGroupKey", newKeyContext.
toString());
5012 if(!skippingConfigPair)
5014 __SUP_COUT__ <<
"New table member map complete." << __E__;
5021 "Merger of group " + groupANameConfig +
" (" + groupAKeyConfig.
toString() +
5022 ") and " + groupBNameConfig +
" (" + groupBKeyConfig.
toString() +
").");
5025 xmlOut.addTextElementToData(
"ConfigGroupName", groupANameConfig);
5026 xmlOut.addTextElementToData(
"ConfigGroupKey", newKeyConfig.
toString());
5031 std::string mergeReportBasePath = std::string(__ENV__(
"USER_DATA"));
5032 std::string mergeReportPath =
"/ServiceData/";
5034 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
5035 mergeReportPath +=
"ConfigurationGUI_mergeReports/";
5037 mkdir((mergeReportBasePath + mergeReportPath).c_str(), 0755);
5040 "merge_" + std::to_string(time(0)) +
"_" + std::to_string(clock()) +
".txt";
5041 __SUP_COUTV__(mergeReportPath);
5043 FILE* fp = fopen((mergeReportBasePath + mergeReportPath).c_str(),
"w");
5046 fprintf(fp,
"%s", mergeReport.str().c_str());
5048 xmlOut.addTextElementToData(
"MergeReportFile",
5049 "/$USER_DATA/" + mergeReportPath);
5052 xmlOut.addTextElementToData(
"MergeReportFile",
"FILE FAILURE");
5056 catch(std::runtime_error& e)
5058 __SUP_SS__ <<
"Error merging context group pair " << groupANameContext <<
" ("
5059 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
5060 << groupBKeyContext <<
") and table group pair " << groupANameConfig
5061 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
5062 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
"': \n\n"
5063 << e.what() << __E__;
5064 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5065 xmlOut.addTextElementToData(
"Error", ss.str());
5069 __SUP_SS__ <<
"Unknown error merging context group pair " << groupANameContext <<
" ("
5070 << groupAKeyContext <<
") & " << groupBNameContext <<
" ("
5071 << groupBKeyContext <<
") and table group pair " << groupANameConfig
5072 <<
" (" << groupAKeyConfig <<
") & " << groupBNameConfig <<
" ("
5073 << groupBKeyConfig <<
") with approach '" << mergeApproach <<
".' \n\n";
5078 catch(
const std::exception& e)
5080 ss <<
"Exception message: " << e.what();
5085 __SUP_COUT_ERR__ <<
"\n" << ss.
str() << __E__;
5086 xmlOut.addTextElementToData(
"Error", ss.str());
5091 void ConfigurationGUISupervisor::handleSavePlanCommandSequenceXML(
5094 const std::string& groupName,
5096 const std::string& modifiedTables,
5097 const std::string& author,
5098 const std::string& planName,
5099 const std::string& commandString)
5102 __COUT__ <<
"handleSavePlanCommandSequenceXML " << planName << __E__;
5105 setupActiveTablesXML(xmlOut,
5120 TableEditStruct loopTable(IterateTable::MACRO_DIM_LOOP_TABLE, cfgMgr);
5121 TableEditStruct loopParamTable(IterateTable::MACRO_DIM_LOOP_PARAM_TABLE, cfgMgr);
5127 for(
const auto& commandPair : IterateTable::commandToTableMap_)
5128 if(commandPair.second !=
"")
5129 commandTableToEditMap.emplace(std::pair<std::string, TableEditStruct>(
5146 std::string groupName = planName +
"-Plan";
5147 __SUP_COUT__ <<
"Handling commands for group " << groupName << __E__;
5149 unsigned int groupIdCol =
5150 planTable.tableView_->findCol(IterateTable::planTableCols_.GroupID_);
5151 unsigned int cmdTypeCol =
5152 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandType_);
5154 unsigned int targetGroupIdCol =
5155 targetTable.tableView_->findCol(IterateTable::targetCols_.GroupID_);
5156 unsigned int targetTableCol =
5157 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLink_);
5158 unsigned int targetUIDCol =
5159 targetTable.tableView_->findCol(IterateTable::targetCols_.TargetLinkUID_);
5161 unsigned int loopGroupIdCol =
5162 loopTable.tableView_->findCol(IterateTable::macroDimLoopCols_.GroupID_);
5163 unsigned int loopPriorityCol =
5164 loopTable.tableView_->findCol(IterateTable::macroDimLoopCols_.Priority_);
5165 unsigned int loopNumIterCol = loopTable.tableView_->findCol(
5166 IterateTable::macroDimLoopCols_.NumberOfIterations_);
5167 unsigned int loopParamLinkCol =
5168 loopTable.tableView_->findCol(IterateTable::macroDimLoopCols_.ParamLink_);
5169 unsigned int loopParamLinkGroupIdCol = loopTable.tableView_->findCol(
5170 IterateTable::macroDimLoopCols_.ParamLinkGroupID_);
5171 unsigned int loopStepLabelCol = (
unsigned int)-1;
5175 loopTable.tableView_->findCol(IterateTable::macroDimLoopCols_.StepLabel_);
5180 <<
"Table '" << IterateTable::MACRO_DIM_LOOP_TABLE <<
"' has no '"
5181 << IterateTable::macroDimLoopCols_.StepLabel_
5182 <<
"' column; macro argument step labels will not be saved. "
5183 "Save a new version of the table to add the column."
5186 unsigned int loopParamGroupIdCol =
5187 loopParamTable.tableView_->findCol(IterateTable::macroParamCols_.GroupID_);
5188 unsigned int loopParamNameCol =
5189 loopParamTable.tableView_->findCol(IterateTable::macroParamCols_.Name_);
5190 unsigned int loopParamValueCol =
5191 loopParamTable.tableView_->findCol(IterateTable::macroParamCols_.Value_);
5192 unsigned int loopParamStepCol =
5193 loopParamTable.tableView_->findCol(IterateTable::macroParamCols_.Step_);
5194 std::string loopGroupLinkIndex =
5195 loopTable.tableView_->getColumnInfo(loopGroupIdCol).getChildLinkIndex();
5196 std::string loopParamGroupLinkIndex =
5197 loopParamTable.tableView_->getColumnInfo(loopParamGroupIdCol)
5198 .getChildLinkIndex();
5200 std::string groupLinkIndex =
5201 planTable.tableView_->getColumnInfo(groupIdCol).getChildLinkIndex();
5202 __SUP_COUT__ <<
"groupLinkIndex: " << groupLinkIndex << __E__;
5204 std::pair<
unsigned int ,
unsigned int > commandUidLink;
5207 planTable.tableView_->getChildLink(
5208 planTable.tableView_->findCol(IterateTable::planTableCols_.CommandLink_),
5213 unsigned int cmdRow, cmdCol;
5214 std::string targetGroupName;
5218 std::string targetUID, cmdType;
5220 for(
unsigned int row = 0; row < planTable.tableView_->getNumberOfRows();
5223 targetUID = planTable.tableView_
5224 ->getDataView()[row][planTable.tableView_->getColUID()];
5225 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
5228 if(planTable.tableView_->isEntryInGroup(row, groupLinkIndex, groupName))
5230 __SUP_COUT__ <<
"Removing." << __E__;
5234 cmdType = planTable.tableView_->getDataView()[row][cmdTypeCol];
5235 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(cmdType);
5236 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
5237 cmdTypeTableIt->second !=
5241 commandTableToEditMap.at(cmdTypeTableIt->second);
5242 cmdRow = cmdTypeTableEdit.tableView_->findRow(
5243 cmdTypeTableEdit.tableView_->getColUID(),
5244 planTable.tableView_
5245 ->getDataView()[row][commandUidLink.second]);
5252 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5253 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
5254 targetGroupName = cmdTypeTableEdit.tableView_
5255 ->getDataView()[cmdRow][cmdCol];
5257 for(
unsigned int trow = 0;
5258 trow < targetTable.tableView_->getNumberOfRows();
5262 if(targetTable.tableView_->isEntryInGroup(
5264 cmdTypeTableEdit.tableView_->getColumnInfo(cmdCol)
5265 .getChildLinkIndex(),
5268 __SUP_COUT__ <<
"Removing target." << __E__;
5270 if(targetTable.tableView_->removeRowFromGroup(
5281 __SUP_COUT__ <<
"No targets." << __E__;
5288 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5289 IterateTable::commandExecuteMacroParams_
5290 .MacroParameterLinkGroupID_);
5291 std::string loopGroupName =
5292 cmdTypeTableEdit.tableView_
5293 ->getDataView()[cmdRow][cmdCol];
5295 for(
unsigned int lrow = 0;
5296 loopGroupName !=
"" &&
5297 lrow < loopTable.tableView_->getNumberOfRows();
5300 if(!loopTable.tableView_->isEntryInGroup(
5301 lrow, loopGroupLinkIndex, loopGroupName))
5304 std::string paramGroupName =
5305 loopTable.tableView_
5306 ->getDataView()[lrow][loopParamLinkGroupIdCol];
5307 for(
unsigned int prow = 0;
5308 paramGroupName !=
"" &&
5309 prow < loopParamTable.tableView_->getNumberOfRows();
5311 if(loopParamTable.tableView_->isEntryInGroup(
5313 loopParamGroupLinkIndex,
5315 loopParamTable.tableView_->removeRowFromGroup(
5317 loopParamGroupIdCol,
5325 __SUP_COUT__ <<
"Removing macro argument loop row."
5327 if(loopTable.tableView_->removeRowFromGroup(
5333 loopTable.modified_ =
true;
5340 __SUP_COUT__ <<
"No macro argument loops." << __E__;
5345 cmdTypeTableEdit.tableView_->deleteRow(cmdRow);
5351 if(planTable.tableView_->removeRowFromGroup(
5352 row, groupIdCol, groupName,
true ))
5361 std::vector<IterateTable::Command> commands;
5366 std::istringstream f(commandString);
5367 std::string commandSubString, paramSubString, paramValue;
5369 while(getline(f, commandSubString,
';'))
5371 __SUP_COUTT__ <<
"commandSubString " << commandSubString << __E__;
5372 std::istringstream g(commandSubString);
5375 while(getline(g, paramSubString,
','))
5377 __SUP_COUTT__ <<
"paramSubString " << paramSubString << __E__;
5380 if(paramSubString !=
"type")
5382 __SUP_SS__ <<
"Invalid command sequence" << __E__;
5386 commands.push_back(IterateTable::Command());
5388 getline(g, paramValue,
',');
5390 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
5391 commands.back().type_ = paramValue;
5395 getline(g, paramValue,
',');
5397 __SUP_COUTT__ <<
"paramValue " << paramValue << __E__;
5399 if(paramSubString ==
"TargetSubsystem")
5400 commands.back().targetSubsystem_ =
5403 commands.back().params_.emplace(
5404 std::pair<std::string ,
5416 __SUP_COUT__ <<
"commands size " << commands.size() << __E__;
5423 unsigned int row, tgtRow;
5424 unsigned int targetIndex;
5425 std::string targetStr, cmdUID;
5427 for(
auto& command : commands)
5429 __SUP_COUT__ <<
"command " << command.type_ << __E__;
5430 __SUP_COUT__ <<
"table " << IterateTable::commandToTableMap_.at(command.type_)
5434 row = planTable.tableView_->addRow(
5435 author,
true ,
"planCommand");
5436 planTable.tableView_->addRowToGroup(row, groupIdCol, groupName);
5439 planTable.tableView_->setURIEncodedValue(command.type_, row, cmdTypeCol);
5444 unsigned int tsCol = planTable.tableView_->findCol(
5445 IterateTable::planTableCols_.TargetSubsystem_);
5446 planTable.tableView_->setValueAsString(
5447 command.targetSubsystem_, row, tsCol);
5454 planTable.tableView_->setValueAsString(
5455 "1", row, planTable.tableView_->getColStatus());
5458 auto cmdTypeTableIt = IterateTable::commandToTableMap_.find(command.type_);
5459 if(cmdTypeTableIt != IterateTable::commandToTableMap_.end() &&
5460 cmdTypeTableIt->second !=
5464 commandTableToEditMap.at(cmdTypeTableIt->second);
5465 __SUP_COUT__ <<
"table " << cmdTypeTableEdit.tableName_ << __E__;
5470 cmdRow = cmdTypeTableEdit.tableView_->addRow(
5471 author,
true , command.type_ +
"_COMMAND_");
5477 for(
auto& param : command.params_)
5479 __SUP_COUT__ <<
"\t param " << param.first <<
" : " << param.second
5482 if(param.first == IterateTable::targetParams_.Tables_)
5484 __SUP_COUT__ <<
"\t\t found target tables" << __E__;
5485 std::istringstream f(param.second);
5488 while(getline(f, targetStr,
'='))
5490 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
5491 if(!command.targets_.size() ||
5492 command.targets_.back().table_ !=
"")
5494 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
5497 command.addTarget();
5498 command.targets_.back().table_ = targetStr;
5501 command.targets_[targetIndex++].table_ = targetStr;
5507 if(param.first == IterateTable::targetParams_.UIDs_)
5509 __SUP_COUT__ <<
"\t\t found target UIDs" << __E__;
5510 std::istringstream f(param.second);
5513 while(getline(f, targetStr,
'='))
5515 __SUP_COUT__ <<
"\t\t targetStr = " << targetStr << __E__;
5516 if(!command.targets_.size() ||
5517 command.targets_.back().UID_ !=
"")
5519 __SUP_COUT__ <<
"\t\t make targetStr = " << targetStr
5522 command.addTarget();
5523 command.targets_.back().UID_ = targetStr;
5526 command.targets_[targetIndex++].UID_ = targetStr;
5531 if(param.first == IterateTable::commandExecuteMacroParams_.MacroArgs_)
5534 cmdCol = cmdTypeTableEdit.tableView_->findCol(param.first);
5536 __SUP_COUT__ <<
"param col " << cmdCol << __E__;
5538 cmdTypeTableEdit.tableView_->setURIEncodedValue(
5539 param.second, cmdRow, cmdCol);
5543 cmdTypeTableEdit.tableView_
5544 ->getDataView()[cmdRow][cmdTypeTableEdit.tableView_->getColUID()];
5549 auto macroArgsIt = command.params_.find(
5550 IterateTable::commandExecuteMacroParams_.MacroArgs_);
5551 bool isMacroCommand =
false;
5554 cmdTypeTableEdit.tableView_->findCol(
5555 IterateTable::commandExecuteMacroParams_.MacroParameterLink_);
5556 isMacroCommand =
true;
5565 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5566 IterateTable::commandExecuteMacroParams_.MacroParameterLink_);
5567 cmdTypeTableEdit.tableView_->setValueAsString(
5568 IterateTable::MACRO_DIM_LOOP_TABLE, cmdRow, cmdCol);
5569 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5570 IterateTable::commandExecuteMacroParams_
5571 .MacroParameterLinkGroupID_);
5572 cmdTypeTableEdit.tableView_->setValueAsString(
5573 cmdUID +
"_Loops", cmdRow, cmdCol);
5575 std::vector<std::string> labelOrder;
5578 std::vector<std::vector<std::string> >>
5581 if(macroArgsIt != command.params_.end() &&
5582 macroArgsIt->second !=
"")
5584 std::vector<std::string> entries =
5587 for(
const auto& entry : entries)
5591 std::vector<std::string> pieces =
5594 if(pieces.size() != 4 || pieces[0] ==
"")
5597 <<
"Invalid macro argument entry '" << entry
5598 <<
"' for command '" << command.type_
5599 <<
".' Expected name:start:step:label." << __E__;
5602 for(
auto& piece : pieces)
5605 if(argsByLabel.find(pieces[3]) == argsByLabel.end())
5606 labelOrder.push_back(pieces[3]);
5607 argsByLabel[pieces[3]].push_back(
5608 {pieces[0], pieces[1], pieces[2]});
5612 for(
size_t li = 0; li < labelOrder.size(); ++li)
5614 const std::string& label = labelOrder[li];
5615 std::string paramGroupName =
5616 cmdUID +
"_L" + std::to_string(li) +
"_Params";
5618 unsigned int lrow = loopTable.tableView_->addRow(
5619 author,
true , cmdUID +
"_Dim");
5620 loopTable.tableView_->addRowToGroup(
5621 lrow, loopGroupIdCol, cmdUID +
"_Loops");
5622 loopTable.tableView_->setValueAsString(
5623 std::to_string(li), lrow, loopPriorityCol);
5624 loopTable.tableView_->setValueAsString(
5625 "1", lrow, loopNumIterCol);
5626 if(loopStepLabelCol != (
unsigned int)-1)
5627 loopTable.tableView_->setURIEncodedValue(
5628 label, lrow, loopStepLabelCol);
5629 loopTable.tableView_->setValueAsString(
5630 IterateTable::MACRO_DIM_LOOP_PARAM_TABLE,
5633 loopTable.tableView_->setValueAsString(
5634 paramGroupName, lrow, loopParamLinkGroupIdCol);
5635 loopTable.modified_ =
true;
5637 for(
const auto& arg : argsByLabel[label])
5639 unsigned int prow = loopParamTable.tableView_->addRow(
5643 loopParamTable.tableView_->addRowToGroup(
5644 prow, loopParamGroupIdCol, paramGroupName);
5645 loopParamTable.tableView_->setURIEncodedValue(
5646 arg[0], prow, loopParamNameCol);
5647 loopParamTable.tableView_->setURIEncodedValue(
5648 arg[1], prow, loopParamValueCol);
5649 loopParamTable.tableView_->setURIEncodedValue(
5650 arg[2], prow, loopParamStepCol);
5651 loopParamTable.modified_ =
true;
5653 __SUP_COUT__ <<
"Macro argument loop row for label '" << label
5654 <<
"' with " << argsByLabel[label].size()
5655 <<
" argument(s)." << __E__;
5660 if(command.targets_.size())
5664 __SUP_COUT__ <<
"targets found for command UID=" << cmdUID << __E__;
5667 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5668 IterateTable::commandTargetCols_.TargetsLink_);
5669 cmdTypeTableEdit.tableView_->setValueAsString(
5670 IterateTable::TARGET_TABLE, cmdRow, cmdCol);
5672 cmdCol = cmdTypeTableEdit.tableView_->findCol(
5673 IterateTable::commandTargetCols_.TargetsLinkGroupID_);
5674 cmdTypeTableEdit.tableView_->setValueAsString(
5675 cmdUID +
"_Targets", cmdRow, cmdCol);
5679 for(
const auto& target : command.targets_)
5681 __SUP_COUT__ << target.
table_ <<
" " << target.UID_ << __E__;
5684 tgtRow = targetTable.tableView_->addRow(
5685 author,
true ,
"commandTarget");
5686 targetTable.tableView_->addRowToGroup(
5687 tgtRow, targetGroupIdCol, cmdUID +
"_Targets");
5690 targetTable.tableView_->setValueAsString(
5691 target.table_, tgtRow, targetTableCol);
5694 targetTable.tableView_->setValueAsString(
5695 target.UID_, tgtRow, targetUIDCol);
5700 planTable.tableView_->setValueAsString(
5701 cmdTypeTableEdit.tableName_, row, commandUidLink.first);
5702 planTable.tableView_->setValueAsString(
5703 cmdUID, row, commandUidLink.second);
5705 __SUP_COUT__ <<
"linked to uid = " << cmdUID << __E__;
5715 planTable.tableView_->print();
5716 planTable.tableView_->init();
5718 __SUP_COUT__ <<
"requestType tables:" << __E__;
5720 for(
auto& modifiedConfig : commandTableToEditMap)
5722 __SUP_COUTV__(modifiedConfig.second.modified_);
5723 modifiedConfig.second.tableView_->print();
5724 modifiedConfig.second.tableView_->init();
5727 targetTable.tableView_->print();
5728 targetTable.tableView_->init();
5730 loopTable.tableView_->init();
5731 loopParamTable.tableView_->init();
5736 __SUP_COUT__ <<
"Handling command table errors while saving. Erasing all newly "
5743 {&planTable, &targetTable, &loopTable, &loopParamTable})
5744 if(editTable->createdTemporaryVersion_)
5746 __SUP_COUT__ <<
"Erasing temporary version " << editTable->tableName_
5747 <<
"-v" << editTable->temporaryVersion_ << __E__;
5750 editTable->temporaryVersion_);
5753 for(
auto& modifiedConfig : commandTableToEditMap)
5755 if(modifiedConfig.second
5756 .createdTemporaryVersion_)
5758 __SUP_COUT__ <<
"Erasing temporary version "
5759 << modifiedConfig.second.tableName_ <<
"-v"
5760 << modifiedConfig.second.temporaryVersion_ << __E__;
5763 modifiedConfig.second.temporaryVersion_);
5777 planTable.tableName_,
5778 planTable.originalVersion_,
5781 planTable.temporaryVersion_,
5784 __SUP_COUT__ <<
"Final plan version is " << planTable.tableName_ <<
"-v"
5785 << finalVersion << __E__;
5790 targetTable.tableName_,
5791 targetTable.originalVersion_,
5794 targetTable.temporaryVersion_,
5797 __SUP_COUT__ <<
"Final target version is " << targetTable.tableName_ <<
"-v"
5798 << finalVersion << __E__;
5802 if(!editTable->modified_)
5804 if(editTable->createdTemporaryVersion_)
5806 __SUP_COUT__ <<
"Erasing unmodified temporary version "
5807 << editTable->tableName_ <<
"-v"
5808 << editTable->temporaryVersion_ << __E__;
5810 editTable->temporaryVersion_);
5817 editTable->tableName_,
5818 editTable->originalVersion_,
5821 editTable->temporaryVersion_,
5823 __SUP_COUT__ <<
"Final version is " << editTable->tableName_ <<
"-v"
5824 << finalVersion << __E__;
5827 for(
auto& modifiedConfig : commandTableToEditMap)
5829 if(!modifiedConfig.second.modified_)
5831 if(modifiedConfig.second
5832 .createdTemporaryVersion_)
5834 __SUP_COUT__ <<
"Erasing unmodified temporary version "
5835 << modifiedConfig.second.tableName_ <<
"-v"
5836 << modifiedConfig.second.temporaryVersion_ << __E__;
5839 modifiedConfig.second.temporaryVersion_);
5847 modifiedConfig.second.tableName_,
5848 modifiedConfig.second.originalVersion_,
5850 modifiedConfig.second.table_,
5851 modifiedConfig.second.temporaryVersion_,
5854 __SUP_COUT__ <<
"Final version is " << modifiedConfig.second.tableName_ <<
"-v"
5855 << finalVersion << __E__;
5858 handleFillModifiedTablesXML(xmlOut, cfgMgr);
5860 catch(std::runtime_error& e)
5862 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << e.what() << __E__;
5863 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5864 xmlOut.addTextElementToData(
"Error", ss.str());
5868 __SUP_SS__ <<
"Error detected saving Iteration Plan!\n\n " << __E__;
5873 catch(
const std::exception& e)
5875 ss <<
"Exception message: " << e.what();
5880 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
5881 xmlOut.addTextElementToData(
"Error", ss.str());
5894 void ConfigurationGUISupervisor::handleSaveTreeNodeEditXML(
HttpXmlDocument& xmlOut,
5896 const std::string& tableName,
5898 const std::string& type,
5899 const std::string& uid,
5900 const std::string& colName,
5901 const std::string& newValue,
5902 const std::string& author)
5905 __SUP_COUT__ <<
"Editing table " << tableName <<
"(" << version <<
") uid=" << uid
5906 <<
" type=" << type << __E__;
5916 table->setActiveView(version);
5920 if(version.isTemporaryVersion())
5923 __SUP_COUT__ <<
"Failed to find stored version, so attempting to load version: "
5924 << version << __E__;
5928 __SUP_COUT__ <<
"Active version is " << table->getViewVersion() << __E__;
5929 __SUP_COUTTV__(table->getView().getComment());
5931 if(version != table->getViewVersion())
5933 __SUP_SS__ <<
"Target table version (" << version
5934 <<
") is not the currently active version (" << table->getViewVersion()
5935 <<
"). Try refreshing the tree." << __E__;
5939 unsigned int col = -1;
5940 if(type ==
"uid" || type ==
"delete-uid" || type ==
"tree-copy")
5941 col = table->getView().getColUID();
5942 else if(type ==
"node-comment")
5943 col = table->getView().findCol(TableViewColumnInfo::COL_NAME_COMMENT);
5944 else if(type ==
"link-UID" || type ==
"link-GroupID" || type ==
"value" ||
5945 type ==
"value-groupid" || type ==
"value-bool" || type ==
"value-bitmap")
5946 col = table->getView().findCol(colName);
5947 else if(type ==
"table" || type ==
"link-comment" || type ==
"table-newGroupRow" ||
5948 type ==
"table-newUIDRow" || type ==
"table-newRow")
5952 __SUP_SS__ <<
"Impossible! Unrecognized edit type: " << type << __E__;
5957 if(type ==
"table" || type ==
"link-comment")
5960 if(table->getView().isURIEncodedCommentTheSame(newValue))
5963 <<
"' is the same as the current comment. No need to save change."
5979 TableVersion temporaryVersion = table->createTemporaryView(version);
5981 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
5983 TableView* cfgView = table->getTemporaryView(temporaryVersion);
5986 __SUP_COUTTV__(table->getView().getComment());
5992 if(type ==
"table" || type ==
"link-comment")
5997 else if(type ==
"table-newRow" || type ==
"table-newUIDRow")
6000 unsigned int row = cfgView->
addRow(
6001 author,
true , newValue );
6016 else if(type ==
"table-newGroupRow")
6019 unsigned int csvIndex = newValue.find(
',');
6021 std::string linkIndex = newValue.substr(0, csvIndex);
6022 std::string groupId = newValue.substr(csvIndex + 1);
6025 csvIndex = groupId.find(
',');
6026 std::string newRowUID = groupId.substr(csvIndex + 1);
6027 groupId = groupId.substr(0, csvIndex);
6029 __SUP_COUT__ <<
"newValue " << linkIndex <<
"," << groupId <<
"," << newRowUID
6033 unsigned int row = cfgView->
addRow(author,
6059 else if(type ==
"delete-uid")
6062 unsigned int row = cfgView->
findRow(col, uid);
6065 else if(type ==
"tree-copy")
6068 __COUTV__(newValue);
6069 std::vector<std::string> paramArray =
6075 if(paramArray.size() < 2 || paramArray.size() > 3)
6077 __SS__ <<
"Illegal parameters for tree copy request: must be number of "
6078 "copy instances & depth of copy (optionally followed by a "
6079 "custom UID for the new record)."
6084 unsigned int row = cfgView->
findRow(col, uid);
6087 unsigned int numberOfInstances = atoi(paramArray[0].c_str());
6088 unsigned int depth = atoi(paramArray[1].c_str());
6089 std::string customUID = paramArray.size() == 3
6093 __COUTV__(numberOfInstances);
6094 __COUTV__(customUID);
6095 if(numberOfInstances > 1000)
6097 __SS__ <<
"Illegal parameters - the maximum number of copy instances is "
6098 "1000. Number of instances provided was "
6099 << numberOfInstances << __E__;
6102 if(!customUID.empty() && numberOfInstances != 1)
6104 __SS__ <<
"A custom UID can only be supplied when copying a single "
6105 "instance. Requested instances: "
6106 << numberOfInstances << __E__;
6114 unsigned int rowsBeforeCopy = cfgView->getNumberOfRows();
6115 ConfigurationSupervisorBase::recursiveCopyTreeUIDNode(xmlOut,
6125 if(!customUID.empty() && cfgView->getNumberOfRows() > rowsBeforeCopy)
6127 unsigned int uidCol = cfgView->
getColUID();
6128 unsigned int newRow = cfgView->getNumberOfRows() - 1;
6130 xmlOut.addTextElementToData(
"CopiedRecordUID", customUID);
6133 else if(type ==
"uid" || type ==
"value" || type ==
"value-groupid" ||
6134 type ==
"value-bool" || type ==
"value-bitmap" || type ==
"node-comment")
6140 __SUP_SS__ <<
"Value '" << newValue
6141 <<
"' is the same as the current value. No need to save "
6142 "change to tree node."
6147 else if(type ==
"link-UID" || type ==
"link-GroupID")
6150 std::pair<
unsigned int ,
unsigned int > linkPair;
6154 __SUP_SS__ <<
"Col '" << colName <<
"' is not a link column." << __E__;
6158 __SUP_COUT__ <<
"linkPair " << linkPair.first <<
"," << linkPair.second
6161 std::string linkIndex = cfgView->getColumnInfo(col).getChildLinkIndex();
6163 __SUP_COUT__ <<
"linkIndex " << linkIndex << __E__;
6166 unsigned int csvIndexStart = 0, csvIndex = newValue.find(
',');
6168 std::string newTable = newValue.substr(csvIndexStart, csvIndex);
6169 csvIndexStart = csvIndex + 1;
6170 csvIndex = newValue.find(
',', csvIndexStart);
6171 std::string newLinkId = newValue.substr(
6176 __SUP_COUT__ <<
"newValue " << newTable <<
"," << newLinkId << __E__;
6180 bool changed =
false;
6181 bool needSecondaryChange = (type ==
"link-GroupID");
6186 __SUP_COUT__ <<
"Value '" << newTable
6187 <<
"' is the same as the current value." << __E__;
6195 std::string originalValue = cfgView->
getValueAsString(row, linkPair.second);
6199 __SUP_COUT__ <<
"Value '" << newLinkId
6200 <<
"' is the same as the current value." << __E__;
6205 needSecondaryChange =
6211 if(needSecondaryChange)
6213 bool secondaryChanged =
false;
6214 bool defaultIsInGroup =
6220 __SUP_COUT__ <<
"No changes to primary view. Erasing temporary table."
6222 table->eraseView(temporaryVersion);
6243 catch(std::runtime_error&
6246 __SUP_COUT__ <<
"Caught error while editing main table. Erasing "
6247 "temporary version."
6249 table->eraseView(temporaryVersion);
6253 xmlOut.addTextElementToData(
6255 "Error saving primary tree node! " + std::string(e.what()));
6265 __SUP_COUTV__(newValue);
6266 csvIndexStart = csvIndex + 1;
6267 csvIndex = newValue.find(
',', csvIndexStart);
6269 csvIndexStart, csvIndex - csvIndexStart));
6272 if(newTable == TableViewColumnInfo::DATATYPE_LINK_DEFAULT)
6283 table->setActiveView(version);
6287 if(version.isTemporaryVersion())
6290 __SUP_COUT__ <<
"Failed to find stored version, so attempting to "
6292 << newTable <<
" v" << version << __E__;
6296 __SUP_COUT__ << newTable <<
" active version is "
6297 << table->getViewVersion() << __E__;
6299 if(version != table->getViewVersion())
6302 if(version.isMockupVersion())
6303 ss <<
"Target table '" << newTable
6304 <<
"' is likely not a member of the current table group "
6305 <<
"since the mock-up version was not successfully loaded. "
6310 "To add a table to a group, click the group name to go to "
6312 "group view, then click 'Add/Remove/Modify Member Tables.' "
6314 "can then add or remove tables and save the new group." +
6316 "OR!!! Click the following button to add the table '" +
6318 "' to the currently active Configuration Group: " +
6319 "<input type='button' style='color:black !important;' " +
6320 "title='Click to add table to the active Configuration "
6322 "onclick='addTableToConfigurationGroup(\"" + newTable +
6323 "\"); Debug.closeErrorPop();event.stopPropagation();' "
6324 "value='Add Table'>" +
6328 ss <<
"Target table version (" << version
6329 <<
") is not the currently active version ("
6330 << table->getViewVersion() <<
"). Try refreshing the tree."
6336 temporaryVersion = table->createTemporaryView(version);
6338 __SUP_COUT__ <<
"Created temporary version " << temporaryVersion << __E__;
6340 cfgView = table->getTemporaryView(temporaryVersion);
6344 if(type ==
"link-UID")
6354 __SUP_COUT__ <<
"target col " << col << __E__;
6356 unsigned int row = -1;
6359 row = cfgView->
findRow(col, newLinkId);
6364 if(row == (
unsigned int)-1)
6366 __SUP_COUT__ <<
"New link UID '" << newLinkId
6367 <<
"' was not found, so attempting to change UID of "
6369 << originalValue <<
"'" << __E__;
6372 row = cfgView->
findRow(col, originalValue);
6375 secondaryChanged =
true;
6376 __SUP_COUT__ <<
"Original target record '"
6377 << originalValue <<
"' was changed to '"
6378 << newLinkId <<
"'" << __E__;
6383 __SUP_COUT__ <<
"Original target record '" << originalValue
6384 <<
"' not found." << __E__;
6388 else if(type ==
"link-GroupID")
6396 __SUP_COUT__ <<
"target col " << col << __E__;
6399 std::vector<std::string> memberUIDs;
6402 csvIndexStart = csvIndex + 1;
6403 csvIndex = newValue.find(
',', csvIndexStart);
6404 memberUIDs.push_back(
6405 newValue.substr(csvIndexStart, csvIndex - csvIndexStart));
6406 __SUP_COUT__ <<
"memberUIDs: " << memberUIDs.back() << __E__;
6408 (
unsigned int)std::string::npos);
6418 std::string targetUID;
6419 bool shouldBeInGroup;
6422 for(
unsigned int row = 0; row < cfgView->getNumberOfRows(); ++row)
6424 targetUID = cfgView->getDataView()[row][cfgView->
getColUID()];
6425 __SUP_COUT__ <<
"targetUID: " << targetUID << __E__;
6427 shouldBeInGroup =
false;
6428 for(
unsigned int i = 0; i < memberUIDs.size(); ++i)
6429 if(targetUID == memberUIDs[i])
6432 shouldBeInGroup =
true;
6439 if(shouldBeInGroup && !isInGroup)
6441 __SUP_COUT__ <<
"Changed to YES: " << row << __E__;
6442 secondaryChanged =
true;
6447 else if(!shouldBeInGroup && isInGroup)
6449 __SUP_COUT__ <<
"Changed to NO: " << row << __E__;
6450 secondaryChanged =
true;
6454 else if(targetUID ==
6456 ->getDefaultRowValues()[cfgView->
getColUID()] &&
6460 defaultIsInGroup =
true;
6466 if(!secondaryChanged)
6469 <<
"No changes to secondary view. Erasing temporary table."
6471 table->eraseView(temporaryVersion);
6492 catch(std::runtime_error&
6495 __SUP_COUT__ <<
"Caught error while editing secondary table. "
6496 "Erasing temporary version."
6498 table->eraseView(temporaryVersion);
6499 secondaryChanged =
false;
6502 xmlOut.addTextElementToData(
6504 "Error saving secondary tree node! " + std::string(e.what()));
6512 if(0 && !changed && !secondaryChanged && !defaultIsInGroup)
6514 __SUP_SS__ <<
"Link to table '" << newTable <<
"', linkID '"
6516 <<
"', and selected group members are the same as the "
6518 <<
"No need to save changes to tree." << __E__;
6524 else if(0 && !changed)
6529 __SUP_SS__ <<
"Link to table '" << newTable <<
"' and linkID '"
6531 <<
"' are the same as the current values. No need to save "
6532 "change to tree node."
6542 __SUP_COUT__ <<
"Caught error while editing. Erasing temporary version." << __E__;
6543 table->eraseView(temporaryVersion);
6557 catch(std::runtime_error& e)
6559 __SUP_SS__ <<
"Error saving tree node! " << e.what() << __E__;
6560 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
6561 xmlOut.addTextElementToData(
"Error", ss.str());
6565 __SUP_SS__ <<
"Unknown Error saving tree node! " << __E__;
6570 catch(
const std::exception& e)
6572 ss <<
"Exception message: " << e.what();
6577 __SUP_COUT_ERR__ <<
"\n" << ss.str() << __E__;
6578 xmlOut.addTextElementToData(
"Error", ss.str());
6622 void ConfigurationGUISupervisor::handleGetTableXML(
HttpXmlDocument& xmlOut,
6624 const std::string& tableName,
6626 bool allowIllegalColumns ,
6628 bool descriptionOnly )
6631 xercesc::DOMElement *parentEl, *subparentEl;
6633 std::string accumulatedErrors =
"";
6635 if(allowIllegalColumns)
6636 xmlOut.addTextElementToData(
"allowIllegalColumns",
"1");
6638 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo(
6639 allowIllegalColumns ,
6640 allowIllegalColumns ? &accumulatedErrors : 0,
6649 xmlOut.addTextElementToData(
"ExistingTableNames",
6650 TableViewColumnInfo::DATATYPE_LINK_DEFAULT);
6651 for(
auto& configPair : allTableInfo)
6653 xmlOut.addTextElementToData(
"ExistingTableNames", configPair.first);
6654 if(configPair.first == tableName &&
6655 configPair.second.versions_.find(version) ==
6656 configPair.second.versions_.end())
6658 __SUP_COUT__ <<
"Version not found, so using mockup." << __E__;
6664 xmlOut.addTextElementToData(
"TableName", tableName);
6665 xmlOut.addTextElementToData(
"TableDescription",
6666 table->getTableDescription());
6683 for(
const auto& aliases : versionAliases)
6684 for(
const auto& alias : aliases.second)
6685 __SUP_COUTT__ <<
"ALIAS: " << aliases.first <<
" " << alias.first
6686 <<
" ==> " << alias.second << __E__;
6688 catch(
const std::runtime_error& e)
6690 __SUP_COUT__ <<
"Could not get backbone information for version aliases: "
6691 << e.what() << __E__;
6694 auto tableIterator = versionAliases.find(tableName);
6696 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
6699 for(
const TableVersion& v : allTableInfo.at(tableName).versions_)
6705 std::vector<std::string> aliases;
6706 if(tableIterator != versionAliases.end())
6709 for(
const auto& aliasPair : tableIterator->second)
6711 if(v == aliasPair.second)
6713 __SUP_COUT__ <<
"Found Alias " << aliasPair.second <<
" --> "
6714 << aliasPair.first << __E__;
6715 aliases.push_back(aliasPair.first);
6723 __SUP_COUT__ <<
"Handling version w/aliases" << __E__;
6726 TableVersion::INVALID)
6731 else if(hi.
version() + 1 == v.version())
6738 if(lo.
version() != TableVersion::INVALID)
6748 if(versionAliases.size())
6752 for(
const auto& alias : aliases)
6754 hi = lo = TableVersion::INVALID;
6759 if(lo.
version() != TableVersion::INVALID)
6773 if(version.isInvalid())
6775 tableViewPtr = table->getMockupViewP();
6783 std::string localAccumulatedErrors =
"";
6788 allowIllegalColumns ,
6789 &localAccumulatedErrors,
6795 xmlOut.addTextElementToData(
"TableRawData",
6796 tableViewPtr->getSourceRawData());
6798 const std::set<std::string>& srcColNames =
6799 tableViewPtr->getSourceColumnNames();
6800 for(
auto& srcColName : srcColNames)
6801 xmlOut.addTextElementToData(
"ColumnHeader", srcColName);
6803 if(!version.isTemporaryVersion())
6808 tableViewPtr = cfgMgr
6812 allowIllegalColumns ,
6813 &localAccumulatedErrors,
6819 if(localAccumulatedErrors !=
"")
6820 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
6822 catch(std::runtime_error& e)
6824 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << version
6825 <<
"... defaulting to mock-up! " << __E__;
6826 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
6828 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6830 tableViewPtr = table->getMockupViewP();
6832 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6836 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << version
6837 <<
"... defaulting to mock-up! "
6838 <<
"(You may want to try again to see what was partially loaded "
6839 "into cache before failure. "
6840 <<
"If you think, the failure is due to a column name change, "
6841 <<
"you can also try to Copy the failing view to the new column "
6843 <<
"'Copy and Move' functionality.)" << __E__;
6848 catch(
const std::exception& e)
6850 ss <<
"Exception message: " << e.what();
6856 __SUP_COUT_ERR__ <<
"\n" << ss.str();
6858 tableViewPtr = table->getMockupViewP();
6860 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
6863 xmlOut.addTextElementToData(
"TableVersion", version.toString());
6869 xercesc::DOMElement* choicesParentEl;
6870 parentEl = xmlOut.addTextElementToData(
"CurrentVersionColumnHeaders",
"");
6872 std::vector<TableViewColumnInfo> colInfo = tableViewPtr->getColumnsInfo();
6874 for(
int i = 0; i < (int)colInfo.size(); ++i)
6879 "ColumnDataType", colInfo[i].getDataType(), parentEl);
6884 "ColumnDefaultValue", colInfo[i].getDefaultValue(), parentEl);
6888 if(colInfo[i].getType() == TableViewColumnInfo::TYPE_FIXED_CHOICE_DATA ||
6889 colInfo[i].getType() == TableViewColumnInfo::TYPE_BITMAP_DATA ||
6890 colInfo[i].isChildLink())
6892 for(
auto& choice : colInfo[i].getDataChoices())
6897 "ColumnMinValue", colInfo[i].getMinValue(), parentEl);
6899 "ColumnMaxValue", colInfo[i].getMaxValue(), parentEl);
6905 if(version.isInvalid())
6906 tableViewPtr->
init();
6908 catch(std::runtime_error& e)
6911 __THROW__(e.what() + std::string(
"\n\n") + accumulatedErrors);
6918 parentEl = xmlOut.addTextElementToData(
"CurrentVersionRows",
"");
6920 int numRows = (int)tableViewPtr->getNumberOfRows();
6921 int numCols = (int)tableViewPtr->getNumberOfColumns();
6923 for(
int c = 0; c < numCols; ++c)
6926 csvStr.reserve(numRows * 20);
6927 for(
int r = 0; r < numRows; ++r)
6931 if(colInfo[c].getDataType() == TableViewColumnInfo::DATATYPE_TIME)
6933 std::string timeAsString;
6934 tableViewPtr->
getValue(timeAsString, r, c);
6935 csvStr += StringMacros::encodeURIComponent(timeAsString);
6939 StringMacros::encodeURIComponent(tableViewPtr->getDataView()[r][c]);
6945 xmlOut.addTextElementToData(
"TableComment", tableViewPtr->getComment());
6946 xmlOut.addTextElementToData(
"TableAuthor", tableViewPtr->getAuthor());
6947 xmlOut.addTextElementToData(
"TableCreationTime",
6948 std::to_string(tableViewPtr->getCreationTime()));
6949 xmlOut.addTextElementToData(
"TableLastAccessTime",
6950 std::to_string(tableViewPtr->getLastAccessTime()));
6955 std::vector<std::string> defaultRowValues =
6956 table->getMockupViewP()->getDefaultRowValues();
6958 for(
unsigned int c = 0; c < defaultRowValues.size() - 2; ++c)
6960 xmlOut.addTextElementToData(
"DefaultRowValue", defaultRowValues[c]);
6963 const std::set<std::string> srcColNames = tableViewPtr->getSourceColumnNames();
6965 if(accumulatedErrors !=
"")
6967 __SUP_SS__ << (std::string(
"Column errors were allowed for this request, so "
6968 "perhaps you can ignore this, ") +
6969 "but please note the following warnings:\n" + accumulatedErrors)
6971 __SUP_COUT_ERR__ << ss.str();
6972 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6974 else if(!version.isTemporaryVersion() &&
6976 (srcColNames.size() != tableViewPtr->getNumberOfColumns() ||
6977 tableViewPtr->getSourceColumnMismatch() !=
6980 __SUP_SS__ <<
"\n\nThere were warnings found when loading the table " << tableName
6981 <<
":v" << version <<
". Please see the details below:\n\n"
6982 << tableViewPtr->getMismatchColumnInfo();
6984 __SUP_COUT__ <<
"\n" << ss.str();
6985 xmlOut.addTextElementToData(
"TableWarnings", ss.str());
6989 catch(std::runtime_error& e)
6991 __SUP_SS__ <<
"Error getting table view!\n\n " << e.what() << __E__;
6992 __SUP_COUT_ERR__ << ss.str();
6993 xmlOut.addTextElementToData(
"Error", ss.str());
6997 __SUP_SS__ <<
"Error getting table view!\n\n " << __E__;
7002 catch(
const std::exception& e)
7004 ss <<
"Exception message: " << e.what();
7009 __SUP_COUT_ERR__ << ss.str();
7010 xmlOut.addTextElementToData(
"Error", ss.str());
7021 std::string username,
bool refresh)
7023 uint64_t sessionIndex =
7026 std::stringstream ssMapKey;
7027 ssMapKey << username <<
":" << sessionIndex;
7028 std::string mapKey = ssMapKey.str();
7029 __SUP_COUTT__ <<
"Using Config Session " << mapKey
7030 <<
" ... Total Session Count: " << userConfigurationManagers_.size()
7031 <<
" refresh=" << refresh << __E__;
7033 time_t now = time(0);
7039 for(
auto& pair : userConfigurationManagers_)
7040 __SUP_COUTTV__(pair.first);
7043 const std::string preLoadCfgMgrName =
":0";
7044 if(userConfigurationManagers_.size() == 1 &&
7045 userConfigurationManagers_.find(preLoadCfgMgrName) !=
7046 userConfigurationManagers_.end())
7048 __SUP_COUT__ <<
"Using pre-loaded Configuration Manager. time=" << time(0) <<
" "
7049 << clock() <<
" Setting author from "
7050 << userConfigurationManagers_.at(preLoadCfgMgrName)->getUsername()
7051 <<
" to " << username << __E__;
7052 userConfigurationManagers_[mapKey] =
7053 userConfigurationManagers_.at(preLoadCfgMgrName);
7054 userLastUseTime_[mapKey] = userLastUseTime_.at(preLoadCfgMgrName);
7056 userConfigurationManagers_.at(mapKey)->setUsername(username);
7059 if(userConfigurationManagers_.find(mapKey) == userConfigurationManagers_.end())
7061 __SUP_COUT__ <<
"Creating new Configuration Manager. time=" << time(0) <<
" "
7062 << clock() << __E__;
7068 userConfigurationManagers_[mapKey]->getAllTableInfo(
7076 else if(userLastUseTime_.find(mapKey) == userLastUseTime_.end())
7078 __SUP_SS__ <<
"Fatal error managing user sessions! Check the logs for "
7079 "Configuration Interface failure."
7081 __SUP_COUT_ERR__ <<
"\n" << ss.str();
7086 (now - userLastUseTime_[mapKey]) >
7087 CONFIGURATION_MANAGER_REFRESH_THRESHOLD)
7089 __SUP_COUT__ <<
"Refreshing all table info." << __E__;
7090 userConfigurationManagers_[mapKey]->getAllTableInfo(
7098 __SUP_COUTT__ <<
"Configuration Manager for author="
7099 << userConfigurationManagers_[mapKey]->getUsername()
7100 <<
" ready. time=" << time(0) <<
" " << clock() <<
" runTimeSeconds()="
7101 << userConfigurationManagers_[mapKey]->runTimeSeconds() << __E__;
7104 userLastUseTime_[mapKey] = now;
7107 for(std::map<std::string, time_t>::iterator it = userLastUseTime_.begin();
7108 it != userLastUseTime_.end();
7110 if(now - it->second > CONFIGURATION_MANAGER_EXPIRATION_TIME)
7112 __SUP_COUT__ << now <<
":" << it->second <<
" = " << now - it->second
7114 delete userConfigurationManagers_[it->first];
7115 if(!(userConfigurationManagers_.erase(it->first)))
7117 __SUP_SS__ <<
"Fatal error erasing configuration manager by key!"
7119 __SUP_COUT_ERR__ <<
"\n" << ss.str();
7122 userLastUseTime_.erase(it);
7129 return userConfigurationManagers_[mapKey];
7137 void ConfigurationGUISupervisor::handleDeleteTableInfoXML(
HttpXmlDocument& xmlOut,
7139 std::string& tableName)
7141 if(0 == rename((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
7142 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused").c_str()))
7143 __SUP_COUT_INFO__ << (
"Table Info File successfully renamed: " +
7144 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
7148 __SUP_COUT_ERR__ << (
"Error renaming file to " +
7149 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused"))
7152 xmlOut.addTextElementToData(
7154 (
"Error renaming Table Info File to " +
7155 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT +
".unused")));
7170 void ConfigurationGUISupervisor::handleSaveTableInfoXML(
7173 std::string& tableName,
7174 const std::string& data,
7175 const std::string& tableDescription,
7176 const std::string& columnChoicesCSV,
7177 bool allowOverwrite)
7181 std::string capsName;
7186 catch(std::runtime_error& e)
7188 xmlOut.addTextElementToData(
"Error", e.what());
7194 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"r");
7198 xmlOut.addTextElementToData(
"TableName", tableName);
7199 xmlOut.addTextElementToData(
"OverwriteError",
"1");
7200 xmlOut.addTextElementToData(
7202 "File already exists! ('" +
7203 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT) +
"')");
7208 __SUP_COUT__ <<
"capsName=" << capsName << __E__;
7209 __SUP_COUT__ <<
"tableName=" << tableName << __E__;
7210 __SUP_COUT__ <<
"tableDescription=" << tableDescription << __E__;
7211 __SUP_COUT__ <<
"columnChoicesCSV=" << columnChoicesCSV << __E__;
7214 std::stringstream outss;
7216 outss <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
7217 outss <<
"\t<ROOT xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "
7218 "xsi:noNamespaceSchemaLocation=\"TableInfo.xsd\">\n";
7219 outss <<
"\t\t<TABLE Name=\"" << tableName <<
"\">\n";
7220 outss <<
"\t\t\t<VIEW Name=\"" << capsName
7221 <<
"\" Type=\"File,Database,DatabaseTest\" Description=\"" << tableDescription
7227 std::istringstream columnChoicesISS(columnChoicesCSV);
7228 std::string columnChoicesString;
7229 std::string columnDefaultValue, columnMinValue, columnMaxValue;
7230 std::vector<std::string> columnParameters;
7231 std::vector<std::string> columnData =
7234 std::set<std::string> childLinkIndices, childLinkUIDIndices, childLinkGroupIDIndices;
7236 for(
unsigned int c = 0; c < columnData.size() - 1; ++c)
7240 __COUT__ <<
"Column #" << c <<
": "
7242 for(
unsigned int p = 0; p < columnParameters.size(); ++p)
7244 __COUT__ <<
"\t Parameter #" << p <<
": " << columnParameters[p] << __E__;
7246 __COUT__ <<
"\t creating the new xml" << __E__;
7248 std::string& columnType = columnParameters[0];
7249 std::string& columnName = columnParameters[1];
7250 std::string& columnDataType = columnParameters[2];
7251 const std::string columnStorageName =
7254 outss <<
"\t\t\t\t<COLUMN Type=\"";
7255 outss << columnType;
7256 outss <<
"\" \t Name=\"";
7257 outss << columnName;
7258 outss <<
"\" \t StorageName=\"";
7261 outss << columnStorageName;
7263 catch(std::runtime_error& e)
7265 xmlOut.addTextElementToData(
7267 std::string(
"For column name '") + columnName +
"' - " + e.what());
7270 outss <<
"\" \t DataType=\"";
7271 outss << columnDataType;
7275 std::string* columnDefaultValuePtr =
nullptr;
7276 if(columnDefaultValue !=
7279 __SUP_COUT__ <<
"FOUND user spec'd default value '" << columnDefaultValue
7281 outss <<
"\" \t DefaultValue=\"";
7282 outss << columnParameters[3];
7283 columnDefaultValuePtr = &columnParameters[3];
7285 getline(columnChoicesISS, columnChoicesString,
';');
7286 outss <<
"\" \t DataChoices=\"";
7287 outss << columnChoicesString;
7289 std::string* columnMinValuePtr =
nullptr;
7290 std::string* columnMaxValuePtr =
nullptr;
7292 if(columnParameters.size() > 4 &&
7296 if(columnMinValue !=
"")
7298 if(columnMinValue !=
7301 __SUP_COUT__ <<
"FOUND user spec'd min value '" << columnParameters[4]
7306 __SS__ <<
"Inavlid user spec'd min value '" << columnParameters[4]
7307 <<
"' which evaluates to '" << columnMinValue
7308 <<
"' and is not a valid number. The minimum value must "
7309 "be a number (environment variables and math "
7310 "operations are allowed)."
7314 outss <<
"\" \t MinValue=\"" << columnParameters[4];
7315 columnMinValuePtr = &columnParameters[4];
7320 if(columnMaxValue !=
"")
7322 if(columnMaxValue !=
7325 __SUP_COUT__ <<
"FOUND user spec'd max value = " << columnMaxValue
7330 __SS__ <<
"Inavlid user spec'd max value '" << columnParameters[5]
7331 <<
"' which evaluates to '" << columnMaxValue
7332 <<
"' and is not a valid number. The maximum value must "
7333 "be a number (environment variables and math "
7334 "operations are allowed)."
7338 outss <<
"\" \t MaxValue=\"" << columnParameters[5];
7339 columnMaxValuePtr = &columnParameters[5];
7351 columnDefaultValuePtr,
7352 columnChoicesString,
7358 catch(
const std::runtime_error& e)
7360 __SS__ <<
"Error identified with Column #" << c <<
": \n" << e.what();
7365 childLinkIndices.insert(columnType.substr(
sizeof(
"ChildLink-") - 1));
7366 else if(columnType.find(
"ChildLinkUID-") == 0)
7367 childLinkUIDIndices.insert(columnType.substr(
sizeof(
"ChildLinkUID-") - 1));
7368 else if(columnType.find(
"ChildLinkGroupID-") == 0)
7369 childLinkGroupIDIndices.insert(
7370 columnType.substr(
sizeof(
"ChildLinkGroupID-") - 1));
7377 for(
const auto& idx : childLinkUIDIndices)
7378 if(childLinkIndices.find(idx) == childLinkIndices.end())
7380 __SS__ <<
"Column type 'ChildLinkUID-" << idx
7381 <<
"' has no matching 'ChildLink-" << idx
7382 <<
"' column. A ChildLinkUID column must be paired with a "
7383 "ChildLink column using the same link index."
7387 for(
const auto& idx : childLinkGroupIDIndices)
7388 if(childLinkIndices.find(idx) == childLinkIndices.end())
7390 __SS__ <<
"Column type 'ChildLinkGroupID-" << idx
7391 <<
"' has no matching 'ChildLink-" << idx
7392 <<
"' column. A ChildLinkGroupID column must be paired with a "
7393 "ChildLink column using the same link index. "
7394 "Did you intend to make a target of a Group Link? "
7395 "If so, use the 'GroupID' column type instead."
7399 for(
const auto& idx : childLinkIndices)
7400 if(childLinkUIDIndices.find(idx) == childLinkUIDIndices.end() &&
7401 childLinkGroupIDIndices.find(idx) == childLinkGroupIDIndices.end())
7403 __SS__ <<
"Column type 'ChildLink-" << idx
7404 <<
"' has no matching 'ChildLinkUID-" << idx
7405 <<
"' or 'ChildLinkGroupID-" << idx
7406 <<
"' column. A ChildLink column must be paired with either a "
7407 "ChildLinkUID or ChildLinkGroupID column using the same link index."
7412 outss <<
"\t\t\t</VIEW>\n";
7413 outss <<
"\t\t</TABLE>\n";
7414 outss <<
"\t</ROOT>\n";
7416 __SUP_COUT__ << outss.str() << __E__;
7418 FILE* fp = fopen((TABLE_INFO_PATH + tableName + TABLE_INFO_EXT).c_str(),
"w");
7421 xmlOut.addTextElementToData(
"Error",
7422 "Failed to open destination Table Info file:" +
7423 (TABLE_INFO_PATH + tableName + TABLE_INFO_EXT));
7427 fprintf(fp,
"%s", outss.str().c_str());
7430 __SUP_COUT_INFO__ <<
"Finished saving Table Info for '" << tableName
7431 <<
".' Looking for errors in all table column info..." << __E__;
7435 std::string accumulatedErrors =
"";
7439 if(accumulatedErrors !=
"")
7441 __SUP_SS__ << (
"The new version of the '" + tableName +
7442 "' table column info was saved, however errors were detected "
7443 "reading back the table '" +
7444 tableName +
"' after the save attempt:\n\n" + accumulatedErrors)
7447 __SUP_COUT_ERR__ << ss.str() << __E__;
7448 xmlOut.addTextElementToData(
"Error", ss.str());
7454 handleGetTableXML(xmlOut, cfgMgr, tableName,
TableVersion());
7457 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
7460 for(
const auto& cfgInfo : allTableInfo)
7466 catch(std::runtime_error& e)
7468 __SUP_COUT_WARN__ <<
"\n\n##############################################\n"
7469 <<
"Error identified in column info of table '"
7470 << cfgInfo.first <<
"':\n\n"
7471 << e.what() <<
"\n\n"
7485 void ConfigurationGUISupervisor::handleSetGroupAliasInBackboneXML(
7488 const std::string& groupAliasCSV,
7489 const std::string& groupNameCSV,
7490 const std::string& groupKeyCSV,
7491 const std::string& author)
7495 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7497 const std::string groupAliasesTableName =
7498 ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
7499 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
7501 __SUP_SS__ <<
"Active version of " << groupAliasesTableName <<
" missing!"
7503 xmlOut.addTextElementToData(
"Error", ss.str());
7508 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
7509 for(
auto& memberName : backboneMembers)
7511 __SUP_COUT__ <<
"activeVersions[\"" << memberName
7512 <<
"\"]=" << activeVersions[memberName] << __E__;
7514 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7515 xmlOut.addTextElementToData(
"oldBackboneVersion",
7516 activeVersions[memberName].toString());
7524 TableVersion originalVersion = activeVersions[groupAliasesTableName];
7525 TableVersion temporaryVersion = table->createTemporaryView(originalVersion);
7527 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7528 bool isDifferent =
false;
7532 TableView* configView = table->getTemporaryView(temporaryVersion);
7534 unsigned int col = configView->
findCol(
"GroupKeyAlias");
7535 unsigned int ccol = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7536 unsigned int ncol = configView->
findCol(
"GroupName");
7537 unsigned int kcol = configView->
findCol(
"GroupKey");
7540 std::vector<std::string> groupAliases =
7542 std::vector<std::string> groupNames =
7544 std::vector<std::string> groupKeys =
7551 for(
const auto& groupAlias : groupAliases)
7553 if(groupAlias ==
"" || groupNames[i] ==
"" || groupKeys[i] ==
"")
7556 __SUP_COUT_WARN__ <<
"Empty alias parameter found [" << i <<
"] = {"
7557 << groupAlias <<
", " << groupNames[i] <<
"("
7558 << groupKeys[i] <<
")}" << __E__;
7563 bool localIsDifferent =
false;
7564 const std::string& groupName = groupNames[i];
7568 unsigned int row = -1;
7572 row = configView->
findRow(col, groupAlias);
7578 if(row == (
unsigned int)-1)
7580 localIsDifferent =
true;
7581 row = configView->
addRow();
7585 "This Group Alias was automatically setup by the server.", row, ccol);
7586 configView->
setValue(groupAlias, row, col);
7589 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
7591 __SUP_COUT__ <<
"\t\t groupName: " << groupName <<
" vs "
7592 << configView->getDataView()[row][ncol] << __E__;
7593 if(groupName != configView->getDataView()[row][ncol])
7595 configView->
setValue(groupName, row, ncol);
7596 localIsDifferent =
true;
7599 __SUP_COUT__ <<
"\t\t groupKey: " << groupKey <<
" vs "
7600 << configView->getDataView()[row][kcol] << __E__;
7601 if(groupKey.
toString() != configView->getDataView()[row][kcol])
7604 localIsDifferent =
true;
7607 if(localIsDifferent)
7612 configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7616 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7623 __SUP_COUT_ERR__ <<
"Error editing Group Alias view!" << __E__;
7626 table->eraseView(temporaryVersion);
7633 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
7640 table->getTableName(),
7651 <<
"\t\t**************************** Using the existing table version"
7655 table->eraseView(temporaryVersion);
7656 newAssignedVersion = activeVersions[groupAliasesTableName];
7658 xmlOut.addTextElementToData(
"savedName", groupAliasesTableName);
7659 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7662 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
7664 catch(std::runtime_error& e)
7666 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << e.what() << __E__;
7667 __SUP_COUT_ERR__ << ss.str();
7668 xmlOut.addTextElementToData(
"Error", ss.str());
7672 __SUP_SS__ <<
"Error saving new Group Alias view!\n\n " << __E__;
7677 catch(
const std::exception& e)
7679 ss <<
"Exception message: " << e.what();
7684 __SUP_COUT_ERR__ << ss.str();
7685 xmlOut.addTextElementToData(
"Error", ss.str());
7696 void ConfigurationGUISupervisor::handleSetTableAliasInBackboneXML(
7699 const std::string& tableAlias,
7700 const std::string& tableName,
7702 const std::string& author)
7706 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7708 const std::string versionAliasesTableName =
7709 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7710 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7712 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
7714 xmlOut.addTextElementToData(
"Error", ss.str());
7719 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
7720 for(
auto& memberName : backboneMembers)
7722 __SUP_COUT__ <<
"activeVersions[\"" << memberName
7723 <<
"\"]=" << activeVersions[memberName] << __E__;
7725 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7726 xmlOut.addTextElementToData(
"oldBackboneVersion",
7727 activeVersions[memberName].toString());
7735 TableVersion originalVersion = activeVersions[versionAliasesTableName];
7736 TableVersion temporaryVersion = table->createTemporaryView(originalVersion);
7738 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7740 bool isDifferent =
false;
7744 TableView* configView = table->getTemporaryView(temporaryVersion);
7747 unsigned int col2 = configView->
findCol(
"VersionAlias");
7748 unsigned int col3 = configView->
findCol(
"TableName");
7752 unsigned int row = -1;
7757 unsigned int tmpRow = -1;
7760 tmpRow = configView->
findRow(col3, tableName, tmpRow + 1);
7761 }
while(configView->getDataView()[tmpRow][col2] != tableAlias);
7768 if(row == (
unsigned int)-1)
7771 row = configView->
addRow();
7774 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7776 std::string(
"Entry was added by server in ") +
7777 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7781 col = configView->
findCol(
"VersionAliasUID");
7783 tableName.substr(0, tableName.rfind(
"Table")) + tableAlias, row, col);
7785 configView->
setValue(tableAlias, row, col2);
7786 configView->
setValue(tableName, row, col3);
7789 __SUP_COUT__ <<
"\t\t row: " << row << __E__;
7791 col = configView->
findCol(
"Version");
7792 __SUP_COUT__ <<
"\t\t version: " << version <<
" vs "
7793 << configView->getDataView()[row][col] << __E__;
7794 if(version.toString() != configView->getDataView()[row][col])
7796 configView->
setValue(version.toString(), row, col);
7803 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
7807 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
7812 __SUP_COUT_ERR__ <<
"Error editing Version Alias view!" << __E__;
7815 table->eraseView(temporaryVersion);
7822 __SUP_COUT__ <<
"\t\t**************************** Save as new table version"
7828 table->getTableName(),
7838 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
7842 table->eraseView(temporaryVersion);
7843 newAssignedVersion = activeVersions[versionAliasesTableName];
7845 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
7846 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
7849 __SUP_COUT__ <<
"\t\t newAssignedVersion: " << newAssignedVersion << __E__;
7851 catch(std::runtime_error& e)
7853 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
7854 __SUP_COUT_ERR__ << ss.str();
7855 xmlOut.addTextElementToData(
"Error", ss.str());
7859 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
7864 catch(
const std::exception& e)
7866 ss <<
"Exception message: " << e.what();
7871 __SUP_COUT_ERR__ << ss.str();
7872 xmlOut.addTextElementToData(
"Error", ss.str());
7881 void ConfigurationGUISupervisor::handleAliasGroupMembersInBackboneXML(
7884 const std::string& versionAlias,
7885 const std::string& groupName,
7887 const std::string& author)
7891 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
7893 const std::string versionAliasesTableName =
7894 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
7895 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
7897 __SUP_SS__ <<
"Active version of " << versionAliasesTableName <<
" missing!"
7899 xmlOut.addTextElementToData(
"Error", ss.str());
7904 const std::set<std::string> backboneMembers = cfgMgr->getBackboneMemberNames();
7905 for(
auto& memberName : backboneMembers)
7907 __SUP_COUT__ <<
"activeVersions[\"" << memberName
7908 <<
"\"]=" << activeVersions[memberName] << __E__;
7910 xmlOut.addTextElementToData(
"oldBackboneName", memberName);
7911 xmlOut.addTextElementToData(
"oldBackboneVersion",
7912 activeVersions[memberName].toString());
7921 table->createTemporaryView(activeVersions[versionAliasesTableName]);
7923 __SUP_COUT__ <<
"\t\t temporaryVersion: " << temporaryVersion << __E__;
7925 TableView* configView = table->getTemporaryView(temporaryVersion);
7928 bool isDifferent =
false;
7947 xmlOut.addTextElementToData(
7950 "\" can not be retrieved!");
7955 unsigned int col2 = configView->
findCol(
"VersionAlias");
7956 unsigned int col3 = configView->
findCol(
"TableName");
7958 for(
auto& memberPair : memberMap)
7960 bool thisMemberIsDifferent =
false;
7961 unsigned int row = -1;
7963 __SUP_COUT__ <<
"Adding alias for " << memberPair.first <<
"_v"
7964 << memberPair.second <<
" to " << versionAlias << __E__;
7970 unsigned int tmpRow = -1;
7973 tmpRow = configView->
findRow(col3, memberPair.first, tmpRow + 1);
7974 }
while(configView->getDataView()[tmpRow][col2] != versionAlias);
7981 if(row == (
unsigned int)-1)
7983 thisMemberIsDifferent =
true;
7984 row = configView->
addRow();
7987 col = configView->
findCol(TableViewColumnInfo::COL_NAME_COMMENT);
7989 std::string(
"Entry was added by server in ") +
7990 "ConfigurationGUISupervisor::setTableAliasInActiveBackbone().",
7996 memberPair.first.substr(0, memberPair.first.rfind(
"Table")) +
8001 configView->
setValue(versionAlias, row, col2);
8002 configView->
setValue(memberPair.first, row, col3);
8005 col = configView->
findCol(
"Version");
8007 if(memberPair.second.toString() != configView->getDataView()[row][col])
8009 configView->
setValue(memberPair.second.toString(), row, col);
8010 thisMemberIsDifferent =
true;
8013 if(thisMemberIsDifferent)
8016 author, row, configView->
findCol(TableViewColumnInfo::COL_NAME_AUTHOR));
8020 configView->
findCol(TableViewColumnInfo::COL_NAME_CREATION));
8023 if(thisMemberIsDifferent)
8032 __SUP_COUT__ <<
"\t\t**************************** Save v" << temporaryVersion
8033 <<
" as new table version" << __E__;
8035 newAssignedVersion =
8036 cfgMgr->
saveNewTable(versionAliasesTableName, temporaryVersion);
8040 __SUP_COUT__ <<
"\t\t**************************** Using existing table version"
8044 table->eraseView(temporaryVersion);
8045 newAssignedVersion = activeVersions[versionAliasesTableName];
8048 xmlOut.addTextElementToData(
"savedName", versionAliasesTableName);
8049 xmlOut.addTextElementToData(
"savedVersion", newAssignedVersion.
toString());
8050 __SUP_COUT__ <<
"\t\t Resulting Version: " << newAssignedVersion << __E__;
8052 catch(std::runtime_error& e)
8054 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << e.what() << __E__;
8055 __SUP_COUT_ERR__ << ss.str();
8056 xmlOut.addTextElementToData(
"Error", ss.str());
8060 __SUP_SS__ <<
"Error saving new Version Alias view!\n\n " << __E__;
8065 catch(
const std::exception& e)
8067 ss <<
"Exception message: " << e.what();
8072 __SUP_COUT_ERR__ << ss.str();
8073 xmlOut.addTextElementToData(
"Error", ss.str());
8087 void ConfigurationGUISupervisor::handleGroupAliasesXML(
HttpXmlDocument& xmlOut,
8091 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
8093 std::string groupAliasesTableName = ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
8094 if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
8096 __SUP_SS__ <<
"\nActive version of " << groupAliasesTableName <<
" missing! "
8097 << groupAliasesTableName
8098 <<
" is a required member of the Backbone table group."
8099 <<
"\n\nLikely you need to activate a valid Backbone table group."
8101 __SUP_COUT__ << ss.str();
8106 __SUP_COUT__ <<
"activeVersions[\"" << groupAliasesTableName
8107 <<
"\"]=" << activeVersions[groupAliasesTableName] << __E__;
8108 xmlOut.addTextElementToData(
"GroupAliasesTableName", groupAliasesTableName);
8109 xmlOut.addTextElementToData(
"GroupAliasesTableVersion",
8110 activeVersions[groupAliasesTableName].toString());
8112 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
8115 const int numOfThreads = StringMacros::getConcurrencyCount() / 2;
8116 __SUP_COUT__ <<
" getConcurrencyCount " << StringMacros::getConcurrencyCount()
8117 <<
" ==> " << numOfThreads <<
" threads for alias group loads." << __E__;
8119 if(numOfThreads < 2)
8121 std::string groupName, groupKey, groupComment, groupAuthor, groupCreateTime,
8123 for(
auto& aliasNodePair : aliasNodePairs)
8125 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
8126 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
8128 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
8129 xmlOut.addTextElementToData(
"GroupName", groupName);
8130 xmlOut.addTextElementToData(
"GroupKey", groupKey);
8131 xmlOut.addTextElementToData(
8133 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
8134 .getValueAsString());
8138 ConfigurationManager::UNKNOWN_INFO;
8139 groupType = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
8156 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
8157 << groupKey <<
")' to extract group comment and type."
8160 xmlOut.addTextElementToData(
"GroupComment", groupComment);
8161 xmlOut.addTextElementToData(
"GroupType", groupType);
8166 int threadsLaunched = 0;
8167 int foundThreadIndex = 0;
8168 std::vector<std::shared_ptr<std::atomic<bool>>> threadDone;
8169 for(
int i = 0; i < numOfThreads; ++i)
8170 threadDone.push_back(std::make_shared<std::atomic<bool>>(
true));
8172 std::vector<std::shared_ptr<ots::GroupInfo>> sharedGroupInfoPtrs;
8173 std::string groupName, groupKey;
8175 for(
auto& aliasNodePair : aliasNodePairs)
8178 sharedGroupInfoPtrs.push_back(std::make_shared<ots::GroupInfo>());
8180 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
8181 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
8183 if(threadsLaunched >= numOfThreads)
8186 foundThreadIndex = -1;
8187 while(foundThreadIndex == -1)
8189 for(
int i = 0; i < numOfThreads; ++i)
8190 if(*(threadDone[i]))
8192 foundThreadIndex = i;
8195 if(foundThreadIndex == -1)
8197 __SUP_COUTT__ <<
"Waiting for available thread..." << __E__;
8201 threadsLaunched = numOfThreads - 1;
8203 __SUP_COUTT__ <<
"Starting load group thread... " << groupName <<
"("
8204 << groupKey <<
")" << __E__;
8205 *(threadDone[foundThreadIndex]) =
false;
8209 std::string theGroupName,
8211 std::shared_ptr<ots::GroupInfo> theGroupInfo,
8212 std::shared_ptr<std::atomic<bool>> theThreadDone) {
8222 sharedGroupInfoPtrs.back(),
8223 threadDone[foundThreadIndex])
8234 foundThreadIndex = -1;
8235 for(
int i = 0; i < numOfThreads; ++i)
8236 if(!*(threadDone[i]))
8238 foundThreadIndex = i;
8241 if(foundThreadIndex != -1)
8243 __SUP_COUTT__ <<
"Waiting for thread to finish... " << foundThreadIndex
8247 }
while(foundThreadIndex != -1);
8251 for(
auto& aliasNodePair : aliasNodePairs)
8253 groupName = aliasNodePair.second.getNode(
"GroupName").getValueAsString();
8254 groupKey = aliasNodePair.second.getNode(
"GroupKey").getValueAsString();
8256 if(groupKey != sharedGroupInfoPtrs[i]->getLatestKey().toString())
8258 __SUP_SS__ <<
"Error loading group information for the group alias '"
8259 << aliasNodePair.first <<
"' mapping to group '" << groupName
8260 <<
"(" << groupKey <<
")" << __E__;
8264 xmlOut.addTextElementToData(
"GroupAlias", aliasNodePair.first);
8265 xmlOut.addTextElementToData(
"GroupName", groupName);
8266 xmlOut.addTextElementToData(
8267 "GroupKey", sharedGroupInfoPtrs[i]->getLatestKey().toString());
8268 xmlOut.addTextElementToData(
8270 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
8271 .getValueAsString());
8273 xmlOut.addTextElementToData(
8274 "GroupComment", sharedGroupInfoPtrs[i]->getLatestKeyGroupComment());
8275 xmlOut.addTextElementToData(
8276 "GroupAuthor", sharedGroupInfoPtrs[i]->getLatestKeyGroupAuthor());
8277 xmlOut.addTextElementToData(
8278 "GroupCreationTime",
8279 sharedGroupInfoPtrs[i]->getLatestKeyGroupCreationTime());
8280 xmlOut.addTextElementToData(
8281 "GroupType", sharedGroupInfoPtrs[i]->getLatestKeyGroupTypeString());
8300 void ConfigurationGUISupervisor::handleVersionAliasesXML(
HttpXmlDocument& xmlOut,
8304 std::map<std::string, TableVersion> activeVersions = cfgMgr->
getActiveVersions();
8306 std::string versionAliasesTableName =
8307 ConfigurationManager::VERSION_ALIASES_TABLE_NAME;
8308 if(activeVersions.find(versionAliasesTableName) == activeVersions.end())
8310 __SUP_SS__ <<
"Active version of VersionAliases missing!"
8311 <<
"Make sure you have a valid active Backbone Group." << __E__;
8312 xmlOut.addTextElementToData(
"Error", ss.str());
8315 __SUP_COUT__ <<
"activeVersions[\"" << versionAliasesTableName
8316 <<
"\"]=" << activeVersions[versionAliasesTableName] << __E__;
8317 xmlOut.addTextElementToData(
"VersionAliasesVersion",
8318 activeVersions[versionAliasesTableName].toString());
8320 std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
8323 for(
auto& aliasNodePair : aliasNodePairs)
8327 xmlOut.addTextElementToData(
8329 aliasNodePair.second.getNode(
"VersionAlias").getValueAsString());
8330 xmlOut.addTextElementToData(
8331 "TableName", aliasNodePair.second.getNode(
"TableName").getValueAsString());
8332 xmlOut.addTextElementToData(
8333 "Version", aliasNodePair.second.getNode(
"Version").getValueAsString());
8334 xmlOut.addTextElementToData(
8336 aliasNodePair.second.getNode(TableViewColumnInfo::COL_NAME_COMMENT)
8337 .getValueAsString());
8347 void ConfigurationGUISupervisor::handleGetTableGroupTypeXML(
8351 std::string name, versionStr;
8352 auto c = tableList.find(
',', 0);
8355 while(c < tableList.length())
8358 name = tableList.substr(i, c - i);
8360 c = tableList.find(
',', i);
8361 if(c == std::string::npos)
8363 __SUP_SS__ <<
"Incomplete Table Name-Version pair!" << __E__;
8364 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8365 xmlOut.addTextElementToData(
"Error", ss.str());
8369 versionStr = tableList.substr(i, c - i);
8371 c = tableList.find(
',', i);
8376 std::string groupTypeString =
"";
8382 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
8384 catch(std::runtime_error& e)
8386 __SUP_SS__ <<
"Table group has invalid type! " << e.what() << __E__;
8387 __SUP_COUT__ <<
"\n" << ss.str();
8388 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
8389 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
8393 __SUP_SS__ <<
"Table group has invalid type! " << __E__;
8398 catch(
const std::exception& e)
8400 ss <<
"Exception message: " << e.what();
8405 __SUP_COUT__ <<
"\n" << ss.str();
8406 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
8407 xmlOut.addTextElementToData(
"TableGroupType", groupTypeString);
8427 void ConfigurationGUISupervisor::handleTableGroupsXML(
HttpXmlDocument& xmlOut,
8431 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
8437 if(!cfgMgr->getAllGroupInfo().size() ||
8438 cfgMgr->getAllGroupInfo().begin()->second.getLatestKeyGroupTypeString() ==
"" ||
8439 cfgMgr->getAllGroupInfo().begin()->second.getLatestKeyGroupTypeString() ==
8440 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN ||
8442 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE) !=
8443 TableGroupKey::INVALID &&
8444 cfgMgr->getAllGroupInfo().find(cfgMgr->getActiveGroupName(
8445 ConfigurationManager::GroupType::CONTEXT_TYPE)) !=
8446 cfgMgr->getAllGroupInfo().end() &&
8447 (cfgMgr->getAllGroupInfo()
8448 .at(cfgMgr->getActiveGroupName(
8449 ConfigurationManager::GroupType::CONTEXT_TYPE))
8450 .getLatestKeyGroupTypeString() ==
"" ||
8451 cfgMgr->getAllGroupInfo()
8452 .at(cfgMgr->getActiveGroupName(
8453 ConfigurationManager::GroupType::CONTEXT_TYPE))
8454 .getLatestKeyGroupTypeString() ==
8455 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)) ||
8457 cfgMgr->getActiveGroupKey(
8458 ConfigurationManager::GroupType::CONFIGURATION_TYPE) !=
8459 TableGroupKey::INVALID &&
8460 cfgMgr->getAllGroupInfo().find(cfgMgr->getActiveGroupName(
8461 ConfigurationManager::GroupType::CONFIGURATION_TYPE)) !=
8462 cfgMgr->getAllGroupInfo().end() &&
8463 (cfgMgr->getAllGroupInfo()
8464 .at(cfgMgr->getActiveGroupName(
8465 ConfigurationManager::GroupType::CONFIGURATION_TYPE))
8466 .getLatestKeyGroupTypeString() ==
"" ||
8467 cfgMgr->getAllGroupInfo()
8468 .at(cfgMgr->getActiveGroupName(
8469 ConfigurationManager::GroupType::CONFIGURATION_TYPE))
8470 .getLatestKeyGroupTypeString() ==
8471 ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN)))
8474 <<
"Group Info cache appears empty or stale. Attempting to regenerate..."
8484 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
8486 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
8488 std::string groupName;
8489 std::string groupString, groupTypeString, groupComment, groupCreationTime,
8491 for(
auto& groupInfo : allGroupInfo)
8493 groupName = groupInfo.first;
8498 if(groupInfo.second.getKeys().size() == 0)
8500 __SUP_COUT__ <<
"Group name '" << groupName
8501 <<
"' found, but no keys so ignoring." << __E__;
8505 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
8506 xmlOut.dataSs_ <<
"<TableGroupKey value='" << groupInfo.second.getLatestKey()
8510 xmlOut.dataSs_ <<
"<TableGroupType value='"
8511 << groupInfo.second.getLatestKeyGroupTypeString() <<
"'/>"
8513 xmlOut.dataSs_ <<
"<TableGroupComment value='"
8515 groupInfo.second.getLatestKeyGroupComment(),
8518 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
8519 << groupInfo.second.getLatestKeyGroupAuthor() <<
"'/>" << __E__;
8520 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
8521 << groupInfo.second.getLatestKeyGroupCreationTime() <<
"'/>"
8527 xmlOut.dataSs_ <<
"<TableGroupMembers value=''>" << __E__;
8529 for(
auto& memberPair : groupInfo.second.getLatestKeyMemberMap())
8531 xmlOut.dataSs_ <<
"\t<MemberName value='" << memberPair.first <<
"'/>"
8533 xmlOut.dataSs_ <<
"\t<MemberVersion value='" << memberPair.second <<
"'/>"
8540 xmlOut.dataSs_ <<
"</TableGroupMembers>" << __E__;
8545 for(
auto& keyInSet : groupInfo.second.getKeys())
8547 if(keyInSet == groupInfo.second.getLatestKey())
8550 xmlOut.dataSs_ <<
"<TableGroupName value='" << groupName <<
"'/>" << __E__;
8551 xmlOut.dataSs_ <<
"<TableGroupKey value='" << keyInSet <<
"'/>" << __E__;
8556 bool loadingHistoricalInfo =
false;
8557 if(loadingHistoricalInfo)
8576 groupTypeString = ConfigurationManager::GROUP_TYPE_NAME_UNKNOWN;
8577 __SUP_COUT_WARN__ <<
"Failed to load group '" << groupName <<
"("
8579 <<
")' to extract group comment and type." << __E__;
8582 xmlOut.dataSs_ <<
"<TableGroupType value='" << groupTypeString <<
"'/>"
8584 xmlOut.dataSs_ <<
"<TableGroupComment value='"
8588 xmlOut.dataSs_ <<
"<TableGroupAuthor value='" << groupAuthor <<
"'/>"
8590 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='" << groupCreationTime
8600 xmlOut.dataSs_ <<
"<TableGroupType value='"
8601 << groupInfo.second.getLatestKeyGroupTypeString() <<
"'/>"
8604 xmlOut.dataSs_ <<
"<TableGroupComment value='"
8607 xmlOut.dataSs_ <<
"<TableGroupAuthor value='"
8610 xmlOut.dataSs_ <<
"<TableGroupCreationTime value='"
8618 xmlOut.dataSs_ <<
"<TableGroupMembers/>" << __E__;
8623 __SUP_COUTT__ << groupName <<
" runtime=" << cfgMgr->runTimeSeconds() << __E__;
8625 __SUP_COUTT__ <<
"cfgMgr runtime=" << cfgMgr->runTimeSeconds() << __E__;
8647 void ConfigurationGUISupervisor::handleTablesXML(
HttpXmlDocument& xmlOut,
8649 const std::string& filterStartTimeStr,
8650 const std::string& filterEndTimeStr,
8651 const std::string& filterMode)
8653 time_t filterStartTime = 0;
8654 time_t filterEndTime = 0;
8655 if(filterStartTimeStr !=
"")
8659 filterStartTime =
static_cast<time_t
>(std::stoll(filterStartTimeStr));
8661 catch(
const std::exception& e)
8663 __SUP_SS__ <<
"Error parsing startTime parameter: " << e.what() << __E__;
8664 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8665 xmlOut.addTextElementToData(
"Error", ss.str());
8669 if(filterEndTimeStr !=
"")
8673 filterEndTime =
static_cast<time_t
>(std::stoll(filterEndTimeStr));
8675 catch(
const std::exception& e)
8677 __SUP_SS__ <<
"Error parsing endTime parameter: " << e.what() << __E__;
8678 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8679 xmlOut.addTextElementToData(
"Error", ss.str());
8683 if(filterStartTime != 0 && filterEndTime != 0 && filterStartTime > filterEndTime)
8685 __SUP_SS__ <<
"Invalid time range: startTime (" << filterStartTime
8686 <<
") must be <= endTime (" << filterEndTime <<
")." << __E__;
8689 if(filterMode !=
"created" && filterMode !=
"loaded")
8691 __SUP_SS__ <<
"Invalid filterMode parameter '" << filterMode
8692 <<
".' Expected 'created' or 'loaded.'" << __E__;
8693 __SUP_COUT_ERR__ <<
"\n" << ss.str();
8694 xmlOut.addTextElementToData(
"Error", ss.str());
8698 const auto diagStartTime = std::chrono::steady_clock::now();
8699 auto diagElapsedSec = [](
const std::chrono::steady_clock::time_point& start) {
8700 return std::chrono::duration<double>(std::chrono::steady_clock::now() - start)
8704 if(cfgMgr->getAllGroupInfo().size() == 0 || cfgMgr->
getActiveVersions().size() == 0)
8706 __SUP_COUT__ <<
"Table Info cache appears empty. Attempting to regenerate."
8714 __SUP_COUT__ <<
"getAllTableInfo() regenerate took "
8715 << diagElapsedSec(diagStartTime) <<
" s" << __E__;
8718 xercesc::DOMElement* parentEl;
8719 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
8722 std::set<std::string, StringMacros::IgnoreCaseCompareStruct> orderedTableSet;
8723 for(
const auto& tablePair : allTableInfo)
8724 orderedTableSet.emplace(tablePair.first);
8728 __SUP_COUT__ <<
"# of tables to consider: " << allTableInfo.size() << __E__;
8730 const auto diagAliasStartTime = std::chrono::steady_clock::now();
8731 std::map<std::string, std::map<std::string, TableVersion>> versionAliases =
8734 __SUP_COUT__ <<
"# of tables w/aliases: " << versionAliases.size() <<
" (took "
8735 << diagElapsedSec(diagAliasStartTime) <<
" s)" << __E__;
8737 if(filterStartTime != 0 && filterEndTime != 0 && filterMode ==
"created")
8742 const auto diagPreloadStartTime = std::chrono::steady_clock::now();
8744 __SUP_COUT__ <<
"Version creation time cache pre-warm took "
8745 << diagElapsedSec(diagPreloadStartTime) <<
" s" << __E__;
8749 size_t diagNumTablesFound = 0;
8750 size_t diagNumVersionsConsidered = 0;
8751 size_t diagNumVersionsMatched = 0;
8752 size_t diagNumTimeLookups = 0;
8753 double diagTimeLookupSec = 0;
8754 double diagSlowestTableSec = 0;
8755 std::string diagSlowestTableName =
"";
8756 size_t diagTableCount = 0;
8758 for(
const auto& orderedTableName : orderedTableSet)
8761 std::map<std::string, TableInfo>::const_iterator it =
8762 allTableInfo.find(orderedTableName);
8763 if(it == allTableInfo.end())
8765 __SS__ <<
"Impossible missing table in map '" << orderedTableName <<
"'"
8774 xmlOut.addTextElementToData(
"TableName", it->first);
8775 parentEl = xmlOut.addTextElementToData(
"TableVersions",
"");
8778 if(versionAliases.find(it->first) != versionAliases.end())
8779 for(
auto& aliasVersion : versionAliases[it->first])
8780 if(it->second.versions_.find(aliasVersion.second) !=
8781 it->second.versions_
8785 ConfigurationManager::ALIAS_VERSION_PREAMBLE + aliasVersion.first,
8793 auto vSpanToXML = [&diagNumVersionsConsidered,
8794 &diagNumVersionsMatched,
8795 &diagNumTimeLookups,
8796 &diagTimeLookupSec](
auto const& sortedKeys,
8799 const std::string& tableName,
8801 const time_t filterStartTime,
8802 const time_t filterEndTime,
8803 const std::string& filterMode) {
8805 size_t lo = -1, hi = -1;
8806 bool allVersionsFiltered =
true;
8807 for(
auto& keyInOrder : sortedKeys)
8810 if(keyInOrder.isScratchVersion())
8813 ++diagNumVersionsConsidered;
8815 if(filterStartTime != 0 && filterEndTime != 0)
8817 const auto diagLookupStartTime = std::chrono::steady_clock::now();
8826 time_t tableVersionTime =
8827 filterMode ==
"loaded"
8828 ? cfgMgr->getVersionLastAccessTime(tableName, keyInOrder)
8829 : cfgMgr->getVersionCreationTime(tableName, keyInOrder);
8831 ++diagNumTimeLookups;
8832 diagTimeLookupSec +=
8833 std::chrono::duration<double>(
8834 std::chrono::steady_clock::now() - diagLookupStartTime)
8837 if(tableVersionTime < filterStartTime ||
8838 tableVersionTime > filterEndTime)
8842 __COUTT__ <<
"Table '" << tableName <<
"' version v"
8843 << keyInOrder <<
" " << filterMode
8844 <<
" time is outside the filter range, so "
8850 catch(
const std::runtime_error&)
8852 ++diagNumTimeLookups;
8853 diagTimeLookupSec +=
8854 std::chrono::duration<double>(
8855 std::chrono::steady_clock::now() - diagLookupStartTime)
8857 __COUT__ <<
"Failed to get " << filterMode <<
" time for table '"
8858 << tableName <<
"' version v" << keyInOrder
8859 <<
", so skipping." << __E__;
8864 allVersionsFiltered =
false;
8865 ++diagNumVersionsMatched;
8867 if(lo ==
size_t(-1))
8869 hi = lo = keyInOrder.
version();
8872 else if(hi + 1 == keyInOrder.version())
8880 xmlOut.addNumberElementToParent(
"Version", lo, configEl);
8882 xmlOut.addTextElementToParent(
8884 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
8886 hi = lo = keyInOrder.
version();
8889 if(lo !=
size_t(-1))
8892 xmlOut.addNumberElementToParent(
"Version", lo, configEl);
8894 xmlOut.addTextElementToParent(
8896 "_" + std::to_string(lo) +
"_" + std::to_string(hi),
8899 return allVersionsFiltered;
8902 const auto diagTableStartTime = std::chrono::steady_clock::now();
8903 if(vSpanToXML(it->second.versions_,
8911 filterStartTime != 0 && filterEndTime != 0)
8917 unsigned int childCount = xmlOut.getChildrenCount();
8920 xmlOut.removeDataElement(childCount - 1);
8921 xmlOut.removeDataElement(childCount - 2);
8925 ++diagNumTablesFound;
8928 double diagTableSec = diagElapsedSec(diagTableStartTime);
8929 if(diagTableSec > diagSlowestTableSec)
8931 diagSlowestTableSec = diagTableSec;
8932 diagSlowestTableName = it->first;
8934 if(diagTableSec > 1.0)
8935 __SUP_COUT__ <<
"Slow table filter: '" << it->first <<
"' with "
8936 << it->second.versions_.size() <<
" versions took "
8937 << diagTableSec <<
" s" << __E__;
8939 if(diagTableCount % 50 == 0)
8940 __SUP_COUT__ <<
"getTables filter progress: " << diagTableCount <<
" of "
8941 << orderedTableSet.size() <<
" tables in "
8942 << diagElapsedSec(diagStartTime) <<
" s (" << diagNumTimeLookups
8943 <<
" version time lookups taking " << diagTimeLookupSec
8944 <<
" s so far)" << __E__;
8949 xmlOut.addTextElementToData(
"NumberOfTablesConsidered",
8950 std::to_string(allTableInfo.size()));
8951 xmlOut.addTextElementToData(
"NumberOfTablesFound",
8952 std::to_string(diagNumTablesFound));
8953 xmlOut.addTextElementToData(
"NumberOfVersionsConsidered",
8954 std::to_string(diagNumVersionsConsidered));
8955 xmlOut.addTextElementToData(
"NumberOfVersionsFound",
8956 std::to_string(diagNumVersionsMatched));
8958 __SUP_COUT__ <<
"getTables filter summary: mode=" << filterMode <<
" range=["
8959 << filterStartTime <<
"," << filterEndTime <<
"]"
8960 <<
" tables considered=" << allTableInfo.size()
8961 <<
" found=" << diagNumTablesFound
8962 <<
"; versions considered=" << diagNumVersionsConsidered
8963 <<
" matched=" << diagNumVersionsMatched <<
"; " << diagNumTimeLookups
8964 <<
" version time lookups took " << diagTimeLookupSec
8965 <<
" s; slowest table '" << diagSlowestTableName <<
"' took "
8966 << diagSlowestTableSec <<
" s; total " << diagElapsedSec(diagStartTime)
8980 void ConfigurationGUISupervisor::handleGetArtdaqNodeRecordsXML(
8983 const std::string& modifiedTables,
8984 const std::string& tableGroup,
8986 const std::string& contextGroup,
8988 bool suppressMultiNode)
8990 __COUT__ <<
"Retrieving artdaq nodes..." << __E__;
8993 setupActiveTablesXML(xmlOut,
9000 if(contextGroup !=
"" && !contextGroupKey.
isInvalid())
9007 cfgMgr->
getTableByName(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME);
9011 __SUP_SS__ <<
"Failed to cast "
9012 << ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME
9013 <<
" to XDAQContextTable." << __E__;
9019 std::map<std::string ,
9020 std::map<std::string , std::vector<std::string >>>
9021 nodeTypeToObjectMap;
9022 std::map<std::string , std::string >
9025 std::vector<std::string > artdaqSupervisorInfo;
9027 std::string artdaqSupervisorName;
9028 const ARTDAQTableBase::ARTDAQInfo& info =
9030 nodeTypeToObjectMap,
9032 artdaqSupervisorInfo,
9035 bool hasArtdaqSupervisor =
9036 (artdaqSupervisorInfo.size() == 4 );
9041 xercesc::DOMElement* parentEl =
nullptr;
9042 unsigned int paramIndex = 0;
9043 std::string typeString;
9045 if(hasArtdaqSupervisor)
9048 parentEl = xmlOut.addTextElementToData(
"artdaqSupervisor",
9049 artdaqSupervisorInfo[paramIndex++]);
9050 typeString =
"artdaqSupervisor";
9052 typeString +
"-status", artdaqSupervisorInfo[paramIndex++], parentEl);
9054 typeString +
"-contextAddress", artdaqSupervisorInfo[paramIndex++], parentEl);
9056 typeString +
"-contextPort", artdaqSupervisorInfo[paramIndex++], parentEl);
9058 for(
auto& subsystem : info.subsystems)
9060 typeString =
"subsystem";
9062 __SUP_COUT__ <<
"\t\t"
9063 <<
"Found " << typeString <<
" " << subsystem.first <<
" \t := '"
9064 << subsystem.second.label <<
"'" << __E__;
9068 typeString +
"-id", std::to_string(subsystem.first), parentEl);
9071 std::to_string(subsystem.second.sources.size()),
9075 std::to_string(subsystem.second.destination),
9081 __SUP_COUT__ <<
"No artdaq supervisor found — scanning for online monitors."
9083 parentEl = xmlOut.addTextElementToData(
"artdaqSupervisor",
"");
9086 __SUP_COUT__ <<
"========== "
9087 <<
"Found " << nodeTypeToObjectMap.size() <<
" process types." << __E__;
9089 for(
auto& nameTypePair : nodeTypeToObjectMap)
9091 typeString = nameTypePair.first;
9093 __SUP_COUT__ <<
"\t"
9094 <<
"Found " << nameTypePair.second.size() <<
" " << typeString
9097 for(
auto& artdaqNode : nameTypePair.second)
9099 __SUP_COUT__ <<
"\t\t"
9100 <<
"Found '" << artdaqNode.first <<
"' " << typeString << __E__;
9103 if(artdaqNode.second.size() < 2)
9105 __SUP_SS__ <<
"Impossible parameter size for node '" << artdaqNode.first
9106 <<
"' " << typeString <<
" - please notify admins!" << __E__;
9114 if(artdaqNode.second.size() > paramIndex)
9116 __SUP_COUTT__ <<
"\t\t\t"
9117 <<
"-multinode: " << artdaqNode.second[paramIndex] << __E__;
9119 typeString +
"-multinode", artdaqNode.second[paramIndex++], nodeEl);
9121 if(artdaqNode.second.size() > paramIndex)
9123 __SUP_COUTT__ <<
"\t\t\t"
9124 <<
"-nodefixedwidth: " << artdaqNode.second[paramIndex]
9127 artdaqNode.second[paramIndex++],
9130 if(artdaqNode.second.size() > paramIndex)
9132 __SUP_COUTT__ <<
"\t\t\t"
9133 <<
"-hostarray: " << artdaqNode.second[paramIndex] << __E__;
9135 typeString +
"-hostarray", artdaqNode.second[paramIndex++], nodeEl);
9137 if(artdaqNode.second.size() > paramIndex)
9139 __SUP_COUTT__ <<
"\t\t\t"
9140 <<
"-hostfixedwidth: " << artdaqNode.second[paramIndex]
9143 artdaqNode.second[paramIndex++],
9148 __SUP_COUTT__ <<
"\t\t\t"
9149 <<
"-status: " << artdaqNode.second[paramIndex] << __E__;
9151 typeString +
"-status", artdaqNode.second[paramIndex++], parentEl);
9152 __SUP_COUTT__ <<
"\t\t\t"
9153 <<
"-hostname: " << artdaqNode.second[paramIndex] << __E__;
9155 typeString +
"-hostname", artdaqNode.second[paramIndex++], parentEl);
9156 __SUP_COUTT__ <<
"\t\t\t"
9157 <<
"-subsystem: " << artdaqNode.second[paramIndex] << __E__;
9159 typeString +
"-subsystem", artdaqNode.second[paramIndex], parentEl);
9168 cfgMgr->
getTableByName(ConfigurationManager::XDAQ_CONTEXT_TABLE_NAME));
9172 typeString =
"monitor";
9173 unsigned int monitorCount = 0;
9175 for(
auto& ctx : ctxTable->getContexts())
9180 for(
auto& app : ctx.applications_)
9184 if(app.class_.find(
"ARTDAQOnlineMonitorSupervisor") ==
9190 std::string monitorLabel = app.applicationUID_;
9194 XDAQContextTable::getSupervisorConfigNode(
9195 cfgMgr, ctx.contextUID_, app.applicationUID_);
9201 <<
"Could not follow supervisor config link for "
9202 << app.applicationUID_ <<
" in context " << ctx.contextUID_
9203 <<
"; using application UID as label." << __E__;
9207 std::string hostname = ctx.address_;
9209 auto pos = hostname.find(
"://");
9210 if(pos != std::string::npos)
9211 hostname = hostname.substr(pos + 3);
9214 __SUP_COUT__ <<
"\t\tFound online monitor '" << monitorLabel
9215 <<
"' on " << hostname << __E__;
9220 typeString +
"-hostname",
9221 StringMacros::encodeURIComponent(hostname),
9224 typeString +
"-subsystem",
"", parentEl);
9230 __SUP_COUT__ <<
"Found " << monitorCount <<
" online monitor supervisor(s)."
9235 __SUP_COUT__ <<
"Done retrieving artdaq nodes." << __E__;
9246 void ConfigurationGUISupervisor::handleSaveArtdaqNodeRecordsXML(
9247 const std::string& nodeString,
9248 const std::string& subsystemString,
9251 const std::string& modifiedTables)
9253 __SUP_COUT__ <<
"Saving artdaq nodes..." << __E__;
9256 setupActiveTablesXML(
9257 xmlOut, cfgMgr,
"",
TableGroupKey(-1), modifiedTables,
false );
9260 std::map<std::string ,
9261 std::map<std::string , std::vector<std::string >>>
9262 nodeTypeToObjectMap;
9268 std::map<std::string , std::string >
9269 nodeTypeToStringMap;
9274 for(
auto& typePair : nodeTypeToStringMap)
9276 if(typePair.first ==
"")
9281 nodeTypeToObjectMap.emplace(
9283 std::map<std::string ,
9284 std::vector<std::string /*property*/>>()));
9286 std::map<std::string , std::string >
9287 nodeRecordToStringMap;
9290 typePair.second, nodeRecordToStringMap, {
';'}, {
'='});
9294 for(
auto& nodePair : nodeRecordToStringMap)
9296 if(nodePair.first ==
"")
9301 std::vector<std::string > nodePropertyVector;
9304 nodePair.second, nodePropertyVector, {
','});
9309 for(
unsigned int i = 0; i < nodePropertyVector.size(); ++i)
9314 nodePropertyVector[i] =
9318 nodeTypeToObjectMap[typePair.first].emplace(
9320 nodePropertyVector));
9326 std::map<std::string , std::string >
9333 std::map<std::string , std::string >
9334 tmpSubsystemObjectMap;
9336 subsystemString, tmpSubsystemObjectMap, {
';'}, {
':'});
9341 for(
auto& subsystemPair : tmpSubsystemObjectMap)
9346 subsystemObjectMap.emplace(
9353 cfgMgr, nodeTypeToObjectMap, subsystemObjectMap);
9355 __SUP_COUT__ <<
"Done saving artdaq nodes." << __E__;
9365 void ConfigurationGUISupervisor::handleLoadArtdaqNodeLayoutXML(
9369 const std::string& contextGroupName ,
9372 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
9375 const std::string& finalContextGroupName =
9377 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
9381 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
9383 const std::string& finalConfigGroupName =
9384 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
9386 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
9391 std::stringstream layoutPath;
9392 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
9393 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
9394 << finalConfigGroupKey <<
".dat";
9396 fp = fopen(layoutPath.str().c_str(),
"r");
9399 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
9400 << finalContextGroupKey <<
") + " << finalConfigGroupName <<
"("
9401 << finalConfigGroupKey <<
")': " << layoutPath.
str() << __E__;
9405 __SUP_COUTV__(layoutPath.str());
9410 std::stringstream layoutPath;
9411 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
9412 <<
"_" << finalContextGroupKey <<
".dat";
9413 __SUP_COUTV__(layoutPath.str());
9415 fp = fopen(layoutPath.str().c_str(),
"r");
9418 __SUP_COUT__ <<
"Layout file not found for '" << finalContextGroupName <<
"("
9419 << finalContextGroupKey <<
")': " << layoutPath.str() << __E__;
9423 __SUP_COUTV__(layoutPath.str());
9430 const size_t maxLineSz = 1000;
9431 char line[maxLineSz];
9432 if(!fgets(line, maxLineSz, fp))
9441 unsigned int rows, cols;
9443 sscanf(line,
"%u %u", &rows, &cols);
9445 __COUT__ <<
"Grid rows,cols = " << rows <<
"," << cols << __E__;
9447 xmlOut.addTextElementToData(
"grid-rows", std::to_string(rows));
9448 xmlOut.addTextElementToData(
"grid-cols", std::to_string(cols));
9451 char name[maxLineSz];
9452 char type[maxLineSz];
9454 while(fgets(line, maxLineSz, fp))
9457 sscanf(line,
"%s %s %u %u", type, name, &x, &y);
9459 xmlOut.addTextElementToData(
"node-type", type);
9460 xmlOut.addTextElementToData(
"node-name", name);
9461 xmlOut.addTextElementToData(
"node-x", std::to_string(x));
9462 xmlOut.addTextElementToData(
"node-y", std::to_string(y));
9476 void ConfigurationGUISupervisor::handleSaveArtdaqNodeLayoutXML(
9479 const std::string& layoutString,
9480 const std::string& contextGroupName,
9483 bool usingActiveGroups = (contextGroupName ==
"" || contextGroupKey.
isInvalid());
9485 const std::string& finalContextGroupName =
9487 ? cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONTEXT_TYPE)
9491 ? cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONTEXT_TYPE)
9493 const std::string& finalConfigGroupName =
9494 cfgMgr->getActiveGroupName(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
9496 cfgMgr->getActiveGroupKey(ConfigurationManager::GroupType::CONFIGURATION_TYPE);
9498 __SUP_COUTV__(layoutString);
9500 std::stringstream layoutPath;
9501 layoutPath << ARTDAQTableBase::ARTDAQ_CONFIG_LAYOUTS_PATH << finalContextGroupName
9502 <<
"_" << finalContextGroupKey <<
"." << finalConfigGroupName <<
"_"
9503 << finalConfigGroupKey <<
".dat";
9504 __SUP_COUTV__(layoutPath.str());
9509 if(fields.size() < 2 || (fields.size() - 2) % 4 != 0)
9511 __SUP_SS__ <<
"Invalid layout string fields size of " << fields.size() << __E__;
9515 FILE* fp = fopen(layoutPath.str().c_str(),
"w");
9518 __SUP_SS__ <<
"Could not open layout file for writing for '"
9519 << finalContextGroupName <<
"(" << finalContextGroupKey <<
") + "
9520 << finalConfigGroupName <<
"(" << finalConfigGroupKey
9521 <<
")': " << layoutPath.
str() << __E__;
9528 fprintf(fp,
"%s %s\n", fields[0].c_str(), fields[1].c_str());
9531 for(
unsigned int i = 2; i < fields.size(); i += 4)
9534 fields[i + 0].c_str(),
9535 fields[i + 1].c_str(),
9536 fields[i + 2].c_str(),
9537 fields[i + 3].c_str());
9545 void ConfigurationGUISupervisor::handleOtherSubsystemActiveGroups(
9549 std::string targetSubsystem )
9555 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
9558 for(
auto subsystem : children)
9560 __SUP_COUTV__(subsystem.first);
9564 std::string userPath =
9565 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
9566 __SUP_COUTV__(userPath);
9569 catch(
const std::runtime_error& e)
9571 __SUP_COUT__ <<
"Ignoring errors in handling other subsystem active groups "
9572 "(assuming the subsystem information map is not setup in "
9573 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
9574 <<
") -- here is the error: \n"
9575 << e.what() << __E__;
9582 cfgMgr->
getNode(ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE);
9584 for(
auto subsystem : children)
9586 if(targetSubsystem !=
"" && targetSubsystem != subsystem.first)
9589 xercesc::DOMElement* parent =
9590 xmlOut.addTextElementToData(
"SubsystemName", subsystem.first);
9595 std::string filename, userDataPath;
9596 std::string username, hostname;
9598 std::map<std::string ,
9600 retMap = cfgMgr->getOtherSubsystemActiveTableGroups(
9601 subsystem.first, &userDataPath, &hostname, &username);
9603 for(
const auto& retPair : retMap)
9606 retPair.second.first,
9609 retPair.second.second.toString(),
9613 std::vector<std::string> filenameTypes = {
"Configured",
9617 "ActivatedBackbone",
9618 "ActivatedIterator"};
9620 std::vector<std::string> filenames = {
9621 ConfigurationManager::LAST_CONFIGURED_CONFIG_GROUP_FILE,
9622 ConfigurationManager::LAST_STARTED_CONFIG_GROUP_FILE,
9623 ConfigurationManager::LAST_ACTIVATED_CONFIG_GROUP_FILE,
9624 ConfigurationManager::LAST_ACTIVATED_CONTEXT_GROUP_FILE,
9625 ConfigurationManager::LAST_ACTIVATED_BACKBONE_GROUP_FILE,
9626 ConfigurationManager::LAST_ACTIVATED_ITERATE_GROUP_FILE};
9628 std::string userPath =
9629 subsystem.second.getNode(
"SubsystemUserDataPath").getValue();
9631 std::string cmdResult;
9632 for(
unsigned int i = 0; i < filenames.size(); ++i)
9634 filename = userDataPath +
"/ServiceData/RunControlData/" + filenames[i];
9635 __SUP_COUTV__(filename);
9637 std::string tmpSubsystemFilename =
9638 ConfigurationManager::LAST_TABLE_GROUP_SAVE_PATH +
"/" + filenames[i] +
9639 "." + subsystem.first;
9640 __SUP_COUTV__(tmpSubsystemFilename);
9642 if(splitPath.size() == 2)
9646 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + username +
9647 "@" + hostname +
":" + filename +
" " + tmpSubsystemFilename +
9648 " 2>&1; cat " + tmpSubsystemFilename +
" 2>&1")
9652 (
"rm " + tmpSubsystemFilename +
" 2>/dev/null; scp " + hostname +
9653 ":" + filename +
" " + tmpSubsystemFilename +
" 2>&1; cat " +
9654 tmpSubsystemFilename +
" 2>&1")
9657 else if(splitPath.size() == 1)
9660 " 2>/dev/null; cp " + filename +
" " +
9661 tmpSubsystemFilename +
" 2>&1; cat " +
9662 tmpSubsystemFilename +
" 2>&1")
9666 __SUP_COUTV__(cmdResult);
9667 std::string timeString;
9670 filenames[i] +
"." + subsystem.first, timeString);
9674 "Last" + filenameTypes[i] +
"GroupName", theGroup.first, parent);
9676 theGroup.second.toString(),
9679 "Last" + filenameTypes[i] +
"GroupTime", timeString, parent);
9684 catch(
const std::runtime_error& e)
9687 <<
"An error occurred handling subsystem active groups (Please check the "
9688 "subsystem user data path information map setup in the Context group table "
9689 << ConfigurationManager::CONTEXT_SUBSYSTEM_OPTIONAL_TABLE
9690 <<
") -- here is the error: \n"
9691 << e.what() << __E__;
9697 void ConfigurationGUISupervisor::handleSearchFieldInGroupXML(
9700 const std::string& searchText,
9701 const bool activeGroupsOnly,
9702 const std::string& groupType,
9703 const std::string& optionGroups,
9704 const std::string& versionsToCheck)
9707 if(searchText.empty() || searchText.find_first_not_of(
" \t\r\n") == std::string::npos)
9709 __COUT_WARN__ <<
"searchText is empty or whitespace; aborting search." << __E__;
9710 xmlOut.addTextElementToData(
"Error",
"Search text must not be empty.");
9714 bool searchAllGroups =
false;
9715 if(optionGroups.size() == 0)
9717 __COUT__ <<
"No optionGroups specified, searching all groups of type "
9718 << groupType << __E__;
9719 searchAllGroups =
true;
9721 std::vector<std::string> optionGroupsList =
9724 const std::map<std::string, GroupInfo>& allGroupInfo = cfgMgr->getAllGroupInfo();
9726 int searchMinThreshold = 0;
9727 int searchMaxThreshold = 0;
9728 size_t dashPos = -1;
9731 if(versionsToCheck.empty())
9733 searchMaxThreshold = INT_MAX;
9735 else if(versionsToCheck.find(
'-') != std::string::npos)
9737 __COUT__ <<
"Parsing versionsToCheck for range: " << versionsToCheck << __E__;
9738 dashPos = versionsToCheck.find(
'-');
9743 std::string minStr = versionsToCheck.substr(0, dashPos);
9744 std::string maxStr = versionsToCheck.substr(dashPos + 1);
9746 searchMinThreshold = atoi(minStr.c_str());
9747 searchMaxThreshold = atoi(maxStr.c_str());
9750 else if(versionsToCheck !=
"")
9753 searchMinThreshold = atoi(versionsToCheck.c_str());
9754 searchMaxThreshold = INT_MAX;
9758 __COUT__ <<
"Unable to set min and max thresholds for versionsToCheck: "
9759 << versionsToCheck << __E__;
9760 xmlOut.addTextElementToData(
9762 "Unable to set min and max thresholds for versionsToCheck: " +
9765 __SUP_COUT__ <<
"versionsToCheck range: " << searchMinThreshold <<
" to "
9766 << searchMaxThreshold << __E__;
9768 auto parentEl = xmlOut.addTextElementToData(
"SearchResults",
"");
9770 for(
auto& groupInfo : allGroupInfo)
9772 __COUT__ <<
"Checking group: " << groupInfo.first
9773 <<
" group type : " << groupInfo.second.getLatestKeyGroupTypeString()
9776 if(groupInfo.second.getLatestKeyGroupTypeString() != groupType)
9780 if(!searchAllGroups &&
9781 std::find(optionGroupsList.begin(), optionGroupsList.end(), groupInfo.first) ==
9782 optionGroupsList.end())
9784 __COUT__ <<
"\tSkipping group not in optionGroups list." << __E__;
9788 std::set<
TableGroupKey > allGroupKeys = groupInfo.second.getKeys();
9790 std::vector<TableGroupKey> groupKeysVec(allGroupKeys.begin(), allGroupKeys.end());
9793 __COUT__ <<
"Group keys:" << groupKeysStr << __E__;
9798 std::string offsetStr = versionsToCheck.substr(1);
9800 atoi(offsetStr.c_str()) - 1;
9802 __SUP_COUT__ <<
"versionsToCheck offset from end: " << offset << __E__;
9805 if(groupKeysVec.size() > 0)
9808 groupKeysVec.size() - 1);
9809 int maxVersionNum = std::stoi(maxVersion.
toString());
9810 int minVersionNum = std::max(0, maxVersionNum - offset);
9812 searchMinThreshold = minVersionNum;
9813 searchMaxThreshold = maxVersionNum;
9815 __SUP_COUT__ <<
"Version range: " << searchMinThreshold <<
" to "
9816 << searchMaxThreshold << __E__;
9822 if(activeGroupsOnly)
9824 std::set<TableGroupKey> singleKeySet;
9825 singleKeySet.insert(groupInfo.second.getLatestKey());
9826 groupKeys = std::move(singleKeySet);
9829 groupKeys = std::move(allGroupKeys);
9831 for(
const auto& groupKey : groupKeys)
9833 __COUT__ <<
"\tProcessing group: " << groupInfo.first <<
" v" << groupKey
9836 if(!activeGroupsOnly &&
9837 (std::stoi(groupKey.toString()) < searchMinThreshold ||
9838 std::stoi(groupKey.toString()) > searchMaxThreshold))
9840 __COUT__ <<
"\tSkipping group version outside of versionsToCheck range."
9861 for(
auto& tablePair : memberMap)
9863 __COUT__ <<
"\t\tTable: " << tablePair.first <<
" v"
9864 << tablePair.second << __E__;
9870 tablePair.first, tablePair.second);
9873 const TableView& tableView = memberTable->getView();
9876 for(
unsigned int row = 0; row < tableView.getNumberOfRows();
9879 for(
unsigned int col = 0;
9880 col < tableView.getNumberOfColumns();
9883 const std::string& cellValue =
9884 tableView.getDataView()[row][col];
9887 if(cellValue.find(searchText) != std::string::npos)
9889 __COUT__ <<
"\t\t\tMatch found in " << tablePair.first
9890 <<
" v" << tablePair.second <<
" row " << row
9891 <<
" column " << col
9892 <<
" value: " << cellValue << __E__;
9896 groupInfo.first +
"/" + tablePair.first,
9899 "MatchRow", std::to_string(row), groupTableEl);
9902 tableView.getColumnInfo(col).getName(),
9905 groupKey.toString(),
9908 "MatchTableVersion",
9909 tablePair.second.toString(),
9915 catch(
const std::runtime_error& e)
9917 __COUT_WARN__ <<
"Failed to search table " << tablePair.first
9918 <<
" v" << tablePair.second <<
": " << e.what()
9923 catch(
const std::runtime_error& e)
9925 __COUT_WARN__ <<
"Failed to load group members for " << groupInfo.first
9926 <<
": " << e.what() << __E__;
9934 void ConfigurationGUISupervisor::handleSearchFieldInTableXML(
9937 const std::string& searchText,
9938 const std::string& tableName,
9939 const std::string& searchVersionToCheck,
9940 bool activeTablesOnly)
9943 if(searchText.empty() || searchText.find_first_not_of(
" \t\r\n") == std::string::npos)
9945 __COUT_WARN__ <<
"searchText is empty or whitespace; aborting search." << __E__;
9946 xmlOut.addTextElementToData(
"Error",
"Search text must not be empty.");
9950 const std::map<std::string, TableInfo>& allTableInfo = cfgMgr->
getAllTableInfo();
9951 std::map<std::string, TableVersion> allActivePairs = cfgMgr->
getActiveVersions();
9953 int searchMinThreshold = 0;
9954 int searchMaxThreshold = 0;
9957 if(searchVersionToCheck.empty())
9959 searchMaxThreshold = INT_MAX;
9961 else if(searchVersionToCheck.find(
'-') != std::string::npos)
9963 size_t dashPos = searchVersionToCheck.find(
'-');
9968 std::string offsetStr = searchVersionToCheck.substr(1);
9970 atoi(offsetStr.c_str()) - 1;
9972 __SUP_COUT__ <<
"searchVersionToCheck offset from end: " << offset << __E__;
9975 if(allTableInfo.find(tableName) != allTableInfo.end())
9977 const TableInfo& tableInfo = allTableInfo.at(tableName);
9978 if(tableInfo.versions_.size() > 0)
9980 auto maxVersionIter = tableInfo.versions_.rbegin();
9981 int maxVersionNum = maxVersionIter->version();
9982 int minVersionNum = std::max(0, maxVersionNum - offset);
9984 searchMinThreshold = minVersionNum;
9985 searchMaxThreshold = maxVersionNum;
9987 __SUP_COUT__ <<
"Version range: " << searchMinThreshold <<
" to "
9988 << searchMaxThreshold << __E__;
9995 std::string minStr = searchVersionToCheck.substr(0, dashPos);
9996 std::string maxStr = searchVersionToCheck.substr(dashPos + 1);
9998 searchMinThreshold = atoi(minStr.c_str());
9999 searchMaxThreshold = atoi(maxStr.c_str());
10002 else if(searchVersionToCheck !=
"")
10005 searchMinThreshold = atoi(searchVersionToCheck.c_str());
10006 searchMaxThreshold = INT_MAX;
10010 __COUT__ <<
"Unable to set min and max thresholds for searchVersionToCheck: "
10011 << searchVersionToCheck << __E__;
10012 xmlOut.addTextElementToData(
10014 "Unable to set min and max thresholds for searchVersionToCheck: " +
10015 searchVersionToCheck);
10017 __SUP_COUT__ <<
"searchVersionToCheck range: " << searchMinThreshold <<
" to "
10018 << searchMaxThreshold << __E__;
10022 if(allTableInfo.find(tableName) == allTableInfo.end())
10024 __SUP_SS__ <<
"Table '" << tableName <<
"' not found." << __E__;
10025 xmlOut.addTextElementToData(
"Error", ss.str());
10029 const TableInfo& tableInfo = allTableInfo.at(tableName);
10030 __COUT__ <<
"tableInfo versions length " << tableInfo.versions_.size() << __E__;
10032 unsigned int matchCount = 0;
10033 bool allowIllegalColumns =
true;
10035 auto parentEl = xmlOut.addTextElementToData(
"SearchResults",
"");
10038 for(
const auto& version : tableInfo.versions_)
10042 auto activeIt = allActivePairs.find(tableName);
10043 bool isActiveVersion =
10044 (activeIt != allActivePairs.end() && activeIt->second == version);
10045 __COUT__ <<
"Active check for " << tableName <<
" v" << version <<
" => "
10046 << (isActiveVersion ?
"active" :
"inactive") << __E__;
10047 if(!isActiveVersion && activeTablesOnly)
10050 if((std::stoi(version.toString()) < searchMinThreshold ||
10051 std::stoi(version.toString()) > searchMaxThreshold) &&
10052 activeTablesOnly ==
false )
10054 __COUT__ <<
"Skipping version " << version <<
" out of range "
10055 << searchMinThreshold <<
" to " << searchMaxThreshold
10063 if(version.isInvalid())
10065 __COUT__ <<
"Using mock-up for table " << tableName <<
" version "
10066 << version << __E__;
10067 tableViewPtr = table->getMockupViewP();
10075 std::string localAccumulatedErrors =
"";
10081 allowIllegalColumns ,
10082 &localAccumulatedErrors,
10086 if(localAccumulatedErrors !=
"")
10087 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
10089 catch(
const std::runtime_error& e)
10091 __COUT__ <<
"Error loading version " << version <<
" for table "
10092 << tableName <<
": " << e.what() << __E__;
10093 __SUP_COUT_WARN__ <<
"Could not load version " << version
10094 <<
" for table " << tableName <<
": "
10095 << e.what() << __E__;
10097 tableViewPtr = table->getMockupViewP();
10101 __COUT__ <<
"Getting table " << tableName <<
" version " << version
10105 for(
unsigned int row = 0; row < tableViewPtr->getNumberOfRows(); ++row)
10107 for(
unsigned int col = 0; col < tableViewPtr->getNumberOfColumns();
10110 const std::string& cellValue =
10111 tableViewPtr->getDataView()[row][col];
10113 if(cellValue.find(searchText) != std::string::npos)
10115 __COUT__ <<
"Match found in row " << row <<
" column " << col
10116 <<
" value: " << cellValue << __E__;
10118 "Match", cellValue, parentEl);
10120 "MatchVersion", version.toString(), matchEl);
10122 "MatchRow", std::to_string(row), matchEl);
10125 tableViewPtr->getColumnInfo(col).getName(),
10133 catch(
const std::runtime_error& e)
10135 __COUT__ <<
"Error searching in version " << version <<
" for table "
10136 << tableName <<
": " << e.what() << __E__;
10137 __SUP_COUT_WARN__ <<
"Could not load version " << version <<
" for table "
10138 << tableName <<
": " << e.what() << __E__;
10142 xmlOut.addTextElementToData(
"MatchCount", std::to_string(matchCount));
10144 catch(std::runtime_error& e)
10146 __SUP_SS__ <<
"Error searching in table '" << tableName <<
"'!\n\n " << e.what()
10148 __SUP_COUT_ERR__ << ss.str();
10149 xmlOut.addTextElementToData(
"Error", ss.str());
10153 __SUP_SS__ <<
"Error searching in table '" << tableName <<
"'!\n\n " << __E__;
10158 catch(
const std::exception& e)
10160 ss <<
"Exception message: " << e.what();
10165 __SUP_COUT_ERR__ << ss.str();
10166 xmlOut.addTextElementToData(
"Error", ss.str());
10172 void ConfigurationGUISupervisor::handleGroupDiff(
10175 const std::string& groupName,
10178 const std::string& diffGroupNameInput )
10184 std::string diffGroupName;
10187 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
10188 <<
") with the active group." << __E__;
10191 if(diffGroupNameInput ==
"")
10192 diffGroupName = groupName;
10194 diffGroupName = diffGroupNameInput;
10196 __SUP_COUT__ <<
"Differencing group " << groupName <<
"(" << groupKey
10197 <<
") with group " << diffGroupName <<
"(" << diffKey <<
")"
10203 std::map<std::string ,
TableVersion > memberMap, diffMemberMap;
10204 std::string groupType, accumulateErrors;
10205 std::stringstream diffReport;
10206 bool noDifference =
true;
10214 &accumulateErrors ,
10225 std::map<std::string , std::pair<std::string, TableGroupKey>>
10232 __SUP_COUTV__(groupType);
10234 if(activeGroups.find(groupType) == activeGroups.end() ||
10235 activeGroups.at(groupType).first ==
"" ||
10236 activeGroups.at(groupType).second.isInvalid())
10238 __SUP_SS__ <<
"Could not find an active group of type '" << groupType
10239 <<
".' Please check the expected active configuration groups "
10240 "for errors (going to 'System View' of the Config App may "
10246 __SUP_COUT__ <<
"active " << groupType <<
" group is "
10247 << activeGroups.at(groupType).first <<
"("
10248 << activeGroups.at(groupType).second <<
")" << __E__;
10250 diffReport <<
"This difference report is between " << groupType
10251 <<
" group <b>'" << groupName <<
"(" << groupKey <<
")'</b>"
10252 <<
" and active group <b>'" << activeGroups.at(groupType).first
10253 <<
"(" << activeGroups.at(groupType).second <<
")'</b>." << __E__;
10256 activeGroups.at(groupType).second,
10260 &accumulateErrors ,
10266 diffReport <<
"\n\n"
10267 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
10268 << memberMap.size() <<
" member tables</b>, and "
10269 <<
"'" << activeGroups.at(groupType).first <<
"("
10270 << activeGroups.at(groupType).second <<
")' has <b>"
10271 << diffMemberMap.size() <<
" member tables</b>." << __E__;
10275 diffReport <<
"This difference report is between group <b>'" << groupName
10276 <<
"(" << groupKey <<
")'</b>"
10277 <<
" and group <b>'" << diffGroupName <<
"(" << diffKey
10278 <<
")'</b>." << __E__;
10285 &accumulateErrors ,
10291 diffReport <<
"\n\n"
10292 <<
"'" << groupName <<
"(" << groupKey <<
")' has <b>"
10293 << memberMap.size() <<
" member tables</b>, and "
10294 <<
"'" << diffGroupName <<
"(" << diffKey <<
")' has <b>"
10295 << diffMemberMap.size() <<
" member tables</b>." << __E__;
10300 diffReport <<
"<INDENT><ol>";
10302 unsigned int tableDifferences = 0;
10304 for(
auto& member : memberMap)
10306 if(diffMemberMap.find(member.first) == diffMemberMap.end())
10308 diffReport <<
"\n\n<li>"
10309 <<
"Table <b>" << member.first <<
"-v" << member.second
10310 <<
"</b> not found in active group."
10311 <<
"</li>" << __E__;
10312 noDifference =
false;
10313 ++tableDifferences;
10317 __SUP_COUTT__ <<
"Comparing " << member.first <<
"-v" << member.second
10318 <<
" ... " << member.first <<
"-v"
10319 << diffMemberMap.at(member.first) << __E__;
10321 if(member.second == diffMemberMap.at(member.first))
10324 diffReport <<
"\n\n<li>"
10325 <<
"Table <b>" << member.first <<
" v" << member.second
10326 <<
"</b> in " << groupName <<
"(" << groupKey <<
")' ...vs... "
10327 <<
" <b>v" << diffMemberMap.at(member.first) <<
"</b> in "
10328 << diffGroupName <<
"(" << diffKey <<
")':" << __E__;
10332 diffReport <<
"<ul>";
10333 std::map<std::string , std::vector<std::string >>
10335 if(!table->diffTwoVersions(member.second,
10336 diffMemberMap.at(member.first),
10341 noDifference =
false;
10342 ++tableDifferences;
10344 xmlOut.addTextElementToData(
"TableWithDiff", member.first);
10345 for(
auto& modifiedRecord : modifiedRecords)
10348 "RecordWithDiff", modifiedRecord.first, parentEl);
10349 for(
auto& modifiedColumn : modifiedRecord.second)
10351 "ColNameWithDiff", modifiedColumn, recordParentEl);
10354 diffReport <<
"</ul></li>";
10358 for(
auto& diffMember : diffMemberMap)
10360 if(memberMap.find(diffMember.first) == memberMap.end())
10363 diffReport <<
"\n\n<li>"
10364 <<
"Active Group Table <b>" << diffMember.first <<
"-v"
10365 << diffMember.second <<
"</b> not found in '" << groupName
10366 <<
"(" << groupKey <<
")'."
10367 <<
"</li>" << __E__;
10369 diffReport <<
"\n\n<li>" << diffGroupName <<
"(" << diffKey
10370 <<
") Table <b>" << diffMember.first <<
"-v"
10371 << diffMember.second <<
"</b> not found in '" << groupName
10372 <<
"(" << groupKey <<
")'."
10373 <<
"</li>" << __E__;
10375 noDifference =
false;
10376 ++tableDifferences;
10380 diffReport <<
"\n</ol></INDENT>";
10385 diffReport <<
"\n\nNo difference found between "
10386 <<
"<b>'" << groupName <<
"(" << groupKey
10387 <<
")'</b> and active group "
10388 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
10389 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
10391 diffReport <<
"\n\n<b>" << tableDifferences
10392 <<
"</b> member table differences identified between "
10393 <<
"<b>'" << groupName <<
"(" << groupKey
10394 <<
")'</b> and active group "
10395 <<
"<b>'" << activeGroups.at(groupType).first <<
"("
10396 << activeGroups.at(groupType).second <<
")'</b>." << __E__;
10401 diffReport <<
"\n\nNo difference found between "
10402 <<
"<b>'" << groupName <<
"(" << groupKey
10403 <<
")'</b> and group "
10404 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
10407 diffReport <<
"\n\n<b>" << tableDifferences
10408 <<
"</b> member table differences identified between "
10409 <<
"<b>'" << groupName <<
"(" << groupKey
10410 <<
")'</b> and group "
10411 <<
"<b>'" << diffGroupName <<
"(" << diffKey <<
")'</b>."
10415 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
10416 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
10418 catch(
const std::runtime_error& e)
10420 __SUP_COUT_ERR__ <<
"Caught error while differencing group " << groupName <<
"("
10421 << groupKey <<
") with group " << diffGroupName <<
"(" << diffKey
10422 <<
")" << __E__ << e.what() << __E__;
10429 void ConfigurationGUISupervisor::handleTableDiff(
HttpXmlDocument& xmlOut,
10431 const std::string& tableName,
10435 __SUP_COUT__ <<
"Differencing tableName " << tableName <<
" v" << vA <<
" with v"
10445 std::string localAccumulatedErrors =
"";
10449 &localAccumulatedErrors,
10452 if(localAccumulatedErrors !=
"")
10453 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
10455 catch(std::runtime_error& e)
10457 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vA;
10458 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
10459 __SUP_COUT_ERR__ <<
"\n" << ss.str();
10461 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
10465 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vA << __E__;
10470 catch(
const std::exception& e)
10472 ss <<
"Exception message: " << e.what();
10478 __SUP_COUT_ERR__ <<
"\n" << ss.str();
10479 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
10485 std::string localAccumulatedErrors =
"";
10489 &localAccumulatedErrors,
10492 if(localAccumulatedErrors !=
"")
10493 xmlOut.addTextElementToData(
"Error", localAccumulatedErrors);
10495 catch(std::runtime_error& e)
10497 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version " << vB;
10498 ss <<
"\n\n...Here is why it failed:\n\n" << e.what() << __E__;
10499 __SUP_COUT_ERR__ <<
"\n" << ss.str();
10501 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
10505 __SUP_SS__ <<
"Failed to get table " << tableName <<
" version: " << vB << __E__;
10510 catch(
const std::exception& e)
10512 ss <<
"Exception message: " << e.what();
10518 __SUP_COUT_ERR__ <<
"\n" << ss.str();
10519 xmlOut.addTextElementToData(
"Error",
"Error getting view! " + ss.str());
10522 bool noDifference =
true;
10523 std::stringstream diffReport;
10525 diffReport <<
"This difference report is between table " << tableName <<
" v" << vA
10526 <<
" and v" << vB <<
"</b>." << __E__;
10528 diffReport <<
"<INDENT>";
10529 diffReport <<
"<ul>";
10530 std::map<std::string , std::vector<std::string >>
10532 if(!table->diffTwoVersions(vA, vB, &diffReport))
10533 noDifference =
false;
10534 diffReport <<
"</ul></INDENT>";
10536 xmlOut.addTextElementToData(
"NoDifference", noDifference ?
"1" :
"0");
10537 xmlOut.addTextElementToData(
"DiffReport", diffReport.str());
10543 void ConfigurationGUISupervisor::testXDAQContext()
10547 __COUT_INFO__ <<
"Hello0!";
10549 __COUT_INFO__ <<
"Hello1!";
10551 __COUT_INFO__ <<
"Hello2!";
10553 __COUT_INFO__ <<
"Hello3!";
10559 __SUP_COUT_INFO__ <<
"Attempting test activation of the context group." << __E__;
10563 catch(
const std::runtime_error& e)
10566 <<
"The test activation of the context group failed. Ignoring error: \n"
10567 << e.what() << __E__;
10572 __SUP_COUT_WARN__ <<
"The test activation of the context group failed. Ignoring."
10577 __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, bool suppressMultiNode=false)
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
static std::string getData(cgicc::Cgicc &cgi, const std::string &needle)
virtual void forceSupervisorPropertyValues(void) override
override to force supervisor property values (and ignore user settings)
virtual void setSupervisorPropertyDefaults(void) override
ConfigurationGUISupervisor(xdaq::ApplicationStub *s)
static xdaq::Application * instantiate(xdaq::ApplicationStub *s)
TableVersion saveNewTable(const std::string &tableName, TableVersion temporaryVersion=TableVersion(), bool makeTemporary=false)
void testXDAQContext(void)
const GroupInfo & getGroupInfo(const std::string &groupName, bool attemptToReloadKeys=false)
void clearAllCachedVersions(void)
const std::map< std::string, TableInfo > & getAllTableInfo(bool refresh=false, std::string *accumulatedWarnings=0, const std::string &errorFilterName="", bool getGroupKeys=false, bool getGroupInfo=false, bool initializeActiveGroups=false)
void loadTableGroup(const std::string &tableGroupName, const TableGroupKey &tableGroupKey, bool doActivate=false, std::map< std::string, TableVersion > *groupMembers=0, ProgressBar *progressBar=0, std::string *accumulateWarnings=0, std::string *groupComment=0, std::string *groupAuthor=0, std::string *groupCreateTime=0, bool doNotLoadMember=false, std::string *groupTypeString=0, std::map< std::string, std::string > *groupAliases=0, ConfigurationManager::LoadGroupType groupTypeToLoad=ConfigurationManager::LoadGroupType::ALL_TYPES, bool ignoreVersionTracking=false)
TableVersion copyViewToCurrentColumns(const std::string &tableName, TableVersion sourceVersion)
TableGroupKey saveNewTableGroup(const std::string &groupName, std::map< std::string, TableVersion > &groupMembers, const std::string &groupComment=TableViewColumnInfo::DATATYPE_COMMENT_DEFAULT, std::map< std::string, std::string > *groupAliases=0)
void activateTableGroup(const std::string &tableGroupName, TableGroupKey tableGroupKey, std::string *accumulatedTreeErrors=0, std::string *groupTypeString=0)
void clearCachedVersions(const std::string &tableName)
const std::string & getUsername(void) const
std::map< std::string, std::map< std::string, TableVersion > > getVersionAliases(void) const
void eraseTemporaryVersion(const std::string &tableName, TableVersion targetVersion=TableVersion())
void preloadVersionCreationTimes(void)
static void loadTableGroupThread(ConfigurationManagerRW *cfgMgr, std::string groupName, ots::TableGroupKey groupKey, std::shared_ptr< ots::GroupInfo > theGroupInfo, std::shared_ptr< std::atomic< bool >> theThreadDone)
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
TableBase * getVersionedTableByName(const std::string &tableName, TableVersion version, bool looseColumnMatching=false, std::string *accumulatedErrors=0, bool getRawData=false, bool touchLastAccessTime=true)
void init(std::string *accumulatedErrors=0, bool initForWriteAccess=false, std::string *accumulatedWarnings=0)
static const std::string & getTypeNameOfGroup(const std::map< std::string, TableVersion > &memberMap)
void destroyTableGroup(const std::string &theGroup="", bool onlyDeactivate=false)
std::vector< std::pair< std::string, ConfigurationTree > > getChildren(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, TableVersion > *memberMap=0, std::string *accumulatedTreeErrors=0) const
static std::vector< std::map< std::string, std::string > > loadGroupHistory(const std::string &groupAction, const std::string &groupType, bool formatTime=false)
TableGroupKey loadConfigurationBackbone(void)
const TableBase * getTableByName(const std::string &configurationName) const
static std::pair< std::string, TableGroupKey > loadGroupNameAndKey(const std::string &fileName, std::string &returnedTimeString)
static void getConfigurationStatusXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &username)
static void handleGetTableGroupXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &groupName, TableGroupKey groupKey, bool ignoreWarnings=false, bool cacheOnly=false)
static TableVersion saveModifiedVersionXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &tableName, TableVersion originalVersion, bool makeTemporary, TableBase *config, TableVersion temporaryModifiedVersion, bool ignoreDuplicates=false, bool lookForEquivalent=false)
static void handleCreateTableXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &tableName, TableVersion version, bool makeTemporary, const std::string &data, const int &dataOffset, const std::string &author, const std::string &comment, bool sourceTableAsIs, bool lookForEquivalent)
static void handleCreateTableGroupXML(HttpXmlDocument &xmlOut, ConfigurationManagerRW *cfgMgr, const std::string &groupName, const std::string &configList, bool allowDuplicates=false, bool ignoreWarnings=false, const std::string &groupComment="", bool lookForEquivalent=false)
bool isUIDNode(void) const
const TableVersion & getTableVersion(void) const
bool isDisconnected(void) const
const std::string & getAuthor(void) const
const std::string & getComment(void) const
std::vector< std::string > getChildrenNames(bool byPriority=false, bool onlyStatusTrue=false) const
bool isEnabled(void) const
const std::string & getTableName(void) const
const unsigned int & getFieldRow(void) const
std::map< std::string, ConfigurationTree > getChildrenMap(std::map< std::string, std::string > filterMap=std::map< std::string, std::string >(), bool onlyStatusTrue=false) const
const std::string & getValueName(void) const
const std::string & getValueAsString(bool returnLinkTableValue=false) const
const std::string & getChildLinkIndex(void) const
void getValue(T &value) 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
static std::string convertToCaps(std::string &str, bool isConfigName=false)
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="")
std::string toString(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)
bool isChildLink(void) const
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="")
void extractContexts(ConfigurationManager *configManager)
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, bool forHtml=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)